Compare commits
229 Commits
v0.22-alph
...
install
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0666bfdf33 | ||
|
|
7c57581c33 | ||
|
|
881daaa389 | ||
|
|
0dcf16de6b | ||
|
|
8abb40249c | ||
|
|
3ab73edb74 | ||
|
|
aeb1c8ac11 | ||
|
|
2d3df6a94e | ||
|
|
0249d01ca7 | ||
|
|
71100a9545 | ||
|
|
118b4573fe | ||
|
|
f77843f4a5 | ||
|
|
5f62a8639a | ||
|
|
fa1db1d90b | ||
|
|
1a2e87bb6a | ||
|
|
7dbd983ec5 | ||
|
|
d2d395f1fc | ||
|
|
ff93f79c0a | ||
|
|
5deb09eb45 | ||
|
|
70b8be5c5d | ||
|
|
2a08e20b47 | ||
|
|
3328d8f4ac | ||
|
|
f7fb814894 | ||
|
|
3a3b0bbd80 | ||
|
|
ca095f3f16 | ||
|
|
baf2467939 | ||
|
|
abba3bf876 | ||
|
|
346373ed23 | ||
|
|
bb996056c9 | ||
|
|
0e0b1cdc31 | ||
|
|
eceaa0ec91 | ||
|
|
f29686b9f4 | ||
|
|
b7f1f2b391 | ||
|
|
6b0bb41564 | ||
|
|
563e5acad6 | ||
|
|
5932faa29c | ||
|
|
bcc2e86e6f | ||
|
|
e80a1cc7d6 | ||
|
|
5fd3a92c7b | ||
|
|
84b87055df | ||
|
|
7cc0f066c7 | ||
|
|
868fc728dd | ||
|
|
faa90b89f6 | ||
|
|
f4d07e2c2c | ||
|
|
fad7886012 | ||
|
|
7eb139fd22 | ||
|
|
855d13e210 | ||
|
|
781b8962be | ||
|
|
047a965f9f | ||
|
|
47060db84b | ||
|
|
2693fd4ace | ||
|
|
faa702cab0 | ||
|
|
150ecbe29d | ||
|
|
df5e83e416 | ||
|
|
1f2ba65669 | ||
|
|
27be9eb281 | ||
|
|
f8222e1028 | ||
|
|
dce0c00773 | ||
|
|
dc8c5d9db9 | ||
|
|
261faaec0e | ||
|
|
dbd9a4a238 | ||
|
|
80d446e857 | ||
|
|
609a7ab014 | ||
|
|
c0d9bd7ef0 | ||
|
|
cdd6000c58 | ||
|
|
480a9b1f0a | ||
|
|
4943cb94b0 | ||
|
|
e0ca1272bb | ||
|
|
cb88537ddc | ||
|
|
659380c575 | ||
|
|
b4a8119bd7 | ||
|
|
c72eb1b440 | ||
|
|
f825901a19 | ||
|
|
200c5dea57 | ||
|
|
0504569b0c | ||
|
|
9829ee2e72 | ||
|
|
dfdaf3aa4f | ||
|
|
63f979c2ff | ||
|
|
b8dafce816 | ||
|
|
19e0b94fda | ||
|
|
957e57692c | ||
|
|
0d49c426eb | ||
|
|
b1f104ce5e | ||
|
|
80177b3ea4 | ||
|
|
3223d3817e | ||
|
|
4612f7e9f0 | ||
|
|
a026410fdb | ||
|
|
dd1a212cd0 | ||
|
|
20b6824012 | ||
|
|
6f6933234c | ||
|
|
3edafbef97 | ||
|
|
7740a136ce | ||
|
|
380112de6a | ||
|
|
79f5c6d0e7 | ||
|
|
e207b55966 | ||
|
|
043a4ad67c | ||
|
|
dbeb2b354d | ||
|
|
6134965f2a | ||
|
|
976bb7aeea | ||
|
|
faa0e6d8d2 | ||
|
|
d02151aedd | ||
|
|
7f0606397e | ||
|
|
fb2842a0a1 | ||
|
|
9a9621ab4b | ||
|
|
171804149c | ||
|
|
0cb7494023 | ||
|
|
e0a81e0ca8 | ||
|
|
1e5e9cdc43 | ||
|
|
5e315c477e | ||
|
|
f45000f595 | ||
|
|
48a1385a1a | ||
|
|
765c470baa | ||
|
|
fd69beed7b | ||
|
|
1d4179bccf | ||
|
|
0b2095bbb8 | ||
|
|
a0436fbcc5 | ||
|
|
aee867d6bc | ||
|
|
3c078ab92f | ||
|
|
d780aedb88 | ||
|
|
a16d9d80fc | ||
|
|
10d250d96a | ||
|
|
acdcf20392 | ||
|
|
796d614f5e | ||
|
|
f8de7443d7 | ||
|
|
5c3ffdbeb6 | ||
|
|
1c732137c6 | ||
|
|
345aad9e64 | ||
|
|
02c67ea71a | ||
|
|
050e0fedb9 | ||
|
|
0e9b54934c | ||
|
|
793b614b7b | ||
|
|
62ab5c2357 | ||
|
|
181a78e4a9 | ||
|
|
c72eb0c027 | ||
|
|
5d99e44c30 | ||
|
|
5eb9b4acbe | ||
|
|
30ada8f311 | ||
|
|
e717829945 | ||
|
|
50dc17badb | ||
|
|
1dea541df2 | ||
|
|
d6b950b726 | ||
|
|
e2a1d3aaeb | ||
|
|
165e4d1a61 | ||
|
|
4f631300d4 | ||
|
|
e252a1cddc | ||
|
|
25dd17c286 | ||
|
|
b9395e3d18 | ||
|
|
a32dd7dcdd | ||
|
|
1e12e34070 | ||
|
|
3ff675d794 | ||
|
|
bb3e4befe5 | ||
|
|
fe71007ebd | ||
|
|
68cec159f7 | ||
|
|
4e8127f690 | ||
|
|
8f78f2b6e4 | ||
|
|
c8163cd38b | ||
|
|
7831992d6a | ||
|
|
873befdba9 | ||
|
|
c3cbc305c3 | ||
|
|
b71e802a2e | ||
|
|
3c5f2c958e | ||
|
|
267993aec4 | ||
|
|
86dd42c3b3 | ||
|
|
9d338d843b | ||
|
|
3e100bee91 | ||
|
|
8a29b9a37a | ||
|
|
2e80a06db1 | ||
|
|
0003985c3b | ||
|
|
f250916ede | ||
|
|
ee2944a1d3 | ||
|
|
a088524468 | ||
|
|
215fe237ca | ||
|
|
8c1b5c19d0 | ||
|
|
779dfb3f4f | ||
|
|
23d503adc5 | ||
|
|
0350ecbff7 | ||
|
|
12bed337dc | ||
|
|
6a1b609ccd | ||
|
|
3d5c51a42e | ||
|
|
3702ed0c86 | ||
|
|
741abadb54 | ||
|
|
c6dc732867 | ||
|
|
ba76e51966 | ||
|
|
7951f0e2ba | ||
|
|
cd58c03c0f | ||
|
|
ce6b2530c4 | ||
|
|
14e4af76aa | ||
|
|
f3f1557b0b | ||
|
|
18d410db24 | ||
|
|
207dc88579 | ||
|
|
58f6ac4b39 | ||
|
|
688e4f0ca9 | ||
|
|
7cbe823700 | ||
|
|
df681e0a79 | ||
|
|
8aad2fc363 | ||
|
|
3c8dd14c9d | ||
|
|
3a20bc3212 | ||
|
|
1105cd8750 | ||
|
|
43d7e7c70b | ||
|
|
7a1e885df1 | ||
|
|
9a9c2d5c9f | ||
|
|
eaeb146878 | ||
|
|
2452be05ff | ||
|
|
a4336a39c9 | ||
|
|
9cdf7dea41 | ||
|
|
b90dc3c020 | ||
|
|
91252d8d50 | ||
|
|
c4b94390e9 | ||
|
|
1b4167365e | ||
|
|
01ec592abb | ||
|
|
e2e2e04381 | ||
|
|
27e0189cf5 | ||
|
|
e3d89cbc4c | ||
|
|
a0ac85e0d3 | ||
|
|
83e5911110 | ||
|
|
05d634d2d3 | ||
|
|
4967d651bd | ||
|
|
91f948d3f4 | ||
|
|
ebf55244f4 | ||
|
|
5b6d08e25d | ||
|
|
8036214406 | ||
|
|
5d3c8c89cb | ||
|
|
2075fa52ef | ||
|
|
b0e1e1ffae | ||
|
|
4482f973db | ||
|
|
b1c7ee6b66 | ||
|
|
ff9e669352 | ||
|
|
6c8291749f | ||
|
|
039d2438cd |
29
.github/workflows/build-image.yaml
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
name: Build RPi image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ '*' ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
release:
|
||||||
|
types: [ created ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-image:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Build image
|
||||||
|
run: |
|
||||||
|
docker run --privileged --rm -v /dev:/dev -v $(pwd):/builder/repo -e TRAVIS_TAG="${{ github.event.release.tag_name }}" sfalexrog/img-tool:qemu-update
|
||||||
|
- name: Compress image
|
||||||
|
run: |
|
||||||
|
sudo chmod -R 777 images && zip -9 $(echo images/clover_*).zip images/clover_* && ls -l images
|
||||||
|
- name: Upload image
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
if: ${{ github.event_name == 'release' }}
|
||||||
|
with:
|
||||||
|
files: images/clover_*.zip
|
||||||
|
prerelease: true
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
23
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
name: Build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ '*' ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-melodic:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Native Melodic build
|
||||||
|
run: |
|
||||||
|
docker run --rm -v $(pwd):/root/catkin_ws/src/clover ros:melodic-ros-base /root/catkin_ws/src/clover/builder/standalone-install.sh
|
||||||
|
build-noetic:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Native Noetic build
|
||||||
|
run: |
|
||||||
|
docker run --rm -v $(pwd):/root/catkin_ws/src/clover ros:noetic-ros-base /root/catkin_ws/src/clover/builder/standalone-install.sh
|
||||||
54
.github/workflows/docs.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
name: Documentation
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ '*' ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
documentation:
|
||||||
|
runs-on: ubuntu-18.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Use Node.js
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with: { node-version: '10' }
|
||||||
|
- name: Setup tools
|
||||||
|
run: |
|
||||||
|
sudo sh -c "echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | debconf-set-selections"
|
||||||
|
sudo apt-get update && sudo apt-get install -y calibre msttcorefonts
|
||||||
|
npm install gitbook-cli -g
|
||||||
|
gitbook fetch 3.2.3 && npm i npm@3.10.10 --prefix=~/.gitbook/versions/3.2.3/ # fixing https://travis-ci.org/github/CopterExpress/clover/jobs/766541125#L932
|
||||||
|
npm install markdownlint-cli -g
|
||||||
|
npm install svgexport -g
|
||||||
|
gitbook -V
|
||||||
|
markdownlint -V
|
||||||
|
- name: Run markdownlint
|
||||||
|
run: markdownlint docs
|
||||||
|
- name: Check Assets
|
||||||
|
run: |
|
||||||
|
./check_assets_size.py
|
||||||
|
./check_unused_assets.py
|
||||||
|
- name: Build GitBook
|
||||||
|
run: |
|
||||||
|
gitbook install
|
||||||
|
gitbook build
|
||||||
|
- name: Generate PDF
|
||||||
|
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||||
|
run: |
|
||||||
|
for i in 1 2 3 4; do gitbook pdf ./ _book/clover.pdf && break || sleep 1; done
|
||||||
|
sudo apt-get -q install ghostscript
|
||||||
|
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/default -dNOPAUSE -dQUIET -dBATCH -dDetectDuplicateImages -dCompressFonts=true -r150 -sOutputFile=_book/clover_ru_compressed.pdf _book/clover_ru.pdf
|
||||||
|
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/default -dNOPAUSE -dQUIET -dBATCH -dDetectDuplicateImages -dCompressFonts=true -r150 -sOutputFile=_book/clover_en_compressed.pdf _book/clover_en.pdf
|
||||||
|
rm _book/clover_ru.pdf && mv _book/clover_ru_compressed.pdf _book/clover_ru.pdf
|
||||||
|
rm _book/clover_en.pdf && mv _book/clover_en_compressed.pdf _book/clover_en.pdf
|
||||||
|
ls -lah _book/clover*.pdf
|
||||||
|
- name: Deploy
|
||||||
|
uses: JamesIves/github-pages-deploy-action@4.1.3
|
||||||
|
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||||
|
with:
|
||||||
|
branch: gh-pages
|
||||||
|
folder: _book
|
||||||
|
clean: true
|
||||||
|
single-commit: true # to avoid multiple copies of large pdf files
|
||||||
18
.github/workflows/editorconfig.yaml
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
name: Editorconfig lint
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ '*' ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
editorconfig:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: .editorconfig Linter
|
||||||
|
run: |
|
||||||
|
wget --no-verbose https://github.com/okalachev/editorconfig-checker/releases/download/1.2.1-disable-spaces-amount/ec-linux-amd64
|
||||||
|
chmod +x ec-linux-amd64
|
||||||
|
./ec-linux-amd64 -spaces-after-tabs -e "roslib.js|ros3d.js|eventemitter2.js|draw.cpp|BinUtils.swift|\.idea|apps/android/app|blockly/|clover_blocks/programs/|highlight/|python.js|Assets.xcassets|test_parser_pass.txt|test_node_failure.txt|aruco_pose/vendor|\.stl|\.dxf|\.dae"
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
"ROS Melodic",
|
"ROS Melodic",
|
||||||
"ROS Noetic",
|
"ROS Noetic",
|
||||||
"OpenCV",
|
"OpenCV",
|
||||||
|
"OpenVPN",
|
||||||
"Gazebo",
|
"Gazebo",
|
||||||
"GitHub",
|
"GitHub",
|
||||||
"FPV",
|
"FPV",
|
||||||
@@ -107,7 +108,10 @@
|
|||||||
"UDP",
|
"UDP",
|
||||||
"QR",
|
"QR",
|
||||||
"Li-ion",
|
"Li-ion",
|
||||||
"Nvidia"
|
"Nvidia",
|
||||||
|
"VirtualBox",
|
||||||
|
"VMware",
|
||||||
|
"DuoCam"
|
||||||
],
|
],
|
||||||
"code_blocks": false
|
"code_blocks": false
|
||||||
},
|
},
|
||||||
|
|||||||
125
.travis.yml
@@ -1,125 +0,0 @@
|
|||||||
os: linux
|
|
||||||
dist: xenial
|
|
||||||
language: generic
|
|
||||||
services:
|
|
||||||
- docker
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- DOCKER="sfalexrog/img-tool:qemu-aarch64"
|
|
||||||
- TARGET_REPO="https://github.com/${TRAVIS_REPO_SLUG}.git"
|
|
||||||
- IMAGE_VERSION=${TRAVIS_TAG:-${TRAVIS_COMMIT:0:7}}
|
|
||||||
- IMAGE_NAME="$(basename -s '.git' ${TARGET_REPO})_${IMAGE_VERSION}.img"
|
|
||||||
git:
|
|
||||||
depth: 50
|
|
||||||
jobs:
|
|
||||||
fast_finish: true
|
|
||||||
include:
|
|
||||||
- stage: Build
|
|
||||||
name: "Raspberry Pi Image Build"
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- imgcache
|
|
||||||
before_script:
|
|
||||||
- docker pull ${DOCKER}
|
|
||||||
# Check if there are any cached images, copy them to our "images" directory
|
|
||||||
- if [ -n "$(ls -A imgcache/*.zip)" ]; then mkdir -p images && cp imgcache/*.zip images; fi
|
|
||||||
script:
|
|
||||||
- if [[ -z ${TRAVIS_TAG} && "${TRAVIS_PULL_REQUEST}" != "false" ]]; then
|
|
||||||
echo "Commit range is ${TRAVIS_COMMIT_RANGE}" &&
|
|
||||||
if [ $(git diff --name-only ${TRAVIS_COMMIT_RANGE} | grep -v ^"docs/" | wc -l) -eq 0 ]; then
|
|
||||||
echo " === Docs-only change; skipping build ===" &&
|
|
||||||
export SKIP_BUILD=true;
|
|
||||||
fi;
|
|
||||||
fi
|
|
||||||
- if [ -z ${SKIP_BUILD} ]; then
|
|
||||||
docker run --privileged --rm -v /dev:/dev -v $(pwd):/builder/repo -e TRAVIS_TAG="${TRAVIS_TAG}" ${DOCKER};
|
|
||||||
fi
|
|
||||||
before_cache:
|
|
||||||
- cp images/*.zip imgcache
|
|
||||||
after_success:
|
|
||||||
- sudo chmod -R 777 *
|
|
||||||
- cd images && zip ${IMAGE_NAME}.zip ${IMAGE_NAME} && stat --printf="Compressed image size:%s\n" ${IMAGE_NAME}.zip
|
|
||||||
before_deploy:
|
|
||||||
# Set up git user name and tag this commit
|
|
||||||
- git config --local user.name "goldarte"
|
|
||||||
- git config --local user.email "goldartt@gmail.com"
|
|
||||||
deploy:
|
|
||||||
provider: releases
|
|
||||||
token: ${GITHUB_OAUTH_TOKEN}
|
|
||||||
file: ${IMAGE_NAME}.zip
|
|
||||||
skip_cleanup: true
|
|
||||||
on:
|
|
||||||
tags: true
|
|
||||||
draft: true
|
|
||||||
name: ${TRAVIS_TAG}
|
|
||||||
- stage: Build
|
|
||||||
name: "Native Kinetic build"
|
|
||||||
env:
|
|
||||||
- NATIVE_DOCKER=ros:kinetic-ros-base
|
|
||||||
before_script:
|
|
||||||
- docker pull ${NATIVE_DOCKER}
|
|
||||||
script:
|
|
||||||
- docker run --rm -v $(pwd):/root/catkin_ws/src/clover ${NATIVE_DOCKER} /root/catkin_ws/src/clover/builder/standalone-install.sh
|
|
||||||
- stage: Build
|
|
||||||
name: "Native Melodic build"
|
|
||||||
env:
|
|
||||||
- NATIVE_DOCKER=ros:melodic-ros-base
|
|
||||||
before_script:
|
|
||||||
- docker pull ${NATIVE_DOCKER}
|
|
||||||
script:
|
|
||||||
- docker run --rm -v $(pwd):/root/catkin_ws/src/clover ${NATIVE_DOCKER} /root/catkin_ws/src/clover/builder/standalone-install.sh
|
|
||||||
- stage: Build
|
|
||||||
name: "Native Noetic build"
|
|
||||||
env:
|
|
||||||
- NATIVE_DOCKER=ros:noetic-ros-base
|
|
||||||
before_script:
|
|
||||||
- docker pull ${NATIVE_DOCKER}
|
|
||||||
script:
|
|
||||||
- docker run --rm -v $(pwd):/root/catkin_ws/src/clover ${NATIVE_DOCKER} /root/catkin_ws/src/clover/builder/standalone-install.sh
|
|
||||||
- stage: Build
|
|
||||||
name: "Documentation"
|
|
||||||
language: node_js
|
|
||||||
node_js:
|
|
||||||
- "10"
|
|
||||||
before_script:
|
|
||||||
- sudo sh -c "echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | debconf-set-selections"
|
|
||||||
- sudo apt update && sudo apt install -y calibre msttcorefonts
|
|
||||||
- npm install gitbook-cli -g
|
|
||||||
- npm install markdownlint-cli -g
|
|
||||||
- npm install svgexport -g
|
|
||||||
- gitbook -V
|
|
||||||
- markdownlint -V
|
|
||||||
script:
|
|
||||||
- markdownlint docs
|
|
||||||
- ./check_assets_size.py
|
|
||||||
- ./check_unused_assets.py
|
|
||||||
- gitbook install
|
|
||||||
- gitbook build
|
|
||||||
- gitbook pdf ./ _book/clover.pdf
|
|
||||||
deploy:
|
|
||||||
provider: pages
|
|
||||||
local_dir: _book
|
|
||||||
skip_cleanup: true
|
|
||||||
token: ${GITHUB_OAUTH_TOKEN}
|
|
||||||
keep_history: true
|
|
||||||
target_branch: master
|
|
||||||
repo: CopterExpress/clover.coex.tech
|
|
||||||
fqdn: clover.coex.tech
|
|
||||||
verbose: true
|
|
||||||
on:
|
|
||||||
branch: master
|
|
||||||
- stage: Build
|
|
||||||
name: Editorconfig-lint
|
|
||||||
language: generic
|
|
||||||
before_script:
|
|
||||||
- wget https://github.com/okalachev/editorconfig-checker/releases/download/1.2.1-disable-spaces-amount/ec-linux-amd64
|
|
||||||
- chmod +x ec-linux-amd64
|
|
||||||
script:
|
|
||||||
- ./ec-linux-amd64 -spaces-after-tabs -e "roslib.js|ros3d.js|eventemitter2.js|draw.cpp|BinUtils.swift|\.idea|apps/android/app|blockly/|clover_blocks/programs/|highlight/|python.js|Assets.xcassets|test_parser_pass.txt|test_node_failure.txt|aruco_pose/vendor|\.stl|\.dxf|\.dae"
|
|
||||||
stages:
|
|
||||||
- Build
|
|
||||||
# More info there
|
|
||||||
# https://github.com/travis-ci/travis-ci/issues/6893
|
|
||||||
# https://docs.travis-ci.com/user/customizing-the-build/
|
|
||||||
# https://docs.travis-ci.com/user/deployment/releases
|
|
||||||
# https://docs.travis-ci.com/user/environment-variables/
|
|
||||||
19
README.md
@@ -1,12 +1,14 @@
|
|||||||
# COEX Clover Drone Kit
|
# clover🍀: create autonomous drones easily
|
||||||
|
|
||||||
<img src="docs/assets/clever4-front-white.png" align="right" width="400px" alt="Clover Drone">
|
<img src="docs/assets/clover42-main.png" align="right" width="400px" alt="COEX Clover Drone">
|
||||||
|
|
||||||
Clover is an educational programmable drone kit consisting of an unassembled quadcopter, open source software and documentation. The kit includes Pixracer-compatible autopilot running PX4 firmware, Raspberry Pi 4 as companion computer, a camera for computer vision navigation as well as additional sensors and peripheral devices.
|
Clover is an open source [ROS](https://www.ros.org)-based framework, providing user-friendly tools to control [PX4](https://px4.io)-powered drones. Clover is available as a ROS package, but is shipped mainly as a preconfigured image for Raspberry Pi. Once you've installed Raspberry Pi on your drone and flashed the image to its microSD card, taking the drone up in the air is a matter of minutes.
|
||||||
|
|
||||||
The main documentation is available [on Gitbook](https://clover.coex.tech/).
|
COEX Clover Drone is an educational programmable drone kit, suited perfectly for running clover software. The kit is shipped unassembled and includes Pixracer-compatible autopilot running PX4 firmware, Raspberry Pi 4 as a companion computer, a camera for computer vision navigation as well as additional sensors and peripheral devices. Batteries included.
|
||||||
|
|
||||||
Official website: <a href="https://coex.tech/clover">coex.tech/clover</a>.
|
The main documentation is available at [https://clover.coex.tech](https://clover.coex.tech/). Official website: [coex.tech/clover](https://coex.tech/clover).
|
||||||
|
|
||||||
|
[__Support us on Kickstarter!__](https://www.kickstarter.com/projects/copterexpress/cloverdrone)
|
||||||
|
|
||||||
## Video compilation
|
## Video compilation
|
||||||
|
|
||||||
@@ -18,7 +20,8 @@ Clover drone is used on a wide range of educational events, including [Copter Ha
|
|||||||
|
|
||||||
Preconfigured image for Raspberry Pi with installed and configured software, ready to fly, is available [in the Releases section](https://github.com/CopterExpress/clover/releases).
|
Preconfigured image for Raspberry Pi with installed and configured software, ready to fly, is available [in the Releases section](https://github.com/CopterExpress/clover/releases).
|
||||||
|
|
||||||
[](https://travis-ci.org/CopterExpress/clover)
|

|
||||||
|

|
||||||
|
|
||||||
Image features:
|
Image features:
|
||||||
|
|
||||||
@@ -35,6 +38,10 @@ API description for autonomous flights is available [on GitBook](https://clover.
|
|||||||
|
|
||||||
For manual package installation and running see [`clover` package documentation](clover/README.md).
|
For manual package installation and running see [`clover` package documentation](clover/README.md).
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
[](https://t.me/COEXHelpdesk)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
While the Clover platform source code is available under the MIT License, note, that the [documentation](docs/) is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
|
While the Clover platform source code is available under the MIT License, note, that the [documentation](docs/) is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
|
||||||
|
|||||||
8
aruco_pose/CHANGELOG.rst
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Changelog for package aruco_pose
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
0.21.1 (2020-11-17)
|
||||||
|
-------------------
|
||||||
|
* First release of aruco_pose package to ROS
|
||||||
|
* Contributors: Alamoris, Alexey Rogachevskiy, Arthur Golubtsov, Ilya Petrov, Oleg Kalachev
|
||||||
@@ -24,7 +24,7 @@ find_package(catkin REQUIRED COMPONENTS
|
|||||||
|
|
||||||
# Workaround for OpenCV 3/4 support
|
# Workaround for OpenCV 3/4 support
|
||||||
set(_opencv_version 4)
|
set(_opencv_version 4)
|
||||||
find_package(OpenCV ${_opencv_version} QUIET)
|
find_package(OpenCV ${_opencv_version} QUIET COMPONENTS core imgproc calib3d)
|
||||||
if (NOT OpenCV_FOUND)
|
if (NOT OpenCV_FOUND)
|
||||||
message(STATUS "Did not find OpenCV 4, searching for OpenCV 3")
|
message(STATUS "Did not find OpenCV 4, searching for OpenCV 3")
|
||||||
set(_opencv_version 3)
|
set(_opencv_version 3)
|
||||||
@@ -119,7 +119,7 @@ generate_messages(
|
|||||||
|
|
||||||
## Generate dynamic reconfigure parameters in the 'cfg' folder
|
## Generate dynamic reconfigure parameters in the 'cfg' folder
|
||||||
generate_dynamic_reconfigure_options(
|
generate_dynamic_reconfigure_options(
|
||||||
cfg/DetectorParams.cfg
|
cfg/Detector.cfg
|
||||||
)
|
)
|
||||||
|
|
||||||
###################################
|
###################################
|
||||||
@@ -180,6 +180,13 @@ target_link_libraries(aruco_pose
|
|||||||
${OpenCV_LIBRARIES}
|
${OpenCV_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Prevent aruco_pose from having undefined symbols
|
||||||
|
set_property(TARGET aruco_pose
|
||||||
|
APPEND
|
||||||
|
PROPERTY LINK_FLAGS
|
||||||
|
-Wl,--no-undefined
|
||||||
|
)
|
||||||
|
|
||||||
#############
|
#############
|
||||||
## Install ##
|
## Install ##
|
||||||
#############
|
#############
|
||||||
@@ -195,11 +202,11 @@ target_link_libraries(aruco_pose
|
|||||||
# )
|
# )
|
||||||
|
|
||||||
## Mark executables and/or libraries for installation
|
## Mark executables and/or libraries for installation
|
||||||
# install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_node
|
install(TARGETS ${PROJECT_NAME}
|
||||||
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||||
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||||
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||||
# )
|
)
|
||||||
|
|
||||||
## Mark cpp header files for installation
|
## Mark cpp header files for installation
|
||||||
# install(DIRECTORY include/${PROJECT_NAME}/
|
# install(DIRECTORY include/${PROJECT_NAME}/
|
||||||
@@ -219,6 +226,10 @@ catkin_install_python(PROGRAMS src/genmap.py
|
|||||||
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
install(DIRECTORY launch DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
|
||||||
|
|
||||||
|
install(DIRECTORY map DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
|
||||||
|
|
||||||
#############
|
#############
|
||||||
## Testing ##
|
## Testing ##
|
||||||
#############
|
#############
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ p = cv2.aruco.DetectorParameters_create()
|
|||||||
|
|
||||||
gen = ParameterGenerator()
|
gen = ParameterGenerator()
|
||||||
|
|
||||||
|
gen.add("enabled", bool_t, 0, "if detection enabled", True)
|
||||||
|
|
||||||
gen.add("adaptiveThreshConstant", double_t, 0,
|
gen.add("adaptiveThreshConstant", double_t, 0,
|
||||||
"Constant for adaptive thresholding before finding contours",
|
"Constant for adaptive thresholding before finding contours",
|
||||||
p.adaptiveThreshConstant, 0, 100)
|
p.adaptiveThreshConstant, 0, 100)
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<package format="2">
|
<package format="2">
|
||||||
<name>aruco_pose</name>
|
<name>aruco_pose</name>
|
||||||
<version>0.0.1</version>
|
<version>0.21.1</version>
|
||||||
<description>Positioning with ArUco markers</description>
|
<description>Positioning with ArUco markers</description>
|
||||||
|
|
||||||
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ private:
|
|||||||
std::unique_ptr<tf2_ros::Buffer> tf_buffer_;
|
std::unique_ptr<tf2_ros::Buffer> tf_buffer_;
|
||||||
std::unique_ptr<tf2_ros::TransformListener> tf_listener_;
|
std::unique_ptr<tf2_ros::TransformListener> tf_listener_;
|
||||||
std::shared_ptr<dynamic_reconfigure::Server<aruco_pose::DetectorConfig>> dyn_srv_;
|
std::shared_ptr<dynamic_reconfigure::Server<aruco_pose::DetectorConfig>> dyn_srv_;
|
||||||
|
bool enabled_ = true;
|
||||||
cv::Ptr<cv::aruco::Dictionary> dictionary_;
|
cv::Ptr<cv::aruco::Dictionary> dictionary_;
|
||||||
cv::Ptr<cv::aruco::DetectorParameters> parameters_;
|
cv::Ptr<cv::aruco::DetectorParameters> parameters_;
|
||||||
image_transport::Publisher debug_pub_;
|
image_transport::Publisher debug_pub_;
|
||||||
@@ -110,17 +111,14 @@ public:
|
|||||||
image_transport::ImageTransport it(nh_);
|
image_transport::ImageTransport it(nh_);
|
||||||
image_transport::ImageTransport it_priv(nh_priv_);
|
image_transport::ImageTransport it_priv(nh_priv_);
|
||||||
|
|
||||||
map_markers_sub_ = nh_.subscribe("map_markers", 1, &ArucoDetect::mapMarkersCallback, this);
|
dyn_srv_ = std::make_shared<dynamic_reconfigure::Server<aruco_pose::DetectorConfig>>(nh_priv_);
|
||||||
|
dyn_srv_->setCallback(std::bind(&ArucoDetect::paramCallback, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
|
|
||||||
debug_pub_ = it_priv.advertise("debug", 1);
|
debug_pub_ = it_priv.advertise("debug", 1);
|
||||||
markers_pub_ = nh_priv_.advertise<aruco_pose::MarkerArray>("markers", 1);
|
markers_pub_ = nh_priv_.advertise<aruco_pose::MarkerArray>("markers", 1);
|
||||||
vis_markers_pub_ = nh_priv_.advertise<visualization_msgs::MarkerArray>("visualization", 1);
|
vis_markers_pub_ = nh_priv_.advertise<visualization_msgs::MarkerArray>("visualization", 1);
|
||||||
img_sub_ = it.subscribeCamera("image_raw", 1, &ArucoDetect::imageCallback, this);
|
img_sub_ = it.subscribeCamera("image_raw", 1, &ArucoDetect::imageCallback, this);
|
||||||
|
map_markers_sub_ = nh_.subscribe("map_markers", 1, &ArucoDetect::mapMarkersCallback, this);
|
||||||
dyn_srv_ = std::make_shared<dynamic_reconfigure::Server<aruco_pose::DetectorConfig>>(nh_priv_);
|
|
||||||
dynamic_reconfigure::Server<aruco_pose::DetectorConfig>::CallbackType cb;
|
|
||||||
|
|
||||||
cb = std::bind(&ArucoDetect::paramCallback, this, std::placeholders::_1, std::placeholders::_2);
|
|
||||||
dyn_srv_->setCallback(cb);
|
|
||||||
|
|
||||||
NODELET_INFO("ready");
|
NODELET_INFO("ready");
|
||||||
}
|
}
|
||||||
@@ -128,6 +126,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
void imageCallback(const sensor_msgs::ImageConstPtr& msg, const sensor_msgs::CameraInfoConstPtr &cinfo)
|
void imageCallback(const sensor_msgs::ImageConstPtr& msg, const sensor_msgs::CameraInfoConstPtr &cinfo)
|
||||||
{
|
{
|
||||||
|
if (!enabled_) return;
|
||||||
|
|
||||||
Mat image = cv_bridge::toCvShare(msg, "bgr8")->image;
|
Mat image = cv_bridge::toCvShare(msg, "bgr8")->image;
|
||||||
|
|
||||||
vector<int> ids;
|
vector<int> ids;
|
||||||
@@ -356,6 +356,7 @@ private:
|
|||||||
|
|
||||||
void paramCallback(aruco_pose::DetectorConfig &config, uint32_t level)
|
void paramCallback(aruco_pose::DetectorConfig &config, uint32_t level)
|
||||||
{
|
{
|
||||||
|
enabled_ = config.enabled;
|
||||||
parameters_->adaptiveThreshConstant = config.adaptiveThreshConstant;
|
parameters_->adaptiveThreshConstant = config.adaptiveThreshConstant;
|
||||||
parameters_->adaptiveThreshWinSizeMin = config.adaptiveThreshWinSizeMin;
|
parameters_->adaptiveThreshWinSizeMin = config.adaptiveThreshWinSizeMin;
|
||||||
parameters_->adaptiveThreshWinSizeMax = config.adaptiveThreshWinSizeMax;
|
parameters_->adaptiveThreshWinSizeMax = config.adaptiveThreshWinSizeMax;
|
||||||
|
|||||||
@@ -124,6 +124,11 @@ public:
|
|||||||
vis_markers_pub_ = nh_priv_.advertise<visualization_msgs::MarkerArray>("visualization", 1, true);
|
vis_markers_pub_ = nh_priv_.advertise<visualization_msgs::MarkerArray>("visualization", 1, true);
|
||||||
debug_pub_ = it_priv.advertise("debug", 1);
|
debug_pub_ = it_priv.advertise("debug", 1);
|
||||||
|
|
||||||
|
publishMarkersFrames();
|
||||||
|
publishMarkers();
|
||||||
|
publishMapImage();
|
||||||
|
vis_markers_pub_.publish(vis_array_);
|
||||||
|
|
||||||
image_sub_.subscribe(nh_, "image_raw", 1);
|
image_sub_.subscribe(nh_, "image_raw", 1);
|
||||||
info_sub_.subscribe(nh_, "camera_info", 1);
|
info_sub_.subscribe(nh_, "camera_info", 1);
|
||||||
markers_sub_.subscribe(nh_, "markers", 1);
|
markers_sub_.subscribe(nh_, "markers", 1);
|
||||||
@@ -131,11 +136,6 @@ public:
|
|||||||
sync_.reset(new message_filters::Synchronizer<SyncPolicy>(SyncPolicy(10), image_sub_, info_sub_, markers_sub_));
|
sync_.reset(new message_filters::Synchronizer<SyncPolicy>(SyncPolicy(10), image_sub_, info_sub_, markers_sub_));
|
||||||
sync_->registerCallback(boost::bind(&ArucoMap::callback, this, _1, _2, _3));
|
sync_->registerCallback(boost::bind(&ArucoMap::callback, this, _1, _2, _3));
|
||||||
|
|
||||||
publishMarkersFrames();
|
|
||||||
publishMarkers();
|
|
||||||
publishMapImage();
|
|
||||||
vis_markers_pub_.publish(vis_array_);
|
|
||||||
|
|
||||||
NODELET_INFO("ready");
|
NODELET_INFO("ready");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
3
aruco_pose/vendor/VendorOpenCV.cmake
vendored
@@ -7,6 +7,7 @@ endif()
|
|||||||
|
|
||||||
message(STATUS "Adding vendored aruco_pose OpenCV module")
|
message(STATUS "Adding vendored aruco_pose OpenCV module")
|
||||||
add_library(_opencv_aruco STATIC
|
add_library(_opencv_aruco STATIC
|
||||||
|
vendor/aruco/src/apriltag_quad_thresh.cpp
|
||||||
vendor/aruco/src/aruco.cpp
|
vendor/aruco/src/aruco.cpp
|
||||||
vendor/aruco/src/charuco.cpp
|
vendor/aruco/src/charuco.cpp
|
||||||
vendor/aruco/src/dictionary.cpp
|
vendor/aruco/src/dictionary.cpp
|
||||||
@@ -23,7 +24,7 @@ target_compile_definitions(_opencv_aruco PRIVATE
|
|||||||
CV_OVERRIDE=override
|
CV_OVERRIDE=override
|
||||||
)
|
)
|
||||||
target_compile_options(_opencv_aruco PRIVATE
|
target_compile_options(_opencv_aruco PRIVATE
|
||||||
-fpic -fPIC
|
-fpic -fPIC -fvisibility=hidden
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(_opencv_aruco PUBLIC
|
target_include_directories(_opencv_aruco PUBLIC
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ void ptsort_(struct pt *pts, int sz)
|
|||||||
|
|
||||||
// Use stack storage if it's not too big.
|
// Use stack storage if it's not too big.
|
||||||
cv::AutoBuffer<struct pt, 1024> _tmp_stack(sz);
|
cv::AutoBuffer<struct pt, 1024> _tmp_stack(sz);
|
||||||
memcpy(_tmp_stack.data(), pts, sizeof(struct pt) * sz);
|
memcpy(_tmp_stack, pts, sizeof(struct pt) * sz);
|
||||||
|
|
||||||
int asz = sz/2;
|
int asz = sz/2;
|
||||||
int bsz = sz - asz;
|
int bsz = sz - asz;
|
||||||
@@ -470,11 +470,11 @@ int quad_segment_agg(int sz, struct line_fit_pt *lfps, int indices[4]){
|
|||||||
int rvalloc_pos = 0;
|
int rvalloc_pos = 0;
|
||||||
int rvalloc_size = 3*sz;
|
int rvalloc_size = 3*sz;
|
||||||
cv::AutoBuffer<struct remove_vertex, 0> rvalloc_(std::max(1, rvalloc_size));
|
cv::AutoBuffer<struct remove_vertex, 0> rvalloc_(std::max(1, rvalloc_size));
|
||||||
memset(rvalloc_.data(), 0, sizeof(rvalloc_[0]) * rvalloc_.size()); // TODO Add AutoBuffer zero fill
|
memset(rvalloc_, 0, sizeof(rvalloc_[0]) * rvalloc_.size()); // TODO Add AutoBuffer zero fill
|
||||||
struct remove_vertex *rvalloc = rvalloc_.data();
|
struct remove_vertex *rvalloc = rvalloc_;
|
||||||
cv::AutoBuffer<struct segment, 0> segs_(std::max(1, sz)); // TODO Add AutoBuffer zero fill
|
cv::AutoBuffer<struct segment, 0> segs_(std::max(1, sz)); // TODO Add AutoBuffer zero fill
|
||||||
memset(segs_.data(), 0, sizeof(segs_[0]) * segs_.size());
|
memset(segs_, 0, sizeof(segs_[0]) * segs_.size());
|
||||||
struct segment *segs = segs_.data();
|
struct segment *segs = segs_;
|
||||||
|
|
||||||
// populate with initial entries
|
// populate with initial entries
|
||||||
for (int i = 0; i < sz; i++) {
|
for (int i = 0; i < sz; i++) {
|
||||||
@@ -753,8 +753,8 @@ int fit_quad(const Ptr<DetectorParameters> &_params, const Mat im, zarray_t *clu
|
|||||||
// efficiently computed for any contiguous range of indices.
|
// efficiently computed for any contiguous range of indices.
|
||||||
|
|
||||||
cv::AutoBuffer<struct line_fit_pt, 64> lfps_(sz);
|
cv::AutoBuffer<struct line_fit_pt, 64> lfps_(sz);
|
||||||
memset(lfps_.data(), 0, sizeof(lfps_[0]) * lfps_.size()); // TODO Add AutoBuffer zero fill
|
memset(lfps_, 0, sizeof(lfps_[0]) * lfps_.size()); // TODO Add AutoBuffer zero fill
|
||||||
struct line_fit_pt *lfps = lfps_.data();
|
struct line_fit_pt *lfps = lfps_;
|
||||||
|
|
||||||
for (int i = 0; i < sz; i++) {
|
for (int i = 0; i < sz; i++) {
|
||||||
struct pt *p;
|
struct pt *p;
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ echo_stamp "#6 Turn on UART"
|
|||||||
# https://github.com/RPi-Distro/raspi-config/pull/75
|
# https://github.com/RPi-Distro/raspi-config/pull/75
|
||||||
/usr/bin/raspi-config nonint do_serial 1
|
/usr/bin/raspi-config nonint do_serial 1
|
||||||
/usr/bin/raspi-config nonint set_config_var enable_uart 1 /boot/config.txt
|
/usr/bin/raspi-config nonint set_config_var enable_uart 1 /boot/config.txt
|
||||||
/usr/bin/raspi-config nonint set_config_var dtoverlay pi3-disable-bt /boot/config.txt
|
echo dtoverlay=pi3-disable-bt >> /boot/config.txt
|
||||||
systemctl disable hciuart.service
|
systemctl disable hciuart.service
|
||||||
|
|
||||||
# After adding to Raspbian OS
|
# After adding to Raspbian OS
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
|
|
||||||
set -e # Exit immidiately on non-zero result
|
set -e # Exit immidiately on non-zero result
|
||||||
|
|
||||||
SOURCE_IMAGE="https://downloads.raspberrypi.org/raspios_lite_arm64/images/raspios_lite_arm64-2020-08-24/2020-08-20-raspios-buster-arm64-lite.zip"
|
# https://www.raspberrypi.org/software/operating-systems/#raspberry-pi-os-32-bit
|
||||||
|
SOURCE_IMAGE="https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2021-05-28/2021-05-07-raspios-buster-armhf-lite.zip"
|
||||||
|
|
||||||
export DEBIAN_FRONTEND=${DEBIAN_FRONTEND:='noninteractive'}
|
export DEBIAN_FRONTEND=${DEBIAN_FRONTEND:='noninteractive'}
|
||||||
export LANG=${LANG:='C.UTF-8'}
|
export LANG=${LANG:='C.UTF-8'}
|
||||||
@@ -104,8 +105,6 @@ ${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/butterf
|
|||||||
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/monkey.service' '/lib/systemd/system/'
|
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/monkey.service' '/lib/systemd/system/'
|
||||||
# software install
|
# software install
|
||||||
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-software.sh'
|
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-software.sh'
|
||||||
# examples
|
|
||||||
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/examples' '/home/pi/'
|
|
||||||
# network setup
|
# network setup
|
||||||
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-network.sh'
|
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-network.sh'
|
||||||
# avahi setup
|
# avahi setup
|
||||||
|
|||||||
@@ -55,4 +55,7 @@ echo_stamp "Set max space for syslogs"
|
|||||||
# https://unix.stackexchange.com/questions/139513/how-to-clear-journalctl
|
# https://unix.stackexchange.com/questions/139513/how-to-clear-journalctl
|
||||||
sed -i 's/#SystemMaxUse=/SystemMaxUse=200M/' /etc/systemd/journald.conf
|
sed -i 's/#SystemMaxUse=/SystemMaxUse=200M/' /etc/systemd/journald.conf
|
||||||
|
|
||||||
|
echo_stamp "Move /etc/ld.so.preload out of the way"
|
||||||
|
mv /etc/ld.so.preload /etc/ld.so.preload.disabled-for-build
|
||||||
|
|
||||||
echo_stamp "End of init image"
|
echo_stamp "End of init image"
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ my_travis_retry sudo -u pi rosdep update
|
|||||||
|
|
||||||
export ROS_IP='127.0.0.1' # needed for running tests
|
export ROS_IP='127.0.0.1' # needed for running tests
|
||||||
|
|
||||||
echo_stamp "Reconfiguring Clover repository for simplier unshallowing"
|
# echo_stamp "Reconfiguring Clover repository for simplier unshallowing"
|
||||||
cd /home/pi/catkin_ws/src/clover
|
cd /home/pi/catkin_ws/src/clover
|
||||||
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
|
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ apt install -y --no-install-recommends \
|
|||||||
ros-${ROS_DISTRO}-compressed-image-transport=1.14.0-0buster \
|
ros-${ROS_DISTRO}-compressed-image-transport=1.14.0-0buster \
|
||||||
ros-${ROS_DISTRO}-cv-bridge=1.15.0-0buster \
|
ros-${ROS_DISTRO}-cv-bridge=1.15.0-0buster \
|
||||||
ros-${ROS_DISTRO}-cv-camera=0.5.0-0buster \
|
ros-${ROS_DISTRO}-cv-camera=0.5.0-0buster \
|
||||||
ros-${ROS_DISTRO}-image-publisher=1.15.2-0buster \
|
ros-${ROS_DISTRO}-image-publisher=1.15.3-0buster \
|
||||||
ros-${ROS_DISTRO}-web-video-server=0.2.1-0buster
|
ros-${ROS_DISTRO}-web-video-server=0.2.1-0buster
|
||||||
apt-mark hold \
|
apt-mark hold \
|
||||||
ros-${ROS_DISTRO}-compressed-image-transport \
|
ros-${ROS_DISTRO}-compressed-image-transport \
|
||||||
@@ -100,6 +100,9 @@ ros-${ROS_DISTRO}-cv-camera \
|
|||||||
ros-${ROS_DISTRO}-image-publisher \
|
ros-${ROS_DISTRO}-image-publisher \
|
||||||
ros-${ROS_DISTRO}-web-video-server
|
ros-${ROS_DISTRO}-web-video-server
|
||||||
|
|
||||||
|
echo_stamp "Installing libboost-dev" # https://travis-ci.org/github/CopterExpress/clover/jobs/766318908#L6536
|
||||||
|
my_travis_retry apt-get install -y --no-install-recommends libboost-dev libboost-all-dev
|
||||||
|
|
||||||
echo_stamp "Build and install Clover"
|
echo_stamp "Build and install Clover"
|
||||||
cd /home/pi/catkin_ws
|
cd /home/pi/catkin_ws
|
||||||
# Don't try to install gazebo_ros
|
# Don't try to install gazebo_ros
|
||||||
@@ -109,7 +112,8 @@ my_travis_retry pip3 install wheel
|
|||||||
my_travis_retry pip3 install -r /home/pi/catkin_ws/src/clover/clover/requirements.txt
|
my_travis_retry pip3 install -r /home/pi/catkin_ws/src/clover/clover/requirements.txt
|
||||||
source /opt/ros/${ROS_DISTRO}/setup.bash
|
source /opt/ros/${ROS_DISTRO}/setup.bash
|
||||||
# Don't build simulation plugins for actual drone
|
# Don't build simulation plugins for actual drone
|
||||||
catkin_make -j2 -DCMAKE_BUILD_TYPE=Release -DCATKIN_BLACKLIST_PACKAGES=clover_gazebo_plugins
|
catkin_make -j2 -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCATKIN_BLACKLIST_PACKAGES=clover_gazebo_plugins
|
||||||
|
source devel/setup.bash
|
||||||
|
|
||||||
echo_stamp "Install clever package (for backwards compatibility)"
|
echo_stamp "Install clever package (for backwards compatibility)"
|
||||||
cd /home/pi/catkin_ws/src/clover/builder/assets/clever
|
cd /home/pi/catkin_ws/src/clover/builder/assets/clever
|
||||||
@@ -119,6 +123,7 @@ rm -rf build # remove build artifacts
|
|||||||
echo_stamp "Build Clover documentation"
|
echo_stamp "Build Clover documentation"
|
||||||
cd /home/pi/catkin_ws/src/clover
|
cd /home/pi/catkin_ws/src/clover
|
||||||
NPM_CONFIG_UNSAFE_PERM=true npm install gitbook-cli -g
|
NPM_CONFIG_UNSAFE_PERM=true npm install gitbook-cli -g
|
||||||
|
NPM_CONFIG_UNSAFE_PERM=true gitbook fetch 3.2.3 && npm i npm@3.10.10 --prefix=~/.gitbook/versions/3.2.3/ # fixing https://travis-ci.org/github/CopterExpress/clover/jobs/766541125#L932
|
||||||
NPM_CONFIG_UNSAFE_PERM=true gitbook install
|
NPM_CONFIG_UNSAFE_PERM=true gitbook install
|
||||||
gitbook build
|
gitbook build
|
||||||
touch node_modules/CATKIN_IGNORE docs/CATKIN_IGNORE _book/CATKIN_IGNORE clover/www/CATKIN_IGNORE apps/CATKIN_IGNORE # ignore documentation files by catkin
|
touch node_modules/CATKIN_IGNORE docs/CATKIN_IGNORE _book/CATKIN_IGNORE clover/www/CATKIN_IGNORE apps/CATKIN_IGNORE # ignore documentation files by catkin
|
||||||
@@ -131,7 +136,9 @@ my_travis_retry apt-get install -y --no-install-recommends \
|
|||||||
ros-${ROS_DISTRO}-usb-cam \
|
ros-${ROS_DISTRO}-usb-cam \
|
||||||
ros-${ROS_DISTRO}-vl53l1x \
|
ros-${ROS_DISTRO}-vl53l1x \
|
||||||
ros-${ROS_DISTRO}-ws281x \
|
ros-${ROS_DISTRO}-ws281x \
|
||||||
ros-${ROS_DISTRO}-rosshow
|
ros-${ROS_DISTRO}-rosshow \
|
||||||
|
ros-${ROS_DISTRO}-cmake-modules \
|
||||||
|
ros-${ROS_DISTRO}-image-view
|
||||||
|
|
||||||
# TODO move GeographicLib datasets to Mavros debian package
|
# TODO move GeographicLib datasets to Mavros debian package
|
||||||
echo_stamp "Install GeographicLib datasets (needed for mavros)" \
|
echo_stamp "Install GeographicLib datasets (needed for mavros)" \
|
||||||
@@ -145,6 +152,10 @@ catkin_make run_tests #&& catkin_test_results
|
|||||||
echo_stamp "Change permissions for catkin_ws"
|
echo_stamp "Change permissions for catkin_ws"
|
||||||
chown -Rf pi:pi /home/pi/catkin_ws
|
chown -Rf pi:pi /home/pi/catkin_ws
|
||||||
|
|
||||||
|
echo_stamp "Make \$HOME/examples symlink"
|
||||||
|
ln -s "$(catkin_find clover examples --first-only)" /home/pi
|
||||||
|
chown -Rf pi:pi /home/pi/examples
|
||||||
|
|
||||||
echo_stamp "Setup ROS environment"
|
echo_stamp "Setup ROS environment"
|
||||||
cat << EOF >> /home/pi/.bashrc
|
cat << EOF >> /home/pi/.bashrc
|
||||||
LANG='C.UTF-8'
|
LANG='C.UTF-8'
|
||||||
|
|||||||
@@ -64,15 +64,14 @@ echo "APT::Acquire::Retries \"3\";" > /etc/apt/apt.conf.d/80-retries
|
|||||||
echo_stamp "Install apt keys & repos"
|
echo_stamp "Install apt keys & repos"
|
||||||
|
|
||||||
# TODO: This STDOUT consist 'OK'
|
# TODO: This STDOUT consist 'OK'
|
||||||
curl http://deb.coex.tech/aptly_repo_signing.key 2> /dev/null | apt-key add -
|
|
||||||
apt-get update \
|
apt-get update \
|
||||||
&& apt-get install --no-install-recommends -y dirmngr > /dev/null \
|
&& apt-get install --no-install-recommends -y dirmngr > /dev/null \
|
||||||
&& apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
|
&& apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
|
||||||
|
|
||||||
echo "deb http://packages.ros.org/ros/ubuntu buster main" > /etc/apt/sources.list.d/ros-latest.list
|
echo "deb http://packages.ros.org/ros/ubuntu buster main" > /etc/apt/sources.list.d/ros-latest.list
|
||||||
echo "deb http://deb.coex.tech/opencv4 buster main" > /etc/apt/sources.list.d/opencv3.list
|
|
||||||
echo "deb http://deb.coex.tech/ros buster main" > /etc/apt/sources.list.d/rpi-ros-melodic.list
|
wget -O - 'http://packages.coex.tech/key.asc' | apt-key add -
|
||||||
echo "deb http://deb.coex.tech/clover buster main" > /etc/apt/sources.list.d/clover.list
|
echo 'deb http://packages.coex.tech buster main' >> /etc/apt/sources.list
|
||||||
|
|
||||||
echo_stamp "Update apt cache"
|
echo_stamp "Update apt cache"
|
||||||
|
|
||||||
@@ -82,6 +81,7 @@ apt-get update
|
|||||||
|
|
||||||
# Let's retry fetching those packages several times, just in case
|
# Let's retry fetching those packages several times, just in case
|
||||||
echo_stamp "Software installing"
|
echo_stamp "Software installing"
|
||||||
|
my_travis_retry apt-get install --no-install-recommends -y cmake-data=3.13.4-1 cmake=3.13.4-1 # FIXME: using older CMake due to https://travis-ci.org/github/CopterExpress/clover/jobs/764367665#L6984
|
||||||
my_travis_retry apt-get install --no-install-recommends -y \
|
my_travis_retry apt-get install --no-install-recommends -y \
|
||||||
unzip \
|
unzip \
|
||||||
zip \
|
zip \
|
||||||
@@ -94,8 +94,9 @@ lsof \
|
|||||||
git \
|
git \
|
||||||
dnsmasq \
|
dnsmasq \
|
||||||
tmux \
|
tmux \
|
||||||
|
tree \
|
||||||
vim \
|
vim \
|
||||||
cmake \
|
libjpeg8 \
|
||||||
tcpdump \
|
tcpdump \
|
||||||
libpoco-dev \
|
libpoco-dev \
|
||||||
libzbar0 \
|
libzbar0 \
|
||||||
@@ -122,9 +123,10 @@ sed -i "s/updates_available//" /usr/share/byobu/status/status
|
|||||||
|
|
||||||
echo_stamp "Installing pip"
|
echo_stamp "Installing pip"
|
||||||
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
|
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
|
||||||
|
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip2.py
|
||||||
python3 get-pip.py
|
python3 get-pip.py
|
||||||
python get-pip.py
|
python get-pip2.py
|
||||||
rm get-pip.py
|
rm get-pip.py get-pip2.py
|
||||||
#my_travis_retry pip install --upgrade pip
|
#my_travis_retry pip install --upgrade pip
|
||||||
#my_travis_retry pip3 install --upgrade pip
|
#my_travis_retry pip3 install --upgrade pip
|
||||||
|
|
||||||
@@ -134,6 +136,7 @@ pip3 --version
|
|||||||
|
|
||||||
echo_stamp "Install and enable Butterfly (web terminal)"
|
echo_stamp "Install and enable Butterfly (web terminal)"
|
||||||
echo_stamp "Workaround for tornado >= 6.0 breaking butterfly"
|
echo_stamp "Workaround for tornado >= 6.0 breaking butterfly"
|
||||||
|
export CRYPTOGRAPHY_DONT_BUILD_RUST=1
|
||||||
my_travis_retry pip3 install tornado==5.1.1
|
my_travis_retry pip3 install tornado==5.1.1
|
||||||
my_travis_retry pip3 install butterfly
|
my_travis_retry pip3 install butterfly
|
||||||
my_travis_retry pip3 install butterfly[systemd]
|
my_travis_retry pip3 install butterfly[systemd]
|
||||||
@@ -145,15 +148,16 @@ my_travis_retry pip3 install --prefer-binary rpi_ws281x
|
|||||||
echo_stamp "Setup Monkey"
|
echo_stamp "Setup Monkey"
|
||||||
mv /etc/monkey/sites/default /etc/monkey/sites/default.orig
|
mv /etc/monkey/sites/default /etc/monkey/sites/default.orig
|
||||||
mv /root/monkey /etc/monkey/sites/default
|
mv /root/monkey /etc/monkey/sites/default
|
||||||
|
sed -i 's/SymLink Off/SymLink On/' /etc/monkey/monkey.conf
|
||||||
systemctl enable monkey.service
|
systemctl enable monkey.service
|
||||||
|
|
||||||
echo_stamp "Install Node.js"
|
echo_stamp "Install Node.js"
|
||||||
cd /home/pi
|
cd /home/pi
|
||||||
wget https://nodejs.org/dist/v10.15.0/node-v10.15.0-linux-arm64.tar.gz
|
wget --no-verbose https://nodejs.org/dist/v10.15.0/node-v10.15.0-linux-armv6l.tar.gz
|
||||||
tar -xzf node-v10.15.0-linux-arm64.tar.gz
|
tar -xzf node-v10.15.0-linux-armv6l.tar.gz
|
||||||
cp -R node-v10.15.0-linux-arm64/* /usr/local/
|
cp -R node-v10.15.0-linux-armv6l/* /usr/local/
|
||||||
rm -rf node-v10.15.0-linux-arm64/
|
rm -rf node-v10.15.0-linux-armv6l/
|
||||||
rm node-v10.15.0-linux-arm64.tar.gz
|
rm node-v10.15.0-linux-armv6l.tar.gz
|
||||||
|
|
||||||
echo_stamp "Installing ptvsd"
|
echo_stamp "Installing ptvsd"
|
||||||
my_travis_retry pip install ptvsd
|
my_travis_retry pip install ptvsd
|
||||||
|
|||||||
@@ -20,9 +20,16 @@ export ROS_DISTRO='noetic'
|
|||||||
export ROS_IP='127.0.0.1'
|
export ROS_IP='127.0.0.1'
|
||||||
source /opt/ros/${ROS_DISTRO}/setup.bash
|
source /opt/ros/${ROS_DISTRO}/setup.bash
|
||||||
source /home/pi/catkin_ws/devel/setup.bash
|
source /home/pi/catkin_ws/devel/setup.bash
|
||||||
|
systemctl start roscore
|
||||||
|
|
||||||
cd /home/pi/catkin_ws/src/clover/builder/test/
|
cd /home/pi/catkin_ws/src/clover/builder/test/
|
||||||
./tests.sh
|
./tests.sh
|
||||||
./tests.py
|
./tests.py
|
||||||
./tests_py3.py
|
./tests_py3.py
|
||||||
|
[[ $(./test_qr.py) == "Found QRCODE with data Проверка Unicode with center at x=66.0, y=66.0" ]]
|
||||||
[[ $(./tests_clever.py) == "Warning: clever package is renamed to clover" ]] # test backwards compatibility
|
[[ $(./tests_clever.py) == "Warning: clever package is renamed to clover" ]] # test backwards compatibility
|
||||||
|
|
||||||
|
systemctl stop roscore
|
||||||
|
|
||||||
|
echo "Move /etc/ld.so.preload back to its original position"
|
||||||
|
mv /etc/ld.so.preload.disabled-for-build /etc/ld.so.preload
|
||||||
|
|||||||
@@ -3,15 +3,16 @@
|
|||||||
# Perform a "standalone install" in a Docker container
|
# Perform a "standalone install" in a Docker container
|
||||||
set -e
|
set -e
|
||||||
# Step 1: Install pip
|
# Step 1: Install pip
|
||||||
apt update
|
apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 # https://github.com/osrf/docker_images/issues/535
|
||||||
apt install -y curl
|
apt-get update
|
||||||
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
|
apt-get install -y curl
|
||||||
if [ "x${ROS_PYTHON_VERSION}" = "x3" ]; then
|
if [ "x${ROS_PYTHON_VERSION}" = "x3" ]; then
|
||||||
PYTHON=python3
|
PYTHON=python3
|
||||||
|
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
|
||||||
else
|
else
|
||||||
PYTHON=python
|
PYTHON=python
|
||||||
|
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py
|
||||||
fi
|
fi
|
||||||
|
|
||||||
${PYTHON} ./get-pip.py
|
${PYTHON} ./get-pip.py
|
||||||
|
|
||||||
# Step 1.5: Add deb.coex.tech to apt
|
# Step 1.5: Add deb.coex.tech to apt
|
||||||
@@ -40,7 +41,7 @@ ws281x:
|
|||||||
ubuntu:
|
ubuntu:
|
||||||
${CODENAME}: [ros-${ROS_DISTRO}-ws281x]
|
${CODENAME}: [ros-${ROS_DISTRO}-ws281x]
|
||||||
EOF
|
EOF
|
||||||
apt update
|
apt-get update
|
||||||
rosdep update
|
rosdep update
|
||||||
|
|
||||||
# Step 2: Run rosdep to install all dependencies
|
# Step 2: Run rosdep to install all dependencies
|
||||||
@@ -60,3 +61,6 @@ ${PYTHON} -m pip install --upgrade pytest
|
|||||||
cd /root/catkin_ws
|
cd /root/catkin_ws
|
||||||
source devel/setup.bash
|
source devel/setup.bash
|
||||||
catkin_make run_tests && catkin_test_results
|
catkin_make run_tests && catkin_test_results
|
||||||
|
|
||||||
|
# Step 5: Install packages
|
||||||
|
catkin_make install
|
||||||
|
|||||||
BIN
builder/test/qr.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
42
builder/test/test_qr.py
Executable file
@@ -0,0 +1,42 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Test QG recognition example
|
||||||
|
# Should be synced with the documentation: /docs/en/camera.md, /docs/ru/camera.md
|
||||||
|
# TODO: use real ROS topics
|
||||||
|
|
||||||
|
import rospy
|
||||||
|
from pyzbar import pyzbar
|
||||||
|
from cv_bridge import CvBridge
|
||||||
|
from sensor_msgs.msg import Image
|
||||||
|
|
||||||
|
bridge = CvBridge()
|
||||||
|
|
||||||
|
# rospy.init_node('barcode_test')
|
||||||
|
|
||||||
|
# Image subscriber callback function
|
||||||
|
def image_callback(data):
|
||||||
|
cv_image = bridge.imgmsg_to_cv2(data, 'bgr8') # OpenCV image
|
||||||
|
barcodes = pyzbar.decode(cv_image)
|
||||||
|
for barcode in barcodes:
|
||||||
|
b_data = barcode.data.decode("utf-8")
|
||||||
|
b_type = barcode.type
|
||||||
|
(x, y, w, h) = barcode.rect
|
||||||
|
xc = x + w/2
|
||||||
|
yc = y + h/2
|
||||||
|
print("Found {} with data {} with center at x={}, y={}".format(b_type, b_data, xc, yc))
|
||||||
|
# rospy.signal_shutdown('done')
|
||||||
|
|
||||||
|
# image_sub = rospy.Subscriber('main_camera/image_raw', Image, image_callback, queue_size=1)
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# Publish test image
|
||||||
|
# rospy.sleep(2)
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
img = cv2.imread('qr.png')
|
||||||
|
image_callback(bridge.cv2_to_imgmsg(img, 'bgr8'))
|
||||||
|
|
||||||
|
# image_pub = rospy.Publisher('/main_camera/image_raw', Image, queue_size=1, latch=True)
|
||||||
|
# image_pub.publish(bridge.cv2_to_imgmsg(img, 'bgr8'))
|
||||||
|
|
||||||
|
# rospy.spin()
|
||||||
@@ -4,18 +4,26 @@
|
|||||||
|
|
||||||
import rospy
|
import rospy
|
||||||
from geometry_msgs.msg import PoseStamped
|
from geometry_msgs.msg import PoseStamped
|
||||||
|
from sensor_msgs.msg import Range, BatteryState
|
||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
import cv2.aruco
|
import cv2.aruco
|
||||||
|
from sensor_msgs.msg import Image
|
||||||
|
from cv_bridge import CvBridge
|
||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
import mavros
|
import mavros
|
||||||
from mavros_msgs.msg import State, StatusText, ExtendedState
|
from mavros_msgs.msg import State, StatusText, ExtendedState, RCIn, Mavlink
|
||||||
from mavros_msgs.srv import CommandBool, CommandLong, SetMode
|
from mavros_msgs.srv import CommandBool, CommandLong, SetMode
|
||||||
|
|
||||||
from std_srvs.srv import Trigger
|
from std_srvs.srv import Trigger
|
||||||
from clover.srv import GetTelemetry, Navigate, NavigateGlobal, SetPosition, SetVelocity, \
|
from clover.srv import GetTelemetry, Navigate, NavigateGlobal, SetPosition, SetVelocity, \
|
||||||
SetAttitude, SetRates, SetLEDEffect
|
SetAttitude, SetRates, SetLEDEffect
|
||||||
|
from led_msgs.srv import SetLEDs
|
||||||
|
from led_msgs.msg import LEDStateArray, LEDState
|
||||||
|
from aruco_pose.msg import Marker, MarkerArray, Point2D
|
||||||
|
|
||||||
|
import dynamic_reconfigure.client
|
||||||
|
|
||||||
import tf2_ros
|
import tf2_ros
|
||||||
import tf2_geometry_msgs
|
import tf2_geometry_msgs
|
||||||
@@ -25,7 +33,7 @@ import pymavlink
|
|||||||
from pymavlink import mavutil
|
from pymavlink import mavutil
|
||||||
import rpi_ws281x
|
import rpi_ws281x
|
||||||
import pigpio
|
import pigpio
|
||||||
from espeak import espeak
|
# from espeak import espeak
|
||||||
from pyzbar import pyzbar
|
from pyzbar import pyzbar
|
||||||
|
|
||||||
print(cv2.getBuildInformation())
|
print(cv2.getBuildInformation())
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ monkey --version
|
|||||||
pigpiod -v
|
pigpiod -v
|
||||||
i2cdetect -V
|
i2cdetect -V
|
||||||
butterfly -h
|
butterfly -h
|
||||||
espeak --version
|
# espeak --version
|
||||||
mjpg_streamer --version
|
mjpg_streamer --version
|
||||||
|
|
||||||
# ros stuff
|
# ros stuff
|
||||||
@@ -43,6 +43,8 @@ rosversion aruco_pose
|
|||||||
rosversion vl53l1x
|
rosversion vl53l1x
|
||||||
rosversion mavros
|
rosversion mavros
|
||||||
rosversion mavros_extras
|
rosversion mavros_extras
|
||||||
|
rosversion ws281x
|
||||||
|
rosversion led_msgs
|
||||||
rosversion dynamic_reconfigure
|
rosversion dynamic_reconfigure
|
||||||
rosversion tf2_web_republisher
|
rosversion tf2_web_republisher
|
||||||
rosversion compressed_image_transport
|
rosversion compressed_image_transport
|
||||||
@@ -52,6 +54,8 @@ rosversion usb_cam
|
|||||||
rosversion cv_camera
|
rosversion cv_camera
|
||||||
rosversion web_video_server
|
rosversion web_video_server
|
||||||
rosversion rosshow
|
rosversion rosshow
|
||||||
|
rosversion nodelet
|
||||||
|
rosversion image_view
|
||||||
|
|
||||||
# validate examples are present
|
# validate examples are present
|
||||||
[[ $(ls /home/pi/examples/*) ]]
|
[[ $(ls /home/pi/examples/*) ]]
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
EXCLUDE = ('clever4-front-white.png', '.DS_Store', 'clever4-front-black-large.png')
|
EXCLUDE = ('clever4-front-white.png', 'clever4-front-white-large.png', '.DS_Store',
|
||||||
|
'clever4-front-black-large.png','clover42-black.png')
|
||||||
|
|
||||||
code = 0
|
code = 0
|
||||||
|
|
||||||
os.chdir('./docs')
|
os.chdir('./docs')
|
||||||
|
|||||||
8
clover/CHANGELOG.rst
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Changelog for package clover
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
0.21.1 (2020-11-17)
|
||||||
|
-------------------
|
||||||
|
* First release of clover package to ROS
|
||||||
|
* Contributors: Alexey Rogachevskiy, Arthur Golubtsov, Oleg Kalachev
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.3)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
project(clover)
|
project(clover)
|
||||||
|
|
||||||
## Compile as C++11, supported in ROS Kinetic and newer
|
## Compile as C++11, supported in ROS Kinetic and newer
|
||||||
@@ -32,7 +32,7 @@ find_package(GeographicLib REQUIRED)
|
|||||||
|
|
||||||
# Workaround for OpenCV 3/4 support
|
# Workaround for OpenCV 3/4 support
|
||||||
set(_opencv_version 4)
|
set(_opencv_version 4)
|
||||||
find_package(OpenCV ${_opencv_version} QUIET)
|
find_package(OpenCV ${_opencv_version} QUIET COMPONENTS calib3d imgproc)
|
||||||
if (NOT OpenCV_FOUND)
|
if (NOT OpenCV_FOUND)
|
||||||
message(STATUS "Did not find OpenCV 4, searching for OpenCV 3")
|
message(STATUS "Did not find OpenCV 4, searching for OpenCV 3")
|
||||||
set(_opencv_version 3)
|
set(_opencv_version 3)
|
||||||
@@ -241,12 +241,12 @@ target_link_libraries(${PROJECT_NAME}
|
|||||||
# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||||
# )
|
# )
|
||||||
|
|
||||||
## Mark executables and/or libraries for installation
|
# Mark executables and/or libraries for installation
|
||||||
# install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_node
|
install(TARGETS simple_offboard clover_rc camera_markers vpe_publisher clover_led shell clover
|
||||||
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||||
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||||
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||||
# )
|
)
|
||||||
|
|
||||||
## Mark cpp header files for installation
|
## Mark cpp header files for installation
|
||||||
# install(DIRECTORY include/${PROJECT_NAME}/
|
# install(DIRECTORY include/${PROJECT_NAME}/
|
||||||
@@ -266,6 +266,12 @@ catkin_install_python(PROGRAMS src/selfcheck.py
|
|||||||
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
install(DIRECTORY launch DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
|
||||||
|
|
||||||
|
install(DIRECTORY examples DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
|
||||||
|
|
||||||
|
# TODO: install www
|
||||||
|
|
||||||
# Only install udev rules when building a Debian package
|
# Only install udev rules when building a Debian package
|
||||||
# FIXME: Other operating systems may have other prefixes
|
# FIXME: Other operating systems may have other prefixes
|
||||||
string(FIND ${CMAKE_INSTALL_PREFIX} "/opt/ros" _PREFIX_INDEX)
|
string(FIND ${CMAKE_INSTALL_PREFIX} "/opt/ros" _PREFIX_INDEX)
|
||||||
|
|||||||
@@ -44,16 +44,12 @@ Alternatively you may change the `fcu_url` property in `mavros.launch` file to p
|
|||||||
|
|
||||||
## Running
|
## Running
|
||||||
|
|
||||||
To start connection to SITL, use:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
roslaunch clover sitl.launch
|
|
||||||
```
|
|
||||||
|
|
||||||
To start connection to the flight controller, use:
|
To start connection to the flight controller, use:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
roslaunch clover clover.launch
|
roslaunch clover clover.launch
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For the simulation information see the [corresponding article](https://clover.coex.tech/en/simulation.html).
|
||||||
|
|
||||||
> Note that the package is configured to connect to `/dev/px4fmu` by default (see [previous section](#manual-installation)). Install udev rules or specify path to your FCU device in `mavros.launch`.
|
> Note that the package is configured to connect to `/dev/px4fmu` by default (see [previous section](#manual-installation)). Install udev rules or specify path to your FCU device in `mavros.launch`.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Information: https://clover.coex.tech/en/aruco.html
|
# Information: https://clover.coex.tech/aruco
|
||||||
|
|
||||||
import rospy
|
import rospy
|
||||||
from clover import srv
|
from clover import srv
|
||||||
11
clover/examples/get_telemetry.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Information: https://clover.coex.tech/en/simple_offboard.html#gettelemetry
|
||||||
|
|
||||||
|
import rospy
|
||||||
|
from clover import srv
|
||||||
|
|
||||||
|
rospy.init_node('flight')
|
||||||
|
|
||||||
|
get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry)
|
||||||
|
|
||||||
|
# Print drone's state
|
||||||
|
print(get_telemetry())
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# Information: https://clover.coex.tech/en/leds.html
|
# Information: https://clover.coex.tech/led
|
||||||
|
|
||||||
import rospy
|
import rospy
|
||||||
from clover.srv import SetLEDEffect
|
from clover.srv import SetLEDEffect
|
||||||
@@ -7,19 +7,25 @@ rospy.init_node('leds')
|
|||||||
|
|
||||||
set_effect = rospy.ServiceProxy('led/set_effect', SetLEDEffect) # define proxy to ROS-service
|
set_effect = rospy.ServiceProxy('led/set_effect', SetLEDEffect) # define proxy to ROS-service
|
||||||
|
|
||||||
|
print('Fill red')
|
||||||
set_effect(r=255, g=0, b=0) # fill strip with red color
|
set_effect(r=255, g=0, b=0) # fill strip with red color
|
||||||
rospy.sleep(2)
|
rospy.sleep(2)
|
||||||
|
|
||||||
|
print('Fill green')
|
||||||
set_effect(r=0, g=100, b=0) # fill strip with green color
|
set_effect(r=0, g=100, b=0) # fill strip with green color
|
||||||
rospy.sleep(2)
|
rospy.sleep(2)
|
||||||
|
|
||||||
|
print('Fade to blue')
|
||||||
set_effect(effect='fade', r=0, g=0, b=255) # fade to blue color
|
set_effect(effect='fade', r=0, g=0, b=255) # fade to blue color
|
||||||
rospy.sleep(2)
|
rospy.sleep(2)
|
||||||
|
|
||||||
|
print('Flash red')
|
||||||
set_effect(effect='flash', r=255, g=0, b=0) # flash twice with red color
|
set_effect(effect='flash', r=255, g=0, b=0) # flash twice with red color
|
||||||
rospy.sleep(5)
|
rospy.sleep(2)
|
||||||
|
|
||||||
|
print('Blink white')
|
||||||
set_effect(effect='blink', r=255, g=255, b=255) # blink with white color
|
set_effect(effect='blink', r=255, g=255, b=255) # blink with white color
|
||||||
rospy.sleep(5)
|
rospy.sleep(5)
|
||||||
|
|
||||||
|
print('Rainbow')
|
||||||
set_effect(effect='rainbow') # show rainbow
|
set_effect(effect='rainbow') # show rainbow
|
||||||
@@ -9,14 +9,14 @@
|
|||||||
<!-- For additional help go to https://clover.coex.tech/aruco -->
|
<!-- For additional help go to https://clover.coex.tech/aruco -->
|
||||||
|
|
||||||
<!-- aruco_detect: detect aruco markers, estimate poses -->
|
<!-- aruco_detect: detect aruco markers, estimate poses -->
|
||||||
<node name="aruco_detect" pkg="nodelet" if="$(arg aruco_detect)" type="nodelet" args="load aruco_pose/aruco_detect nodelet_manager" output="screen" clear_params="true">
|
<node name="aruco_detect" pkg="nodelet" if="$(arg aruco_detect)" type="nodelet" args="load aruco_pose/aruco_detect main_camera_nodelet_manager" output="screen" clear_params="true" respawn="true">
|
||||||
<remap from="image_raw" to="main_camera/image_raw"/>
|
<remap from="image_raw" to="main_camera/image_raw"/>
|
||||||
<remap from="camera_info" to="main_camera/camera_info"/>
|
<remap from="camera_info" to="main_camera/camera_info"/>
|
||||||
<remap from="map_markers" to="aruco_map/markers" if="$(arg aruco_map)"/>
|
<remap from="map_markers" to="aruco_map/markers" if="$(arg aruco_map)"/>
|
||||||
<param name="estimate_poses" value="true"/>
|
<param name="estimate_poses" value="true"/>
|
||||||
<param name="send_tf" value="true"/>
|
<param name="send_tf" value="true"/>
|
||||||
<param name="known_tilt" value="map" if="$(eval placement == 'floor')"/>
|
<param name="known_tilt" value="map" if="$(eval placement == 'floor')"/>
|
||||||
<param name="known_tilt" value="map_flipped" if="$(eval position == 'ceiling')"/>
|
<param name="known_tilt" value="map_flipped" if="$(eval placement == 'ceiling')"/>
|
||||||
<param name="length" value="$(arg length)"/>
|
<param name="length" value="$(arg length)"/>
|
||||||
<!-- aruco detector parameters -->
|
<!-- aruco detector parameters -->
|
||||||
<param name="cornerRefinementMethod" value="2"/> <!-- contour refinement -->
|
<param name="cornerRefinementMethod" value="2"/> <!-- contour refinement -->
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
</node>
|
</node>
|
||||||
|
|
||||||
<!-- aruco_map: estimate aruco map pose -->
|
<!-- aruco_map: estimate aruco map pose -->
|
||||||
<node name="aruco_map" pkg="nodelet" type="nodelet" if="$(arg aruco_map)" args="load aruco_pose/aruco_map nodelet_manager" output="screen" clear_params="true">
|
<node name="aruco_map" pkg="nodelet" type="nodelet" if="$(arg aruco_map)" args="load aruco_pose/aruco_map main_camera_nodelet_manager" output="screen" clear_params="true" respawn="true">
|
||||||
<remap from="image_raw" to="main_camera/image_raw"/>
|
<remap from="image_raw" to="main_camera/image_raw"/>
|
||||||
<remap from="camera_info" to="main_camera/camera_info"/>
|
<remap from="camera_info" to="main_camera/camera_info"/>
|
||||||
<remap from="markers" to="aruco_detect/markers"/>
|
<remap from="markers" to="aruco_detect/markers"/>
|
||||||
|
|||||||
@@ -11,8 +11,7 @@
|
|||||||
<arg name="rangefinder_vl53l1x" default="true"/>
|
<arg name="rangefinder_vl53l1x" default="true"/>
|
||||||
<arg name="led" default="true"/>
|
<arg name="led" default="true"/>
|
||||||
<arg name="blocks" default="false"/>
|
<arg name="blocks" default="false"/>
|
||||||
<arg name="rc" default="true"/>
|
<arg name="rc" default="false"/>
|
||||||
<arg name="shell" default="true"/>
|
|
||||||
|
|
||||||
<arg name="simulator" default="false"/> <!-- flag that we are operating on a simulated drone -->
|
<arg name="simulator" default="false"/> <!-- flag that we are operating on a simulated drone -->
|
||||||
|
|
||||||
@@ -37,18 +36,13 @@
|
|||||||
<include file="$(find clover)/launch/aruco.launch" if="$(arg aruco)"/>
|
<include file="$(find clover)/launch/aruco.launch" if="$(arg aruco)"/>
|
||||||
|
|
||||||
<!-- optical flow -->
|
<!-- optical flow -->
|
||||||
<node pkg="nodelet" type="nodelet" name="optical_flow" args="load clover/optical_flow nodelet_manager" if="$(arg optical_flow)" clear_params="true" output="screen">
|
<node pkg="nodelet" type="nodelet" name="optical_flow" args="load clover/optical_flow main_camera_nodelet_manager" if="$(arg optical_flow)" clear_params="true" output="screen" respawn="true">
|
||||||
<remap from="image_raw" to="main_camera/image_raw"/>
|
<remap from="image_raw" to="main_camera/image_raw"/>
|
||||||
<remap from="camera_info" to="main_camera/camera_info"/>
|
<remap from="camera_info" to="main_camera/camera_info"/>
|
||||||
<param name="calc_flow_gyro" value="true"/>
|
<param name="calc_flow_gyro" value="true"/>
|
||||||
<param name="roi_rad" value="0.8"/>
|
<param name="roi_rad" value="0.8"/>
|
||||||
</node>
|
</node>
|
||||||
|
|
||||||
<!-- main nodelet manager -->
|
|
||||||
<node pkg="nodelet" type="nodelet" name="nodelet_manager" args="manager" output="screen" clear_params="true">
|
|
||||||
<param name="num_worker_threads" value="2"/>
|
|
||||||
</node>
|
|
||||||
|
|
||||||
<node pkg="tf2_ros" type="static_transform_publisher" name="map_flipped_frame" args="0 0 0 3.1415926 3.1415926 0 map map_flipped"/>
|
<node pkg="tf2_ros" type="static_transform_publisher" name="map_flipped_frame" args="0 0 0 3.1415926 3.1415926 0 map map_flipped"/>
|
||||||
|
|
||||||
<!-- simplified offboard control -->
|
<!-- simplified offboard control -->
|
||||||
@@ -91,9 +85,6 @@
|
|||||||
<param name="use_fake_gcs" value="false"/>
|
<param name="use_fake_gcs" value="false"/>
|
||||||
</node>
|
</node>
|
||||||
|
|
||||||
<!-- Shell access through ROS service -->
|
|
||||||
<node name="shell" pkg="clover" type="shell" output="screen" if="$(arg shell)"/>
|
|
||||||
|
|
||||||
<!-- Update static directory -->
|
<!-- Update static directory -->
|
||||||
<node pkg="roswww_static" name="roswww_static" type="main.py" clear_params="true">
|
<node pkg="roswww_static" name="roswww_static" type="main.py" clear_params="true">
|
||||||
<param name="default_package" value="clover"/>
|
<param name="default_package" value="clover"/>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<arg name="ws281x" default="true"/>
|
<arg name="ws281x" default="true"/>
|
||||||
<arg name="led_effect" default="true"/>
|
<arg name="led_effect" default="true"/>
|
||||||
<arg name="led_notify" default="true"/>
|
<arg name="led_notify" default="true"/>
|
||||||
<arg name="led_count" default="58"/>
|
<arg name="led_count" default="72"/>
|
||||||
<arg name="gpio_pin" default="21"/>
|
<arg name="gpio_pin" default="21"/>
|
||||||
|
|
||||||
<arg name="simulator" default="false"/>
|
<arg name="simulator" default="false"/>
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
posctl: { r: 50, g: 100, b: 220 }
|
posctl: { r: 50, g: 100, b: 220 }
|
||||||
offboard: { r: 220, g: 20, b: 250 }
|
offboard: { r: 220, g: 20, b: 250 }
|
||||||
low_battery: { threshold: 3.6, effect: blink_fast, r: 255, g: 0, b: 0 }
|
low_battery: { threshold: 3.6, effect: blink_fast, r: 255, g: 0, b: 0 }
|
||||||
error: { effect: flash, r: 255, g: 0, b: 0 }
|
error: { effect: flash, r: 255, g: 0, b: 0, ignore: [ "[lpe] vision position timeout" ]}
|
||||||
</rosparam>
|
</rosparam>
|
||||||
</node>
|
</node>
|
||||||
</launch>
|
</launch>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
<arg name="direction_z" default="down"/> <!-- direction the camera points: down, up -->
|
<arg name="direction_z" default="down"/> <!-- direction the camera points: down, up -->
|
||||||
<arg name="direction_y" default="backward"/> <!-- direction the camera cable points: backward, forward -->
|
<arg name="direction_y" default="backward"/> <!-- direction the camera cable points: backward, forward -->
|
||||||
|
<arg name="device" default="/dev/video0"/> <!-- v4l2 device -->
|
||||||
<arg name="simulator" default="false"/>
|
<arg name="simulator" default="false"/>
|
||||||
|
|
||||||
<node if="$(eval direction_z == 'down' and direction_y == 'backward')" pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 -0.07 -1.5707963 0 3.1415926 base_link main_camera_optical"/>
|
<node if="$(eval direction_z == 'down' and direction_y == 'backward')" pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 -0.07 -1.5707963 0 3.1415926 base_link main_camera_optical"/>
|
||||||
@@ -17,9 +18,14 @@
|
|||||||
<!-- static_transform_publisher arguments: x y z yaw pitch roll frame_id child_frame_id -->
|
<!-- static_transform_publisher arguments: x y z yaw pitch roll frame_id child_frame_id -->
|
||||||
<!-- <node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 -0.07 -1.5707963 0 3.1415926 base_link main_camera_optical"/> -->
|
<!-- <node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 -0.07 -1.5707963 0 3.1415926 base_link main_camera_optical"/> -->
|
||||||
|
|
||||||
|
<!-- camera nodelet manager -->
|
||||||
|
<node pkg="nodelet" type="nodelet" name="main_camera_nodelet_manager" args="manager" output="screen" clear_params="true" respawn="true">
|
||||||
|
<param name="num_worker_threads" value="2"/>
|
||||||
|
</node>
|
||||||
|
|
||||||
<!-- camera node -->
|
<!-- camera node -->
|
||||||
<node pkg="nodelet" type="nodelet" name="main_camera" args="load cv_camera/CvCameraNodelet nodelet_manager" clear_params="true" unless="$(arg simulator)">
|
<node pkg="nodelet" type="nodelet" name="main_camera" args="load cv_camera/CvCameraNodelet main_camera_nodelet_manager" launch-prefix="rosrun clover waitfile $(arg device)" clear_params="true" unless="$(arg simulator)" respawn="true">
|
||||||
<param name="device_path" value="/dev/video0"/> <!-- v4l2 device -->
|
<param name="device_path" value="$(arg device)"/>
|
||||||
<param name="frame_id" value="main_camera_optical"/>
|
<param name="frame_id" value="main_camera_optical"/>
|
||||||
<param name="camera_info_url" value="file://$(find clover)/camera_info/fisheye_cam.yaml"/>
|
<param name="camera_info_url" value="file://$(find clover)/camera_info/fisheye_cam.yaml"/>
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,16 @@
|
|||||||
<arg name="viz" default="true"/>
|
<arg name="viz" default="true"/>
|
||||||
<arg name="respawn" default="true"/>
|
<arg name="respawn" default="true"/>
|
||||||
<arg name="distance_sensor_remap" default="rangefinder/range"/>
|
<arg name="distance_sensor_remap" default="rangefinder/range"/>
|
||||||
|
<arg name="usb_device" default="/dev/px4fmu"/>
|
||||||
|
<arg name="prefix" default="" unless="$(eval fcu_conn == 'usb')"/>
|
||||||
|
<arg name="prefix" default="rosrun clover waitfile $(arg usb_device)" if="$(eval fcu_conn == 'usb')"/>
|
||||||
|
|
||||||
<node pkg="mavros" type="mavros_node" name="mavros" required="false" clear_params="true" respawn="$(arg respawn)" unless="$(eval fcu_conn == 'none')" respawn_delay="1" output="screen">
|
<node pkg="mavros" type="mavros_node" name="mavros" launch-prefix="$(arg prefix)" required="false" clear_params="true" respawn="$(arg respawn)" unless="$(eval fcu_conn == 'none')" respawn_delay="1" output="screen">
|
||||||
<!-- UART connection -->
|
<!-- UART connection -->
|
||||||
<param name="fcu_url" value="/dev/ttyAMA0:921600" if="$(eval fcu_conn is None or fcu_conn == 'uart')"/>
|
<param name="fcu_url" value="/dev/ttyAMA0:921600" if="$(eval fcu_conn is None or fcu_conn == 'uart')"/>
|
||||||
|
|
||||||
<!-- USB connection -->
|
<!-- USB connection -->
|
||||||
<param name="fcu_url" value="/dev/px4fmu" if="$(eval fcu_conn == 'usb')"/>
|
<param name="fcu_url" value="$(arg usb_device)" if="$(eval fcu_conn == 'usb')"/>
|
||||||
|
|
||||||
<!-- sitl before PX4 1.9.0 -->
|
<!-- sitl before PX4 1.9.0 -->
|
||||||
<param name="fcu_url" value="udp://@$(arg fcu_ip):14557" if="$(eval fcu_conn == 'udp')"/>
|
<param name="fcu_url" value="udp://@$(arg fcu_ip):14557" if="$(eval fcu_conn == 'udp')"/>
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
<launch>
|
|
||||||
<!-- clover configuration for testing in sitl -->
|
|
||||||
<arg name="ip" default="127.0.0.1"/>
|
|
||||||
<arg name="rosbridge" default="false"/>
|
|
||||||
|
|
||||||
<include file="$(find clover)/launch/clover.launch">
|
|
||||||
<arg name="fcu_conn" value="udp"/>
|
|
||||||
<arg name="fcu_ip" value="$(arg ip)"/>
|
|
||||||
<arg name="gcs_bridge" value="false"/>
|
|
||||||
<arg name="optical_flow" value="false"/>
|
|
||||||
<arg name="web_video_server" default="false"/>
|
|
||||||
<arg name="main_camera" default="false"/>
|
|
||||||
<arg name="rosbridge" value="$(arg rosbridge)"/>
|
|
||||||
<arg name="aruco" default="false"/>
|
|
||||||
<arg name="rangefinder_vl53l1x" default="false"/>
|
|
||||||
<arg name="led" default="false"/>
|
|
||||||
<arg name="rc" default="false"/>
|
|
||||||
</include>
|
|
||||||
</launch>
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<package format="3">
|
<package format="3">
|
||||||
<name>clover</name>
|
<name>clover</name>
|
||||||
<version>0.0.1</version>
|
<version>0.21.1</version>
|
||||||
<description>The Clover package</description>
|
<description>The Clover package</description>
|
||||||
|
|
||||||
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <ros/ros.h>
|
#include <ros/ros.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
#include <clover/SetLEDEffect.h>
|
#include <clover/SetLEDEffect.h>
|
||||||
@@ -29,6 +30,7 @@ ros::Timer timer;
|
|||||||
ros::Time start_time;
|
ros::Time start_time;
|
||||||
double blink_rate, blink_fast_rate, flash_delay, fade_period, wipe_period, rainbow_period;
|
double blink_rate, blink_fast_rate, flash_delay, fade_period, wipe_period, rainbow_period;
|
||||||
double low_battery_threshold;
|
double low_battery_threshold;
|
||||||
|
std::vector<std::string> error_ignore;
|
||||||
bool blink_state;
|
bool blink_state;
|
||||||
led_msgs::SetLEDs set_leds;
|
led_msgs::SetLEDs set_leds;
|
||||||
led_msgs::LEDStateArray state, start_state;
|
led_msgs::LEDStateArray state, start_state;
|
||||||
@@ -274,6 +276,10 @@ void handleMavrosState(const mavros_msgs::State& msg)
|
|||||||
void handleLog(const rosgraph_msgs::Log& log)
|
void handleLog(const rosgraph_msgs::Log& log)
|
||||||
{
|
{
|
||||||
if (log.level >= rosgraph_msgs::Log::ERROR) {
|
if (log.level >= rosgraph_msgs::Log::ERROR) {
|
||||||
|
// check if ignored
|
||||||
|
for (auto const& str : error_ignore) {
|
||||||
|
if (log.msg.find(str) != std::string::npos) return;
|
||||||
|
}
|
||||||
notify("error");
|
notify("error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -302,6 +308,7 @@ int main(int argc, char **argv)
|
|||||||
nh_priv.param("rainbow_period", rainbow_period, 5.0);
|
nh_priv.param("rainbow_period", rainbow_period, 5.0);
|
||||||
|
|
||||||
nh_priv.param("notify/low_battery/threshold", low_battery_threshold, 3.7);
|
nh_priv.param("notify/low_battery/threshold", low_battery_threshold, 3.7);
|
||||||
|
nh_priv.param("notify/error/ignore", error_ignore, {});
|
||||||
|
|
||||||
ros::service::waitForService("set_leds"); // cannot work without set_leds service
|
ros::service::waitForService("set_leds"); // cannot work without set_leds service
|
||||||
set_leds_srv = nh.serviceClient<led_msgs::SetLEDs>("set_leds", true);
|
set_leds_srv = nh.serviceClient<led_msgs::SetLEDs>("set_leds", true);
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ private:
|
|||||||
roi_rad_ = nh_priv.param("roi_rad", 0.0);
|
roi_rad_ = nh_priv.param("roi_rad", 0.0);
|
||||||
calc_flow_gyro_ = nh_priv.param("calc_flow_gyro", false);
|
calc_flow_gyro_ = nh_priv.param("calc_flow_gyro", false);
|
||||||
|
|
||||||
img_sub_ = it.subscribeCamera("image_raw", 1, &OpticalFlow::flow, this);
|
|
||||||
img_pub_ = it_priv.advertise("debug", 1);
|
img_pub_ = it_priv.advertise("debug", 1);
|
||||||
flow_pub_ = nh.advertise<mavros_msgs::OpticalFlowRad>("mavros/px4flow/raw/send", 1);
|
flow_pub_ = nh.advertise<mavros_msgs::OpticalFlowRad>("mavros/px4flow/raw/send", 1);
|
||||||
velo_pub_ = nh_priv.advertise<geometry_msgs::TwistStamped>("angular_velocity", 1);
|
velo_pub_ = nh_priv.advertise<geometry_msgs::TwistStamped>("angular_velocity", 1);
|
||||||
@@ -83,6 +82,8 @@ private:
|
|||||||
flow_.distance = -1; // no distance sensor available
|
flow_.distance = -1; // no distance sensor available
|
||||||
flow_.temperature = 0;
|
flow_.temperature = 0;
|
||||||
|
|
||||||
|
img_sub_ = it.subscribeCamera("image_raw", 1, &OpticalFlow::flow, this);
|
||||||
|
|
||||||
NODELET_INFO("Optical Flow initialized");
|
NODELET_INFO("Optical Flow initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +153,7 @@ private:
|
|||||||
cv::Point2d shift = cv::phaseCorrelate(prev_, curr_, hann_, &response);
|
cv::Point2d shift = cv::phaseCorrelate(prev_, curr_, hann_, &response);
|
||||||
|
|
||||||
// Publish raw shift in pixels
|
// Publish raw shift in pixels
|
||||||
static geometry_msgs::Vector3Stamped shift_vec;
|
geometry_msgs::Vector3Stamped shift_vec;
|
||||||
shift_vec.header.stamp = msg->header.stamp;
|
shift_vec.header.stamp = msg->header.stamp;
|
||||||
shift_vec.header.frame_id = msg->header.frame_id;
|
shift_vec.header.frame_id = msg->header.frame_id;
|
||||||
shift_vec.vector.x = shift.x;
|
shift_vec.vector.x = shift.x;
|
||||||
@@ -179,7 +180,7 @@ private:
|
|||||||
double flow_y = atan2(points_undist[0].y, focal_length_y);
|
double flow_y = atan2(points_undist[0].y, focal_length_y);
|
||||||
|
|
||||||
// // Convert to FCU frame
|
// // Convert to FCU frame
|
||||||
static geometry_msgs::Vector3Stamped flow_camera, flow_fcu;
|
geometry_msgs::Vector3Stamped flow_camera, flow_fcu;
|
||||||
flow_camera.header.frame_id = msg->header.frame_id;
|
flow_camera.header.frame_id = msg->header.frame_id;
|
||||||
flow_camera.header.stamp = msg->header.stamp;
|
flow_camera.header.stamp = msg->header.stamp;
|
||||||
flow_camera.vector.x = flow_y; // +y means counter-clockwise rotation around Y axis
|
flow_camera.vector.x = flow_y; // +y means counter-clockwise rotation around Y axis
|
||||||
@@ -198,7 +199,7 @@ private:
|
|||||||
if (calc_flow_gyro_) {
|
if (calc_flow_gyro_) {
|
||||||
try {
|
try {
|
||||||
auto flow_gyro_camera = calcFlowGyro(msg->header.frame_id, prev_stamp_, msg->header.stamp);
|
auto flow_gyro_camera = calcFlowGyro(msg->header.frame_id, prev_stamp_, msg->header.stamp);
|
||||||
static geometry_msgs::Vector3Stamped flow_gyro_fcu;
|
geometry_msgs::Vector3Stamped flow_gyro_fcu;
|
||||||
tf_buffer_->transform(flow_gyro_camera, flow_gyro_fcu, fcu_frame_id_);
|
tf_buffer_->transform(flow_gyro_camera, flow_gyro_fcu, fcu_frame_id_);
|
||||||
flow_.integrated_xgyro = flow_gyro_fcu.vector.x;
|
flow_.integrated_xgyro = flow_gyro_fcu.vector.x;
|
||||||
flow_.integrated_ygyro = flow_gyro_fcu.vector.y;
|
flow_.integrated_ygyro = flow_gyro_fcu.vector.y;
|
||||||
@@ -206,7 +207,7 @@ private:
|
|||||||
} catch (const tf2::TransformException& e) {
|
} catch (const tf2::TransformException& e) {
|
||||||
// Invalidate previous frame
|
// Invalidate previous frame
|
||||||
prev_.release();
|
prev_.release();
|
||||||
return;
|
goto publish_debug;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,6 +219,10 @@ private:
|
|||||||
flow_.quality = (uint8_t)(response * 255);
|
flow_.quality = (uint8_t)(response * 255);
|
||||||
flow_pub_.publish(flow_);
|
flow_pub_.publish(flow_);
|
||||||
|
|
||||||
|
prev_ = curr_.clone();
|
||||||
|
prev_stamp_ = msg->header.stamp;
|
||||||
|
|
||||||
|
publish_debug:
|
||||||
// Publish debug image
|
// Publish debug image
|
||||||
if (img_pub_.getNumSubscribers() > 0) {
|
if (img_pub_.getNumSubscribers() > 0) {
|
||||||
// publish debug image
|
// publish debug image
|
||||||
@@ -231,15 +236,12 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Publish estimated angular velocity
|
// Publish estimated angular velocity
|
||||||
static geometry_msgs::TwistStamped velo;
|
geometry_msgs::TwistStamped velo;
|
||||||
velo.header.stamp = msg->header.stamp;
|
velo.header.stamp = msg->header.stamp;
|
||||||
velo.header.frame_id = fcu_frame_id_;
|
velo.header.frame_id = fcu_frame_id_;
|
||||||
velo.twist.angular.x = flow_.integrated_x / integration_time.toSec();
|
velo.twist.angular.x = flow_fcu.vector.x / integration_time.toSec();
|
||||||
velo.twist.angular.y = flow_.integrated_y / integration_time.toSec();
|
velo.twist.angular.y = flow_fcu.vector.y / integration_time.toSec();
|
||||||
velo_pub_.publish(velo);
|
velo_pub_.publish(velo);
|
||||||
|
|
||||||
prev_ = curr_.clone();
|
|
||||||
prev_stamp_ = msg->header.stamp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -496,10 +496,16 @@ inline void checkManualControl()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (check_kill_switch) {
|
if (check_kill_switch) {
|
||||||
const int KILL_SWITCH_BIT = 12; // https://github.com/PX4/Firmware/blob/c302514a0809b1765fafd13c014d705446ae1113/src/modules/mavlink/mavlink_messages.cpp#L3975
|
// switch values: https://github.com/PX4/PX4-Autopilot/blob/c302514a0809b1765fafd13c014d705446ae1113/msg/manual_control_setpoint.msg#L3
|
||||||
bool kill_switch = manual_control.buttons & (1 << KILL_SWITCH_BIT);
|
const uint8_t SWITCH_POS_NONE = 0; // switch is not mapped
|
||||||
|
const uint8_t SWITCH_POS_ON = 1; // switch activated
|
||||||
|
const uint8_t SWITCH_POS_MIDDLE = 2; // middle position
|
||||||
|
const uint8_t SWITCH_POS_OFF = 3; // switch not activated
|
||||||
|
|
||||||
if (kill_switch)
|
const int KILL_SWITCH_BIT = 12; // https://github.com/PX4/Firmware/blob/c302514a0809b1765fafd13c014d705446ae1113/src/modules/mavlink/mavlink_messages.cpp#L3975
|
||||||
|
uint8_t kill_switch = (manual_control.buttons & (0b11 << KILL_SWITCH_BIT)) >> KILL_SWITCH_BIT;
|
||||||
|
|
||||||
|
if (kill_switch == SWITCH_POS_ON)
|
||||||
throw std::runtime_error("Kill switch is on");
|
throw std::runtime_error("Kill switch is on");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -706,7 +712,7 @@ bool serve(enum setpoint_type_t sp_type, float x, float y, float z, float vx, fl
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sp_type == VELOCITY) {
|
if (sp_type == VELOCITY) {
|
||||||
static Vector3Stamped vel;
|
Vector3Stamped vel;
|
||||||
vel.header.frame_id = frame_id;
|
vel.header.frame_id = frame_id;
|
||||||
vel.header.stamp = stamp;
|
vel.header.stamp = stamp;
|
||||||
vel.vector.x = vx;
|
vel.vector.x = vx;
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ void publishZero(const ros::TimerEvent& e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ROS_INFO_THROTTLE(10, "publish zero");
|
ROS_INFO_THROTTLE(10, "publish zero");
|
||||||
static geometry_msgs::PoseStamped zero;
|
geometry_msgs::PoseStamped zero;
|
||||||
zero.header.frame_id = local_frame_id;
|
zero.header.frame_id = local_frame_id;
|
||||||
zero.header.stamp = e.current_real;
|
zero.header.stamp = e.current_real;
|
||||||
zero.pose.orientation.w = 1;
|
zero.pose.orientation.w = 1;
|
||||||
|
|||||||
9
clover/src/waitfile
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# $ ./waitfile <file> <command> <args...>
|
||||||
|
# wait until <file> appears and then invoke <command> with <args>
|
||||||
|
|
||||||
|
echo "wait for file $1"
|
||||||
|
while [ ! -e "$1" ]; do sleep 1; done;
|
||||||
|
echo "file $1 appeared"
|
||||||
|
exec "${@:2}"
|
||||||
@@ -33,19 +33,3 @@ def test_web_video_server(node):
|
|||||||
# Python 3
|
# Python 3
|
||||||
import urllib.request as urllib
|
import urllib.request as urllib
|
||||||
urllib.urlopen("http://localhost:8080").read()
|
urllib.urlopen("http://localhost:8080").read()
|
||||||
|
|
||||||
def test_shell(node):
|
|
||||||
execute = rospy.ServiceProxy('exec', srv.Execute)
|
|
||||||
execute.wait_for_service(5)
|
|
||||||
|
|
||||||
res = execute(cmd='echo foo')
|
|
||||||
assert res.code == 0
|
|
||||||
assert res.output == 'foo\n'
|
|
||||||
|
|
||||||
res = execute(cmd='foo')
|
|
||||||
assert res.code == 32512
|
|
||||||
assert res.output == ''
|
|
||||||
|
|
||||||
res = execute(cmd='ls foo')
|
|
||||||
assert res.code == 512
|
|
||||||
assert res.output == ''
|
|
||||||
|
|||||||
1
clover/www/clover.err
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/tmp/clover.err
|
||||||
1
clover/www/clover_version
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/etc/clover_version
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
<title>Clover Drone Kit Tools</title>
|
||||||
|
|
||||||
<h1>Clover Drone Kit Tools</h1>
|
<h1>Clover Drone Kit Tools</h1>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
@@ -7,19 +9,20 @@
|
|||||||
<li><a href="viz.html">View 3D visualization</a> (<code>ros3djs</code>)</li>
|
<li><a href="viz.html">View 3D visualization</a> (<code>ros3djs</code>)</li>
|
||||||
<li><a href="aruco_map.html">3D visualization for markers map</a> (<code>ros3djs</code>)</li>
|
<li><a href="aruco_map.html">3D visualization for markers map</a> (<code>ros3djs</code>)</li>
|
||||||
<li><a href="../clover_blocks/">Blocks programming</a> (<code>Blockly</code>)</li>
|
<li><a href="../clover_blocks/">Blocks programming</a> (<code>Blockly</code>)</li>
|
||||||
|
<li><a href="clover.err">Clover console</a> (<code>/tmp/clover.err</code>)</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="version"></div>
|
<div class="version"></div>
|
||||||
|
|
||||||
<script src="js/roslib.js"></script>
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
document.querySelector("#wvs").href = location.protocol + '//' + location.hostname + ':8080';
|
document.querySelector("#wvs").href = location.protocol + '//' + location.hostname + ':8080';
|
||||||
document.querySelector("#butterfly").href = location.protocol + '//' + location.hostname + ':57575';
|
document.querySelector("#butterfly").href = location.protocol + '//' + location.hostname + ':57575';
|
||||||
|
|
||||||
// Determine image version
|
// Determine image version
|
||||||
var ros = new ROSLIB.Ros({ url: 'ws://' + location.hostname + ':9090' });
|
fetch('clover_version').then(function(response) {
|
||||||
var exec = new ROSLIB.Service({ ros: ros, name : '/exec', serviceType : 'clover/Execute' });
|
if (response.status !== 200) return;
|
||||||
exec.callService(new ROSLIB.ServiceRequest({ cmd: 'cat /etc/clover_version' }), function(result) {
|
response.text().then(function(text) {
|
||||||
document.querySelector('.version').innerHTML = 'Version: ' + result.output;
|
document.querySelector('.version').innerHTML = 'Version: ' + text;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
8
clover_blocks/CHANGELOG.rst
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Changelog for package clover_blocks
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
0.21.1 (2020-11-17)
|
||||||
|
-------------------
|
||||||
|
* First release of clover_blocks package to ROS
|
||||||
|
* Contributors: Oleg Kalachev
|
||||||
@@ -73,6 +73,11 @@ catkin_install_python(PROGRAMS src/clover_blocks
|
|||||||
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# TODO: store programs in home directory?
|
||||||
|
install(DIRECTORY programs
|
||||||
|
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
|
||||||
|
)
|
||||||
|
|
||||||
#############
|
#############
|
||||||
## Testing ##
|
## Testing ##
|
||||||
#############
|
#############
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<package format="2">
|
<package format="2">
|
||||||
<name>clover_blocks</name>
|
<name>clover_blocks</name>
|
||||||
<version>0.0.0</version>
|
<version>0.21.1</version>
|
||||||
<description>Blockly programming support for Clover</description>
|
<description>Blockly programming support for Clover</description>
|
||||||
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
||||||
<license>MIT</license>
|
<license>MIT</license>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
</value>
|
</value>
|
||||||
<value name="Z">
|
<value name="Z">
|
||||||
<shadow type="math_number" id="n0ULZn64%k.:,l(,D?TZ">
|
<shadow type="math_number" id="n0ULZn64%k.:,l(,D?TZ">
|
||||||
<field name="NUM">0</field>
|
<field name="NUM">1</field>
|
||||||
</shadow>
|
</shadow>
|
||||||
</value>
|
</value>
|
||||||
<value name="ID">
|
<value name="ID">
|
||||||
|
|||||||
@@ -1,106 +1,91 @@
|
|||||||
<xml xmlns="https://developers.google.com/blockly/xml">
|
<xml xmlns="https://developers.google.com/blockly/xml">
|
||||||
<variables>
|
<block type="controls_whileUntil" id="U1it{GcGuSS:=[xiwZr1" x="113" y="113">
|
||||||
<variable id="_{V-S5HPBUl]CcJkL1Jw">led_count</variable>
|
<field name="MODE">WHILE</field>
|
||||||
</variables>
|
<value name="BOOL">
|
||||||
<block type="variables_set" id="{)^J~:UMX%D;RWvztWLN" x="113" y="87">
|
<block type="logic_boolean" id="]7ZDRwde}/RqjQCX}aVW">
|
||||||
<field name="VAR" id="_{V-S5HPBUl]CcJkL1Jw">led_count</field>
|
<field name="BOOL">TRUE</field>
|
||||||
<value name="VALUE">
|
|
||||||
<block type="math_number" id="V_W$3,VFwZjcc|?|1o`l">
|
|
||||||
<field name="NUM">58</field>
|
|
||||||
</block>
|
</block>
|
||||||
</value>
|
</value>
|
||||||
<next>
|
<statement name="DO">
|
||||||
<block type="controls_whileUntil" id="U1it{GcGuSS:=[xiwZr1">
|
<block type="set_effect" id="WI0zqOz/z3].cR/6UWHn">
|
||||||
<field name="MODE">WHILE</field>
|
<field name="EFFECT">FILL</field>
|
||||||
<value name="BOOL">
|
<value name="COLOR">
|
||||||
<block type="logic_boolean" id="]7ZDRwde}/RqjQCX}aVW">
|
<shadow type="colour_picker" id="B`6;Xv{s2TFp8Yd=ZpSD">
|
||||||
<field name="BOOL">TRUE</field>
|
<field name="COLOUR">#000000</field>
|
||||||
</block>
|
</shadow>
|
||||||
</value>
|
</value>
|
||||||
<statement name="DO">
|
<next>
|
||||||
<block type="set_effect" id="WI0zqOz/z3].cR/6UWHn">
|
<block type="set_led" id="^Vcs}ki?#ctf7rAchix$">
|
||||||
<field name="EFFECT">FILL</field>
|
<value name="INDEX">
|
||||||
<value name="COLOR">
|
<shadow type="math_number" id="U;VWW$[*LOF7Gf,~?YR7">
|
||||||
<shadow type="colour_picker" id="B`6;Xv{s2TFp8Yd=ZpSD">
|
<field name="NUM">0</field>
|
||||||
<field name="COLOUR">#000000</field>
|
|
||||||
</shadow>
|
</shadow>
|
||||||
</value>
|
<block type="math_arithmetic" id="AI6PZBd`]_Z%_~4c-%dB">
|
||||||
<next>
|
<field name="OP">MULTIPLY</field>
|
||||||
<block type="set_led" id="^Vcs}ki?#ctf7rAchix$">
|
<value name="A">
|
||||||
<value name="INDEX">
|
<shadow type="math_number" id="|p}X]`SedK3).F/;}NlB">
|
||||||
<shadow type="math_number" id="U;VWW$[*LOF7Gf,~?YR7">
|
<field name="NUM">1</field>
|
||||||
<field name="NUM">0</field>
|
|
||||||
</shadow>
|
</shadow>
|
||||||
<block type="math_arithmetic" id="AI6PZBd`]_Z%_~4c-%dB">
|
<block type="math_arithmetic" id="-haE#:,cg{-J=NZERA;F">
|
||||||
<field name="OP">MULTIPLY</field>
|
<field name="OP">DIVIDE</field>
|
||||||
<value name="A">
|
<value name="A">
|
||||||
<shadow type="math_number" id="|p}X]`SedK3).F/;}NlB">
|
<shadow type="math_number" id="::st;ot}[r]csqceURu*">
|
||||||
<field name="NUM">1</field>
|
<field name="NUM">1</field>
|
||||||
</shadow>
|
</shadow>
|
||||||
<block type="math_arithmetic" id="-haE#:,cg{-J=NZERA;F">
|
<block type="math_arithmetic" id="a%+LN)F~=Igg+,p02[qo">
|
||||||
<field name="OP">DIVIDE</field>
|
<field name="OP">ADD</field>
|
||||||
<value name="A">
|
<value name="A">
|
||||||
<shadow type="math_number" id="::st;ot}[r]csqceURu*">
|
<shadow type="math_number" id="*yIGN((y)/^z0:f5:VDw">
|
||||||
<field name="NUM">1</field>
|
<field name="NUM">1</field>
|
||||||
</shadow>
|
</shadow>
|
||||||
<block type="math_arithmetic" id="a%+LN)F~=Igg+,p02[qo">
|
<block type="get_yaw" id="mf%77q30bEqNfc/3`Mtb">
|
||||||
<field name="OP">ADD</field>
|
<field name="FRAME_ID">MAP</field>
|
||||||
<value name="A">
|
<value name="ID">
|
||||||
<shadow type="math_number" id="*yIGN((y)/^z0:f5:VDw">
|
<shadow type="math_number" id="xb32G.N#ip`|^Xv*MOmY">
|
||||||
<field name="NUM">1</field>
|
<field name="NUM">0</field>
|
||||||
</shadow>
|
|
||||||
<block type="get_yaw" id="mf%77q30bEqNfc/3`Mtb">
|
|
||||||
<field name="FRAME_ID">MAP</field>
|
|
||||||
<value name="ID">
|
|
||||||
<shadow type="math_number" id="xb32G.N#ip`|^Xv*MOmY">
|
|
||||||
<field name="NUM">0</field>
|
|
||||||
</shadow>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="B">
|
|
||||||
<shadow type="math_number" id="T/fTrm;j2Azgav;gI{ZW">
|
|
||||||
<field name="NUM">180</field>
|
|
||||||
</shadow>
|
</shadow>
|
||||||
</value>
|
</value>
|
||||||
</block>
|
</block>
|
||||||
</value>
|
</value>
|
||||||
<value name="B">
|
<value name="B">
|
||||||
<shadow type="math_number" id="Wo1/ZCeir,u6/.e1H+BB">
|
<shadow type="math_number" id="T/fTrm;j2Azgav;gI{ZW">
|
||||||
<field name="NUM">360</field>
|
<field name="NUM">180</field>
|
||||||
</shadow>
|
</shadow>
|
||||||
</value>
|
</value>
|
||||||
</block>
|
</block>
|
||||||
</value>
|
</value>
|
||||||
<value name="B">
|
<value name="B">
|
||||||
<shadow type="math_number" id="jENTcXz0C5/=)Xpd!}LL">
|
<shadow type="math_number" id="Wo1/ZCeir,u6/.e1H+BB">
|
||||||
<field name="NUM">1</field>
|
<field name="NUM">360</field>
|
||||||
</shadow>
|
</shadow>
|
||||||
<block type="variables_get" id="Ko,`n=i88FY~`YbQLA?[">
|
|
||||||
<field name="VAR" id="_{V-S5HPBUl]CcJkL1Jw">led_count</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
</value>
|
||||||
</block>
|
</block>
|
||||||
</value>
|
</value>
|
||||||
<value name="COLOR">
|
<value name="B">
|
||||||
<shadow type="colour_picker" id="+vw3bff.5c[=_w,Xm^C(">
|
<shadow type="math_number" id="jENTcXz0C5/=)Xpd!}LL">
|
||||||
<field name="COLOUR">#3366ff</field>
|
<field name="NUM">1</field>
|
||||||
|
</shadow>
|
||||||
|
<block type="led_count" id="vM@X8s!xa]v}AaK6PWF5"></block>
|
||||||
|
</value>
|
||||||
|
</block>
|
||||||
|
</value>
|
||||||
|
<value name="COLOR">
|
||||||
|
<shadow type="colour_picker" id="+vw3bff.5c[=_w,Xm^C(">
|
||||||
|
<field name="COLOUR">#3366ff</field>
|
||||||
|
</shadow>
|
||||||
|
</value>
|
||||||
|
<next>
|
||||||
|
<block type="wait" id="DT%f$bn1*1El5zsgUW8Y">
|
||||||
|
<value name="TIME">
|
||||||
|
<shadow type="math_number" id="~Y0hNY[_^#v@aZkE-TH[">
|
||||||
|
<field name="NUM">0.1</field>
|
||||||
</shadow>
|
</shadow>
|
||||||
</value>
|
</value>
|
||||||
<next>
|
|
||||||
<block type="wait" id="DT%f$bn1*1El5zsgUW8Y">
|
|
||||||
<value name="TIME">
|
|
||||||
<shadow type="math_number" id="~Y0hNY[_^#v@aZkE-TH[">
|
|
||||||
<field name="NUM">0.1</field>
|
|
||||||
</shadow>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</next>
|
|
||||||
</block>
|
</block>
|
||||||
</next>
|
</next>
|
||||||
</block>
|
</block>
|
||||||
</statement>
|
</next>
|
||||||
</block>
|
</block>
|
||||||
</next>
|
</statement>
|
||||||
</block>
|
</block>
|
||||||
</xml>
|
</xml>
|
||||||
@@ -11,7 +11,8 @@
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
import rospy
|
import rospy
|
||||||
import os
|
import os, sys
|
||||||
|
import traceback
|
||||||
import threading
|
import threading
|
||||||
import re
|
import re
|
||||||
import uuid
|
import uuid
|
||||||
@@ -116,7 +117,12 @@ def run(req):
|
|||||||
rospy.loginfo('Program forced to stop')
|
rospy.loginfo('Program forced to stop')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
rospy.logerr(str(e))
|
rospy.logerr(str(e))
|
||||||
error_pub.publish(str(e))
|
traceback.print_exc()
|
||||||
|
etype, value, tb = sys.exc_info()
|
||||||
|
fmt = traceback.format_exception(etype, value, tb)
|
||||||
|
fmt.pop(1) # remove 'clover_blocks' file frame
|
||||||
|
exc_info = ''.join(fmt)
|
||||||
|
error_pub.publish(str(e) + '\n\n' + exc_info)
|
||||||
|
|
||||||
rospy.loginfo('Program terminated')
|
rospy.loginfo('Program terminated')
|
||||||
running_lock.release()
|
running_lock.release()
|
||||||
@@ -140,6 +146,7 @@ def stop(req):
|
|||||||
return {'success': True}
|
return {'success': True}
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: find dir in installed package
|
||||||
programs_path = rospy.get_param('~programs_dir', os.path.dirname(os.path.abspath(__file__)) + '/../programs')
|
programs_path = rospy.get_param('~programs_dir', os.path.dirname(os.path.abspath(__file__)) + '/../programs')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -353,6 +353,17 @@ Blockly.Blocks['set_effect'] = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['led_count'] = {
|
||||||
|
init: function () {
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField("LED count");
|
||||||
|
this.setOutput(true, "Number");
|
||||||
|
this.setColour(COLOR_LED);
|
||||||
|
this.setTooltip("Returns the number of LEDs (configured in led.launch).");
|
||||||
|
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Blockly.Blocks['take_off'] = {
|
Blockly.Blocks['take_off'] = {
|
||||||
init: function () {
|
init: function () {
|
||||||
this.appendValueInput("ALT")
|
this.appendValueInput("ALT")
|
||||||
@@ -535,7 +546,7 @@ Blockly.Blocks['gpio_read'] = {
|
|||||||
this.setOutput(true, "Boolean");
|
this.setOutput(true, "Boolean");
|
||||||
this.setColour(COLOR_GPIO);
|
this.setColour(COLOR_GPIO);
|
||||||
this.setTooltip("Returns if there is voltage on a GPIO pin.");
|
this.setTooltip("Returns if there is voltage on a GPIO pin.");
|
||||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
this.setHelpUrl(DOCS_URL + '#GPIO');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -552,7 +563,7 @@ Blockly.Blocks['gpio_write'] = {
|
|||||||
this.setPreviousStatement(true, null);
|
this.setPreviousStatement(true, null);
|
||||||
this.setNextStatement(true, null);
|
this.setNextStatement(true, null);
|
||||||
this.setTooltip("Set GPIO pin level.");
|
this.setTooltip("Set GPIO pin level.");
|
||||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
this.setHelpUrl(DOCS_URL + '#GPIO');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -568,7 +579,24 @@ Blockly.Blocks['set_servo'] = {
|
|||||||
this.setColour(COLOR_GPIO);
|
this.setColour(COLOR_GPIO);
|
||||||
this.setPreviousStatement(true, null);
|
this.setPreviousStatement(true, null);
|
||||||
this.setNextStatement(true, null);
|
this.setNextStatement(true, null);
|
||||||
this.setTooltip("Set PWM on a GPIO pin to control servo. PWM is specified in range of 500–2500 ms.");
|
this.setTooltip("Set PWM on a GPIO pin to control servo. PWM is specified in range of 500–2500 μs.");
|
||||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
this.setHelpUrl(DOCS_URL + '#GPIO');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks['set_duty_cycle'] = {
|
||||||
|
init: function () {
|
||||||
|
this.appendValueInput("PIN")
|
||||||
|
.setCheck("Number")
|
||||||
|
.appendField("set GPIO pin");
|
||||||
|
this.appendValueInput("DUTY_CYCLE")
|
||||||
|
.setCheck("Number")
|
||||||
|
.appendField("to duty cycle");
|
||||||
|
this.setInputsInline(true);
|
||||||
|
this.setColour(COLOR_GPIO);
|
||||||
|
this.setPreviousStatement(true, null);
|
||||||
|
this.setNextStatement(true, null);
|
||||||
|
this.setTooltip("Set PWM duty cycle on a GPIO pin (better to control LEDs, etc). Duty cycle is set in range of 0–1.");
|
||||||
|
this.setHelpUrl(DOCS_URL + '#GPIO');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -106,6 +106,7 @@
|
|||||||
<value name="INDEX"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
<value name="INDEX"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||||
<value name="COLOR"><shadow type="colour_picker"></shadow></value>
|
<value name="COLOR"><shadow type="colour_picker"></shadow></value>
|
||||||
</block>
|
</block>
|
||||||
|
<block type="led_count"></block>
|
||||||
</category>
|
</category>
|
||||||
<category name="GPIO" colour="#5b97cc">
|
<category name="GPIO" colour="#5b97cc">
|
||||||
<block type="gpio_read">
|
<block type="gpio_read">
|
||||||
@@ -119,6 +120,10 @@
|
|||||||
<value name="PIN"><shadow type="math_number"><field name="NUM">1</field></shadow></value>
|
<value name="PIN"><shadow type="math_number"><field name="NUM">1</field></shadow></value>
|
||||||
<value name="PWM"><shadow type="math_number"><field name="NUM">1500</field></shadow></value>
|
<value name="PWM"><shadow type="math_number"><field name="NUM">1500</field></shadow></value>
|
||||||
</block>
|
</block>
|
||||||
|
<block type="set_duty_cycle">
|
||||||
|
<value name="PIN"><shadow type="math_number"><field name="NUM">1</field></shadow></value>
|
||||||
|
<value name="DUTY_CYCLE"><shadow type="math_number"><field name="NUM">0.5</field></shadow></value>
|
||||||
|
</block>
|
||||||
</category>
|
</category>
|
||||||
<sep></sep>
|
<sep></sep>
|
||||||
<category name="Logic" colour="#5b80a5">
|
<category name="Logic" colour="#5b80a5">
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ Blockly.Python.addReservedWords('_b,_print');
|
|||||||
Blockly.Python.addReservedWords('rospy,srv,Trigger,get_telemetry,navigate,set_velocity,land');
|
Blockly.Python.addReservedWords('rospy,srv,Trigger,get_telemetry,navigate,set_velocity,land');
|
||||||
Blockly.Python.addReservedWords('navigate_wait,land_wait,wait_arrival,wait_yaw,get_distance');
|
Blockly.Python.addReservedWords('navigate_wait,land_wait,wait_arrival,wait_yaw,get_distance');
|
||||||
Blockly.Python.addReservedWords('pigpio,pi,Range');
|
Blockly.Python.addReservedWords('pigpio,pi,Range');
|
||||||
Blockly.Python.addReservedWords('SetLEDEffect,set_effect');
|
Blockly.Python.addReservedWords('SetLEDEffect,set_effect,led_count,get_led_count');
|
||||||
Blockly.Python.addReservedWords('SetLEDs,LEDState,set_leds');
|
Blockly.Python.addReservedWords('SetLEDs,LEDState,set_leds');
|
||||||
|
|
||||||
const IMPORT_SRV = `from clover import srv
|
const IMPORT_SRV = `from clover import srv
|
||||||
@@ -87,6 +87,9 @@ function generateROSDefinitions() {
|
|||||||
Blockly.Python.definitions_['import_set_led'] = 'from led_msgs.srv import SetLEDs\nfrom led_msgs.msg import LEDState';
|
Blockly.Python.definitions_['import_set_led'] = 'from led_msgs.srv import SetLEDs\nfrom led_msgs.msg import LEDState';
|
||||||
code += `set_leds = rospy.ServiceProxy('led/set_leds', SetLEDs, persistent=True)\n`;
|
code += `set_leds = rospy.ServiceProxy('led/set_leds', SetLEDs, persistent=True)\n`;
|
||||||
}
|
}
|
||||||
|
if (rosDefinitions.ledStateArray) {
|
||||||
|
Blockly.Python.definitions_['import_led_state_array'] = 'from led_msgs.msg import LEDStateArray';
|
||||||
|
}
|
||||||
if (rosDefinitions.navigateWait) {
|
if (rosDefinitions.navigateWait) {
|
||||||
Blockly.Python.definitions_['import_math'] = 'import math';
|
Blockly.Python.definitions_['import_math'] = 'import math';
|
||||||
code += NAVIGATE_WAIT();
|
code += NAVIGATE_WAIT();
|
||||||
@@ -388,29 +391,48 @@ Blockly.Python.set_led = function(block) {
|
|||||||
|
|
||||||
if (/^'(.*)'$/.test(colorCode)) { // is simple string
|
if (/^'(.*)'$/.test(colorCode)) { // is simple string
|
||||||
let color = parseColor(colorCode);
|
let color = parseColor(colorCode);
|
||||||
return `set_leds([LEDState(index=${index}, r=${color.r}, g=${color.g}, b=${color.b})])\n`;
|
return `set_leds([LEDState(index=int(${index}), r=${color.r}, g=${color.g}, b=${color.b})])\n`; // TODO: check for simple int
|
||||||
} else {
|
} else {
|
||||||
let parseColor = Blockly.Python.provideFunction_('parse_color', [PARSE_COLOR]);
|
let parseColor = Blockly.Python.provideFunction_('parse_color', [PARSE_COLOR]);
|
||||||
return `set_leds([LEDState(index=${index}, **${parseColor}(${colorCode})])\n`;
|
return `set_leds([LEDState(index=${index}, **${parseColor}(${colorCode}))])\n`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const GET_LED_COUNT = `led_count = None
|
||||||
|
|
||||||
|
def get_led_count():
|
||||||
|
global led_count
|
||||||
|
if led_count is None:
|
||||||
|
led_count = len(rospy.wait_for_message('led/state', LEDStateArray, timeout=10).leds)
|
||||||
|
return led_count\n`;
|
||||||
|
|
||||||
|
Blockly.Python.led_count = function(block) {
|
||||||
|
rosDefinitions.ledStateArray = true;
|
||||||
|
initNode();
|
||||||
|
Blockly.Python.definitions_['get_led_count'] = GET_LED_COUNT;
|
||||||
|
return [`get_led_count()`, Blockly.Python.ORDER_FUNCTION_CALL]
|
||||||
|
}
|
||||||
|
|
||||||
function pigpio() {
|
function pigpio() {
|
||||||
Blockly.Python.definitions_['import_pigpio'] = 'import pigpio';
|
Blockly.Python.definitions_['import_pigpio'] = 'import pigpio';
|
||||||
Blockly.Python.definitions_['init_pigpio'] = 'pi = pigpio.pi()';
|
Blockly.Python.definitions_['init_pigpio'] = 'pi = pigpio.pi()';
|
||||||
}
|
}
|
||||||
|
|
||||||
const GPIO_READ = `\ndef gpio_read(pin):
|
const GPIO_READ = `\ndef gpio_read(pin):
|
||||||
pi.set_mode(pin, pigpio.INPUT)
|
pi.set_mode(pin, pigpio.INPUT)
|
||||||
return pi.read(pin)\n`;
|
return pi.read(pin)\n`;
|
||||||
|
|
||||||
const GPIO_WRITE = `\ndef gpio_write(pin, level):
|
const GPIO_WRITE = `\ndef gpio_write(pin, level):
|
||||||
pi.set_mode(pin, pigpio.OUTPUT)
|
pi.set_mode(pin, pigpio.OUTPUT)
|
||||||
pi.write(pin, level)\n`;
|
pi.write(pin, level)\n`;
|
||||||
|
|
||||||
const SET_SERVO = `\ndef set_servo(pin, pwm):
|
const SET_SERVO = `\ndef set_servo(pin, pwm):
|
||||||
pi.set_mode(pin, pigpio.OUTPUT)
|
pi.set_mode(pin, pigpio.OUTPUT)
|
||||||
pi.set_servo_pulsewidth(pin, pwm)\n`;
|
pi.set_servo_pulsewidth(pin, pwm)\n`;
|
||||||
|
|
||||||
|
const SET_DUTY_CYCLE = `\ndef set_duty_cycle(pin, duty_cycle):
|
||||||
|
pi.set_mode(pin, pigpio.OUTPUT)
|
||||||
|
pi.set_PWM_dutycycle(pin, duty_cycle * 255)\n`;
|
||||||
|
|
||||||
Blockly.Python.gpio_read = function(block) {
|
Blockly.Python.gpio_read = function(block) {
|
||||||
pigpio();
|
pigpio();
|
||||||
@@ -434,3 +456,11 @@ Blockly.Python.set_servo = function(block) {
|
|||||||
var pwm = Blockly.Python.valueToCode(block, 'PWM', Blockly.Python.ORDER_NONE);
|
var pwm = Blockly.Python.valueToCode(block, 'PWM', Blockly.Python.ORDER_NONE);
|
||||||
return `set_servo(${pin}, ${pwm})\n`;
|
return `set_servo(${pin}, ${pwm})\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Blockly.Python.set_duty_cycle = function(block) {
|
||||||
|
pigpio();
|
||||||
|
Blockly.Python.definitions_['set_duty_cycle'] = SET_DUTY_CYCLE;
|
||||||
|
var pin = Blockly.Python.valueToCode(block, 'PIN', Blockly.Python.ORDER_NONE);
|
||||||
|
var dutyCycle = Blockly.Python.valueToCode(block, 'DUTY_CYCLE', Blockly.Python.ORDER_NONE);
|
||||||
|
return `set_duty_cycle(${pin}, ${dutyCycle})\n`;
|
||||||
|
}
|
||||||
|
|||||||
9
clover_description/CHANGELOG.rst
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Changelog for package clover_description
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
0.21.1 (2020-11-17)
|
||||||
|
-------------------
|
||||||
|
* First release of clover_description package to ROS
|
||||||
|
* Contributors: Alexey Rogachevskiy
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<package format="2">
|
<package format="2">
|
||||||
<name>clover_description</name>
|
<name>clover_description</name>
|
||||||
<version>0.0.1</version>
|
<version>0.21.1</version>
|
||||||
<description>The clover_description package provides URDF models of the Clover series of quadcopters.</description>
|
<description>The clover_description package provides URDF models of the Clover series of quadcopters.</description>
|
||||||
|
|
||||||
<maintainer email="sfalexrog@gmail.com">Alexey Rogachevskiy</maintainer>
|
<maintainer email="sfalexrog@gmail.com">Alexey Rogachevskiy</maintainer>
|
||||||
|
|||||||
8
clover_simulation/CHANGELOG.rst
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Changelog for package clover_simulation
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
0.21.1 (2020-11-17)
|
||||||
|
-------------------
|
||||||
|
* First release of clover_simulation package to ROS
|
||||||
|
* Contributors: Alexey Rogachevskiy
|
||||||
@@ -52,7 +52,7 @@ target_compile_options(throttling_camera PRIVATE -std=c++11)
|
|||||||
add_dependencies(throttling_camera ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
|
add_dependencies(throttling_camera ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
|
||||||
|
|
||||||
install(DIRECTORY launch DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
|
install(DIRECTORY launch DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
|
||||||
install(DIRECTORY meshes DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
|
install(DIRECTORY models DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
|
||||||
install(DIRECTORY resources DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
|
install(DIRECTORY resources DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
|
||||||
|
|
||||||
catkin_install_python(PROGRAMS scripts/aruco_gen
|
catkin_install_python(PROGRAMS scripts/aruco_gen
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<launch>
|
<launch>
|
||||||
|
<arg name="type" default="gazebo"/> <!-- gazebo, jmavsim, none (only clover packages) -->
|
||||||
<arg name="mav_id" default="0"/>
|
<arg name="mav_id" default="0"/>
|
||||||
<arg name="est" default="ekf2"/> <!-- PX4 estimator: lpe, ekf2 -->
|
<arg name="est" default="ekf2"/> <!-- PX4 estimator: lpe, ekf2 -->
|
||||||
<arg name="vehicle" default="clover"/> <!-- PX4 vehicle configuration: clover, clover_vpe -->
|
<arg name="vehicle" default="clover"/> <!-- PX4 vehicle configuration: clover, clover_vpe -->
|
||||||
@@ -9,22 +10,22 @@
|
|||||||
<arg name="use_clover_physics" default="false"/> <!-- Use inertial parameters from CAD models -->
|
<arg name="use_clover_physics" default="false"/> <!-- Use inertial parameters from CAD models -->
|
||||||
|
|
||||||
<!-- Gazebo instance -->
|
<!-- Gazebo instance -->
|
||||||
<include file="$(find gazebo_ros)/launch/empty_world.launch">
|
<include file="$(find gazebo_ros)/launch/empty_world.launch" if="$(eval type == 'gazebo')">
|
||||||
<!-- Workaround for crashes in VMware -->
|
<!-- Workaround for crashes in VMware -->
|
||||||
<env name="SVGA_VGPU10" value="0"/>
|
<env name="SVGA_VGPU10" value="0"/>
|
||||||
<arg name="gui" value="true"/>
|
<arg name="gui" value="true"/>
|
||||||
<arg name="world_name" value="$(find clover_simulation)/resources/worlds/clover.world"/>
|
<arg name="world_name" value="$(find clover_simulation)/resources/worlds/clover_aruco.world"/>
|
||||||
<arg name="verbose" value="true"/>
|
<arg name="verbose" value="true"/>
|
||||||
</include>
|
</include>
|
||||||
|
|
||||||
<!-- PX4 instance -->
|
<!-- PX4 instance -->
|
||||||
<node name="sitl_$(arg mav_id)" pkg="px4" type="px4" output="screen" args="$(find px4)/ROMFS/px4fmu_common -s etc/init.d-posix/rcS -i $(arg mav_id)">
|
<node name="sitl_$(arg mav_id)" pkg="px4" type="px4" output="screen" args="$(find px4)/ROMFS/px4fmu_common -s etc/init.d-posix/rcS -i $(arg mav_id)" unless="$(eval type == 'none')">
|
||||||
<env name="PX4_SIM_MODEL" value="$(arg vehicle)"/>
|
<env name="PX4_SIM_MODEL" value="$(arg vehicle)"/>
|
||||||
<env name="PX4_ESTIMATOR" value="$(arg est)"/>
|
<env name="PX4_ESTIMATOR" value="$(arg est)"/>
|
||||||
</node>
|
</node>
|
||||||
|
|
||||||
<!-- Clover model -->
|
<!-- Clover model -->
|
||||||
<include file="$(find clover_description)/launch/spawn_drone.launch">
|
<include file="$(find clover_description)/launch/spawn_drone.launch" if="$(eval type == 'gazebo')">
|
||||||
<arg name="main_camera" value="$(arg main_camera)"/>
|
<arg name="main_camera" value="$(arg main_camera)"/>
|
||||||
<arg name="rangefinder" value="$(arg rangefinder)"/>
|
<arg name="rangefinder" value="$(arg rangefinder)"/>
|
||||||
<arg name="led" value="$(arg led)"/>
|
<arg name="led" value="$(arg led)"/>
|
||||||
@@ -32,10 +33,20 @@
|
|||||||
<arg name="use_clover_physics" value="$(arg use_clover_physics)"/>
|
<arg name="use_clover_physics" value="$(arg use_clover_physics)"/>
|
||||||
</include>
|
</include>
|
||||||
|
|
||||||
|
<node name="jmavsim" pkg="px4" type="jmavsim_run.sh" output="screen" if="$(eval type == 'jmavsim')"/>
|
||||||
|
|
||||||
|
<param name="use_sim_time" value="false" if="$(eval type == 'jmavsim')"/>
|
||||||
|
|
||||||
<!-- Clover services -->
|
<!-- Clover services -->
|
||||||
<include file="$(find clover)/launch/clover.launch">
|
<include file="$(find clover)/launch/clover.launch">
|
||||||
<arg name="simulator" value="true"/>
|
<arg name="simulator" value="true"/>
|
||||||
<arg name="fcu_conn" value="sitl"/>
|
<arg name="fcu_conn" value="sitl"/>
|
||||||
<arg name="fcu_ip" value="127.0.0.1"/>
|
<arg name="fcu_ip" value="127.0.0.1"/>
|
||||||
|
<arg name="gcs_bridge" value=""/>
|
||||||
|
<arg name="rc" default="false"/>
|
||||||
|
<arg name="web_video_server" default="false" if="$(eval type == 'jmavsim')"/>
|
||||||
|
<arg name="main_camera" default="false" if="$(eval type == 'jmavsim')"/>
|
||||||
|
<arg name="aruco" default="false" if="$(eval type == 'jmavsim')"/>
|
||||||
|
<arg name="led" default="false" if="$(eval type == 'jmavsim')"/>
|
||||||
</include>
|
</include>
|
||||||
</launch>
|
</launch>
|
||||||
|
|||||||
1693
clover_simulation/models/aruco_cmit_txt/aruco_model.sdf
Normal file
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 93 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 93 B |
|
After Width: | Height: | Size: 93 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 93 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 93 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 93 B |
|
After Width: | Height: | Size: 93 B |
|
After Width: | Height: | Size: 93 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 93 B |
|
After Width: | Height: | Size: 93 B |
|
After Width: | Height: | Size: 94 B |