Compare commits

..

2 Commits

Author SHA1 Message Date
mcsauder db0f4ecc48 Disable multicopter attitude autotuner for fmu-v5 test build. 2023-06-07 15:24:05 -06:00
mcsauder f9a13aa82f Format/group/organize/alphabetize methods and variables in Commander.cpp/hpp, format GeofenceResult.msg
Scope VEHICLE_MODE_FLAG to the Commander class.
2023-06-07 15:23:21 -06:00
1527 changed files with 34606 additions and 77262 deletions
+5 -12
View File
@@ -9,7 +9,7 @@ pipeline {
script {
def build_nodes = [:]
def docker_images = [
armhf: "px4io/px4-dev-armhf:2023-06-26",
armhf: "px4io/px4-dev-armhf:2022-08-12",
arm64: "px4io/px4-dev-aarch64:2022-08-12",
base: "px4io/px4-dev-ros2-foxy:2022-08-12",
nuttx: "px4io/px4-dev-nuttx-focal:2022-08-12",
@@ -40,8 +40,6 @@ pipeline {
"ark_can-flow_default",
"ark_can-gps_canbootloader",
"ark_can-gps_default",
"ark_cannode_canbootloader",
"ark_cannode_default",
"ark_can-rtk-gps_canbootloader",
"ark_can-rtk-gps_default",
"ark_fmu-v6x_bootloader",
@@ -55,10 +53,8 @@ pipeline {
"cuav_nora_default",
"cuav_x7pro_default",
"cubepilot_cubeorange_default",
"cubepilot_cubeorangeplus_default",
"cubepilot_cubeyellow_default",
"diatone_mamba-f405-mk2_default",
"flywoo_gn-f405_default",
"freefly_can-rtk-gps_canbootloader",
"freefly_can-rtk-gps_default",
"holybro_can-gps-v1_canbootloader",
@@ -76,7 +72,7 @@ pipeline {
"matek_h743_default",
"modalai_fc-v1_default",
"modalai_fc-v2_default",
"mro_ctrl-zero-classic_default",
"modalai_voxl2-io_default",
"mro_ctrl-zero-f7_default",
"mro_ctrl-zero-f7-oem_default",
"mro_ctrl-zero-h7-oem_default",
@@ -88,7 +84,7 @@ pipeline {
"nxp_fmuk66-e_socketcan",
"nxp_fmuk66-v3_default",
"nxp_fmuk66-v3_socketcan",
"nxp_mr-canhubk3_default",
"nxp_fmurt1062-v1_default",
"nxp_ucans32k146_canbootloader",
"nxp_ucans32k146_default",
"omnibus_f4sd_default",
@@ -110,16 +106,13 @@ pipeline {
"px4_fmu-v6c_default",
"px4_fmu-v6u_default",
"px4_fmu-v6x_default",
"px4_fmu-v6xrt_bootloader",
"px4_fmu-v6xrt_default",
"px4_io-v2_default",
"raspberrypi_pico_default",
"sky-drones_smartap-airlink_default",
"spracing_h7extreme_default",
"thepeach_k1_default",
"thepeach_r1_default",
"uvify_core_default",
"siyi_n7_default"
"uvify_core_default"
],
image: docker_images.nuttx,
archive: true
@@ -171,7 +164,7 @@ pipeline {
}
options {
buildDiscarder(logRotator(numToKeepStr: '5', artifactDaysToKeepStr: '14'))
timeout(time: 120, unit: 'MINUTES')
timeout(time: 90, unit: 'MINUTES')
}
}
+10 -10
View File
@@ -12,7 +12,7 @@ pipeline {
stage("build cubepilot_cubeorange_test") {
agent {
docker {
image 'px4io/px4-dev-nuttx-focal:2022-08-12'
image 'px4io/px4-dev-nuttx-focal:2021-09-08'
args '--cpu-shares 512 -e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
@@ -91,7 +91,7 @@ pipeline {
stage("build cuav_x7pro_test") {
agent {
docker {
image 'px4io/px4-dev-nuttx-focal:2022-08-12'
image 'px4io/px4-dev-nuttx-focal:2021-09-08'
args '--cpu-shares 512 -e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
@@ -165,7 +165,7 @@ pipeline {
stage("build px4_fmu-v4_test") {
agent {
docker {
image 'px4io/px4-dev-nuttx-focal:2022-08-12'
image 'px4io/px4-dev-nuttx-focal:2021-09-08'
args '--cpu-shares 512 -e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
@@ -238,7 +238,7 @@ pipeline {
stage("build px4_fmu-v4pro_test") {
agent {
docker {
image 'px4io/px4-dev-nuttx-focal:2022-08-12'
image 'px4io/px4-dev-nuttx-focal:2021-09-08'
args '--cpu-shares 512 -e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
@@ -312,7 +312,7 @@ pipeline {
stage("build px4_fmu-v5_debug") {
agent {
docker {
image 'px4io/px4-dev-nuttx-focal:2022-08-12'
image 'px4io/px4-dev-nuttx-focal:2021-09-08'
args '--cpu-shares 512 -e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
@@ -362,7 +362,7 @@ pipeline {
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-*` --cmd "sd_stress"'
// test dataman
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-*` --cmd "tests dataman" --ignore-stdout-errors'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-*` --cmd "tests dataman"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-*` --cmd "tests file" || true'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-*` --cmd "uorb_tests"'
@@ -403,7 +403,7 @@ pipeline {
stage("build px4_fmu-v5_stackcheck") {
agent {
docker {
image 'px4io/px4-dev-nuttx-focal:2022-08-12'
image 'px4io/px4-dev-nuttx-focal:2021-09-08'
args '--cpu-shares 512 -e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
@@ -449,7 +449,7 @@ pipeline {
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-*` --cmd "uorb_tests latency_test" || true'
// test dataman
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-*` --cmd "tests dataman" --ignore-stdout-errors'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-*` --cmd "tests dataman"'
}
}
stage("status") {
@@ -486,7 +486,7 @@ pipeline {
stage("build px4_fmu-v5_test") {
agent {
docker {
image 'px4io/px4-dev-nuttx-focal:2022-08-12'
image 'px4io/px4-dev-nuttx-focal:2021-09-08'
args '--cpu-shares 512 -e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
@@ -560,7 +560,7 @@ pipeline {
stage("build nxp_fmuk66-v3_test") {
agent {
docker {
image 'px4io/px4-dev-nuttx-focal:2022-08-12'
image 'px4io/px4-dev-nuttx-focal:2021-09-08'
args '--cpu-shares 512 -e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
+2 -3
View File
@@ -2,7 +2,7 @@
// https://github.com/microsoft/vscode-dev-containers/tree/v0.134.0/containers/cpp
{
"name": "px4-dev-nuttx",
"image": "px4io/px4-dev-nuttx-focal:2022-08-12",
"image": "px4io/px4-dev-nuttx-focal:2021-09-08",
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ],
@@ -29,8 +29,7 @@
"twxs.cmake",
"uavcan.dsdl",
"wholroyd.jinja",
"zixuanwang.linkerscript",
"ms-vscode.makefile-tools"
"zixuanwang.linkerscript"
],
"containerUser": "user",
+34
View File
@@ -0,0 +1,34 @@
---
name: 🐛 Bug report
about: Create a report to help us improve
labels: bug-report
---
## Describe the bug
A clear and concise description of the bug.
## To Reproduce
Steps to reproduce the behavior:
1. Drone switched on '...'
2. Uploaded mission '....' (attach QGC mission file)
3. Took off '....'
4. See error
## Expected behavior
A clear and concise description of what you expected to happen.
## Log Files and Screenshots
*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)
Add screenshots to help explain your problem.
## Drone (please complete the following information):
- Describe the type of drone.
- Photo of the IMU / autopilot setup if possible.
## Additional context
Add any other context about the problem here.
@@ -0,0 +1,20 @@
---
name: 🚀 Feature Request
about: Suggest an idea for this project
labels: feature-request
---
For general questions please use [PX4 Discuss](http://discuss.px4.io/) or Discord (you can find an invite link on this project README).
## Describe problem solved by the proposed feature
A clear and concise description of the problem, if any, this feature will solve. E.g. I'm always frustrated when ...
## Describe your preferred solution
A clear and concise description of what you want to happen.
## Describe possible alternatives
A clear and concise description of alternative solutions or features you've considered.
## Additional context
Add any other context or screenshots for the feature request here.
@@ -0,0 +1,13 @@
---
name: ⛔ Support Question
about: See http://discuss.px4.io/ for questions about using PX4.
---
## Attention! Please read the note below
We use GitHub issues only to discuss PX4 bugs and new features.
**For questions about using PX4 or related components, please use [PX4 Discuss](http://discuss.px4.io/).**
Thanks!
@@ -0,0 +1,11 @@
---
name: ⛔ Documentation Issue
about: See https://github.com/PX4/px4_user_guide for documentation issues
---
## Attention! Please read the note below
**Please submit the documentation issue to the [User Guide](https://github.com/PX4/px4_user_guide) repository.**
Thanks!
-94
View File
@@ -1,94 +0,0 @@
name: 🐛 Bug report
description: Create a report to help us improve
title: "[Bug] "
labels: ["bug-report"]
body:
- type: textarea
attributes:
label: Describe the bug
description: A clear and concise description of the bug.
validations:
required: true
- type: textarea
attributes:
label: To Reproduce
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: true
- type: textarea
attributes:
label: Expected behavior
description: A clear and concise description of what you expected to happen.
validations:
required: true
- 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)
placeholder: |
# PASTE HERE THE LINK TO THE LOG
validations:
required: true
- 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: true
- type: input
attributes:
label: Flight controller
description: Specify your flight controller model (what type is it, where was it bought from, ...).
validations:
required: true
- 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.
-8
View File
@@ -1,8 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: Support Question
url: https://docs.px4.io/main/en/contribute/support.html#forums-and-chat
about: For questions about using PX4 or related components, please use the discuss forum and discord server
- name: Documentation Issue
url: https://github.com/PX4/PX4-user_guide/issues
about: If you found an issue in documentation, please submit it directly to the docs repository issues
@@ -1,35 +0,0 @@
name: 🚀 Feature Request
description: Suggest an idea for this project
labels: ["feature-request"]
body:
- type: markdown
attributes:
value: |
## Please note that feature requests are not 'fire and forget'
It is a lot more likely that the feature you would like to have will be implemented if you keep watching your feature request, and provide more details to developers looking into implementing your feature, and help them with testing.
- type: textarea
attributes:
label: Describe problem solved by the proposed feature
description: A clear and concise description of the problem, if any, this feature will solve. E.g. I'm always frustrated when ...
validations:
required: true
- type: textarea
attributes:
label: Describe your preferred solution
description: A clear and concise description of what you want to happen.
validations:
required: true
- type: textarea
attributes:
label: Describe possible alternatives
description: A clear and concise description of any alternative solutions or features you've considered.
validations:
required: true
- type: textarea
attributes:
label: Additional context
description: Add any other context or screenshots for the feature request here.
+24
View File
@@ -0,0 +1,24 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="90" height="20">
<linearGradient id="smooth" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<mask id="round">
<rect width="90" height="20" rx="3" fill="#fff"/>
</mask>
<g mask="url(#round)">
<rect width="42" height="20" fill="#555"/>
<rect x="42" width="48" height="20" fill="#E01563"/>
<rect width="90" height="20" fill="url(#smooth)"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="22" y="15" fill="#010101" fill-opacity=".3">slack</text>
<text x="22" y="14">slack</text>
<text x="65" y="15" fill="#010101" fill-opacity=".3">Join us!</text>
<text x="65" y="14">Join us!</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 894 B

+15
View File
@@ -0,0 +1,15 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 90
# Number of days of inactivity before a stale issue is closed, or `false` to disable
daysUntilClose: false
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. Thank you for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
+1 -1
View File
@@ -28,7 +28,7 @@ jobs:
"parameters_metadata",
]
container:
image: px4io/px4-dev-nuttx-focal:2022-08-12
image: px4io/px4-dev-nuttx-focal:2021-09-08
options: --privileged --ulimit core=-1 --security-opt seccomp=unconfined
steps:
- uses: actions/checkout@v1
+3 -7
View File
@@ -1,12 +1,9 @@
name: Compile Linux Targets
name: Linux Targets
on:
push:
branches:
- 'main'
- 'stable'
- 'beta'
- 'release/*'
pull_request:
branches:
- '*'
@@ -14,7 +11,7 @@ on:
jobs:
build:
runs-on: ubuntu-latest
container: px4io/px4-dev-armhf:2023-06-26
container: px4io/px4-dev-armhf:2021-09-08
strategy:
matrix:
config: [
@@ -27,8 +24,7 @@ jobs:
- uses: actions/checkout@v1
with:
token: ${{secrets.ACCESS_TOKEN}}
- name: ownership workaround
run: git config --system --add safe.directory '*'
- name: Prepare ccache timestamp
id: ccache_cache_timestamp
shell: cmake -P {0}
+2 -5
View File
@@ -1,12 +1,9 @@
name: Compile Linux ARM64 Targets
name: Linux ARM64 Targets
on:
push:
branches:
- 'main'
- 'stable'
- 'beta'
- 'release/*'
pull_request:
branches:
- '*'
@@ -14,7 +11,7 @@ on:
jobs:
build:
runs-on: ubuntu-latest
container: px4io/px4-dev-aarch64:2022-08-12
container: px4io/px4-dev-aarch64:2021-09-08
strategy:
matrix:
config: [
+2 -6
View File
@@ -10,19 +10,15 @@ on:
jobs:
build:
runs-on: macos-latest
runs-on: macos-10.15
strategy:
matrix:
config: [
px4_fmu-v5_default,
px4_sitl
#tests, # includes px4_sitl
]
steps:
- name: install Python 3.10
uses: actions/setup-python@v4
with:
python-version: "3.10"
- uses: actions/checkout@v1
with:
token: ${{secrets.ACCESS_TOKEN}}
+4 -8
View File
@@ -1,12 +1,9 @@
name: Compile Nuttx Targets
name: Nuttx Targets
on:
push:
branches:
- 'main'
- 'stable'
- 'beta'
- 'release/*'
pull_request:
branches:
- '*'
@@ -14,7 +11,7 @@ on:
jobs:
build:
runs-on: ubuntu-latest
container: px4io/px4-dev-nuttx-focal:2022-08-12
container: px4io/px4-dev-nuttx-focal:2021-09-08
strategy:
fail-fast: false
matrix:
@@ -57,6 +54,7 @@ jobs:
mro_x21-777,
nxp_fmuk66-e,
nxp_fmuk66-v3,
nxp_fmurt1062-v1,
nxp_mr-canhubk3,
nxp_ucans32k146,
omnibus_f4sd,
@@ -69,12 +67,10 @@ jobs:
px4_fmu-v6c,
px4_fmu-v6u,
px4_fmu-v6x,
px4_fmu-v6xrt,
raspberrypi_pico,
sky-drones_smartap-airlink,
spracing_h7extreme,
uvify_core,
siyi_n7
uvify_core
]
steps:
- uses: actions/checkout@v1
+1 -4
View File
@@ -24,15 +24,12 @@ jobs:
needs: enumerate_targets
strategy:
matrix: ${{fromJson(needs.enumerate_targets.outputs.matrix)}}
container: ${{ matrix.container }}
container: px4io/px4-dev-${{ matrix.container }}:2021-09-08
steps:
- uses: actions/checkout@v1
with:
token: ${{secrets.ACCESS_TOKEN}}
- name: ownership workaround
run: git config --system --add safe.directory '*'
- name: make ${{matrix.target}}
run: make ${{matrix.target}}
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
"failsafe_web",
]
container:
image: px4io/px4-dev-nuttx-focal:2022-08-12
image: px4io/px4-dev-nuttx-focal:2021-09-08
options: --privileged --ulimit core=-1 --security-opt seccomp=unconfined
steps:
- uses: actions/checkout@v1
+1 -3
View File
@@ -103,7 +103,7 @@ jobs:
uorb_graph:
runs-on: ubuntu-latest
container: px4io/px4-dev-nuttx-focal:2022-08-12
container: px4io/px4-dev-nuttx-focal:2021-09-08
steps:
- uses: actions/checkout@v1
with:
@@ -128,6 +128,4 @@ jobs:
run: |
git clone https://github.com/PX4/px4_msgs.git
rm px4_msgs/msg/*.msg
rm px4_msgs/srv/*.srv
cp msg/*.msg px4_msgs/msg/
cp srv/*.srv px4_msgs/srv/
-32
View File
@@ -1,32 +0,0 @@
name: Nuttx Target with extra env config
on:
push:
branches:
- 'main'
pull_request:
branches:
- '*'
jobs:
build:
runs-on: ubuntu-latest
container: px4io/px4-dev-nuttx-focal:2022-08-12
strategy:
matrix:
config: [
px4_fmu-v5,
]
steps:
- uses: actions/checkout@v1
with:
token: ${{secrets.ACCESS_TOKEN}}
- name: make ${{matrix.config}}
env:
PX4_EXTRA_NUTTX_CONFIG: "CONFIG_NSH_LOGIN_PASSWORD=\"test\";CONFIG_NSH_CONSOLE_LOGIN=y"
run: |
echo "PX4_EXTRA_NUTTX_CONFIG: $PX4_EXTRA_NUTTX_CONFIG"
make ${{matrix.config}} nuttx_context
# Check that the config option is set
grep CONFIG_NSH_LOGIN_PASSWORD build/${{matrix.config}}_default/NuttX/nuttx/.config
+11 -7
View File
@@ -1,4 +1,4 @@
name: 'Handle stale issues and PRs'
name: 'Close stale issues and PRs'
on:
schedule:
- cron: '30 1 * * *'
@@ -7,10 +7,14 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v8
- uses: actions/stale@v4.1.1
with:
days-before-stale: 30
days-before-close: -1
stale-issue-label: 'stale'
stale-pr-label: 'stale'
remove-stale-when-updated: true
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.'
stale-pr-message: 'This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 10 days.'
close-issue-message: 'This issue was closed because it has been stalled for 5 days with no activity.'
close-pr-message: 'This PR was closed because it has been stalled for 10 days with no activity.'
days-before-issue-stale: 30
days-before-pr-stale: 45
days-before-issue-close: 5
days-before-pr-close: 10
debug-only: true
-14
View File
@@ -62,17 +62,3 @@
path = src/modules/uxrce_dds_client/Micro-XRCE-DDS-Client
url = https://github.com/PX4/Micro-XRCE-DDS-Client.git
branch = px4
[submodule "src/lib/cdrstream/cyclonedds"]
path = src/lib/cdrstream/cyclonedds
url = https://github.com/px4/cyclonedds
[submodule "src/lib/cdrstream/rosidl"]
path = src/lib/cdrstream/rosidl
url = https://github.com/px4/rosidl
[submodule "src/modules/zenoh/zenoh-pico"]
path = src/modules/zenoh/zenoh-pico
url = https://github.com/px4/zenoh-pico
branch = pr-zubf-werror-fix
[submodule "src/lib/heatshrink/heatshrink"]
path = src/lib/heatshrink/heatshrink
url = https://github.com/PX4/heatshrink.git
branch = px4
-15
View File
@@ -81,16 +81,6 @@ CONFIG:
buildType: MinSizeRel
settings:
CONFIG: px4_fmu-v6x_bootloader
px4_fmu-v6xrt_default:
short: px4_fmu-v6xrt
buildType: MinSizeRel
settings:
CONFIG: px4_fmu-v6xrt_default
px4_fmu-v6xrt_bootloader:
short: px4_fmu-v6xrt_bootloader
buildType: MinSizeRel
settings:
CONFIG: px4_fmu-v6xrt_bootloader
airmind_mindpx-v2_default:
short: airmind_mindpx-v2
buildType: MinSizeRel
@@ -191,11 +181,6 @@ CONFIG:
buildType: MinSizeRel
settings:
CONFIG: cubepilot_cubeorange_test
cubepilot_cubeorangeplus_test:
short: cubepilot_cubeorangeplus
buildType: MinSizeRel
settings:
CONFIG: cubepilot_cubeorangeplus_test
emlid_navio2_default:
short: emlid_navio2
buildType: MinSizeRel
+1 -2
View File
@@ -18,7 +18,6 @@
"twxs.cmake",
"uavcan.dsdl",
"wholroyd.jinja",
"zixuanwang.linkerscript",
"ms-vscode.makefile-tools"
"zixuanwang.linkerscript"
]
}
+1 -2
View File
@@ -127,6 +127,5 @@
"terminal.integrated.scrollback": 15000,
"yaml.schemas": {
"${workspaceFolder}/validation/module_schema.yaml": "${workspaceFolder}/src/modules/*/module.yaml"
},
"ros.distro": "humble"
}
}
-5
View File
@@ -414,8 +414,6 @@ endif()
#
add_library(parameters_interface INTERFACE)
add_library(kernel_parameters_interface INTERFACE)
add_library(events_interface INTERFACE)
add_library(kernel_events_interface INTERFACE)
include(px4_add_library)
add_subdirectory(src/lib EXCLUDE_FROM_ALL)
@@ -442,11 +440,8 @@ add_subdirectory(src/lib/parameters EXCLUDE_FROM_ALL)
if(${PX4_PLATFORM} STREQUAL "nuttx" AND NOT CONFIG_BUILD_FLAT)
target_link_libraries(parameters_interface INTERFACE usr_parameters)
target_link_libraries(kernel_parameters_interface INTERFACE parameters)
target_link_libraries(events_interface INTERFACE usr_events)
target_link_libraries(kernel_events_interface INTERFACE events)
else()
target_link_libraries(parameters_interface INTERFACE parameters)
target_link_libraries(events_interface INTERFACE events)
endif()
# firmware added last to generate the builtin for included modules
Vendored
+2 -5
View File
@@ -94,7 +94,7 @@ pipeline {
stage('failsafe docs') {
agent {
docker { image 'px4io/px4-dev-nuttx-focal:2022-08-12' }
docker { image 'px4io/px4-dev-nuttx-focal:2021-08-18' }
}
steps {
sh '''#!/bin/bash -l
@@ -105,7 +105,6 @@ pipeline {
./emsdk activate latest;
cd ..;
. ./_emscripten_sdk/emsdk_env.sh;
git fetch --all --tags;
make failsafe_web;
cd build/px4_sitl_default_failsafe_web;
mkdir -p failsafe_sim;
@@ -126,7 +125,7 @@ pipeline {
stage('uORB graphs') {
agent {
docker {
image 'px4io/px4-dev-nuttx-focal:2022-08-12'
image 'px4io/px4-dev-nuttx-focal:2021-08-18'
args '-e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
@@ -231,9 +230,7 @@ pipeline {
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/srv/*.srv')
sh('cp msg/*.msg px4_msgs/msg/')
sh('cp srv/*.srv px4_msgs/srv/')
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')
-2
View File
@@ -205,5 +205,3 @@ menu "platforms"
depends on PLATFORM_QURT || PLATFORM_POSIX
source "platforms/common/Kconfig"
endmenu
source "src/lib/*/Kconfig"
+1 -2
View File
@@ -266,6 +266,7 @@ px4fmu_firmware: \
misc_qgc_extra_firmware: \
check_nxp_fmuk66-v3_default \
check_nxp_fmurt1062-v1_default \
check_mro_x21_default \
check_bitcraze_crazyflie_default \
check_bitcraze_crazyflie21_default \
@@ -483,9 +484,7 @@ validate_module_configs:
@find "$(SRC_DIR)"/src/modules "$(SRC_DIR)"/src/drivers "$(SRC_DIR)"/src/lib -name *.yaml -type f \
-not -path "$(SRC_DIR)/src/lib/mixer_module/*" \
-not -path "$(SRC_DIR)/src/modules/uxrce_dds_client/dds_topics.yaml" \
-not -path "$(SRC_DIR)/src/modules/zenoh/zenoh-pico/*" \
-not -path "$(SRC_DIR)/src/lib/events/libevents/*" \
-not -path "$(SRC_DIR)/src/lib/cdrstream/*" \
-not -path "$(SRC_DIR)/src/lib/crypto/libtommath/*" -print0 | \
xargs -0 "$(SRC_DIR)"/Tools/validate_yaml.py --schema-file "$(SRC_DIR)"/validation/module_schema.yaml
+1 -1
View File
@@ -114,7 +114,7 @@ These boards are maintained to be compatible with PX4-Autopilot by the Manufactu
### Community supported
These boards don't fully comply industry standards, and thus is solely maintained by the PX4 public community members.
These boards don't fully comply industry standards, and thus is solely maintained by the PX4 publc community members.
### Experimental
@@ -31,7 +31,6 @@ param set-default PWM_MAIN_FUNC4 104
# EKF2
param set-default EKF2_GPS_CTRL 0
param set-default EKF2_HGT_REF 0
param set-default EKF2_EVP_NOISE 0.05
param set-default EKF2_EVA_NOISE 0.05
param set-default EKF2_OF_CTRL 1
@@ -40,9 +39,6 @@ param set-default EKF2_OF_CTRL 1
param set-default LPE_FUSION 242
param set-default LPE_FAKE_ORIGIN 1
# Commander
# param set-default COM_HOME_EN 0 # Disable setting of home position
param set-default MPC_ALT_MODE 2
param set-default SENS_FLOW_ROT 6
@@ -1,8 +0,0 @@
#!/bin/sh
#
# @name 3DR Iris Quadrotor with a depth camera (forward-facing)
#
# @type Quadrotor Wide
#
. ${R}etc/init.d-posix/airframes/10015_gazebo-classic_iris
@@ -1,8 +0,0 @@
#!/bin/sh
#
# @name 3DR Iris Quadrotor with a depth camera (downward-facing)
#
# @type Quadrotor Wide
#
. ${R}etc/init.d-posix/airframes/10015_gazebo-classic_iris
@@ -7,7 +7,6 @@
param set-default FW_LAUN_DETCN_ON 1
param set-default FW_THR_IDLE 0.1 # needs to be running before throw as that's how gazebo detects arming
param set-default FW_LAUN_AC_THLD 10
param set-default FW_LND_ANG 8
@@ -8,6 +8,7 @@
param set-default FW_LND_ANG 8
param set-default FW_THR_LND_MAX 0
param set-default NPFG_PERIOD 12
@@ -35,6 +36,7 @@ param set-default NAV_DLL_ACT 2
param set-default RWTO_TKOFF 1
#param set-default SYS_CTRL_ALLOC 1
param set-default CA_AIRFRAME 1
param set-default CA_ROTOR_COUNT 1
@@ -59,3 +61,7 @@ param set-default PWM_MAIN_FUNC7 202
param set-default PWM_MAIN_FUNC8 203
param set-default PWM_MAIN_FUNC9 206
param set-default PWM_MAIN_REV 256
set MIXER_FILE etc/mixers-sitl/plane_sitl.main.mix
set MIXER custom
@@ -47,8 +47,6 @@ param set-default PWM_MAIN_FUNC6 201
param set-default PWM_MAIN_FUNC7 202
param set-default PWM_MAIN_FUNC8 203
param set-default FW_AIRSPD_MAX 25
param set-default FW_THR_ASPD_MAX 0.4
param set-default NPFG_PERIOD 12
param set-default FW_PR_FF 0.2
param set-default FW_PR_P 0.9
@@ -64,18 +62,19 @@ param set-default FW_T_SINK_MAX 2.7
param set-default FW_T_SINK_MIN 2.2
param set-default MC_AIRMODE 1
param set-default MC_ROLL_P 4
param set-default MC_ROLLRATE_P 0.3
param set-default MC_YAW_P 1.6
param set-default MC_YAWRATE_P 0.3
param set-default MIS_TAKEOFF_ALT 10
param set-default MPC_XY_P 0.8
param set-default MPC_XY_VEL_P_ACC 3
param set-default MPC_XY_VEL_I_ACC 4
param set-default MPC_XY_VEL_D_ACC 0.1
param set-default NAV_ACC_RAD 5
param set-default VT_FWD_THRUST_EN 4
param set-default VT_FWD_THRUST_SC 1
param set-default VT_F_TRANS_THR 0.75
param set-default VT_TYPE 2
@@ -76,7 +76,7 @@ param set-default CA_SV_CS1_TRQ_R 0.5
param set-default CA_SV_CS2_TYPE 3
param set-default CA_SV_CS2_TRQ_P 1.0
param set-default NPFG_PERIOD 12
param set-default FW_L1_PERIOD 12
param set-default FW_PR_FF 0.2
param set-default FW_PR_P 0.9
param set-default FW_PSP_OFF 2
@@ -52,8 +52,12 @@ param set-default MAV_1_MODE 9
# param set-default SER_TEL1_BAUD 921600 Not found
# Vehicle attitude PID tuning
param set-default MC_ACRO_EXPO 0
param set-default MC_ACRO_EXPO_Y 0
param set-default MC_ACRO_P_MAX 200
param set-default MC_ACRO_R_MAX 200
param set-default MC_ACRO_SUPEXPO 0
param set-default MC_ACRO_SUPEXPOY 0
param set-default MC_ACRO_Y_MAX 150
param set-default MC_PITCHRATE_D 0.0015
param set-default MC_ROLLRATE_D 0.0015
@@ -1,82 +0,0 @@
#!/bin/sh
#
# @name Advanced Plane SITL
#
. ${R}etc/init.d/rc.fw_defaults
PX4_SIMULATOR=${PX4_SIMULATOR:=gz}
PX4_GZ_WORLD=${PX4_GZ_WORLD:=default}
PX4_SIM_MODEL=${PX4_SIM_MODEL:=advanced_plane}
param set-default SIM_GZ_EN 1
param set-default SENS_EN_GPSSIM 1
param set-default SENS_EN_MAGSIM 1
param set-default SENS_EN_ARSPDSIM 1
param set-default FW_LND_ANG 8
param set-default NPFG_PERIOD 12
param set-default FW_MAN_P_MAX 30
param set-default FW_PR_P 0.9
param set-default FW_PR_FF 0.5
param set-default FW_PR_I 0.5
param set-default FW_PSP_OFF 2
param set-default FW_P_LIM_MAX 32
param set-default FW_P_LIM_MIN -15
param set-default FW_RR_FF 0.5
param set-default FW_RR_P 0.3
param set-default FW_RR_I 0.5
param set-default FW_YR_FF 0.5
param set-default FW_YR_P 0.6
param set-default FW_YR_I 0.5
param set-default FW_SPOILERS_LND 0.4
param set-default FW_THR_MIN 0.05
param set-default FW_THR_TRIM 0.25
param set-default FW_T_CLMB_MAX 8
param set-default FW_T_SINK_MAX 2.7
param set-default FW_T_SINK_MIN 2.2
param set-default FW_W_EN 1
param set-default MIS_TAKEOFF_ALT 30
param set-default NAV_ACC_RAD 15
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
param set-default CA_SV_CS_COUNT 6
param set-default CA_SV_CS0_TRQ_R -0.5
param set-default CA_SV_CS0_TYPE 1
param set-default CA_SV_CS1_TRQ_R 0.5
param set-default CA_SV_CS1_TYPE 2
param set-default CA_SV_CS2_TRQ_P 1.0
param set-default CA_SV_CS2_TYPE 3
param set-default CA_SV_CS3_TRQ_Y 1.0
param set-default CA_SV_CS3_TYPE 4
param set-default CA_SV_CS4_TYPE 9
param set-default CA_SV_CS5_TYPE 10
param set-default SIM_GZ_EC_FUNC1 101
param set-default SIM_GZ_EC_MIN1 10
param set-default SIM_GZ_EC_MAX1 1600
param set-default SIM_GZ_SV_FUNC1 201
param set-default SIM_GZ_SV_FUNC2 202
param set-default SIM_GZ_SV_FUNC3 203
param set-default SIM_GZ_SV_FUNC4 204
param set-default SIM_GZ_SV_FUNC5 205
param set-default SIM_GZ_SV_FUNC6 206
@@ -1,122 +0,0 @@
#!/bin/sh
#
# @name 6DoF Omnicopter SITL
#
# @type Quadrotor Wide
#
# @maintainer Jaeyoung Lim <jalim@ethz.ch>
#
. ${R}etc/init.d/rc.mc_defaults
PX4_SIMULATOR=${PX4_SIMULATOR:=gz}
PX4_GZ_WORLD=${PX4_GZ_WORLD:=default}
PX4_SIM_MODEL=${PX4_SIM_MODEL:=omnicopter}
param set-default CA_AIRFRAME 0
param set-default CA_ROTOR_COUNT 8
param set-default CA_R_REV 255
param set-default CA_ROTOR0_PX 0.14435
param set-default CA_ROTOR0_PY -0.14435
param set-default CA_ROTOR0_PZ -0.14435
param set-default CA_ROTOR0_KM 0.05 # CCW
param set-default CA_ROTOR0_AX -0.788675
param set-default CA_ROTOR0_AY -0.211325
param set-default CA_ROTOR0_AZ -0.57735
param set-default CA_ROTOR1_PX -0.14435
param set-default CA_ROTOR1_PY -0.14435
param set-default CA_ROTOR1_PZ -0.14435
param set-default CA_ROTOR1_KM 0.05
param set-default CA_ROTOR1_AX 0.211325
param set-default CA_ROTOR1_AY -0.788675
param set-default CA_ROTOR1_AZ 0.57735
param set-default CA_ROTOR2_PX 0.14435
param set-default CA_ROTOR2_PY 0.14435
param set-default CA_ROTOR2_PZ -0.14435
param set-default CA_ROTOR2_KM 0.05
param set-default CA_ROTOR2_AX -0.211325
param set-default CA_ROTOR2_AY 0.788675
param set-default CA_ROTOR2_AZ 0.57735
param set-default CA_ROTOR3_PX -0.14435
param set-default CA_ROTOR3_PY 0.14435
param set-default CA_ROTOR3_PZ -0.14435
param set-default CA_ROTOR3_KM 0.05
param set-default CA_ROTOR3_AX 0.788675
param set-default CA_ROTOR3_AY 0.211325
param set-default CA_ROTOR3_AZ -0.57735
param set-default CA_ROTOR4_PX 0.14435
param set-default CA_ROTOR4_PY -0.14435
param set-default CA_ROTOR4_PZ 0.14435
param set-default CA_ROTOR4_KM 0.05
param set-default CA_ROTOR4_AX 0.788675
param set-default CA_ROTOR4_AY 0.211325
param set-default CA_ROTOR4_AZ -0.57735
param set-default CA_ROTOR5_PX -0.14435
param set-default CA_ROTOR5_PY -0.14435
param set-default CA_ROTOR5_PZ 0.14435
param set-default CA_ROTOR5_KM 0.05
param set-default CA_ROTOR5_AX -0.211325
param set-default CA_ROTOR5_AY 0.788675
param set-default CA_ROTOR5_AZ 0.57735
param set-default CA_ROTOR6_PX 0.14435
param set-default CA_ROTOR6_PY 0.14435
param set-default CA_ROTOR6_PZ 0.14435
param set-default CA_ROTOR6_KM 0.05
param set-default CA_ROTOR6_AX 0.211325
param set-default CA_ROTOR6_AY -0.788675
param set-default CA_ROTOR6_AZ 0.57735
param set-default CA_ROTOR7_PX -0.14435
param set-default CA_ROTOR7_PY 0.14435
param set-default CA_ROTOR7_PZ 0.14435
param set-default CA_ROTOR7_KM 0.05
param set-default CA_ROTOR7_AX -0.788675
param set-default CA_ROTOR7_AY -0.211325
param set-default CA_ROTOR7_AZ -0.57735
param set-default SIM_GZ_EN 1
param set-default SENS_EN_GPSSIM 1
param set-default SENS_EN_BAROSIM 0
param set-default SENS_EN_MAGSIM 1
param set-default SIM_GZ_EC_FUNC1 101
param set-default SIM_GZ_EC_FUNC2 102
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_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_MAX1 1100
param set-default SIM_GZ_EC_MAX2 1100
param set-default SIM_GZ_EC_MAX3 1100
param set-default SIM_GZ_EC_MAX4 1100
param set-default SIM_GZ_EC_MAX5 1100
param set-default SIM_GZ_EC_MAX6 1100
param set-default SIM_GZ_EC_MAX7 1100
param set-default SIM_GZ_EC_MAX8 1100
# disable MC desaturation which improves attitude tracking
param set-default CA_METHOD 0
# disable attitude failure detection
param set-default FD_FAIL_P 0
param set-default FD_FAIL_R 0
@@ -39,10 +39,8 @@ px4_add_romfs_files(
1012_gazebo-classic_iris_rplidar
1013_gazebo-classic_iris_vision
1013_gazebo-classic_iris_vision.post
1014_gazebo-classic_iris_obs_avoid
1014_gazebo-classic_iris_obs_avoid.post
1015_gazebo-classic_iris_depth_camera
1016_gazebo-classic_iris_downward_depth_camera
1015_gazebo-classic_iris_obs_avoid
1015_gazebo-classic_iris_obs_avoid.post
1017_gazebo-classic_iris_opt_flow_mockup
1019_gazebo-classic_iris_dual_gps
1021_gazebo-classic_uuv_hippocampus
@@ -79,13 +77,10 @@ px4_add_romfs_files(
4004_gz_standard_vtol
4005_gz_x500_vision
4006_gz_px4vision
4008_gz_advanced_plane
6011_gazebo-classic_typhoon_h480
6011_gazebo-classic_typhoon_h480.post
8011_gz_omnicopter
10015_gazebo-classic_iris
10016_none_iris
10017_jmavsim_iris
@@ -99,6 +94,4 @@ px4_add_romfs_files(
17001_flightgear_tf-g1
17002_flightgear_tf-g2
# [22000, 22999] Reserve for custom models
)
@@ -36,20 +36,7 @@ if [ "$PX4_SIMULATOR" = "sihsim" ] || [ "$(param show -q SYS_AUTOSTART)" -eq "0"
exit 1
fi
elif [ "$PX4_SIMULATOR" = "gz" ] || [ "$(param show -q SIM_GZ_EN)" = "1" ]; then
# set local coordinate frame reference
if [ -n "${PX4_HOME_LAT}" ]; then
param set SIM_GZ_HOME_LAT ${PX4_HOME_LAT}
fi
if [ -n "${PX4_HOME_LON}" ]; then
param set SIM_GZ_HOME_LON ${PX4_HOME_LON}
fi
if [ -n "${PX4_HOME_ALT}" ]; then
param set SIM_GZ_HOME_ALT ${PX4_HOME_LON}
fi
elif [ "$PX4_SIMULATOR" = "gz" ] || [ "$(param show -q SIM_GZ_EN)" -eq "1" ]; then
# source generated gz_env.sh for GZ_SIM_RESOURCE_PATH
if [ -f ./gz_env.sh ]; then
@@ -72,7 +59,7 @@ elif [ "$PX4_SIMULATOR" = "gz" ] || [ "$(param show -q SIM_GZ_EN)" = "1" ]; then
fi
# look for running ${gz_command} gazebo world
gz_world=$( ${gz_command} topic -l | grep -m 1 -e "^/world/.*/clock" | sed 's/\/world\///g; s/\/clock//g' )
gz_world=$( ${gz_command} topic -l | grep -m 1 -e "/world/.*/clock" | sed 's/\/world\///g; s/\/clock//g' )
# shellcheck disable=SC2153
if [ -z "${gz_world}" ] && [ -n "${PX4_GZ_WORLDS}" ] && [ -n "${PX4_GZ_WORLD}" ]; then
@@ -92,7 +79,7 @@ elif [ "$PX4_SIMULATOR" = "gz" ] || [ "$(param show -q SIM_GZ_EN)" = "1" ]; then
fi
# start gz_bridge
if [ -n "${PX4_SIM_MODEL#*gz_}" ] && [ -z "${PX4_GZ_MODEL_NAME}" ]; then
if [ -n "${PX4_GZ_MODEL}" ] && [ -z "${PX4_GZ_MODEL_NAME}" ]; then
# model specified, gz_bridge will spawn model
if [ -n "${PX4_GZ_MODEL_POSE}" ]; then
@@ -106,7 +93,7 @@ elif [ "$PX4_SIMULATOR" = "gz" ] || [ "$(param show -q SIM_GZ_EN)" = "1" ]; then
fi
# start gz bridge with pose arg.
if gz_bridge start -p "${model_pose}" -m "${PX4_SIM_MODEL#*gz_}" -w "${PX4_GZ_WORLD}" -i "${px4_instance}"; then
if gz_bridge start -p "${model_pose}" -m "${PX4_GZ_MODEL}" -w "${PX4_GZ_WORLD}" -i "${px4_instance}"; then
if param compare -s SENS_EN_BAROSIM 1
then
sensor_baro_sim start
@@ -129,7 +116,7 @@ elif [ "$PX4_SIMULATOR" = "gz" ] || [ "$(param show -q SIM_GZ_EN)" = "1" ]; then
exit 1
fi
elif [ -n "${PX4_GZ_MODEL_NAME}" ]; then
elif [ -n "${PX4_GZ_MODEL_NAME}" ] && [ -z "${PX4_GZ_MODEL}" ]; then
# model name specificed, gz_bridge will attach to existing model
if gz_bridge start -n "${PX4_GZ_MODEL_NAME}" -w "${PX4_GZ_WORLD}"; then
@@ -155,8 +142,35 @@ elif [ "$PX4_SIMULATOR" = "gz" ] || [ "$(param show -q SIM_GZ_EN)" = "1" ]; then
exit 1
fi
elif [ -n "${PX4_SIM_MODEL}" ] && [ -z "${PX4_GZ_MODEL_NAME}" ] && [ -z "${PX4_GZ_MODEL}" ]; then
echo "WARN [init] PX4_GZ_MODEL_NAME or PX4_GZ_MODEL not set using PX4_SIM_MODEL."
if gz_bridge start -m "${PX4_SIM_MODEL#*gz_}" -w "${PX4_GZ_WORLD}" -i "${px4_instance}"; then
if param compare -s SENS_EN_BAROSIM 1
then
sensor_baro_sim start
fi
if param compare -s SENS_EN_GPSSIM 1
then
sensor_gps_sim start
fi
if param compare -s SENS_EN_MAGSIM 1
then
sensor_mag_sim start
fi
if param compare -s SENS_EN_ARSPDSIM 1
then
sensor_airspeed_sim start
fi
else
echo "ERROR [init] gz_bridge failed to start"
exit 1
fi
else
echo "ERROR [init] failed to pass only PX4_GZ_MODEL_NAME or PX4_SIM_MODEL"
echo "ERROR [init] failed to pass only PX4_GZ_MODEL_NAME or PX4_GZ_MODEL"
exit 1
fi
-5
View File
@@ -187,11 +187,6 @@ param set-default SYS_FAILURE_EN 1
# does not go below 50% by default, but failure injection can trigger failsafes.
param set-default COM_LOW_BAT_ACT 2
# Allow to override SYS_MC_EST_GROUP via env
if [ -n "$SYS_MC_EST_GROUP" ]; then
param set SYS_MC_EST_GROUP $SYS_MC_EST_GROUP
fi
# Adapt timeout parameters if simulation runs faster or slower than realtime.
if [ -n "$PX4_SIM_SPEED_FACTOR" ]; then
COM_DL_LOSS_T_LONGER=$(echo "$PX4_SIM_SPEED_FACTOR * 10" | bc)
@@ -17,7 +17,6 @@
# @maintainer Andreas Antener <andreas@uaventure.com>
#
# @board bitcraze_crazyflie exclude
# @board diatone_mamba-f405-mk2 exclude
#
. ${R}etc/init.d/rc.fw_defaults
@@ -45,8 +45,12 @@ param set-default MAV_1_MODE 9
param set-default SER_TEL1_BAUD 921600
# Vehicle attitude PID tuning
param set-default MC_ACRO_EXPO 0
param set-default MC_ACRO_EXPO_Y 0
param set-default MC_ACRO_P_MAX 200
param set-default MC_ACRO_R_MAX 200
param set-default MC_ACRO_SUPEXPO 0
param set-default MC_ACRO_SUPEXPOY 0
param set-default MC_ACRO_Y_MAX 150
param set-default MC_PITCHRATE_D 0.0015
param set-default MC_ROLLRATE_D 0.0015
@@ -34,7 +34,9 @@ param set-default CA_ROTOR3_PX -0.25
param set-default CA_ROTOR3_PY 0.25
param set-default CA_ROTOR3_KM -0.05
param set-default PWM_MAIN_FUNC1 101
param set-default PWM_MAIN_FUNC2 102
param set-default PWM_MAIN_FUNC3 103
param set-default PWM_MAIN_FUNC4 104
param set-default PWM_AUX_FUNC1 101
param set-default PWM_AUX_FUNC2 102
param set-default PWM_AUX_FUNC3 103
param set-default PWM_AUX_FUNC4 104
param set-default PWM_AUX_TIM0 -4
@@ -45,8 +45,12 @@ param set-default MAV_1_MODE 9
param set-default SER_TEL1_BAUD 921600
# Vehicle attitude PID tuning
param set-default MC_ACRO_EXPO 0
param set-default MC_ACRO_EXPO_Y 0
param set-default MC_ACRO_P_MAX 200
param set-default MC_ACRO_R_MAX 200
param set-default MC_ACRO_SUPEXPO 0
param set-default MC_ACRO_SUPEXPOY 0
param set-default MC_ACRO_Y_MAX 150
param set-default MC_PITCHRATE_D 0.0015
param set-default MC_ROLLRATE_D 0.0015
@@ -0,0 +1,65 @@
#!/bin/sh
#
# @name Reaper 500 Quad
#
# @type Quadrotor H
# @class Copter
#
# @maintainer Blankered
#
# @board px4_fmu-v2 exclude
# @board bitcraze_crazyflie exclude
#
. ${R}etc/init.d/rc.mc_defaults
param set-default MC_ROLLRATE_P 0.14
param set-default MC_ROLLRATE_I 0.1
param set-default MC_ROLLRATE_D 0.004
param set-default MC_PITCH_P 6
param set-default MC_PITCHRATE_P 0.14
param set-default MC_PITCHRATE_I 0.09
param set-default MC_PITCHRATE_D 0.004
param set-default MC_YAW_P 4
param set-default NAV_ACC_RAD 2
param set-default RTL_RETURN_ALT 30
param set-default RTL_DESCEND_ALT 10
param set-default CA_ROTOR_COUNT 4
param set-default CA_ROTOR0_PX 0.15
param set-default CA_ROTOR0_PY 0.15
param set-default CA_ROTOR0_KM -0.05
param set-default CA_ROTOR1_PX -0.15
param set-default CA_ROTOR1_PY -0.15
param set-default CA_ROTOR1_KM -0.05
param set-default CA_ROTOR2_PX 0.15
param set-default CA_ROTOR2_PY -0.15
param set-default CA_ROTOR2_KM 0.05
param set-default CA_ROTOR3_PX -0.15
param set-default CA_ROTOR3_PY 0.15
param set-default CA_ROTOR3_KM 0.05
param set-default PWM_MAIN_FUNC1 101
param set-default PWM_MAIN_FUNC2 102
param set-default PWM_MAIN_FUNC3 103
param set-default PWM_MAIN_FUNC4 104
param set-default PWM_MAIN_MIN1 1100
param set-default PWM_MAIN_MIN2 1100
param set-default PWM_MAIN_MIN3 1100
param set-default PWM_MAIN_MIN4 1100
param set-default PWM_MAIN_MAX1 1900
param set-default PWM_MAIN_MAX2 1900
param set-default PWM_MAIN_MAX3 1900
param set-default PWM_MAIN_MAX4 1900
param set-default PWM_MAIN_TIM0 50
param set-default PWM_MAIN_TIM1 50
param set-default PWM_MAIN_TIM2 50
param set-default PWM_AUX_TIM0 50
param set-default PWM_AUX_TIM1 50
param set-default PWM_AUX_TIM2 50
@@ -0,0 +1,91 @@
#!/bin/sh
#
# @name Crazyflie 2
#
# @type Quadrotor x
# @class Copter
#
# @maintainer Dennis Shtatov <densht@gmail.com>
#
# @board px4_fmu-v2 exclude
# @board px4_fmu-v3 exclude
# @board px4_fmu-v4 exclude
# @board px4_fmu-v4pro exclude
# @board px4_fmu-v5 exclude
# @board px4_fmu-v5x exclude
#
. ${R}etc/init.d/rc.mc_defaults
param set-default BAT1_N_CELLS 1
param set-default BAT1_CAPACITY 240
param set-default BAT1_SOURCE 1
param set-default CBRK_SUPPLY_CHK 894281
param set-default COM_RC_IN_MODE 1
param set-default EKF2_ABL_LIM 2
param set-default EKF2_HGT_REF 2
param set-default EKF2_RNG_CTRL 2
param set-default EKF2_MAG_TYPE 1
param set-default EKF2_OF_CTRL 1
param set-default EKF2_OF_DELAY 10
param set-default IMU_GYRO_CUTOFF 100
param set-default IMU_ACCEL_CUTOFF 30
param set-default MC_AIRMODE 1
param set-default IMU_DGYRO_CUTOFF 70
param set-default MC_PITCHRATE_D 0.002
param set-default MC_PITCHRATE_P 0.07
param set-default MC_ROLLRATE_D 0.002
param set-default MC_ROLLRATE_P 0.07
param set-default MC_YAW_P 3
param set-default MPC_THR_HOVER 0.7
param set-default MPC_THR_MAX 1
param set-default MPC_Z_P 1.5
param set-default MPC_Z_VEL_P_ACC 8
param set-default MPC_Z_VEL_I_ACC 6
param set-default MPC_HOLD_MAX_XY 0.1
param set-default MPC_MAX_FLOW_HGT 3
param set-default NAV_RCL_ACT 3
param set-default CA_ROTOR_COUNT 4
param set-default CA_ROTOR0_PX 0.03
param set-default CA_ROTOR0_PY 0.03
param set-default CA_ROTOR1_PX -0.03
param set-default CA_ROTOR1_PY 0.03
param set-default CA_ROTOR1_KM -0.05
param set-default CA_ROTOR2_PX -0.03
param set-default CA_ROTOR2_PY -0.03
param set-default CA_ROTOR3_PX 0.03
param set-default CA_ROTOR3_PY -0.03
param set-default CA_ROTOR3_KM -0.05
# Run the motors at 328.125 kHz (recommended)
param set-default PWM_MAIN_TIM0 3921
param set-default PWM_MAIN_TIM1 3921
param set-default PWM_MAIN_FUNC1 101
param set-default PWM_MAIN_FUNC2 102
param set-default PWM_MAIN_FUNC3 103
param set-default PWM_MAIN_FUNC4 104
param set-default PWM_MAIN_DIS0 0
param set-default PWM_MAIN_DIS1 0
param set-default PWM_MAIN_DIS2 0
param set-default PWM_MAIN_DIS3 0
param set-default PWM_MAIN_MIN0 0
param set-default PWM_MAIN_MIN1 0
param set-default PWM_MAIN_MIN2 0
param set-default PWM_MAIN_MIN3 0
param set-default PWM_MAIN_MAX0 255
param set-default PWM_MAIN_MAX1 255
param set-default PWM_MAIN_MAX2 255
param set-default PWM_MAIN_MAX3 255
param set-default SENS_FLOW_MINRNG 0.05
syslink start
mavlink start -d /dev/bridge0 -b 57600 -m osd -r 40000
@@ -13,7 +13,6 @@
# @board px4_fmu-v4pro exclude
# @board px4_fmu-v5 exclude
# @board px4_fmu-v5x exclude
# @board diatone_mamba-f405-mk2 exclude
#
. ${R}etc/init.d/rc.mc_defaults
@@ -42,6 +41,7 @@ param set-default MC_ROLLRATE_P 0.07
param set-default MC_YAW_P 3
param set-default MPC_THR_HOVER 0.7
param set-default MPC_THR_MAX 1
param set-default MPC_Z_P 1.5
param set-default MPC_Z_VEL_P_ACC 8
param set-default MPC_Z_VEL_I_ACC 6
@@ -13,8 +13,6 @@
. ${R}etc/init.d/rc.rover_defaults
param set-default BAT1_N_CELLS 4
param set-default EKF2_GBIAS_INIT 0.01
@@ -54,9 +52,10 @@ param set-default GND_MAX_ANG 3.1415
# Set geometry & output configration
param set-default CA_AIRFRAME 6
param set-default CA_R_REV 3
param set-default PWM_MAIN_FUNC1 101
param set-default PWM_MAIN_FUNC2 102
param set-default PWM_MAIN_DIS1 1500
param set-default PWM_MAIN_DIS2 1500
param set-default PWM_MAIN_TIM0 50
param set-default PWM_MAIN_TIM1 50
param set-default RBCLW_ADDRESS 128
param set-default RBCLW_FUNC1 101
param set-default RBCLW_FUNC2 102
param set-default RBCLW_REV 1
@@ -58,6 +58,7 @@ px4_add_romfs_files(
4017_nxp_hovergames
4019_x500_v2
4020_holybro_px4vision_v1_5
4040_reaper
4041_beta75x
4050_generic_250
4052_holybro_qav250
@@ -66,6 +67,7 @@ px4_add_romfs_files(
4071_ifo
4073_ifo-s
4500_clover4
4900_crazyflie
4901_crazyflie21
# [5000, 5999] Quadrotor +"
+1 -2
View File
@@ -17,7 +17,7 @@ param set-default COM_POS_FS_DELAY 5
# there is a 2.5 factor applied on the _FS thresholds if for invalidation
param set-default COM_POS_FS_EPH 50
param set-default COM_VEL_FS_EVH 3
param set-default COM_VEL_FS_EVH 5
param set-default COM_POS_LOW_EPH 50
@@ -34,7 +34,6 @@ param set-default EKF2_REQ_EPV 10
param set-default EKF2_REQ_HDRIFT 0.5
param set-default EKF2_REQ_SACC 1
param set-default EKF2_REQ_VDRIFT 1.0
param set-default EKF2_RNG_QLTY_T 3.0
param set-default RTL_TYPE 1
param set-default RTL_RETURN_ALT 100
-6
View File
@@ -172,12 +172,6 @@ then
ms5525dso start -X
fi
# TE ASP5033 differential pressure sensor external I2C
if param compare -s SENS_EN_ASP5033 1
then
asp5033 start -X
fi
# SHT3x temperature and hygrometer sensor, external I2C
if param compare -s SENS_EN_SHT3X 1
then
+11 -21
View File
@@ -93,14 +93,6 @@ then
fi
fi
# Check for an update of the ext_autostart folder, and replace the old one with it
if [ -e /fs/microsd/ext_autostart_new ]
then
echo "Updating external autostart files"
rm -r $SDCARD_EXT_PATH
mv /fs/microsd/ext_autostart_new $SDCARD_EXT_PATH
fi
set PARAM_FILE /fs/microsd/params
set PARAM_BACKUP_FILE "/fs/microsd/parameters_backup.bson"
fi
@@ -170,7 +162,7 @@ else
param select-backup $PARAM_BACKUP_FILE
fi
if ver hwcmp PX4_FMU_V5X PX4_FMU_V6X ARK_FMU_V6X PX4_FMU_V6XRT
if ver hwcmp PX4_FMU_V5X PX4_FMU_V6X ARK_FMU_V6X
then
netman update -i eth0
fi
@@ -263,7 +255,6 @@ else
rgbled start -X -q
rgbled_ncp5623c start -X -q
rgbled_lp5562 start -X -q
rgbled_is31fl3195 start -X -q
#
# Override parameters from user configuration file.
@@ -274,9 +265,12 @@ else
. $FCONFIG
fi
if px4io supported
#
# Start IO for PWM output or RC input if enabled
#
if param compare -s SYS_USE_IO 1
then
# Check if PX4IO present and update firmware if needed.
# Check if PX4IO present and update firmware if needed.
if [ -f $IOFW ]
then
if ! px4io checkcrc ${IOFW}
@@ -298,12 +292,12 @@ else
tune_control stop
fi
fi
fi
if ! px4io start
then
echo "PX4IO start failed"
set STARTUP_TUNE 2 # tune 2 = ERROR_TUNE
fi
if ! px4io start
then
echo "PX4IO start failed"
set STARTUP_TUNE 2 # tune 2 = ERROR_TUNE
fi
fi
@@ -534,10 +528,6 @@ else
cyphal start
fi
fi
if param greater -s ZENOH_ENABLE 0
then
zenoh start
fi
#
# End of autostart.
-25
View File
@@ -1,25 +0,0 @@
# Security Policy
## Supported Versions
The following is a list of versions the development team is currently supporting.
| Version | Supported |
| ------- | ------------------ |
| 1.4.x | :white_check_mark: |
| 1.3.3 | :white_check_mark: |
| < 1.3 | :x: |
## Reporting a Vulnerability
We currently only receive security vulnerability reports through GitHub.
To begin a report, please go to the top-level repository, for example, PX4/PX4-Autopilot,
and click on the Security tab. If you are on mobile, click the ... dropdown menu, and then click Security.
Click Report a Vulnerability to open the advisory form. Fill in the advisory details form.
Make sure your title is descriptive, and the development team can find all of the relevant details needed
to verify on the description box. We recommend you add as much data as possible. We welcome logs,
screenshots, photos, and videos, anything that can help us verify and identify the issues being reported.
At the bottom of the form, click Submit report. The maintainer team will be notified and will get back to you ASAP.
+3 -5
View File
@@ -39,7 +39,7 @@ def print_line(line):
print('{0}'.format(line), end='')
def do_nsh_cmd(port_url, baudrate, cmd, ignore_stdout_errors=False):
def do_nsh_cmd(port_url, baudrate, cmd):
ser = serial.serial_for_url(url=port_url, baudrate=baudrate, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=1, xonxoff=False, rtscts=False, dsrdtr=False, inter_byte_timeout=1)
timeout_start = time.monotonic()
@@ -106,7 +106,7 @@ def do_nsh_cmd(port_url, baudrate, cmd, ignore_stdout_errors=False):
if success_cmd in serial_line:
sys.exit(return_code)
else:
if "ERROR " in serial_line and not ignore_stdout_errors:
if "ERROR " in serial_line:
return_code = -1
print_line(serial_line)
@@ -148,8 +148,6 @@ def main():
parser.add_argument('--device', "-d", nargs='?', default=default_device, help='', required=device_required)
parser.add_argument("--baudrate", "-b", dest="baudrate", type=int, help="serial port baud rate (default=57600)", default=57600)
parser.add_argument("--cmd", "-c", dest="cmd", help="Command to run")
parser.add_argument('--ignore-stdout-errors', action='store_true',
help='Ignore errors printed to stdout')
args = parser.parse_args()
tmp_file = "{0}/pyserial_spy_file.txt".format(tempfile.gettempdir())
@@ -157,7 +155,7 @@ def main():
print("pyserial url: {0}".format(port_url))
do_nsh_cmd(port_url, args.baudrate, args.cmd, args.ignore_stdout_errors)
do_nsh_cmd(port_url, args.baudrate, args.cmd)
if __name__ == "__main__":
main()
@@ -25,9 +25,5 @@ exec find boards msg src platforms test \
-path src/lib/crypto/monocypher -prune -o \
-path src/lib/crypto/libtomcrypt -prune -o \
-path src/lib/crypto/libtommath -prune -o \
-path src/lib/heatshrink/heatshrink -prune -o \
-path src/modules/uxrce_dds_client/Micro-XRCE-DDS-Client -prune -o \
-path src/lib/cdrstream/cyclonedds -prune -o \
-path src/lib/cdrstream/rosidl -prune -o \
-path src/modules/zenoh/zenoh-pico -prune -o \
-type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.hpp" \) | grep $PATTERN
-115
View File
@@ -1,115 +0,0 @@
#!/bin/bash
# Flash PX4 to a device running AuterionOS in the local network
if [ "$1" == "-h" ] || [ "$1" == "--help" ] || [ $# -lt 2 ]; then
echo "Usage: $0 -f <firmware.px4|.elf> [-c <configuration_dir>] -d <IP/Device> [-u <user>] [-p <ssh_port>] [--revert]"
exit 1
fi
ssh_port=22
ssh_user=root
while getopts ":f:c:d:p:u:r" opt; do
case ${opt} in
f )
if [ -n "$OPTARG" ]; then
firmware_file="$OPTARG"
else
echo "ERROR: -f requires a non-empty option argument."
exit 1
fi
;;
c )
if [ -f "$OPTARG/rc.autostart" ]; then
config_dir="$OPTARG"
else
echo "ERROR: -c configuration directory is empty or does not contain a valid rc.autostart"
exit 1
fi
;;
d )
if [ "$OPTARG" ]; then
device="$OPTARG"
else
echo "ERROR: -d requires a non-empty option argument."
exit 1
fi
;;
p )
if [[ "$OPTARG" =~ ^[0-9]+$ ]]; then
ssh_port="$OPTARG"
else
echo "ERROR: -p ssh_port must be a number."
exit 1
fi
;;
u )
if [ "$OPTARG" ]; then
ssh_user="$OPTARG"
else
echo "ERROR: -u requires a non-empty option argument."
exit 1
fi
;;
r )
revert=true
;;
esac
done
if [ -z "$device" ]; then
echo "Error: missing device"
exit 1
fi
target_dir=/shared_container_dir/fmu
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"
else
# create custom update-dev.tar
tmp_dir="$(mktemp -d)"
config_path=""
firmware_path=""
if [ -d "$config_dir" ]; then
cp -r "$config_dir" "$tmp_dir/config"
config_path=config
fi
if [ -f "$firmware_file" ]; then
extension="${firmware_file##*.}"
cp "$firmware_file" "$tmp_dir/firmware.$extension"
if [ "$extension" == "elf" ]; then
# ensure the file is stripped to reduce file size
arm-none-eabi-strip "$tmp_dir/firmware.$extension"
fi
firmware_path="firmware.$extension"
fi
pushd "$tmp_dir" &>/dev/null
if [ -z $firmware_path ] && [ -z $config_path ]; then
exit 1
fi
tar_name="tar"
if [ -x "$(command -v gtar)" ]; then
# check if gnu-tar is installed on macOS and use that instead
tar_name="gtar"
fi
$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
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"
-51
View File
@@ -1,51 +0,0 @@
#!/usr/bin/env bash
DIR="$(dirname $(readlink -f $0))"
DEFAULT_AUTOPILOT_HOST=10.41.1.1
DEFAULT_AUTOPILOT_PORT=33333
DEFAULT_AUTOPILOT_USER=auterion
for i in "$@"
do
case $i in
--file=*)
PX4_BINARY_FILE="${i#*=}"
;;
--default-ip=*)
DEFAULT_AUTOPILOT_HOST="${i#*=}"
;;
--default-port=*)
DEFAULT_AUTOPILOT_PORT="${i#*=}"
;;
--default-user=*)
DEFAULT_AUTOPILOT_USER="${i#*=}"
;;
--revert)
REVERT_AUTOPILOT_ARGUMENT=-r
;;
--wifi)
DEFAULT_AUTOPILOT_HOST=10.41.0.1
;;
*)
# unknown option
;;
esac
done
# allow these to be overridden
[ -z "$AUTOPILOT_HOST" ] && AUTOPILOT_HOST=$DEFAULT_AUTOPILOT_HOST
[ -z "$AUTOPILOT_PORT" ] && AUTOPILOT_PORT=$DEFAULT_AUTOPILOT_PORT
[ -z "$AUTOPILOT_USER" ] && AUTOPILOT_USER=$DEFAULT_AUTOPILOT_USER
ARGUMENTS=()
ARGUMENTS+=(-d "$AUTOPILOT_HOST")
ARGUMENTS+=(-p "$AUTOPILOT_PORT")
ARGUMENTS+=(-u "$AUTOPILOT_USER")
ARGUMENTS+=(${PX4_BINARY_FILE:+-f "$PX4_BINARY_FILE"})
ARGUMENTS+=($REVERT_AUTOPILOT_ARGUMENT)
echo "Flashing $AUTOPILOT_HOST ..."
"$DIR"/remote_update_fmu.sh "${ARGUMENTS[@]}"
exit 0
+5 -5
View File
@@ -4,16 +4,16 @@ if [ -z ${PX4_DOCKER_REPO+x} ]; then
echo "guessing PX4_DOCKER_REPO based on input";
if [[ $@ =~ .*px4_fmu.* ]]; then
# nuttx-px4fmu-v{1,2,3,4,5}
PX4_DOCKER_REPO="px4io/px4-dev-nuttx-focal:2022-08-12"
PX4_DOCKER_REPO="px4io/px4-dev-nuttx-focal:2021-09-08"
elif [[ $@ =~ .*navio2.* ]] || [[ $@ =~ .*raspberry.* ]] || [[ $@ =~ .*beaglebone.* ]] || [[ $@ =~ .*pilotpi.default ]]; then
# beaglebone_blue_default, emlid_navio2_default, px4_raspberrypi_default, scumaker_pilotpi_default
PX4_DOCKER_REPO="px4io/px4-dev-armhf:2023-06-26"
PX4_DOCKER_REPO="px4io/px4-dev-armhf:2021-08-18"
elif [[ $@ =~ .*pilotpi.arm64 ]]; then
# scumaker_pilotpi_arm64
PX4_DOCKER_REPO="px4io/px4-dev-aarch64:2022-08-12"
PX4_DOCKER_REPO="px4io/px4-dev-aarch64:latest"
elif [[ $@ =~ .*navio2.* ]] || [[ $@ =~ .*raspberry.* ]] || [[ $@ =~ .*bebop.* ]]; then
# posix_rpi_cross, posix_bebop_default
PX4_DOCKER_REPO="px4io/px4-dev-armhf:2023-06-26"
PX4_DOCKER_REPO="px4io/px4-dev-armhf:2021-08-18"
elif [[ $@ =~ .*clang.* ]] || [[ $@ =~ .*scan-build.* ]]; then
# clang tools
PX4_DOCKER_REPO="px4io/px4-dev-clang:2021-02-04"
@@ -27,7 +27,7 @@ fi
# otherwise default to nuttx
if [ -z ${PX4_DOCKER_REPO+x} ]; then
PX4_DOCKER_REPO="px4io/px4-dev-nuttx-focal:2022-08-12"
PX4_DOCKER_REPO="px4io/px4-dev-nuttx-focal:2021-09-08"
fi
# docker hygiene
+5 -8
View File
@@ -56,14 +56,11 @@ def perform_imu_checks(
# perform the vibration check
imu_status['imu_vibration_check'] = 'Pass'
for imu_vibr_metric in ['imu_coning', 'imu_hfgyro', 'imu_hfaccel']:
mean_metric = '{:s}_mean_warn'.format(imu_vibr_metric)
peak_metric = '{:s}_peak_warn'.format(imu_vibr_metric)
mean_key = '{:s}_mean'.format(imu_vibr_metric)
peak_key = '{:s}_peak'.format(imu_vibr_metric)
if mean_key in imu_metrics and peak_key in imu_metrics:
if imu_metrics[mean_key] > check_levels[mean_metric] \
or imu_metrics[peak_key] > check_levels[peak_metric]:
imu_status['imu_vibration_check'] = 'Warning'
mean_metric = '{:s}_mean'.format(imu_vibr_metric)
peak_metric = '{:s}_peak'.format(imu_vibr_metric)
if imu_metrics[mean_metric] > check_levels['{:s}_warn'.format(mean_metric)] \
or imu_metrics[peak_metric] > check_levels['{:s}_warn'.format(peak_metric)]:
imu_status['imu_vibration_check'] = 'Warning'
if imu_status['imu_vibration_check'] == 'Warning':
print('IMU vibration check warning.')
+3 -3
View File
@@ -104,9 +104,9 @@ def calculate_innov_fail_metrics(
# calculate innovation check fail metrics
for signal_id, signal, result in [('posv', 'reject_ver_pos', 'hgt_fail_percentage'),
('magx', 'fs_bad_mag_x', 'magx_fail_percentage'),
('magy', 'fs_bad_mag_y', 'magy_fail_percentage'),
('magz', 'fs_bad_mag_z', 'magz_fail_percentage'),
('magx', 'reject_mag_x', 'magx_fail_percentage'),
('magy', 'reject_mag_y', 'magy_fail_percentage'),
('magz', 'reject_mag_z', 'magz_fail_percentage'),
('yaw', 'reject_yaw', 'yaw_fail_percentage'),
('velh', 'reject_hor_vel', 'vel_fail_percentage'),
('velv', 'reject_ver_vel', 'vel_fail_percentage'),
+11 -16
View File
@@ -43,11 +43,6 @@ def create_pdf_report(ulog: ULog, multi_instance: int, output_plot_filename: str
except:
raise PreconditionError('could not find estimator_states instance', multi_instance)
try:
estimator_sensor_bias = ulog.get_dataset('estimator_sensor_bias', multi_instance).data
except:
raise PreconditionError('could not find estimator_sensor_bias instance', multi_instance)
try:
estimator_innovations = ulog.get_dataset('estimator_innovations', multi_instance).data
estimator_innovation_variances = ulog.get_dataset('estimator_innovation_variances', multi_instance).data
@@ -227,7 +222,7 @@ def create_pdf_report(ulog: ULog, multi_instance: int, output_plot_filename: str
data_plot = CheckFlagsPlot(
status_flags_time, estimator_status_flags, [['reject_hor_vel', 'reject_hor_pos'], ['reject_ver_vel', 'reject_ver_pos',
'reject_hagl'],
['fs_bad_mag_x', 'fs_bad_mag_y', 'fs_bad_mag_z',
['reject_mag_x', 'reject_mag_y', 'reject_mag_z',
'reject_yaw'], ['reject_airspeed'], ['reject_sideslip'],
['reject_optflow_x',
'reject_optflow_y']], x_label='time (sec)',
@@ -304,21 +299,21 @@ def create_pdf_report(ulog: ULog, multi_instance: int, output_plot_filename: str
data_plot.save()
data_plot.close()
# Plot the gyro bias estimates
# Plot the delta angle bias estimates
data_plot = CheckFlagsPlot(
1e-6 * estimator_sensor_bias['timestamp'], estimator_sensor_bias,
[['gyro_bias[0]'], ['gyro_bias[1]'], ['gyro_bias[2]']],
x_label='time (sec)', y_labels=['X (rad/s)', 'Y (rad/s)', 'Z (rad/s)'],
plot_title='Gyro Bias Estimates', annotate=False, pdf_handle=pdf_pages)
1e-6 * estimator_states['timestamp'], estimator_states,
[['states[10]'], ['states[11]'], ['states[12]']],
x_label='time (sec)', y_labels=['X (rad)', 'Y (rad)', 'Z (rad)'],
plot_title='Delta Angle Bias Estimates', annotate=False, pdf_handle=pdf_pages)
data_plot.save()
data_plot.close()
# Plot the accel bias estimates
# Plot the delta velocity bias estimates
data_plot = CheckFlagsPlot(
1e-6 * estimator_sensor_bias['timestamp'], estimator_sensor_bias,
[['accel_bias[0]'], ['accel_bias[1]'], ['accel_bias[2]']],
x_label='time (sec)', y_labels=['X (m/s^2)', 'Y (m/s^2)', 'Z (m/s^2)'],
plot_title='Accel Bias Estimates', annotate=False, pdf_handle=pdf_pages)
1e-6 * estimator_states['timestamp'], estimator_states,
[['states[13]'], ['states[14]'], ['states[15]']],
x_label='time (sec)', y_labels=['X (m/s)', 'Y (m/s)', 'Z (m/s)'],
plot_title='Delta Velocity Bias Estimates', annotate=False, pdf_handle=pdf_pages)
data_plot.save()
data_plot.close()
+7 -7
View File
@@ -61,19 +61,18 @@ def process_target(px4board_file, target_name):
if platform not in excluded_platforms:
# get the container based on the platform and toolchain
container = platform
if platform == 'posix':
container = 'px4io/px4-dev-base-focal:2021-09-08'
container = 'base-focal'
if toolchain:
if toolchain.startswith('aarch64'):
container = 'px4io/px4-dev-aarch64:2022-08-12'
container = 'aarch64'
elif toolchain == 'arm-linux-gnueabihf':
container = 'px4io/px4-dev-armhf:2023-06-26'
container = 'armhf'
else:
if verbose: print(f'unmatched toolchain: {toolchain}')
if verbose: print(f'possibly unmatched toolchain: {toolchain}')
elif platform == 'nuttx':
container = 'px4io/px4-dev-nuttx-focal:2022-08-12'
else:
if verbose: print(f'unmatched platform: {platform}')
container = 'nuttx-focal'
ret = {'target': target_name, 'container': container}
@@ -114,3 +113,4 @@ extra_args = {}
if args.pretty:
extra_args['indent'] = 2
print(json.dumps(github_action_config, **extra_args))
+7 -1
View File
@@ -302,6 +302,12 @@ When set to -1 (default), the value depends on the function (see {:}).
for key, label, param_suffix, description in standard_params_array:
if key in standard_params:
# values must be in range of an uint16_t
if standard_params[key]['min'] < 0:
raise Exception('minimum value for {:} expected >= 0 (got {:})'.format(key, standard_params[key]['min']))
if standard_params[key]['max'] >= 1<<16:
raise Exception('maximum value for {:} expected <= {:} (got {:})'.format(key, 1<<16, standard_params[key]['max']))
if key == 'failsafe':
standard_params[key]['default'] = -1
standard_params[key]['min'] = -1
@@ -311,7 +317,7 @@ When set to -1 (default), the value depends on the function (see {:}).
'short': channel_label+' ${i} '+label+' Value',
'long': description
},
'type': 'float',
'type': 'int32',
'instance_start': instance_start,
'instance_start_label': instance_start_label,
'num_instances': num_channels,
@@ -1,235 +0,0 @@
#!/usr/bin/env python3
#############################################################################
#
# Copyright (C) 2023 PX4 Pro 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.
#
#############################################################################
"""
Generates cpp source + header files with compressed uorb topic fields from json files
"""
import argparse
import json
import struct
from operator import itemgetter
import sys
import os
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../src/lib/heatshrink'))
import heatshrink_encode
def parse_json_files(json_files: [str]) -> dict:
"""Read list of json files into a dict"""
definitions = {}
for json_file in json_files:
with open(json_file, encoding='utf-8') as file_handle:
definition = json.load(file_handle)
assert definition['name'] not in definitions
definitions[definition['name']] = definition
definitions[definition['name']]['completed'] = False
return definitions
def get_ordered_list_by_dependency(name: str, definitions: dict) -> [str]:
"""Iterate dependency graph and create an ordered list"""
if definitions[name]['completed']:
return []
ret = []
# Get nested types first (DFS)
for dependency in definitions[name]['dependencies']:
ret.extend(get_ordered_list_by_dependency(dependency, definitions))
ret.append(name)
definitions[name]['completed'] = True
return ret
def get_field_definitions(names: [str], definitions: dict) -> (bytes, [str]):
"""Get byte array with all definitions"""
ret = bytes()
formats_list = []
for name in names:
# Format as '<# orb_ids><orb_id0...><# orb_ids dependencies<orb_id_dependency0...><fields><null>'
assert len(definitions[name]['orb_ids']) < 255
assert len(definitions[name]['dependencies']) < 255
ret += struct.pack('<B', len(definitions[name]['orb_ids']))
for orb_id in definitions[name]['orb_ids']:
assert orb_id < (1 << 16)
ret += struct.pack('<H', orb_id)
# Dependencies
ret += struct.pack('<B', len(definitions[name]['dependencies']))
for dependent_message_name in definitions[name]['dependencies']:
# Get ORB ID by looking up the name in all definitions
dependent_orb_id_list = [definitions[k]['main_orb_id'] for k in definitions if
definitions[k]['name'] == dependent_message_name]
assert len(dependent_orb_id_list) == 1
orb_id = dependent_orb_id_list[0]
assert (1 << 16) > orb_id >= 0
ret += struct.pack('<H', orb_id)
ret += bytes(definitions[name]['fields'], 'latin1')
ret += b'\0'
formats_list.append(definitions[name]['fields'])
return ret, formats_list
def write_fields_to_cpp_file(file_name: str, compressed_fields: bytes):
fields_str = ', '.join(str(c) for c in compressed_fields)
with open(file_name, 'w') as file_handle:
file_handle.write('''
// Auto-generated from px4_generate_uorb_compressed_fields.py
#include <uORB/topics/uORBMessageFieldsGenerated.hpp>
namespace uORB {
static const uint8_t compressed_fields[] = {
{FIELDS}
};
const uint8_t* orb_compressed_message_formats()
{
return compressed_fields;
}
unsigned orb_compressed_message_formats_size()
{
return sizeof(compressed_fields) / sizeof(compressed_fields[0]);
}
} // namespace uORB
'''.replace('{FIELDS}', fields_str))
def c_encode(s, encoding='ascii'):
result = ''
for c in s:
if not (32 <= ord(c) < 127) or c in ('\\', '"'):
result += '\\%03o' % ord(c)
else:
result += c
return '"' + result + '"'
def write_fields_to_hpp_file(file_name: str, definitions: dict, window_length: int, lookahead_length: int,
format_list: [str]):
max_tokenized_field_length, max_tokenized_field_length_msg = max(
((len(definitions[k]['fields']), k) for k in definitions), key=itemgetter(0))
max_untokenized_field_length = max(definitions[k]['fields_total_length'] for k in definitions)
max_num_orb_ids = max(len(definitions[k]['orb_ids']) for k in definitions)
max_num_orb_id_dependencies = max(len(definitions[k]['dependencies']) for k in definitions)
with open(file_name, 'w') as file_handle:
file_handle.write('''
// Auto-generated from px4_generate_uorb_compressed_fields.py
#include <cstdint>
namespace uORB {
/**
* Get compressed string of all uorb message format definitions
*/
const uint8_t* orb_compressed_message_formats();
/**
* Get length of compressed message format definitions
*/
unsigned orb_compressed_message_formats_size();
static constexpr unsigned orb_tokenized_fields_max_length = {MAX_TOKENIZED_FIELD_LENGTH}; // {MAX_TOKENIZED_FIELD_LENGTH_MSG}
static constexpr unsigned orb_untokenized_fields_max_length = {MAX_UNTOKENIZED_FIELD_LENGTH};
static constexpr unsigned orb_compressed_max_num_orb_ids = {MAX_NUM_ORB_IDS};
static constexpr unsigned orb_compressed_max_num_orb_id_dependencies = {MAX_NUM_ORB_ID_DEPENDENCIES};
static constexpr unsigned orb_compressed_heatshrink_window_length = {WINDOW_LENGTH};
static constexpr unsigned orb_compressed_heatshrink_lookahead_length = {LOOKAHEAD_LENGTH};
#define ORB_DECOMPRESSED_MESSAGE_FIELDS {{DECOMPRESSED_MESSAGE_FIELDS}}
} // namespace uORB
'''
.replace('{MAX_TOKENIZED_FIELD_LENGTH}', str(max_tokenized_field_length))
.replace('{MAX_TOKENIZED_FIELD_LENGTH_MSG}', max_tokenized_field_length_msg)
.replace('{MAX_UNTOKENIZED_FIELD_LENGTH}', str(max_untokenized_field_length))
.replace('{MAX_NUM_ORB_IDS}', str(max_num_orb_ids))
.replace('{MAX_NUM_ORB_ID_DEPENDENCIES}', str(max_num_orb_id_dependencies))
.replace('{WINDOW_LENGTH}', str(window_length))
.replace('{LOOKAHEAD_LENGTH}', str(lookahead_length))
.replace('{DECOMPRESSED_MESSAGE_FIELDS}', ','.join(c_encode(x) for x in format_list))
)
def main():
parser = argparse.ArgumentParser(description='Generate compressed uorb topic fields')
parser.add_argument('-f', dest='file',
help="json input files",
nargs="+")
parser.add_argument('--source-output-file', dest='output_cpp',
help='cpp output file to generate')
parser.add_argument('--header-output-file', dest='output_hpp',
help='hpp output file to generate')
parser.add_argument('-v', '--verbose',
action='store_true',
help="verbose output")
args = parser.parse_args()
if args.file is not None:
definitions = parse_json_files(args.file)
# Get array of all field definitions
names = []
for definition in definitions:
names.extend(get_ordered_list_by_dependency(definitions[definition]['name'], definitions))
names.reverse() # Dependent definitions must be after
assert len(names) == len(definitions)
for definition in definitions: # sanity check
assert definitions[definition]['completed']
field_definitions, format_list = get_field_definitions(names, definitions)
# Compress
window_size = 8 # Larger value = better compression; memory requirement (for decompression): 2 ^ window_size
lookahead = 4
compressed_field_definitions = heatshrink_encode.encode(field_definitions, window_size, lookahead)
if args.verbose:
print(
f'Field definitions: size: {len(field_definitions)}, reduction from compression: {len(field_definitions) - len(compressed_field_definitions)}')
# Write cpp & hpp file
write_fields_to_cpp_file(args.output_cpp, compressed_field_definitions)
write_fields_to_hpp_file(args.output_hpp, definitions, window_size, lookahead, format_list)
if __name__ == "__main__":
main()
+16 -28
View File
@@ -70,8 +70,9 @@ __license__ = "BSD"
__email__ = "thomasgubler@gmail.com"
TEMPLATE_FILE = ['msg.h.em', 'msg.cpp.em', 'uorb_idl_header.h.em', 'msg.json.em']
TOPICS_LIST_TEMPLATE_FILE = ['uORBTopics.hpp.em', 'uORBTopics.cpp.em', None, None]
TEMPLATE_FILE = ['msg.h.em', 'msg.cpp.em']
TOPICS_LIST_TEMPLATE_FILE = ['uORBTopics.hpp.em', 'uORBTopics.cpp.em']
OUTPUT_FILE_EXT = ['.h', '.cpp']
INCL_DEFAULT = ['std_msgs:./msg/std_msgs']
PACKAGE = 'px4'
TOPICS_TOKEN = '# TOPICS '
@@ -104,7 +105,7 @@ def get_topics(filename):
return result
def generate_output_from_file(format_idx, filename, outputdir, package, templatedir, includepath, all_topics):
def generate_output_from_file(format_idx, filename, outputdir, package, templatedir, includepath):
"""
Converts a single .msg file to an uorb header/source file
"""
@@ -149,12 +150,10 @@ def generate_output_from_file(format_idx, filename, outputdir, package, template
em_globals = {
"name_snake_case": full_type_name_snake,
"file_name_in": filename,
"file_base_name": file_base_name,
"search_path": search_path,
"msg_context": msg_context,
"spec": spec,
"topics": topics,
"all_topics": all_topics,
}
# Make sure output directory exists:
@@ -162,11 +161,7 @@ def generate_output_from_file(format_idx, filename, outputdir, package, template
os.makedirs(outputdir)
template_file = os.path.join(templatedir, TEMPLATE_FILE[format_idx])
extension = os.path.splitext(os.path.splitext(TEMPLATE_FILE[format_idx])[0])[1]
if format_idx == 2:
output_file = os.path.join(outputdir, file_base_name + extension)
else:
output_file = os.path.join(outputdir, full_type_name_snake + extension)
output_file = os.path.join(outputdir, full_type_name_snake + OUTPUT_FILE_EXT[format_idx])
return generate_by_template(output_file, template_file, em_globals)
@@ -196,13 +191,17 @@ def generate_by_template(output_file, template_file, em_globals):
return True
def generate_topics_list_file_from_files(files, outputdir, template_filename, templatedir, all_topics):
def generate_topics_list_file_from_files(files, outputdir, template_filename, templatedir):
# generate cpp file with topics list
filenames = []
for filename in [os.path.basename(p) for p in files if os.path.basename(p).endswith(".msg")]:
filenames.append(re.sub(r'(?<!^)(?=[A-Z])', '_', filename).lower())
tl_globals = {"msgs": filenames, "all_topics": all_topics}
topics = []
for msg_filename in files:
topics.extend(get_topics(msg_filename))
tl_globals = {"msgs": filenames, "topics": topics}
tl_template_file = os.path.join(templatedir, template_filename)
tl_out_file = os.path.join(outputdir, template_filename.replace(".em", ""))
@@ -218,10 +217,8 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Convert msg files to uorb headers/sources')
parser.add_argument('--headers', help='Generate header files', action='store_true')
parser.add_argument('--sources', help='Generate source files', action='store_true')
parser.add_argument('--uorb-idl-header', help='Generate uORB compatible idl header', action='store_true')
parser.add_argument('--json', help='Generate json files', action='store_true')
parser.add_argument('-f', dest='file',
help="files to convert",
help="files to convert (use only without -d)",
nargs="+")
parser.add_argument('-i', dest="include_paths",
help='Additional Include Paths', nargs="*",
@@ -244,22 +241,13 @@ if __name__ == "__main__":
generate_idx = 0
elif args.sources:
generate_idx = 1
elif args.uorb_idl_header:
generate_idx = 2
elif args.json:
generate_idx = 3
else:
print('Error: either --headers, --sources or --json must be specified')
print('Error: either --headers or --sources must be specified')
exit(-1)
if args.file is not None:
all_topics = []
for msg_filename in args.file:
all_topics.extend(get_topics(msg_filename))
all_topics.sort()
for f in args.file:
generate_output_from_file(generate_idx, f, args.outputdir, args.package, args.templatedir, INCL_DEFAULT, all_topics)
generate_output_from_file(generate_idx, f, args.outputdir, args.package, args.templatedir, INCL_DEFAULT)
# Generate topics list header and source file
if TOPICS_LIST_TEMPLATE_FILE[generate_idx] is not None and os.path.isfile(os.path.join(args.templatedir, TOPICS_LIST_TEMPLATE_FILE[generate_idx])):
generate_topics_list_file_from_files(args.file, args.outputdir, TOPICS_LIST_TEMPLATE_FILE[generate_idx], args.templatedir, all_topics)
if os.path.isfile(os.path.join(args.templatedir, TOPICS_LIST_TEMPLATE_FILE[generate_idx])):
generate_topics_list_file_from_files(args.file, args.outputdir, TOPICS_LIST_TEMPLATE_FILE[generate_idx], args.templatedir)
@@ -171,61 +171,6 @@ def get_children_fields(base_type, search_path):
return spec_temp.parsed_fields()
def get_message_fields_str_for_message_hash(msg_fields, search_path):
"""
Get all fields (including for nested types) in the form of:
'''
uint64 timestamp
uint8 esc_count
uint8 esc_online_flags
EscReport[8] esc
uint64 timestamp
uint32 esc_errorcount
int32 esc_rpm
float32 esc_voltage
uint16 failures
int8 esc_power
'''
"""
all_fields_str = ''
for field in msg_fields:
if field.is_header:
continue
type_name = field.type
# detect embedded types
sl_pos = type_name.find('/')
if sl_pos >= 0:
type_name = type_name[sl_pos + 1:]
all_fields_str += type_name + ' ' + field.name + '\n'
if sl_pos >= 0: # nested type, add all nested fields
children_fields = get_children_fields(field.base_type, search_path)
all_fields_str += get_message_fields_str_for_message_hash(children_fields, search_path)
return all_fields_str
def hash_32_fnv1a(data: str):
hash_val = 0x811c9dc5
prime = 0x1000193
for i in range(len(data)):
value = ord(data[i])
hash_val = hash_val ^ value
hash_val *= prime
hash_val &= 0xffffffff
return hash_val
def get_message_hash(msg_fields, search_path):
"""
Get a 32 bit message hash over all fields
"""
all_fields_str = get_message_fields_str_for_message_hash(msg_fields, search_path)
return hash_32_fnv1a(all_fields_str)
def add_padding_bytes(fields, search_path):
"""
Add padding fields before the embedded types, at the end and calculate the
@@ -1,65 +0,0 @@
@{
import genmsg.msgs
import re
from px_generate_uorb_topic_helper import * # this is in Tools/
uorb_struct = '%s_s'%name_snake_case
uorb_struct_upper = name_snake_case.upper()
}@
/****************************************************************
PX4 Cyclone DDS IDL to C Translator compatible idl struct
Source: @file_name_in
Compatible with Cyclone DDS: V0.11.0
*****************************************************************/
#ifndef DDSC_IDL_UORB_@(uorb_struct_upper)_H
#define DDSC_IDL_UORB_@(uorb_struct_upper)_H
#include "dds/ddsc/dds_public_impl.h"
#include "dds/cdr/dds_cdrstream.h"
#include <uORB/topics/@(name_snake_case).h>
@##############################
@# Includes for dependencies
@##############################
@{
for field in spec.parsed_fields():
if (not field.is_builtin):
if (not field.is_header):
(package, name) = genmsg.names.package_resource_name(field.base_type)
package = package or spec.package # convert '' to package
print('#include "%s.h"'%(name))
name = re.sub(r'(?<!^)(?=[A-Z])', '_', name).lower()
print('#include <uORB/topics/%s.h>'%(name))
}@
#ifdef __cplusplus
extern "C" {
#endif
@{
for field in spec.parsed_fields():
if (not field.is_builtin):
if (not field.is_header):
(package, name) = genmsg.names.package_resource_name(field.base_type)
package = package or spec.package # convert '' to package
print('typedef px4_msg_%s px4_msg_px4__msg__%s;' % (name,name))
}@
typedef struct @uorb_struct px4_msg_@(file_base_name);
extern const struct dds_cdrstream_desc px4_msg_@(file_base_name)_cdrstream_desc;
#ifdef __cplusplus
}
#endif
#endif /* DDSC_IDL_UORB_@(uorb_struct_upper)_H */
+2 -3
View File
@@ -124,9 +124,8 @@ static inline constexpr int ucdr_topic_size_@(topic)()
return @(struct_size);
}
static inline bool ucdr_serialize_@(topic)(const void* data, ucdrBuffer& buf, int64_t time_offset = 0)
bool ucdr_serialize_@(topic)(const @(uorb_struct)& topic, ucdrBuffer& buf, int64_t time_offset = 0)
{
const @(uorb_struct)& topic = *static_cast<const @(uorb_struct)*>(data);
@{
for field_type, field_name, field_size, padding in fields:
if padding > 0:
@@ -153,7 +152,7 @@ for field_type, field_name, field_size, padding in fields:
return true;
}
static inline bool ucdr_deserialize_@(topic)(ucdrBuffer& buf, @(uorb_struct)& topic, int64_t time_offset = 0)
bool ucdr_deserialize_@(topic)(ucdrBuffer& buf, @(uorb_struct)& topic, int64_t time_offset = 0)
{
@{
for field_type, field_name, field_size, padding in fields:
+6 -4
View File
@@ -14,7 +14,6 @@
@# - spec (msggen.MsgSpec) Parsed specification of the .msg file
@# - search_path (dict) search paths for genmsg
@# - topics (List of String) topic names
@# - all_topics (List of String) all generated topic names (sorted)
@###############################################
/****************************************************************************
*
@@ -58,9 +57,9 @@ from px_generate_uorb_topic_helper import * # this is in Tools/
uorb_struct = '%s_s'%name_snake_case
message_hash = get_message_hash(spec.parsed_fields(), search_path)
sorted_fields = sorted(spec.parsed_fields(), key=sizeof_field_type, reverse=True)
struct_size, padding_end_size = add_padding_bytes(sorted_fields, search_path)
topic_fields = ["%s %s" % (convert_type(field.type, True), field.name) for field in sorted_fields]
}@
#include <inttypes.h>
@@ -73,9 +72,12 @@ struct_size, padding_end_size = add_padding_bytes(sorted_fields, search_path)
#include <lib/matrix/matrix/math.hpp>
#include <lib/mathlib/mathlib.h>
@# join all msg files in one line e.g: "float[3] position;float[3] velocity;bool armed"
@# This is used for the logger
constexpr char __orb_@(name_snake_case)_fields[] = "@( ";".join(topic_fields) );";
@[for topic in topics]@
static_assert(static_cast<orb_id_size_t>(ORB_ID::@topic) == @(all_topics.index(topic)), "ORB_ID index mismatch");
ORB_DEFINE(@topic, struct @uorb_struct, @(struct_size-padding_end_size), @(message_hash)u, static_cast<orb_id_size_t>(ORB_ID::@topic));
ORB_DEFINE(@topic, struct @uorb_struct, @(struct_size-padding_end_size), __orb_@(name_snake_case)_fields, static_cast<uint8_t>(ORB_ID::@topic));
@[end for]
void print_message(const orb_metadata *meta, const @uorb_struct& message)
-50
View File
@@ -1,50 +0,0 @@
@###############################################
@#
@# PX4 ROS compatible message source code
@# generation for C++
@#
@# EmPy template for generating <msg>.h files
@# Based on the original template for ROS
@#
@###############################################
@# Start of Template
@#
@# Context:
@# - file_name_in (String) Source file
@# - spec (msggen.MsgSpec) Parsed specification of the .msg file
@# - search_path (dict) search paths for genmsg
@# - topics (List of String) topic names
@# - all_topics (List of String) all generated topic names (sorted)
@###############################################
@{
import genmsg.msgs
import json
from px_generate_uorb_topic_helper import * # this is in Tools/
uorb_struct = '%s_s'%name_snake_case
sorted_fields = sorted(spec.parsed_fields(), key=sizeof_field_type, reverse=True)
struct_size, padding_end_size = add_padding_bytes(sorted_fields, search_path)
topic_fields = ["%s %s" % (convert_type(field.type, True), field.name) for field in sorted_fields]
dependencies = []
for field in spec.parsed_fields():
if not field.is_header:
type_name = field.type
# detect embedded types
sl_pos = type_name.find('/')
if sl_pos >= 0: # nested type
dependencies.append(field.base_type)
}@
{
@# join all msg files in one line e.g: "float[3] position;float[3] velocity;bool armed;"
"fields": @( json.dumps(bytearray(";".join(topic_fields)+";", 'utf-8').decode('unicode_escape')) ),
"fields_total_length": @(sum([len(convert_type(field.type))+1+len(field.name)+1 for field in sorted_fields])),
"orb_ids": @( json.dumps([ all_topics.index(topic) for topic in topics]) ),
"main_orb_id": @( all_topics.index(name_snake_case) if name_snake_case in all_topics else -1 ),
"dependencies": @( json.dumps(list(set(dependencies))) ),
"name": "@( spec.full_name )"
}
+7 -5
View File
@@ -8,7 +8,7 @@
@#
@# Context:
@# - msgs (List) list of all msg files
@# - all_topics (List) list of all topic names (sorted)
@# - multi_topics (List) list of all multi-topic names
@###############################################
/****************************************************************************
*
@@ -50,7 +50,9 @@ msg_names = list(set([mn.replace(".msg", "") for mn in msgs])) # set() filters d
msg_names.sort()
msgs_count = len(msg_names)
topics_count = len(all_topics)
topic_names = list(set(topics)) # set() filters duplicates
topic_names.sort()
topics_count = len(topics)
}@
@[for msg_name in msg_names]@
@@ -58,8 +60,8 @@ topics_count = len(all_topics)
@[end for]
const constexpr struct orb_metadata *const uorb_topics_list[ORB_TOPICS_COUNT] = {
@[for idx, topic_name in enumerate(all_topics, 1)]@
ORB_ID(@(topic_name))@[if idx != all_topics], @[end if]
@[for idx, topic_name in enumerate(topic_names, 1)]@
ORB_ID(@(topic_name))@[if idx != topic_names], @[end if]
@[end for]
};
@@ -74,5 +76,5 @@ const struct orb_metadata *get_orb_meta(ORB_ID id)
return nullptr;
}
return uorb_topics_list[static_cast<orb_id_size_t>(id)];
return uorb_topics_list[static_cast<uint8_t>(id)];
}
+6 -5
View File
@@ -7,8 +7,7 @@
@# Start of Template
@#
@# Context:
@# - msgs (List) list of all msg files
@# - all_topics (List) list of all topic names (sorted)
@# - topics (List) list of all topic names
@###############################################
/****************************************************************************
*
@@ -44,7 +43,9 @@
****************************************************************************/
@{
topics_count = len(all_topics)
topics_count = len(topics)
topic_names_all = list(set(topics)) # set() filters duplicates
topic_names_all.sort()
}@
#pragma once
@@ -61,8 +62,8 @@ static constexpr size_t orb_topics_count() { return ORB_TOPICS_COUNT; }
*/
extern const struct orb_metadata *const *orb_get_topics() __EXPORT;
enum class ORB_ID : orb_id_size_t {
@[for idx, topic_name in enumerate(all_topics)]@
enum class ORB_ID : uint8_t {
@[for idx, topic_name in enumerate(topic_names_all)]@
@(topic_name) = @(idx),
@[end for]
INVALID
-16
View File
@@ -250,22 +250,6 @@ class SourceParser(object):
event.group = "arming_check"
event.prepend_arguments([('navigation_mode_group_t', 'modes'),
('uint8_t', 'health_component_index')])
elif call in ['reporter.healthFailureExt', 'reporter.armingCheckFailureExt']: # from ROS2
assert len(args_split) == num_args + 3, \
"Unexpected Number of arguments for: {:}, {:}".format(args_split, num_args)
m = self.re_event_id.search(args_split[0])
if m:
_, event_name = m.group(1, 2)
else:
raise Exception("Could not extract event ID from {:}".format(args_split[0]))
event.name = event_name
event.message = args_split[2][1:-1]
if 'health' in call:
event.group = "health"
else:
event.group = "arming_check"
event.prepend_arguments([('navigation_mode_group_t', 'modes'),
('uint8_t', 'health_component_index')])
else:
raise Exception("unknown event method call: {}, args: {}".format(call, args))
+38 -10
View File
@@ -1,7 +1,7 @@
#! /usr/bin/env bash
## Bash script to setup PX4 development environment on Arch Linux.
## Tested on Arch 2023-03-01
## Tested on Manjaro 20.2.1.
##
## Installs:
## - Common dependencies and tools for nuttx, jMAVSim
@@ -50,7 +50,6 @@ sudo pacman -Sy --noconfirm --needed \
cmake \
cppcheck \
doxygen \
fuse2 \
gdb \
git \
gnutls \
@@ -67,7 +66,7 @@ sudo pacman -Sy --noconfirm --needed \
# Python dependencies
echo "Installing PX4 Python3 dependencies"
pip install --break-system-packages -r ${DIR}/${REQUIREMENTS_FILE}
pip install --user -r ${DIR}/requirements.txt
# NuttX toolchain (arm-none-eabi-gcc)
if [[ $INSTALL_NUTTX == "true" ]]; then
@@ -75,17 +74,45 @@ if [[ $INSTALL_NUTTX == "true" ]]; then
echo "Installing NuttX dependencies"
sudo pacman -S --noconfirm --needed \
arm-none-eabi-gcc \
arm-none-eabi-newlib \
gperf \
vim \
;
if [ ! -z "$USER" ]; then
# add user to dialout group (serial port access)
sudo echo usermod -aG uucp $USER
sudo usermod -aG uucp $USER
fi
# don't run modem manager (interferes with PX4 serial port usage)
sudo systemctl disable --now ModemManager
# remove modem manager (interferes with PX4 serial port usage)
sudo pacman -R modemmanager --noconfirm
# arm-none-eabi-gcc
NUTTX_GCC_VERSION="10-2020-q4-major"
NUTTX_GCC_VERSION_SHORT="10-2020q4"
source $HOME/.profile # load changed path for the case the script is reran before relogin
if [ $(which arm-none-eabi-gcc) ]; then
GCC_VER_STR=$(arm-none-eabi-gcc --version)
GCC_FOUND_VER=$(echo $GCC_VER_STR | grep -c "${NUTTX_GCC_VERSION}")
fi
if [[ "$GCC_FOUND_VER" == "1" ]]; then
echo "arm-none-eabi-gcc-${NUTTX_GCC_VERSION} found, skipping installation"
else
echo "Installing arm-none-eabi-gcc-${NUTTX_GCC_VERSION}";
wget -O /tmp/gcc-arm-none-eabi-${NUTTX_GCC_VERSION}-linux.tar.bz2 https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu-rm/${NUTTX_GCC_VERSION_SHORT}/gcc-arm-none-eabi-${NUTTX_GCC_VERSION}-x86_64-linux.tar.bz2 && \
sudo tar -jxf /tmp/gcc-arm-none-eabi-${NUTTX_GCC_VERSION}-linux.tar.bz2 -C /opt/;
# add arm-none-eabi-gcc to user's PATH
exportline="export PATH=/opt/gcc-arm-none-eabi-${NUTTX_GCC_VERSION}/bin:\$PATH"
if grep -Fxq "$exportline" $HOME/.profile; then
echo "${NUTTX_GCC_VERSION} path already set.";
else
echo $exportline >> $HOME/.profile;
fi
fi
fi
# Simulation tools
@@ -95,7 +122,8 @@ if [[ $INSTALL_SIM == "true" ]]; then
# java (jmavsim)
sudo pacman -S --noconfirm --needed \
ant
ant \
jdk-openjdk \
;
# Gazebo setup
@@ -133,5 +161,5 @@ fi
if [[ $INSTALL_NUTTX == "true" ]]; then
echo
echo "Reboot or logout, login computer before attempting to flash NuttX targets"
echo "Reboot or logout, login computer before attempting to build NuttX targets"
fi
+1 -1
View File
@@ -1 +1 @@
symforce>=0.9.0
symforce>=0.5.0
+1 -1
View File
@@ -2,7 +2,7 @@ argcomplete
argparse>=1.2
cerberus
coverage
empy==3.3.4
empy>=3.3
future
jinja2>=2.8
jsonschema
+2 -2
View File
@@ -155,7 +155,7 @@ if [[ $INSTALL_NUTTX == "true" ]]; then
if [ -n "$USER" ]; then
# add user to dialout group (serial port access)
sudo usermod -aG dialout $USER
sudo usermod -a -G dialout $USER
fi
# arm-none-eabi-gcc
@@ -165,7 +165,7 @@ if [[ $INSTALL_NUTTX == "true" ]]; then
source $HOME/.profile # load changed path for the case the script is reran before relogin
if [ $(which arm-none-eabi-gcc) ]; then
GCC_VER_STR=$(arm-none-eabi-gcc --version)
GCC_FOUND_VER=$(echo $GCC_VER_STR | grep -c "${NUTTX_GCC_VERSION}" || true)
GCC_FOUND_VER=$(echo $GCC_VER_STR | grep -c "${NUTTX_GCC_VERSION}")
fi
if [[ "$GCC_FOUND_VER" == "1" ]]; then
@@ -1,14 +0,0 @@
<?xml version="1.0"?>
<model>
<name>Advanced Plane</name>
<version>1.0</version>
<sdf version='1.5'>model.sdf</sdf>
<author>
<name>Karthik Srivatsan</name>
</author>
<description>
This is a model of a standard plane, which uses the advanced liftdrag plugin.
</description>
</model>
@@ -1,578 +0,0 @@
<?xml version="1.0"?>
<sdf version='1.5'>
<model name='plane'>
<pose>0 0 0.246 0 0 0</pose>
<link name='base_link'>
<pose>0 0 0 0 0 0</pose>
<inertial>
<pose>0 0 0 0 0 0</pose>
<mass>1</mass>
<inertia>
<ixx>0.197563</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>0.1458929</iyy>
<iyz>0</iyz>
<izz>0.1477</izz>
</inertia>
</inertial>
<collision name='base_link_collision'>
<pose>0 0 -0.07 0 0 0</pose>
<geometry>
<box>
<size>0.47 0.47 0.11</size>
</box>
</geometry>
<surface>
<contact>
<ode>
<max_vel>10</max_vel>
<min_depth>0.01</min_depth>
</ode>
</contact>
<friction>
<ode/>
</friction>
</surface>
</collision>
<visual name='base_link_visual'>
<pose>0.07 0 -0.08 0 0 0</pose>
<geometry>
<mesh>
<scale>0.1 0.1 0.1</scale>
<uri>https://fuel.gazebosim.org/1.0/PX4/models/Advanced%20Plane/tip/files/meshes/body.dae</uri>
</mesh>
</geometry>
<material>
<ambient>.175 .175 .175 1.0</ambient>
<diffuse>.175 .175 .175 1.0</diffuse>
</material>
</visual>
<gravity>1</gravity>
<velocity_decay/>
<self_collide>0</self_collide>
<sensor name="imu_sensor" type="imu">
<always_on>1</always_on>
<update_rate>250</update_rate>
</sensor>
<sensor name="air_pressure_sensor" type="air_pressure">
<always_on>1</always_on>
<update_rate>50</update_rate>
<air_pressure>
<pressure>
<noise type="gaussian">
<mean>0</mean>
<stddev>0.01</stddev>
</noise>
</pressure>
</air_pressure>
</sensor>
</link>
<link name='rotor_puller'>
<pose>0.3 0 0.0 0 1.57 0</pose>
<inertial>
<pose>0 0 0 0 0 0</pose>
<mass>0.005</mass>
<inertia>
<ixx>9.75e-07</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>0.000166704</iyy>
<iyz>0</iyz>
<izz>0.000167604</izz>
</inertia>
</inertial>
<collision name='rotor_puller_collision'>
<pose>0.0 0 0.0 0 0 0</pose>
<geometry>
<cylinder>
<length>0.005</length>
<radius>0.1</radius>
</cylinder>
</geometry>
<surface>
<contact>
<ode/>
</contact>
<friction>
<ode/>
</friction>
</surface>
</collision>
<visual name='rotor_puller_visual'>
<pose>0 0 -0.09 0 0 0</pose>
<geometry>
<mesh>
<scale>1 1 1</scale>
<uri>https://fuel.gazebosim.org/1.0/PX4/models/Advanced%20Plane/tip/files/meshes/iris_prop_ccw.dae</uri>
</mesh>
</geometry>
<material>
<ambient>.175 .175 .175 1.0</ambient>
<diffuse>.175 .175 .175 1.0</diffuse>
</material>
</visual>
<gravity>1</gravity>
<velocity_decay/>
<self_collide>0</self_collide>
</link>
<joint name='rotor_puller_joint' type='revolute'>
<child>rotor_puller</child>
<parent>base_link</parent>
<axis>
<xyz>1 0 0</xyz>
<limit>
<lower>-1e+16</lower>
<upper>1e+16</upper>
</limit>
<dynamics>
<spring_reference>0</spring_reference>
<spring_stiffness>0</spring_stiffness>
</dynamics>
<use_parent_model_frame>1</use_parent_model_frame>
</axis>
</joint>
<link name="left_elevon">
<inertial>
<mass>0.00000001</mass>
<inertia>
<ixx>0.000001</ixx>
<ixy>0.0</ixy>
<iyy>0.000001</iyy>
<ixz>0.0</ixz>
<iyz>0.0</iyz>
<izz>0.000001</izz>
</inertia>
<pose>0 0.3 0 0.00 0 0.0</pose>
</inertial>
<visual name='left_elevon_visual'>
<pose>0.07 0.0 -0.08 0.00 0 0.0</pose>
<geometry>
<mesh>
<scale>0.1 0.1 0.1</scale>
<uri>https://fuel.gazebosim.org/1.0/PX4/models/Advanced%20Plane/tip/files/meshes/left_aileron.dae</uri>
</mesh>
</geometry>
<material>
<ambient>1 0 0 1.0</ambient>
<diffuse>1 0 0 1.0</diffuse>
</material>
</visual>
</link>
<link name="right_elevon">
<inertial>
<mass>0.00000001</mass>
<inertia>
<ixx>0.000001</ixx>
<ixy>0.0</ixy>
<iyy>0.000001</iyy>
<ixz>0.0</ixz>
<iyz>0.0</iyz>
<izz>0.000001</izz>
</inertia>
<pose>0 -0.3 0 0.00 0 0.0</pose>
</inertial>
<visual name='right_elevon_visual'>
<pose>0.07 0.0 -0.08 0.00 0 0.0</pose>
<geometry>
<mesh>
<scale>0.1 0.1 0.1</scale>
<uri>https://fuel.gazebosim.org/1.0/PX4/models/Advanced%20Plane/tip/files/meshes/right_aileron.dae</uri>
</mesh>
</geometry>
<material>
<ambient>1 0 0 1.0</ambient>
<diffuse>1 0 0 1.0</diffuse>
</material>
</visual>
</link>
<link name="left_flap">
<inertial>
<mass>0.00000001</mass>
<inertia>
<ixx>0.000001</ixx>
<ixy>0.0</ixy>
<iyy>0.000001</iyy>
<ixz>0.0</ixz>
<iyz>0.0</iyz>
<izz>0.000001</izz>
</inertia>
<pose>0 0.15 0 0.00 0 0.0</pose>
</inertial>
<visual name='left_flap_visual'>
<pose>0.07 0.0 -0.08 0.00 0 0.0</pose>
<geometry>
<mesh>
<scale>0.1 0.1 0.1</scale>
<uri>https://fuel.gazebosim.org/1.0/PX4/models/Advanced%20Plane/tip/files/meshes/left_flap.dae</uri>
</mesh>
</geometry>
<material>
<ambient>1 0 0 1.0</ambient>
<diffuse>1 0 0 1.0</diffuse>
</material>
</visual>
</link>
<link name="right_flap">
<inertial>
<mass>0.00000001</mass>
<inertia>
<ixx>0.000001</ixx>
<ixy>0.0</ixy>
<iyy>0.000001</iyy>
<ixz>0.0</ixz>
<iyz>0.0</iyz>
<izz>0.000001</izz>
</inertia>
<pose>0 -0.15 0 0.00 0 0.0</pose>
</inertial>
<visual name='right_flap_visual'>
<pose>0.07 0.0 -0.08 0.00 0 0.0</pose>
<geometry>
<mesh>
<scale>0.1 0.1 0.1</scale>
<uri>https://fuel.gazebosim.org/1.0/PX4/models/Advanced%20Plane/tip/files/meshes/right_flap.dae</uri>
</mesh>
</geometry>
<material>
<ambient>1 0 0 1.0</ambient>
<diffuse>1 0 0 1.0</diffuse>
</material>
</visual>
</link>
<link name="elevator">
<inertial>
<mass>0.00000001</mass>
<inertia>
<ixx>0.000001</ixx>
<ixy>0.0</ixy>
<iyy>0.000001</iyy>
<ixz>0.0</ixz>
<iyz>0.0</iyz>
<izz>0.000001</izz>
</inertia>
<pose> -0.5 0 0 0.00 0 0.0</pose>
</inertial>
<visual name='elevator_visual'>
<pose>0.07 0.0 -0.08 0.00 0 0.0</pose>
<geometry>
<mesh>
<scale>0.1 0.1 0.1</scale>
<uri>https://fuel.gazebosim.org/1.0/PX4/models/Advanced%20Plane/tip/files/meshes/elevators.dae</uri>
</mesh>
</geometry>
<material>
<ambient>1 0 0 1.0</ambient>
<diffuse>1 0 0 1.0</diffuse>
</material>
</visual>
</link>
<link name="rudder">
<inertial>
<mass>0.00000001</mass>
<inertia>
<ixx>0.000001</ixx>
<ixy>0.0</ixy>
<iyy>0.000001</iyy>
<ixz>0.0</ixz>
<iyz>0.0</iyz>
<izz>0.000001</izz>
</inertia>
<pose>-0.5 0 0.05 0 0 0 </pose>
</inertial>
<visual name='rudder_visual'>
<pose>0.07 0.0 -0.08 0.00 0 0.0</pose>
<geometry>
<mesh>
<scale>0.1 0.1 0.1</scale>
<uri>https://fuel.gazebosim.org/1.0/PX4/models/Advanced%20Plane/tip/files/meshes/rudder.dae</uri>
</mesh>
</geometry>
<material>
<ambient>1 0 0 1.0</ambient>
<diffuse>1 0 0 1.0</diffuse>
</material>
</visual>
</link>
<joint name='servo_0' type='revolute'>
<parent>base_link</parent>
<child>left_elevon</child>
<pose>-0.07 0.4 0.08 0.00 0 0.0</pose>
<axis>
<xyz>0 1 0</xyz>
<limit>
<!-- -30/+30 deg. -->
<lower>-0.53</lower>
<upper>0.53</upper>
</limit>
<dynamics>
<damping>1.000</damping>
</dynamics>
</axis>
<physics>
<ode>
<implicit_spring_damper>1</implicit_spring_damper>
</ode>
</physics>
</joint>
<plugin
filename="gz-sim-joint-position-controller-system" name="gz::sim::systems::JointPositionController">
<joint_name>servo_0</joint_name>
<sub_topic>servo_0</sub_topic>
<p_gain>10</p_gain>
<i_gain>0</i_gain>
<d_gain>0</d_gain>
</plugin>
<joint name='servo_1' type='revolute'>
<parent>base_link</parent>
<child>right_elevon</child>
<pose>-0.07 -0.4 0.08 0.00 0 0.0</pose>
<axis>
<xyz>0 1 0</xyz>
<limit>
<!-- -30/+30 deg. -->
<lower>-0.53</lower>
<upper>0.53</upper>
</limit>
<dynamics>
<damping>1.000</damping>
</dynamics>
</axis>
<physics>
<ode>
<implicit_spring_damper>1</implicit_spring_damper>
</ode>
</physics>
</joint>
<plugin
filename="gz-sim-joint-position-controller-system" name="gz::sim::systems::JointPositionController">
<joint_name>servo_1</joint_name>
<sub_topic>servo_1</sub_topic>
<p_gain>10</p_gain>
<i_gain>0</i_gain>
<d_gain>0</d_gain>
</plugin>
<joint name='servo_4' type='revolute'>
<parent>base_link</parent>
<child>left_flap</child>
<pose>-0.07 0.2 0.08 0.00 0 0.0</pose>
<axis>
<xyz>0 1 0</xyz>
<limit>
<!-- -30/+30 deg. -->
<lower>-0.53</lower>
<upper>0.53</upper>
</limit>
<dynamics>
<damping>1.000</damping>
</dynamics>
</axis>
<physics>
<ode>
<implicit_spring_damper>1</implicit_spring_damper>
</ode>
</physics>
</joint>
<plugin
filename="gz-sim-joint-position-controller-system" name="gz::sim::systems::JointPositionController">
<joint_name>servo_4</joint_name>
<sub_topic>servo_4</sub_topic>
<p_gain>10</p_gain>
<i_gain>0</i_gain>
<d_gain>0</d_gain>
</plugin>
<joint name='servo_5' type='revolute'>
<parent>base_link</parent>
<child>right_flap</child>
<pose>-0.07 -0.2 0.08 0.00 0 0.0</pose>
<axis>
<xyz>0 1 0</xyz>
<limit>
<!-- -30/+30 deg. -->
<lower>-0.53</lower>
<upper>0.53</upper>
</limit>
<dynamics>
<damping>1.000</damping>
</dynamics>
</axis>
<physics>
<ode>
<implicit_spring_damper>1</implicit_spring_damper>
</ode>
</physics>
</joint>
<plugin
filename="gz-sim-joint-position-controller-system" name="gz::sim::systems::JointPositionController">
<joint_name>servo_5</joint_name>
<sub_topic>servo_5</sub_topic>
<p_gain>10</p_gain>
<i_gain>0</i_gain>
<d_gain>0</d_gain>
</plugin>
<joint name='servo_2' type='revolute'>
<parent>base_link</parent>
<child>elevator</child>
<pose> -0.5 0 0 0 0 0</pose>
<axis>
<xyz>0 1 0</xyz>
<limit>
<!-- -30/+30 deg. -->
<lower>-0.53</lower>
<upper>0.53</upper>
</limit>
<dynamics>
<damping>1.000</damping>
</dynamics>
</axis>
<physics>
<ode>
<implicit_spring_damper>1</implicit_spring_damper>
</ode>
</physics>
</joint>
<plugin
filename="gz-sim-joint-position-controller-system" name="gz::sim::systems::JointPositionController">
<joint_name>servo_2</joint_name>
<sub_topic>servo_2</sub_topic>
<p_gain>10</p_gain>
<i_gain>0</i_gain>
<d_gain>0</d_gain>
</plugin>
<joint name='servo_3' type='revolute'>
<parent>base_link</parent>
<child>rudder</child>
<pose>-0.5 0 0.05 0.00 0 0.0</pose>
<axis>
<xyz>0 0 1</xyz>
<limit>
<!-- -30/+30 deg. -->
<lower>-0.53</lower>
<upper>0.53</upper>
</limit>
<dynamics>
<damping>1.000</damping>
</dynamics>
</axis>
<physics>
<ode>
<implicit_spring_damper>1</implicit_spring_damper>
</ode>
</physics>
</joint>
<plugin
filename="gz-sim-joint-position-controller-system" name="gz::sim::systems::JointPositionController">
<joint_name>servo_3</joint_name>
<sub_topic>servo_3</sub_topic>
<p_gain>10</p_gain>
<i_gain>0</i_gain>
<d_gain>0</d_gain>
</plugin>
<plugin filename="gz-sim-advanced-lift-drag-system" name="gz::sim::systems::AdvancedLiftDrag">
<a0>0.0</a0>
<CL0>0.15188</CL0>
<AR>6.5</AR>
<eff>0.97</eff>
<CLa>5.015</CLa>
<CD0>0.029</CD0>
<Cem0>0.075</Cem0>
<Cema>-0.463966</Cema>
<CYb>-0.258244</CYb>
<Cellb>-0.039250</Cellb>
<Cenb>0.100826</Cenb>
<CDp>0.0</CDp>
<CYp>0.065861</CYp>
<CLp>0.0</CLp>
<Cellp>-0.487407</Cellp>
<Cemp>0.0</Cemp>
<Cenp>-0.040416</Cenp>
<CDq>0.055166</CDq>
<CYq>0.0</CYq>
<CLq>7.971792</CLq>
<Cellq>0.0</Cellq>
<Cemq>-12.140140</Cemq>
<Cenq>0.0</Cenq>
<CDr>0.0</CDr>
<CYr>0.230299</CYr>
<CLr>0.0</CLr>
<Cellr>0.078165</Cellr>
<Cemr>0.0</Cemr>
<Cenr>-0.089947</Cenr>
<alpha_stall>0.3391428111</alpha_stall>
<CLa_stall>-3.85</CLa_stall>
<CDa_stall>-0.9233984055</CDa_stall>
<Cema_stall>0</Cema_stall>
<cp>-0.12 0.0 0.0</cp>
<area>0.34</area>
<mac>0.22</mac>
<air_density>1.2041</air_density>
<forward>1 0 0</forward>
<upward>0 0 1</upward>
<link_name>base_link</link_name>
<num_ctrl_surfaces>4</num_ctrl_surfaces>
<control_surface>
<name>servo_0</name>
<index>0</index>
<direction>1</direction>
<CD_ctrl>-0.000059</CD_ctrl>
<CY_ctrl>0.000171</CY_ctrl>
<CL_ctrl>-0.011940</CL_ctrl>
<Cell_ctrl>-0.003331</Cell_ctrl>
<Cem_ctrl>0.001498</Cem_ctrl>
<Cen_ctrl>-0.000057</Cen_ctrl>
</control_surface>
<control_surface>
<name>servo_1</name>
<direction>1</direction>
<index>1</index>
<CD_ctrl>-0.000059</CD_ctrl>
<CY_ctrl>-0.000171</CY_ctrl>
<CL_ctrl>-0.011940</CL_ctrl>
<Cell_ctrl>0.003331</Cell_ctrl>
<Cem_ctrl>0.001498</Cem_ctrl>
<Cen_ctrl>0.000057</Cen_ctrl>
</control_surface>
<control_surface>
<name>servo_2</name>
<direction>-1</direction>
<index>2</index>
<CD_ctrl>0.000274</CD_ctrl>
<CY_ctrl>0</CY_ctrl>
<CL_ctrl>0.010696</CL_ctrl>
<Cell_ctrl>0.0</Cell_ctrl>
<Cem_ctrl>-0.025798</Cem_ctrl>
<Cen_ctrl>0.0</Cen_ctrl>
</control_surface>
<control_surface>
<name>servo_3</name>
<direction>1</direction>
<index>3</index>
<CD_ctrl>0.0</CD_ctrl>
<CY_ctrl>-0.003913</CY_ctrl>
<CL_ctrl>0.0</CL_ctrl>
<Cell_ctrl>-0.000257</Cell_ctrl>
<Cem_ctrl>0.0</Cem_ctrl>
<Cen_ctrl>0.001613</Cen_ctrl>
</control_surface>
</plugin>
<plugin filename="gz-sim-multicopter-motor-model-system" name="gz::sim::systems::MulticopterMotorModel">
<jointName>rotor_puller_joint</jointName>
<linkName>rotor_puller</linkName>
<turningDirection>cw</turningDirection>
<timeConstantUp>0.0125</timeConstantUp>
<timeConstantDown>0.025</timeConstantDown>
<maxRotVelocity>3500</maxRotVelocity>
<motorConstant>8.54858e-06</motorConstant>
<momentConstant>0.01</momentConstant>
<commandSubTopic>command/motor_speed</commandSubTopic>
<motorNumber>0</motorNumber>
<rotorDragCoefficient>8.06428e-05</rotorDragCoefficient>
<rollingMomentCoefficient>1e-06</rollingMomentCoefficient>
<rotorVelocitySlowdownSim>10</rotorVelocitySlowdownSim>
<motorType>velocity</motorType>
</plugin>
</model>
</sdf>
@@ -1,15 +0,0 @@
<?xml version="1.0"?>
<model>
<name>Omnicopter</name>
<version>1.0</version>
<sdf version='1.9'>model.sdf</sdf>
<author>
<name>Jaeyoung Lim</name>
<email>jalim@ethz.ch</email>
</author>
<description>
Omnicopter model for over actuated system
</description>
</model>
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<sdf version='1.9'>
<include>
<name>omnicopter</name>
<pose>0 0 0.2 0 0 0</pose>
<uri>https://fuel.gazebosim.org/1.0/PX4/models/Omnicopter</uri>
</include>
</sdf>
@@ -806,7 +806,7 @@
<plugin filename="gz-sim-multicopter-motor-model-system" name="gz::sim::systems::MulticopterMotorModel">
<jointName>rotor_puller_joint</jointName>
<linkName>rotor_puller</linkName>
<turningDirection>ccw</turningDirection>
<turningDirection>cw</turningDirection>
<timeConstantUp>0.0125</timeConstantUp>
<timeConstantDown>0.025</timeConstantDown>
<maxRotVelocity>1000</maxRotVelocity>
@@ -1,149 +0,0 @@
## Purpose
The idea of this tool is to automate the writing of the Advanced Lift Drag plugin by automatizing the coefficient generation and requiring minimal user calculations.
## Setup
In order to run this tool, it is necessary to follow these steps:
1. Download AVL 3.36 from <https://web.mit.edu/drela/Public/web/avl/>. 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:
```shell
sudo tar -xf avl3.36.tgz
mv ./Avl /home/
```
Follow the README.md found in Avl to finish the setup process for AVL (requires to set up plotlib and eispack libraries). I recommend using the gfortran compile option. This might require you to install gfortran. This can be done by running:
```shell
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. 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.
If you want to move the location of the AVL directory, this can simply be done by passing the `--avl_path` flag to the `input_avl.py` file, using the desired directory location for the flag (don't forget to place a "/" behind the last part of the path). Running this will automatically also adjust the paths where necessary.
## Run
To run the tool all that is needed is to modify the `input.yml` to the plane that you desire and then run `python input_avl.py <your_custom_yaml_file>.yml` Note that you require to have the yaml and argparse packages in your python environment to run this. An example template has been provided in the form of the `input.yml` that implements a standard plane with two ailerons, an elevator and a rudder. This example template can be run using: `python input_avl.py --yaml_file input.yml`.
Once the script has been executed, the generated .avl, .sdf and a plot of the proposed control surfaces can be found in <your-planes-name> directory. The sdf file is the generated Advanced Lift Drag Plugin that can be copied and pasted straight into a model.sdf file, which can then be run in Gazebo.
## Functionality
The tool first asks the user for a range of vehicle specific parameters that are needed in order to specify the geometry and physical properties of the plane. The user has the choice to define a completely custom model, or alternatively select a predefined model template (such as a Cessna or a VTOL), which has a known number of control surfaces, and then provide only some physical properties, without having to define the entire model themselves. The input_avl.py file takes the provided parameter and creates an .avl file from this that can be read by AVL (the program). This happens in the process.sh file. The necessary output generated by AVL will be saved in two files: custom_vehicle_body_axis_derivatives.txt and custom_vehicle_stability_derivatives.txt. These two files contain the parameters that are required in order to populate the Advanced Lift Drag Plugin. Finally, avl_out_parse.py reads the generated .txt files and accordingly assigns parameters to the correct element in sdf. Once this is done, it is only a question of copy and pasting the generated Advanced Lift Drag plugin (found as <custom_plane>.sdf into the desired model.sdf file. )
## Usability
The current implementation provides a minimal working example. More accurate measurements can be made by adjusting the chosen number of vortices along span and chord according to desired preferences. A good starting point for this can be found here: <https://www.redalyc.org/pdf/6735/673571173005.pdf>. Furthermore, one can also more accurately model a vehicle by using a larger number of sections. In the current .yml file, only a left and right edge are defined for each surface yielding exactly one section, but the code supports expanding this to any number of desired sections.
## IMPORTANT POINTS TO NOTE
- A control surface in AVL is always defined from left to right. This means you need to first provide the left edge of a surface and then the right edge. If you do this the opposite way around, a surface will essentially be defined upside down.
- The tool is designed to only support at most two control surfaces of any type on any one vehicle. Having more surfaces than that can lead to faulty behavior.
- Another important point is that these scripts make use of the match, case syntax, which was only introduced in Python in version 3.10.
- The primary reference resource for AVL can be found at <https://web.mit.edu/drela/Public/web/avl/AVL_User_Primer.pdf>. This document was written by the creators of AVL and contains all the variables that could be required in defining the control surfaces.
- AVL cannot predict stall values. As such these need to be calculated/estimated another way. In the current implementation, default stall values have been taken from PX4's Advanced Plane. These should naturally be changed for new/different models.
## Parameter Assignment
Below is a comprehensive list on how the parameters are assigned at output and what files in AVL they are taken from. I am by no means an AVL expert, so please verify that these are actually the correct parameters required by the Advanced Lift Drag Plugin. For an explanation of what the parameters do, please see take a look at the Advanced Lift Drag Plugin.
(name-in-AVL) -> (name-in-plugin)
From the stability derivatives log file, the following advanced lift drag plugin parameters are taken:
Alpha -> alpha The angle of attack
Cmtot -> Cem0 Pitching moment coefficient at zero angle of attack
CLtot -> CL0 Lift Coefficient at zero angle of attack
CDtot -> CD0 Drag coefficient at zero angle of attack
CLa -> CLa dCL/da (slope of CL-alpha curve)
CYa -> CYa dCy/da (sideforce slope wrt alpha)
Cla -> Cella dCl/da (roll moment slope wrt alpha)
Cma -> Cema dCm/da (pitching moment slope wrt alpha - before stall)
Cna -> Cena dCn/da (yaw moment slope wrt alpha)
CLb -> CLb dCL/dbeta (lift coefficient slope wrt beta)
CYb -> CYb dCY/dbeta (side force slope wrt beta)
Clb -> Cellb dCl/dbeta (roll moment slope wrt beta)
Cmb -> Cemb dCm/dbeta (pitching moment slope wrt beta)
Cnb -> Cenb dCn/dbeta (yaw moment slope wrt beta)
From the body axis derivatives log file, the following advanced lift drag plugin parameters are taken:
e -> eff Wing efficiency (Oswald efficiency factor for a 3D wing)
CXp -> CDp dCD/dp (drag coefficient slope wrt roll rate)
CYp -> CYp dCY/dp (sideforce slope wrt roll rate)
CZp -> CLp dCL/dp (lift coefficient slope wrt roll rate)
Clp -> Cellp dCl/dp (roll moment slope wrt roll rate)
Cmp -> Cemp dCm/dp (pitching moment slope wrt roll rate)
Cmp -> Cenp dCn/dp (yaw moment slope wrt roll rate)
CXq -> CDq dCD/dq (drag coefficient slope wrt pitching rate)
CYq -> CYq dCY/dq (side force slope wrt pitching rate)
CZq -> CLq dCL/dq (lift coefficient slope wrt pitching rate)
Clq -> Cellq dCl/dq (roll moment slope wrt pitching rate)
Cmq -> Cemq dCm/dq (pitching moment slope wrt pitching rate)
Cnq -> Cenq dCn/dq (yaw moment slope wrt pitching rate)
CXr -> CDr dCD/dr (drag coefficient slope wrt yaw rate)
CYr -> CYr dCY/dr (side force slope wrt yaw rate)
CZr -> CLr dCL/dr (lift coefficient slope wrt yaw rate)
Clr -> Cellr dCl/dr (roll moment slope wrt yaw rate)
Cmr -> Cemr dCm/dr (pitching moment slope wrt yaw rate)
Cnr -> Cenr dCn/dr (yaw moment slope wrt yaw rate)
Furthermore, every control surface also has six own parameters, which are also derived from this log file. {i} below ranges from 1 to the number of unique control surface types in the model.
CXd{i} -> CD_ctrl Effect of the control surface's deflection on drag
CYd{i} -> CY_ctrl Effect of the control surface's deflection on side force
CZd{i} -> CL_ctrl Effect of the control surface's deflection on lift
Cld{i} -> Cell_ctrl Effect of the control surface's deflection on roll moment
Cmd{i} -> Cem_ctrl Effect of the control surface's deflection on pitching moment
Cnd{i} -> Cen_ctrl Effect of the control surface's deflection on yaw moment
## Future Work
The tool, while self-contained, could be expanded into multiple directions.
1. Currently hinge positions and gains are set at default levels, and these could, if desired be further customized for more control.
2. More vehicles could be added to provide default templates that require less input. At the moment, only "custom" works completely.
3. Fuselage modelling could be included to further improve the accuracy of calculated coefficients.
4. At the moment only NACA airfoils are provided as a way to generate cambered surfaces. An alternative to this would be to use custom airfoil files.
@@ -1,342 +0,0 @@
#!/usr/bin/env
import argparse
import shutil
import fileinput
import subprocess
import os
from typing import TextIO
"""
Get the desired coefficient from the AVL output files by looking through the file line by line and picking it out when encountered.
Args:
file (TextIO): The file from which the desired coefficient should be read.
token (str): The coefficient which to look for.
Return:
value (str): The value associated with the desired coefficient.
"""
def get_coef(file: TextIO,token: str) -> str:
linesplit = []
for line in file:
if f' {token} ' in line:
linesplit = line.split()
break
index = 0
for i,v in enumerate(linesplit):
if v == token:
index = i
value = linesplit[index+2]
return value
"""
Write all gathered, model-wide coefficients to the sdf file.
Args:
file (TextIO): The file to which the desired coefficient should be written.
token_str (str): The coefficients for which the associated value should be written.
token (str): The value which should be placed in the avl.
Return:
None.
"""
def write_coef(file: TextIO, token_str: str, token: str):
old_line = f'<{token_str}></{token_str}>'
new_line = f'<{token_str}>{token}</{token_str}>'
with fileinput.FileInput(file, inplace=True) as output_file:
for line in output_file:
print(line.replace(old_line, new_line), end='')
"""
Write all gathered, control surface specific parameters to the sdf file.
Args:
file (TextIO): The file to which the desired coefficients should be written.
ctrl_surface_vec (list): A vector that contains all 6 necessary coefficient values for the control surface in question.
index (str): The model-wide index number of the control surface in question.
direction (str): The direction in which the control surface can be actuated.
Return:
None.
"""
def ctrl_surface_coef(file: TextIO,ctrl_surface_vec: list,index: str, direction: str):
extracted_text = ''
with open("./templates/control_surface.sdf",'r') as open_file:
for line in open_file:
extracted_text += line
open_file.close()
# Insert necessary coefficient values, index and direction in correct sdf location.
extracted_text = extracted_text.replace("<name></name>",f'<name>servo_{index}</name>')
extracted_text = extracted_text.replace("<index></index>",f'<index>{index}</index>')
extracted_text = extracted_text.replace("<direction></direction>",f'<directon>{direction}</direction>')
extracted_text = extracted_text.replace("<CD_ctrl></CD_ctrl>",f'<CD_ctrl>{ctrl_surface_vec[0]}</CD_ctrl>')
extracted_text = extracted_text.replace("<CY_ctrl></CY_ctrl>",f'<CY_ctrl>{ctrl_surface_vec[1]}</CY_ctrl>')
extracted_text = extracted_text.replace("<CL_ctrl></CL_ctrl>",f'<CL_ctrl>{ctrl_surface_vec[2]}</CL_ctrl>')
extracted_text = extracted_text.replace("<Cell_ctrl></Cell_ctrl>",f'<Cell_ctrl>{ctrl_surface_vec[3]}</Cell_ctrl>')
extracted_text = extracted_text.replace("<Cem_ctrl></Cem_ctrl>",f'<Cem_ctrl>{ctrl_surface_vec[4]}</Cem_ctrl>')
extracted_text = extracted_text.replace("<Cen_ctrl></Cen_ctrl>",f'<Cen_ctrl>{ctrl_surface_vec[5]}</Cen_ctrl>')
# Create model specific template
with open(file,'a') as plugin_file:
plugin_file.write(extracted_text + "\n")
plugin_file.close()
"""
Read out the necessary log files to gather the desired parameters and write them to the sdf plugin file.
Arguments provided here are passed in the input_avl.py file.
Args:
file_name (TextIO): The file to which the desired coefficients should be written.
vehicle_type (str): The type of vehicle in use.
AR (str): The calculated aspect ratio.
mac (str): The calculated mean aerodynamic chord.
ref_pt_x (str): The x coordinate of the reference point, at which forces and moments are applied.
ref_pt_y (str): The y coordinate of the reference point, at which forces and moments are applied.
ref_pt_z (str): The z coordinate of the reference point, at which forces and moments are applied.
num_ctrl_surfaces (str): The number of control surfaces that the model uses.
area (str): The wing surface area.
ctrl_surface_order (list): A list containing the types of control surfaces, in theorder in which
they have been defined in the .avl file.
avl_path (str): A string containing the directory where the AVL directory should be moved to.
Return:
None.
"""
def main(file_name: TextIO, vehicle_type: str, AR: str, mac: str, ref_pt_x: str, ref_pt_y: str, ref_pt_z: str, num_ctrl_surfaces: str, area: str, ctrl_surface_order: list, avl_path:str):
# Set current path for user
curr_path = subprocess.run(['pwd'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if curr_path.returncode == 0:
# Save the output in a variable
savedir = curr_path.stdout.strip()
else:
raise LookupError("Invalid path to directory. Check both the avl_automation directory and the Avl directory are positioned correctly.")
# Set the file directory path from where the AVL output logs can be read.
filedir = f'{avl_path}Avl/runs/'
# Read out all necessary parameters from the stability and body axis derivatives files.
with open(f'{filedir}custom_vehicle_stability_derivatives.txt','r+') as stability_file:
original_position = stability_file.tell()
# As plane is modelled at 0 degree AoA, the total coefficients should(?) correspond to the
# 0 degree coefficients required by the plugin.
alpha = get_coef(stability_file,"Alpha")
Cem0 = get_coef(stability_file,"Cmtot")
CL0 = get_coef(stability_file,"CLtot")
CD0 = get_coef(stability_file,"CDtot")
CLa = get_coef(stability_file,"CLa")
CYa = get_coef(stability_file,"CYa")
Cella = get_coef(stability_file,"Cla")
Cema = get_coef(stability_file,"Cma")
Cena = get_coef(stability_file,"Cna")
stability_file.seek(original_position)
CLb = get_coef(stability_file,"CLb")
CYb = get_coef(stability_file,"CYb")
Cellb = get_coef(stability_file,"Clb")
Cemb = get_coef(stability_file,"Cmb")
Cenb = get_coef(stability_file,"Cnb")
stability_file.close()
with open(f'{filedir}custom_vehicle_body_axis_derivatives.txt') as bodyax_file:
original_position = bodyax_file.tell()
eff = get_coef(bodyax_file,"e")
bodyax_file.seek(original_position)
CDp = get_coef(bodyax_file,"CXp")
CYp = get_coef(bodyax_file,"CYp")
CLp = get_coef(bodyax_file,"CZp")
Cellp = get_coef(bodyax_file,"Clp")
Cemp = get_coef(bodyax_file,"Cmp")
Cenp = get_coef(bodyax_file,"Cnp")
bodyax_file.seek(original_position)
CDq = get_coef(bodyax_file,"CXq")
CYq = get_coef(bodyax_file,"CYq")
CLq = get_coef(bodyax_file,"CZq")
Cellq = get_coef(bodyax_file,"Clq")
Cemq = get_coef(bodyax_file,"Cmq")
Cenq = get_coef(bodyax_file,"Cnq")
bodyax_file.seek(original_position)
CDr = get_coef(bodyax_file,"CXr")
CYr = get_coef(bodyax_file,"CYr")
CLr = get_coef(bodyax_file,"CZr")
Cellr = get_coef(bodyax_file,"Clr")
Cemr = get_coef(bodyax_file,"Cmr")
Cenr = get_coef(bodyax_file,"Cnr")
bodyax_file.close()
plane_type = vehicle_type
ctrl_surface_mat = []
# Maybe in the future you want more types of set aircraft. Thus us a case differentiator.
match plane_type:
case "custom":
ctrl_surface_vec = []
with open(f'{filedir}custom_vehicle_body_axis_derivatives.txt') as bodyax_file:
original_position = bodyax_file.tell()
for i in range(1,(len(set(ctrl_surface_order)))+1):
ctrl_surface_vec = []
ctrl_surface_vec.append(get_coef(bodyax_file,f'CXd{i}'))
ctrl_surface_vec.append(get_coef(bodyax_file,f'CYd{i}'))
ctrl_surface_vec.append(get_coef(bodyax_file,f'CZd{i}'))
ctrl_surface_vec.append(get_coef(bodyax_file,f'Cld{i}'))
ctrl_surface_vec.append(get_coef(bodyax_file,f'Cmd{i}'))
ctrl_surface_vec.append(get_coef(bodyax_file,f'Cnd{i}'))
bodyax_file.seek(original_position)
ctrl_surface_mat.append(ctrl_surface_vec)
# SPECIFY STALL PARAMETERS BASED ON AIRCRAFT TYPE (IF PROVIDED)
if not os.path.exists(f'{savedir}/{file_name}'):
os.makedirs(f'{savedir}/{file_name}')
file_name = f'{savedir}/{file_name}/{file_name}.sdf'
shutil.copy(f'{savedir}/templates/advanced_lift_drag_template.sdf',file_name)
# Get argument coefficients taken directly from the input file.
write_coef(file_name,"a0",alpha)
write_coef(file_name,"CL0",CL0)
write_coef(file_name,"CD0",CD0)
write_coef(file_name,"Cem0",Cem0)
write_coef(file_name,"AR",AR)
write_coef(file_name,"area",area)
write_coef(file_name,"mac",mac)
write_coef(file_name,"air_density",1.2041) # TODO: Provide custom air density option
write_coef(file_name,"forward","1 0 0")
write_coef(file_name,"upward","0 0 1")
write_coef(file_name,"link_name","base_link")
write_coef(file_name,"cp",f'{ref_pt_x} {ref_pt_y} {ref_pt_z}')
write_coef(file_name,"num_ctrl_surfaces",num_ctrl_surfaces)
write_coef(file_name,"CLa",CLa)
write_coef(file_name,"CYa",CYa)
write_coef(file_name,"Cella",Cella)
write_coef(file_name,"Cema",Cema)
write_coef(file_name,"Cena",Cena)
write_coef(file_name,"CLb",CLb)
write_coef(file_name,"CYb",CYb)
write_coef(file_name,"Cellb",Cellb)
write_coef(file_name,"Cemb",Cemb)
write_coef(file_name,"Cenb",Cenb)
write_coef(file_name,"CDp",CDp)
write_coef(file_name,"CYp",CYp)
write_coef(file_name,"CLp",CLp)
write_coef(file_name,"Cellp",Cellp)
write_coef(file_name,"Cemp",Cemp)
write_coef(file_name,"Cenp",Cenp)
write_coef(file_name,"CDq",CDq)
write_coef(file_name,"CYq",CYq)
write_coef(file_name,"CLq",CLq)
write_coef(file_name,"Cellq",Cellq)
write_coef(file_name,"Cemq",Cemq)
write_coef(file_name,"Cenq",Cenq)
write_coef(file_name,"CDr",CDr)
write_coef(file_name,"CYr",CYr)
write_coef(file_name,"CLr",CLr)
write_coef(file_name,"Cellr",Cellr)
write_coef(file_name,"Cemr",Cemr)
write_coef(file_name,"Cenr",Cenr)
write_coef(file_name,"eff",eff)
# TODO: Improve this for custom stall values
# Note: Currently these stall values are simply taken from advanced_plane presets.
write_coef(file_name,"alpha_stall","0.3391428111")
write_coef(file_name,"CLa_stall","-3.85")
write_coef(file_name,"CDa_stall","-0.9233984055")
write_coef(file_name,"Cema_stall","0")
# Check whether a particular type of control surface has been seen before. If it has,
# then the current control surface is the (right) counterpart.
# ASSUMPTION: There is the assumption that an vehicle will only ever have two of any
# particular type of control surface. (left and right). If this is not the case, the negation
# below will likely not work correctly.
type_seen = list()
# Dictionary containing the directions that each type of control surface can move.
ctrl_direction = {"aileron": 1,"elevator": -1,"rudder": 1}
# More set types in the future?
match plane_type:
case "custom":
for i, ctrl_surface in enumerate(ctrl_surface_order):
# Check whether a particular type of control surface has been seen before. If it has,
# then the current control surface is the (right) counterpart. Depending on the exact
# nature of the encountered type you then need to negate the correct parameters.
if ctrl_surface in type_seen:
# Work out what the corresponding index for the first encounter of the ctrl surface is.
seen_index = type_seen.index(ctrl_surface)
if ctrl_surface == 'aileron':
#Change for right wing aileron by flipping sign
ctrl_surface_mat[seen_index][3] = -float(ctrl_surface_mat[0][3])
ctrl_surface_mat[seen_index][5] = -float(ctrl_surface_mat[0][5])
# Split Elevators are assumed to never run differentially. Feel free to add a
# condition if your plane does require differential elevator action.
else:
# If a ctrl surface has not been encountered add it to the type_seen list and
# set the index to the length of the list - 1 as this corresponds to the newest
# unseen element in ctrl_surface_mat .
type_seen.append(ctrl_surface)
seen_index = len(type_seen) - 1
ctrl_surface_coef(file_name,ctrl_surface_mat[seen_index],i,ctrl_direction[ctrl_surface])
# close the sdf file with plugin
with open(file_name,'a') as plugin_file:
plugin_file.write("</plugin>")
plugin_file.close()
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("file_name", help="The file to which the desired coefficients should be written.")
parser.add_argument("vehicle_type", help="The type of vehicle in use.")
parser.add_argument("AR", help="The calculated aspect ratio.")
parser.add_argument("mac", help="The calculated mean aerodynamic chord.")
parser.add_argument("ref_pt_x", help="The x coordinate of the reference point, at which forces and moments are applied.")
parser.add_argument("ref_pt_y", help="The y coordinate of the reference point, at which forces and moments are applied.")
parser.add_argument("ref_pt_z", help="The z coordinate of the reference point, at which forces and moments are applied.")
parser.add_argument("num_ctrl_surfaces", help="The number of control surfaces that the model uses.")
parser.add_argument("area", help= "The wing surface area.")
parser.add_argument("ctrl_surface_order", help=" A list containing the types of control surfaces, in theorder in which \
they have been defined in the .avl file.")
parser.add_argument("avl_path",help="A string containing the directory where the AVL directory should be moved to.")
args = parser.parse_args()
main(args.file_name,args.vehicle_type,args.AR,args.mac,args.ref_pt_x,args.ref_pt_y,
args.ref_pt_z,args.num_ctrl_surfaces,args.area,args.ctrl_surface_order,args.avl_path)
@@ -1,10 +0,0 @@
oper
x
n custom_plane
st custom_vehicle_stability_derivatives.txt
sb custom_vehicle_body_axis_derivatives.txt
g
h
quit
@@ -1,142 +0,0 @@
# Enter a name for your vehicle
vehicle_name: plane_example_2
# Enter the type of airframe you would like to use:
frame_type: custom
# First define some model-wide parameters for custom models:
reference_area: 12
wing_span: 15
# Provide a reference point at which the forces and moments generated will act.
reference_point:
X: 0
Y: 0
Z: 0
#Provide information on each of the Control Surfaces
num_ctrl_surfaces: 4
control_surfaces:
- name: right_wing
type: aileron
nchord: 1
cspace: 1
nspan: 16
sspace: -2
angle: 4
translation:
X: 0
Y: 0
Z: 0
naca: 2412
sections:
- name: section_1
position:
X: -0.25
Y: 0
Z: 0
chord: 1
ainc: 0
nspan: 8
sspace: 1
- name: section_2
position:
X: -0.175
Y: 5
Z: 0.5
chord: 0.7
ainc: 0
nspan: 0
sspace: 0
- name: left_wing
type: aileron
nchord: 1
cspace: 1
nspan: 16
sspace: -2
angle: 4
translation:
X: 0
Y: 0
Z: 0
naca: 2412
sections:
- name: section_1
position:
X: -0.175
Y: -5
Z: 0.5
chord: 0.7
ainc: 0
nspan: 0
sspace: 0
- name: section_2
position:
X: -0.25
Y: 0
Z: 0
chord: 1
ainc: 0
nspan: 8
sspace: 1
- name: elevator
type: elevator
nchord: 1
cspace: 1
nspan: 7
sspace: -2
translation:
X: 6
Y: 0
Z: 0.5
sections:
- name: section_1
position:
X: -0.1
Y: 0
Z: 0
chord: 0.4
ainc: 0
nspan: 7
sspace: -1.25
- name: section_2
position:
X: -0.075
Y: 2
Z: 0
chord: 0.3
ainc: 0
nspan: 0
sspace: 0
- name: fin
type: rudder
nchord: 1
cspace: 1
nspan: 10
sspace: 1
translation:
X: 6
Y: 0
Z: 0.5
sections:
- name: section_1
position:
X: -0.1
Y: 0
Z: 0
chord: 0.4
ainc: 0
nspan: 7
sspace: -1.25
- name: section_2
position:
X: -0.075
Y: 0
Z: 1
chord: 0.3
ainc: 0
nspan: 0
sspace: 0
@@ -1,314 +0,0 @@
#!/usr/bin/env
import argparse
import avl_out_parse
import os
import yaml
import subprocess
import shutil
"""
Write individual airfoil section definitions to the .avl file.
Sections are defined through a 3D point in space and assigned properties such as chord, angle of incidence etc.
AVL then links them up to the other sections of a particular surface. You can define any number of sections for
a particular surface, but there always have to be at least two (a left and right edge).
Args:
plane_name (str): The name of the vehicle.
x (str): The x coordinate of the section.
y (str): The y coordinate of the section.
z (str): The z coordinate of the section.
chord (str): Chord in this section of the surface. Trailing edge is at x + chord, y, z.
ainc (str): Angle of incidence for this section. Taken as a rotation (RH rule) about the surface's
spanwise axis projected onto the Y-Z plane.
nspan (str): Number of spanwise vortices in until the next section.
sspan (str): Controls the spanwise spacing of the vortices.
naca_number (str): The chosen NACA number that will define the cambered properties of this section
of the surface. For help picking an airfoil go to: http://airfoiltools.com/airfoil/naca4digit.
ctrl_surface_type: The selected type of control surface. This should be consistent along the entirety of
the surface. (Question: Flap and Aileron along the same airfoil?)
Return:
None.
"""
def write_section(plane_name: str,x: str,y: str,z: str,chord: str,ainc: str,nspan: str,sspace: str,naca_number: str,ctrl_surf_type: str):
with open(f'{plane_name}.avl','a') as avl_file:
avl_file.write("SECTION \n")
avl_file.write("!Xle Yle Zle Chord Ainc Nspanwise Sspace \n")
avl_file.write(f'{x} {y} {z} {chord} {ainc} {nspan} {sspace} \n')
if naca_number != "0000":
avl_file.write("NACA \n")
avl_file.write(f'{naca_number} \n')
avl_file.close()
match ctrl_surf_type:
case 'aileron':
#TODO provide custom options for gain and hinge positions
with open(f'{plane_name}.avl','a') as avl_file:
avl_file.write("CONTROL \n")
avl_file.write("aileron 1.0 0.0 0.0 0.0 0.0 -1 \n")
avl_file.close()
case 'elevator':
with open(f'{plane_name}.avl','a') as avl_file:
avl_file.write("CONTROL \n")
avl_file.write("elevator 1.0 0.0 0.0 0.0 0.0 1 \n")
avl_file.close()
case 'rudder':
with open(f'{plane_name}.avl','a') as avl_file:
avl_file.write("CONTROL \n")
avl_file.write("rudder 1.0 0.0 0.0 0.0 0.0 1 \n")
avl_file.close()
"""
Read the provided yaml file and generate the corresponding .avl file that can be read into AVL.
Also calls AVL and the avl_out_parse.py file that generates the sdf plugin.
Args:
yaml_file: Path to the input yaml file
avl_path: Set the avl_path to provide a desired directory for where Avl should be located.
Return:
None
"""
def main():
user = os.environ.get('USER')
# This will find Avl on a users machine.
for root, dirs, _ in os.walk(f'/home/{user}/'):
if "Avl" in dirs:
target_directory_path = os.path.join(root, "Avl")
break
parent_directory_path = os.path.dirname(target_directory_path)
filedir = f'{parent_directory_path}/'
print(filedir)
parser = argparse.ArgumentParser()
parser.add_argument("--yaml_file", help="Path to input yaml file.")
parser.add_argument("--avl_path", default=filedir, help="Provide an absolute AVL path. If this argument is passed, AVL will be moved there and the files will adjust their paths accordingly.")
inputs = parser.parse_args()
# If the user passes the avl_path argument then move Avl to that location:
if inputs.avl_path != filedir:
#Check if the directory is already there
if os.path.exists(f'{inputs.avl_path}/Avl') and os.path.isdir(f'{inputs.avl_path}/Avl'):
print("Avl is already at desired location")
else:
shutil.move(f'{filedir}Avl',inputs.avl_path)
# Adjust paths to AVL in process.sh
print("Adjusting paths")
with open("./process.sh", "r") as file:
all_lines = file.readlines()
file.close()
it = 0
for line in all_lines:
if "cp $DIR_PATH/$CUSTOM_MODEL.avl" in line:
new_line = f'cp $DIR_PATH/$CUSTOM_MODEL.avl {inputs.avl_path}Avl/runs\n'
all_lines[it] = new_line
if "/Avl/runs/plot.ps $DIR_PATH/" in line:
new_line =f'mv {inputs.avl_path}Avl/runs/plot.ps $DIR_PATH/\n'
all_lines[it] = new_line
if "cd" in line and "/Avl/runs" in line:
new_line = f'cd {inputs.avl_path}Avl/runs\n'
all_lines[it] = new_line
it += 1
with open("./process.sh", "w") as file:
file.writelines(all_lines)
file.close()
with open(inputs.yaml_file,'r') as yaml_file:
yaml_data = yaml.safe_load(yaml_file)
airframes = ['cessna','standard_vtol','custom']
plane_name = yaml_data['vehicle_name']
frame_type = yaml_data['frame_type']
if not frame_type in airframes:
raise ValueError("\nThis is not a valid airframe, please choose a valid airframe. \n")
# Parameters that need to be provided:
# General
# - Reference Area (Sref)
# - Wing span (Bref) (wing span squared / area = aspect ratio which is a required parameter for the sdf file)
# - Reference point (X,Y,Zref) point at which moments and forces are calculated
#Control Surface specific
# - type (select from options; aileron,elevator,rudder)
# - nchord
# - cspace
# - nspanwise
# - sspace
# - x,y,z 1. (section)
# - chord 1. (section)
# - ainc 1. (section)
# - Nspan 1. (optional for section)
# - sspace 1. (optional for section)
# - x,y,z 2. (section)
# - chord 2. (section)
# - ainc 2. (section)
# - Nspan 2. (optional for section)
# - sspace 2. (optional for section)
# TODO: Find out if elevons are defined
ctrl_surface_types = ['aileron','elevator','rudder']
# - Reference Chord (Cref) (= area/wing span)
delineation = '!***************************************'
sec_demark = '#--------------------------------------------------'
num_ctrl_surfaces = 0
ctrl_surface_order = []
area = 0
span = 0
ref_pt_x = None
ref_pt_y = None
ref_pt_z = None
# Future work: Provide some pre-worked frames for a Cessna and standard VTOL if there is a need for it
match frame_type:
case "custom":
# These parameters are consistent across all models.
# At the moment we do not use any symmetry axis for mirroring.
with open(f'{plane_name}.avl','w') as avl_file:
avl_file.write(f'{delineation} \n')
avl_file.write(f'!{plane_name} input dataset \n')
avl_file.write(f'{delineation} \n')
avl_file.write(f'{plane_name} \n')
avl_file.write('!Mach \n0.0 \n')
avl_file.write('!IYsym IZsym Zsym \n')
avl_file.write('0 0 0 \n')
avl_file.close()
# First define some model-specific parameters for custom models
area = yaml_data["reference_area"]
span = yaml_data["wing_span"]
ref_pt_x = yaml_data["reference_point"]["X"]
ref_pt_y = yaml_data["reference_point"]["Y"]
ref_pt_z = yaml_data["reference_point"]["Z"]
if(span != 0 and area != 0):
ref_chord = float(area)/float(span)
else:
raise ValueError("Invalid reference chord value. Check area and wing span values.")
# Write the gathered model-wide parameters into the .avl file
with open(f'{plane_name}.avl','a') as avl_file:
avl_file.write('!Sref Cref Bref \n')
avl_file.write(f'{area} {str(ref_chord)} {span} \n')
avl_file.write('!Xref Yref Zref \n')
avl_file.write(f'{ref_pt_x} {ref_pt_y} {ref_pt_z} \n')
avl_file.close()
num_ctrl_surfaces = yaml_data["num_ctrl_surfaces"]
for i, control_surface in enumerate(yaml_data["control_surfaces"]):
# Wings always need to be defined from left to right
ctrl_surf_name = control_surface['name']
ctrl_surf_type = control_surface['type']
if ctrl_surf_type not in ctrl_surface_types:
raise ValueError(f'The selected type is invalid. Available types are: {ctrl_surface_types}')
# The order of control surfaces becomes important in the output parsing
# to correctly assign derivatives to particular surfaces.
ctrl_surface_order.append(ctrl_surf_type)
nchord = control_surface["nchord"]
cspace = control_surface["cspace"]
nspanwise = control_surface["nspan"]
sspace = control_surface["sspace"]
# TODO: Add more control surface types that also require Angles.
if ctrl_surf_type.lower() == 'aileron':
angle = control_surface["angle"]
#Translation of control surface, will move the whole surface to specified position
tx = control_surface["translation"]["X"]
ty = control_surface["translation"]["Y"]
tz = control_surface["translation"]["Z"]
# Write common part of this surface to .avl file
with open(f'{plane_name}.avl','a') as avl_file:
avl_file.write(sec_demark)
avl_file.write("\nSURFACE \n")
avl_file.write(f'{ctrl_surf_name} \n')
avl_file.write("!Nchordwise Cspace Nspanwise Sspace \n")
avl_file.write(f'{nchord} {cspace} {nspanwise} {sspace} \n')
# If we have a elevator, we can duplicate the defined control surface along the y-axis of the model
# as both sides are generally modelled and controlled as one in simulation. Adjust for split elevators if desired.
if ctrl_surf_type.lower() == 'elevator':
avl_file.write("\nYDUPLICATE\n")
avl_file.write("0.0\n\n")
# Elevators and Rudders do not require an angle of incidence.
if ctrl_surf_type.lower() == 'aileron':
avl_file.write("ANGLE \n")
avl_file.write(f'{angle} \n')
# Translate the surface to a particular position in space.
avl_file.write("TRANSLATE \n")
avl_file.write(f'{tx} {ty} {tz} \n')
avl_file.close()
# Define NACA airfoil shape.
# For help picking an airfoil go to: http://airfoiltools.com/airfoil/naca4digit
# NOTE: AVL can only use 4-digit NACA codes.
if ctrl_surf_type.lower() == "aileron":
naca_number = control_surface["naca"]
else:
# Provide a default NACA number for unused airfoils
naca_number = '0000'
# Iterating over each defined section for the control surface. There need to be at least
# two in order to define a left and right edge, but there is no upper limit.
# CRITICAL: ALWAYS DEFINE YOUR SECTION FROM LEFT TO RIGHT
for j, section in enumerate(control_surface["sections"]):
print(f'Defining {j}. section of {i+1}. control surface \n')
y = section["position"]["Y"]
z = section["position"]["Z"]
x = section["position"]["X"]
chord = section["chord"]
ainc = section["ainc"]
nspan = section["nspan"]
write_section(plane_name,x,y,z,chord,ainc,nspan,sspace,naca_number,ctrl_surf_type)
print(f'\nPARAMETER DEFINITION FOR {i+1}. CONTROL SURFACE COMPLETED \n')
# Calculation of Aspect Ratio (AR) and Mean Aerodynamic Chord (mac)
AR = str((float(span)*float(span))/float(area))
mac = str((2/3)*(float(area)/float(span)))
# Call shell script that will pass the generated .avl file to AVL
os.system(f'./process.sh {plane_name}')
# Call main function of avl parse script to parse the generated AVL files.
avl_out_parse.main(plane_name,frame_type,AR,mac,ref_pt_x,ref_pt_y,ref_pt_z,num_ctrl_surfaces,area,ctrl_surface_order,inputs.avl_path)
# Finally move all generated files to a new directory and show the generated geometry image:
result = subprocess.run(['pwd'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode == 0:
# Save the output in a variable
current_path = result.stdout.strip()
# Run image plot from avl_automation directory.
os.system(f'mv ./{plane_name}.* ./{plane_name}' )
os.system(f'evince {current_path}/{plane_name}/{plane_name}.ps')
if __name__ == '__main__':
main()
@@ -1,27 +0,0 @@
#!/bin/bash
CUSTOM_MODEL=$1
DIR_PATH=$(pwd)
cp $DIR_PATH/$CUSTOM_MODEL.avl /home/$USER/Avl/runs/
cd
cd /home/$USER/Avl/runs
old_stability_derivatives="custom_vehicle_stability_derivatives.txt"
old_body_ax_derivatives="custom_vehicle_body_axis_derivatives.txt"
if [ -e "$old_stability_derivatives" ]; then
# Delete old stability derivative file
rm "$old_stability_derivatives"
fi
if [ -e "$old_body_ax_derivatives" ]; then
# Delete old body_axis derivative file
rm "$old_body_ax_derivatives"
fi
#avl_steps.txt can be used to run commands on the AVL commandline.
../bin/avl $CUSTOM_MODEL.avl < $DIR_PATH/avl_steps.txt
echo "\n"
#After completion move the plot to avl_automation directory
mv /home/$USER/Avl/runs/plot.ps $DIR_PATH/
mv $DIR_PATH/plot.ps $DIR_PATH/$CUSTOM_MODEL.ps
@@ -1,43 +0,0 @@
<plugin filename="gz-sim-advanced-lift-drag-system" name="gz::sim::systems::AdvancedLiftDrag">
<a0></a0>
<CL0></CL0>
<AR></AR>
<eff></eff>
<CLa></CLa>
<CD0></CD0>
<Cem0></Cem0>
<Cema></Cema>
<CYb></CYb>
<Cellb></Cellb>
<Cenb></Cenb>
<CDp></CDp>
<CYp></CYp>
<CLp></CLp>
<Cellp></Cellp>
<Cemp></Cemp>
<Cenp></Cenp>
<CDq></CDq>
<CYq></CYq>
<CLq></CLq>
<Cellq></Cellq>
<Cemq></Cemq>
<Cenq></Cenq>
<CDr></CDr>
<CYr></CYr>
<CLr></CLr>
<Cellr></Cellr>
<Cemr></Cemr>
<Cenr></Cenr>
<alpha_stall></alpha_stall>
<CLa_stall></CLa_stall>
<CDa_stall></CDa_stall>
<Cema_stall></Cema_stall>
<cp></cp>
<area></area>
<mac></mac>
<air_density></air_density>
<forward></forward>
<upward></upward>
<link_name></link_name>
<num_ctrl_surfaces></num_ctrl_surfaces>
@@ -1,11 +0,0 @@
<control_surface>
<name></name>
<index></index>
<direction></direction>
<CD_ctrl></CD_ctrl>
<CY_ctrl></CY_ctrl>
<CL_ctrl></CL_ctrl>
<Cell_ctrl></Cell_ctrl>
<Cem_ctrl></Cem_ctrl>
<Cen_ctrl></Cen_ctrl>
</control_surface>
-1
View File
@@ -11,7 +11,6 @@
<plugin name='gz::sim::systems::Contact' filename='gz-sim-contact-system'/>
<plugin name='gz::sim::systems::Imu' filename='gz-sim-imu-system'/>
<plugin name='gz::sim::systems::AirPressure' filename='gz-sim-air-pressure-system'/>
<plugin name='gz::sim::systems::ApplyLinkWrench' filename='gz-sim-apply-link-wrench-system'/>
<plugin name='gz::sim::systems::Sensors' filename='gz-sim-sensors-system'>
<render_engine>ogre2</render_engine>
</plugin>
-151
View File
@@ -1,151 +0,0 @@
<sdf version='1.9'>
<world name='windy'>
<physics type="ode">
<max_step_size>0.004</max_step_size>
<real_time_factor>1.0</real_time_factor>
<real_time_update_rate>250</real_time_update_rate>
</physics>
<plugin name='gz::sim::systems::Physics' filename='gz-sim-physics-system'/>
<plugin name='gz::sim::systems::UserCommands' filename='gz-sim-user-commands-system'/>
<plugin name='gz::sim::systems::SceneBroadcaster' filename='gz-sim-scene-broadcaster-system'/>
<plugin name='gz::sim::systems::Contact' filename='gz-sim-contact-system'/>
<plugin name='gz::sim::systems::Imu' filename='gz-sim-imu-system'/>
<plugin name='gz::sim::systems::AirPressure' filename='gz-sim-air-pressure-system'/>
<plugin name='gz::sim::systems::ApplyLinkWrench' filename='gz-sim-apply-link-wrench-system'/>
<plugin name='gz::sim::systems::Sensors' filename='gz-sim-sensors-system'>
<render_engine>ogre2</render_engine>
</plugin>
<gui fullscreen='false'>
<plugin name='3D View' filename='GzScene3D'>
<gz-gui>
<title>3D View</title>
<property type='bool' key='showTitleBar'>0</property>
<property type='string' key='state'>docked</property>
</gz-gui>
<engine>ogre2</engine>
<scene>scene</scene>
<ambient_light>0.5984631152222222 0.5984631152222222 0.5984631152222222</ambient_light>
<background_color>0.8984631152222222 0.8984631152222222 0.8984631152222222</background_color>
<camera_pose>-6 0 6 0 0.5 0</camera_pose>
</plugin>
<plugin name='World control' filename='WorldControl'>
<gz-gui>
<title>World control</title>
<property type='bool' key='showTitleBar'>0</property>
<property type='bool' key='resizable'>0</property>
<property type='double' key='height'>72</property>
<property type='double' key='width'>121</property>
<property type='double' key='z'>1</property>
<property type='string' key='state'>floating</property>
<anchors target='3D View'>
<line own='left' target='left'/>
<line own='bottom' target='bottom'/>
</anchors>
</gz-gui>
<play_pause>1</play_pause>
<step>1</step>
<start_paused>1</start_paused>
</plugin>
<plugin name='World stats' filename='WorldStats'>
<gz-gui>
<title>World stats</title>
<property type='bool' key='showTitleBar'>0</property>
<property type='bool' key='resizable'>0</property>
<property type='double' key='height'>110</property>
<property type='double' key='width'>290</property>
<property type='double' key='z'>1</property>
<property type='string' key='state'>floating</property>
<anchors target='3D View'>
<line own='right' target='right'/>
<line own='bottom' target='bottom'/>
</anchors>
</gz-gui>
<sim_time>1</sim_time>
<real_time>1</real_time>
<real_time_factor>1</real_time_factor>
<iterations>1</iterations>
</plugin>
<plugin name='Entity tree' filename='EntityTree'/>
</gui>
<gravity>0 0 -9.8</gravity>
<magnetic_field>6e-06 2.3e-05 -4.2e-05</magnetic_field>
<atmosphere type='adiabatic'/>
<scene>
<grid>false</grid>
<ambient>0.4 0.4 0.4 1</ambient>
<background>0.7 0.7 0.7 1</background>
<shadows>true</shadows>
</scene>
<model name='ground_plane'>
<static>true</static>
<link name='link'>
<collision name='collision'>
<geometry>
<plane>
<normal>0 0 1</normal>
<size>1 1</size>
</plane>
</geometry>
<surface>
<friction>
<ode/>
</friction>
<bounce/>
<contact/>
</surface>
</collision>
<visual name='visual'>
<geometry>
<plane>
<normal>0 0 1</normal>
<size>100 100</size>
</plane>
</geometry>
<material>
<ambient>0.8 0.8 0.8 1</ambient>
<diffuse>0.8 0.8 0.8 1</diffuse>
<specular>0.8 0.8 0.8 1</specular>
</material>
</visual>
<pose>0 0 0 0 -0 0</pose>
<inertial>
<pose>0 0 0 0 -0 0</pose>
<mass>1</mass>
<inertia>
<ixx>1</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>1</iyy>
<iyz>0</iyz>
<izz>1</izz>
</inertia>
</inertial>
<enable_wind>true</enable_wind>
</link>
<pose>0 0 0 0 -0 0</pose>
<self_collide>false</self_collide>
</model>
<light name='sunUTC' type='directional'>
<pose>0 0 500 0 -0 0</pose>
<cast_shadows>true</cast_shadows>
<intensity>1</intensity>
<direction>0.001 0.625 -0.78</direction>
<diffuse>0.904 0.904 0.904 1</diffuse>
<specular>0.271 0.271 0.271 1</specular>
<attenuation>
<range>2000</range>
<linear>0</linear>
<constant>1</constant>
<quadratic>0</quadratic>
</attenuation>
<spot>
<inner_angle>0</inner_angle>
<outer_angle>0</outer_angle>
<falloff>0</falloff>
</spot>
</light>
<wind>
<linear_velocity>10 10 10</linear_velocity>
</wind>
</world>
</sdf>
@@ -1,175 +0,0 @@
#!/usr/bin/env python3
#############################################################################
#
# Copyright (C) 2013-2022 PX4 Pro 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.
#
#############################################################################
"""
px_generate_zenoh_topic_files.py
Generates c/cpp header/source files for use with zenoh
message files
"""
import os
import argparse
import re
import sys
try:
import em
except ImportError as e:
print("Failed to import em: " + str(e))
print("")
print("You may need to install it using:")
print(" pip3 install --user empy")
print("")
sys.exit(1)
try:
import genmsg.template_tools
except ImportError as e:
print("Failed to import genmsg: " + str(e))
print("")
print("You may need to install it using:")
print(" pip3 install --user pyros-genmsg")
print("")
sys.exit(1)
__author__ = "Sergey Belash, Thomas Gubler, Beat Kueng"
__copyright__ = "Copyright (C) 2013-2022 PX4 Development Team."
__license__ = "BSD"
__email__ = "thomasgubler@gmail.com"
ZENOH_TEMPLATE_FILE = ['Kconfig.topics.em', 'uorb_pubsub_factory.hpp.em']
TOPICS_TOKEN = '# TOPICS '
def get_topics(filename):
"""
Get TOPICS names from a "# TOPICS" line
"""
ofile = open(filename, 'r')
text = ofile.read()
result = []
for each_line in text.split('\n'):
if each_line.startswith(TOPICS_TOKEN):
topic_names_str = each_line.strip()
topic_names_str = topic_names_str.replace(TOPICS_TOKEN, "")
topic_names_list = topic_names_str.split(" ")
for topic in topic_names_list:
# topic name PascalCase (file name) to snake_case (topic name)
topic_name = re.sub(r'(?<!^)(?=[A-Z])', '_', topic).lower()
result.append(topic_name)
ofile.close()
if len(result) == 0:
# topic name PascalCase (file name) to snake_case (topic name)
file_base_name = os.path.basename(filename).replace(".msg", "")
topic_name = re.sub(r'(?<!^)(?=[A-Z])', '_', file_base_name).lower()
result.append(topic_name)
return result
def generate_by_template(output_file, template_file, em_globals):
"""
Invokes empy intepreter to geneate output_file by the
given template_file and predefined em_globals dict
"""
# check if folder exists:
folder_name = os.path.dirname(output_file)
if not os.path.exists(folder_name):
os.makedirs(folder_name)
ofile = open(output_file, 'w')
# todo, reuse interpreter
interpreter = em.Interpreter(output=ofile, globals=em_globals, options={
em.RAW_OPT: True, em.BUFFERED_OPT: True})
try:
interpreter.file(open(template_file))
except OSError as e:
ofile.close()
os.remove(output_file)
raise
interpreter.shutdown()
ofile.close()
return True
def generate_topics_list_file_from_files(files, outputdir, template_filename, templatedir):
# generate cpp file with topics list
filenames = []
for filename in [os.path.basename(p) for p in files if os.path.basename(p).endswith(".msg")]:
filenames.append(re.sub(r'(?<!^)(?=[A-Z])', '_', filename).lower())
datatypes = []
for filename in [os.path.basename(p) for p in files if os.path.basename(p).endswith(".msg")]:
datatypes.append(re.sub(r'(?<!^)(?=[A-Z])', '_', filename).lower().replace(".msg",""))
full_base_names = []
for filename in [os.path.basename(p) for p in files if os.path.basename(p).endswith(".msg")]:
full_base_names.append(filename.replace(".msg",""))
topics = []
for msg_filename in files:
topics.extend(get_topics(msg_filename))
tl_globals = {"msgs": filenames, "topics": topics, "datatypes": datatypes, "full_base_names": full_base_names}
tl_template_file = os.path.join(templatedir, template_filename)
tl_out_file = os.path.join(outputdir, template_filename.replace(".em", ""))
generate_by_template(tl_out_file, tl_template_file, tl_globals)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Convert msg files to uorb headers/sources')
parser.add_argument('--zenoh-config', help='Generate Zenoh Kconfig file', action='store_true')
parser.add_argument('--zenoh-pub-sub', help='Generate Zenoh Pubsub factory', action='store_true')
parser.add_argument('-f', dest='file',
help="files to convert (use only without -d)",
nargs="+")
parser.add_argument('-e', dest='templatedir',
help='directory with template files',)
parser.add_argument('-o', dest='outputdir',
help='output directory for header files')
parser.add_argument('-p', dest='prefix', default='',
help='string added as prefix to the output file '
' name when converting directories')
args = parser.parse_args()
if args.zenoh_config:
generate_topics_list_file_from_files(args.file, args.outputdir, ZENOH_TEMPLATE_FILE[0], args.templatedir)
exit(0)
elif args.zenoh_pub_sub:
generate_topics_list_file_from_files(args.file, args.outputdir, ZENOH_TEMPLATE_FILE[1], args.templatedir)
exit(0)
else:
print('Error: either --headers or --sources must be specified')
exit(-1)

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