mirror of
https://github.com/CopterExpress/clover.git
synced 2026-06-02 16:09:32 +00:00
Compare commits
23 Commits
v0.26-alph
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
492430e994 | ||
|
|
924a6c60da | ||
|
|
8ca24ea293 | ||
|
|
c4e6280ea9 | ||
|
|
d46bfabb65 | ||
|
|
66dd9e61c6 | ||
|
|
dcecb03cd5 | ||
|
|
687041d571 | ||
|
|
449364bffb | ||
|
|
1b313b4c5d | ||
|
|
58ec56895f | ||
|
|
28e89704e6 | ||
|
|
23da41247f | ||
|
|
1e45ec143c | ||
|
|
26ec42f1e6 | ||
|
|
3edb2f48e0 | ||
|
|
3a08085c69 | ||
|
|
4e4dfc1f07 | ||
|
|
6b0ed144e3 | ||
|
|
91bb9d6e38 | ||
|
|
e1ff92ee1f | ||
|
|
4d2b685b06 | ||
|
|
14c41b21b6 |
16
.github/workflows/build-image.yaml
vendored
16
.github/workflows/build-image.yaml
vendored
@@ -13,16 +13,13 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- name: Build image
|
- name: Build image
|
||||||
run: |
|
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
|
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
|
- name: Compress image
|
||||||
# run: |
|
|
||||||
# cd images && sudo chmod -R 777 . && zip -9 $(echo clover_*).zip clover_* && ls -lh . && unzip -l clover_*.zip
|
|
||||||
- name: Compress image using 7-Zip
|
|
||||||
run: |
|
run: |
|
||||||
cd images && sudo chmod -R 777 . && 7z a -mx=9 $(echo *_*).7z *_* && ls -lh . && 7z l *_*.7z
|
cd images && sudo chmod -R 777 . && zip -9 $(echo *_*).zip *_* && ls -l . && unzip -l *_*.zip
|
||||||
- name: Upload image
|
- name: Upload image
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
if: ${{ github.event_name == 'release' }}
|
if: ${{ github.event_name == 'release' }}
|
||||||
@@ -31,10 +28,3 @@ jobs:
|
|||||||
prerelease: true
|
prerelease: true
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Upload image to artifacts
|
|
||||||
if: ${{ github.event_name == 'workflow_dispatch' || github.ref != 'refs/heads/master' }}
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: image
|
|
||||||
path: images/*_*.7z
|
|
||||||
retention-days: 1
|
|
||||||
|
|||||||
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
# melodic:
|
# melodic:
|
||||||
# runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
# steps:
|
# steps:
|
||||||
# - uses: actions/checkout@v2
|
# - uses: actions/checkout@v4
|
||||||
# - name: Native Melodic build
|
# - name: Native Melodic build
|
||||||
# run: |
|
# run: |
|
||||||
# docker run --rm -v $(pwd):/root/catkin_ws/src/clover ros:melodic-ros-base /root/catkin_ws/src/clover/builder/standalone-install.sh
|
# docker run --rm -v $(pwd):/root/catkin_ws/src/clover ros:melodic-ros-base /root/catkin_ws/src/clover/builder/standalone-install.sh
|
||||||
@@ -23,7 +23,7 @@ jobs:
|
|||||||
working-directory: catkin_ws
|
working-directory: catkin_ws
|
||||||
shell: bash
|
shell: bash
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
path: catkin_ws/src/clover
|
path: catkin_ws/src/clover
|
||||||
- name: Install requirements
|
- name: Install requirements
|
||||||
@@ -45,7 +45,7 @@ jobs:
|
|||||||
fakeroot debian/rules binary
|
fakeroot debian/rules binary
|
||||||
cd -
|
cd -
|
||||||
done
|
done
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: debian-packages
|
name: debian-packages
|
||||||
path: catkin_ws/src/clover/*.deb
|
path: catkin_ws/src/clover/*.deb
|
||||||
|
|||||||
14
.github/workflows/docs.yml
vendored
14
.github/workflows/docs.yml
vendored
@@ -20,9 +20,9 @@ jobs:
|
|||||||
docs:
|
docs:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- name: Use Node.js
|
- name: Use Node.js
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v4
|
||||||
with: { node-version: '10' }
|
with: { node-version: '10' }
|
||||||
- name: Setup tools
|
- name: Setup tools
|
||||||
run: |
|
run: |
|
||||||
@@ -57,16 +57,16 @@ jobs:
|
|||||||
rm _book/clover_ru.pdf && mv _book/clover_ru_compressed.pdf _book/clover_ru.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
|
rm _book/clover_en.pdf && mv _book/clover_en_compressed.pdf _book/clover_en.pdf
|
||||||
ls -lah _book/clover*.pdf
|
ls -lah _book/clover*.pdf
|
||||||
echo '::set-output name=GITBOOK_PDF_OK::1'
|
echo 'GITBOOK_PDF_OK=1' >> "$GITHUB_OUTPUT"
|
||||||
- name: Download older PDFs
|
- name: Download older PDFs
|
||||||
if: ${{ !steps.generate-pdf.outputs.GITBOOK_PDF_OK }}
|
if: ${{ !steps.generate-pdf.outputs.GITBOOK_PDF_OK }}
|
||||||
run: |
|
run: |
|
||||||
rm -f _book/clover*.pdf
|
rm -f _book/clover*.pdf
|
||||||
wget --no-verbose https://clover.coex.tech/clover_ru.pdf -P _book/
|
wget --no-verbose https://clovercoex.tech/clover_ru.pdf -P _book/
|
||||||
wget --no-verbose https://clover.coex.tech/clover_en.pdf -P _book/
|
wget --no-verbose https://clovercoex.tech/clover_en.pdf -P _book/
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
# if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
# if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||||
uses: actions/upload-pages-artifact@v1
|
uses: actions/upload-pages-artifact@v3
|
||||||
with:
|
with:
|
||||||
path: _book
|
path: _book
|
||||||
|
|
||||||
@@ -86,4 +86,4 @@ jobs:
|
|||||||
FREEZE_DOCS: ${{ secrets.FREEZE_DOCS }}
|
FREEZE_DOCS: ${{ secrets.FREEZE_DOCS }}
|
||||||
if: ${{ !env.FREEZE_DOCS }}
|
if: ${{ !env.FREEZE_DOCS }}
|
||||||
id: deployment
|
id: deployment
|
||||||
uses: actions/deploy-pages@v1
|
uses: actions/deploy-pages@v4
|
||||||
|
|||||||
4
.github/workflows/editorconfig.yaml
vendored
4
.github/workflows/editorconfig.yaml
vendored
@@ -11,9 +11,9 @@ jobs:
|
|||||||
editorconfig:
|
editorconfig:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- name: .editorconfig Linter
|
- name: .editorconfig Linter
|
||||||
run: |
|
run: |
|
||||||
wget --no-verbose https://github.com/okalachev/editorconfig-checker/releases/download/1.2.1-disable-spaces-amount/ec-linux-amd64
|
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
|
chmod +x ec-linux-amd64
|
||||||
./ec-linux-amd64 -spaces-after-tabs -e "roslib.js|ros3d.js|eventemitter2.js|json-to-pretty-yaml.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|\.material"
|
./ec-linux-amd64 -spaces-after-tabs -e "roslib.js|ros3d.js|eventemitter2.js|yaml.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|\.material"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ Clover is an open source [ROS](https://www.ros.org)-based framework, providing u
|
|||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
The main documentation is available at [https://clover.coex.tech](https://clover.coex.tech/). Official website: [coex.tech/clover](https://coex.tech/clover).
|
The main documentation is available at [https://clovercoex.tech](https://clovercoex.tech/).
|
||||||
|
|
||||||
[__Support us on Kickstarter!__](https://www.kickstarter.com/projects/copterexpress/cloverdrone)
|
[__Support us on Kickstarter!__](https://www.kickstarter.com/projects/copterexpress/cloverdrone)
|
||||||
|
|
||||||
@@ -30,11 +30,11 @@ Image features:
|
|||||||
* Configured networking
|
* Configured networking
|
||||||
* OpenCV
|
* OpenCV
|
||||||
* [`mavros`](http://wiki.ros.org/mavros)
|
* [`mavros`](http://wiki.ros.org/mavros)
|
||||||
* Periphery drivers for ROS ([GPIO](https://clover.coex.tech/en/gpio.html), [LED strip](https://clover.coex.tech/en/leds.html), etc)
|
* Periphery drivers for ROS ([GPIO](https://clovercoex.tech/en/gpio.html), [LED strip](https://clovercoex.tech/en/leds.html), etc)
|
||||||
* `aruco_pose` package for marker-assisted navigation
|
* `aruco_pose` package for marker-assisted navigation
|
||||||
* `clover` package for autonomous drone control
|
* `clover` package for autonomous drone control
|
||||||
|
|
||||||
API description for autonomous flights is available [on GitBook](https://clover.coex.tech/en/simple_offboard.html).
|
API description for autonomous flights is available [on GitBook](https://clovercoex.tech/en/simple_offboard.html).
|
||||||
|
|
||||||
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).
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<package format="3">
|
<package format="3">
|
||||||
<name>aruco_pose</name>
|
<name>aruco_pose</name>
|
||||||
<version>0.24.0</version>
|
<version>0.25.0</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>
|
||||||
@@ -28,7 +28,6 @@
|
|||||||
<depend>sensor_msgs</depend>
|
<depend>sensor_msgs</depend>
|
||||||
<depend>rostest</depend>
|
<depend>rostest</depend>
|
||||||
<depend>dynamic_reconfigure</depend>
|
<depend>dynamic_reconfigure</depend>
|
||||||
<depend>pluginlib</depend>
|
|
||||||
<depend condition="$ROS_PYTHON_VERSION == 2">python-docopt</depend>
|
<depend condition="$ROS_PYTHON_VERSION == 2">python-docopt</depend>
|
||||||
<depend condition="$ROS_PYTHON_VERSION == 3">python3-docopt</depend>
|
<depend condition="$ROS_PYTHON_VERSION == 3">python3-docopt</depend>
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
"blank": true
|
"blank": true
|
||||||
},
|
},
|
||||||
"sitemap": {
|
"sitemap": {
|
||||||
"hostname": "https://clover.coex.tech"
|
"hostname": "https://clovercoex.tech"
|
||||||
},
|
},
|
||||||
"toolbar": {
|
"toolbar": {
|
||||||
"buttons":
|
"buttons":
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Requires=roscore.service
|
|||||||
[Service]
|
[Service]
|
||||||
User=pi
|
User=pi
|
||||||
ExecStart=/bin/bash -c ". /home/pi/catkin_ws/devel/setup.sh; \
|
ExecStart=/bin/bash -c ". /home/pi/catkin_ws/devel/setup.sh; \
|
||||||
ROS_HOSTNAME=`hostname`.local ROS_OS_OVERRIDE=debian:bookworm exec stdbuf -o L roslaunch clover clover.launch --wait --screen --skip-log-check \
|
ROS_HOSTNAME=`hostname`.local exec stdbuf -o L roslaunch clover clover.launch --wait --screen --skip-log-check \
|
||||||
2> >(tee /tmp/clover.err)"
|
2> >(tee /tmp/clover.err)"
|
||||||
|
|
||||||
ExecStartPre=+rm /var/log/clover.log
|
ExecStartPre=+rm /var/log/clover.log
|
||||||
|
|||||||
@@ -13,38 +13,70 @@
|
|||||||
# copies or substantial portions of the Software.
|
# copies or substantial portions of the Software.
|
||||||
#
|
#
|
||||||
|
|
||||||
# https://www.raspberrypi.com/documentation/computers/configuration.html
|
set -e # Exit immidiately on non-zero result
|
||||||
|
|
||||||
|
echo_stamp() {
|
||||||
|
# TEMPLATE: echo_stamp <TEXT> <TYPE>
|
||||||
|
# TYPE: SUCCESS, ERROR, INFO
|
||||||
|
|
||||||
|
# More info there https://www.shellhacks.com/ru/bash-colors/
|
||||||
|
|
||||||
|
TEXT="$(date '+[%Y-%m-%d %H:%M:%S]') $1"
|
||||||
|
TEXT="\e[1m$TEXT\e[0m" # BOLD
|
||||||
|
|
||||||
|
case "$2" in
|
||||||
|
SUCCESS)
|
||||||
|
TEXT="\e[32m${TEXT}\e[0m";; # GREEN
|
||||||
|
ERROR)
|
||||||
|
TEXT="\e[31m${TEXT}\e[0m";; # RED
|
||||||
|
*)
|
||||||
|
TEXT="\e[34m${TEXT}\e[0m";; # BLUE
|
||||||
|
esac
|
||||||
|
echo -e ${TEXT}
|
||||||
|
}
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
# Configure hardware interfaces
|
# Configure hardware interfaces
|
||||||
##################################################
|
##################################################
|
||||||
|
|
||||||
echo "--- Enable sshd"
|
# 1. Enable sshd
|
||||||
/usr/bin/raspi-config nonint do_ssh 0
|
echo_stamp "#1 Turn on sshd"
|
||||||
|
touch /boot/ssh
|
||||||
|
# /usr/bin/raspi-config nonint do_ssh 0
|
||||||
|
|
||||||
echo "--- GPIO enabled by default"
|
# 2. Enable GPIO
|
||||||
|
echo_stamp "#2 GPIO enabled by default"
|
||||||
|
|
||||||
echo "--- Enable I2C"
|
# 3. Enable I2C
|
||||||
|
echo_stamp "#3 Turn on I2C"
|
||||||
/usr/bin/raspi-config nonint do_i2c 0
|
/usr/bin/raspi-config nonint do_i2c 0
|
||||||
|
|
||||||
echo "--- Enable SPI"
|
# 4. Enable SPI
|
||||||
|
echo_stamp "#4 Turn on SPI"
|
||||||
/usr/bin/raspi-config nonint do_spi 0
|
/usr/bin/raspi-config nonint do_spi 0
|
||||||
|
|
||||||
echo "--- Enable raspicam"
|
# 5. Enable raspicam
|
||||||
|
echo_stamp "#5 Turn on raspicam"
|
||||||
/usr/bin/raspi-config nonint do_camera 0
|
/usr/bin/raspi-config nonint do_camera 0
|
||||||
|
|
||||||
echo "--- Setup UART"
|
# 6. Enable hardware UART
|
||||||
|
echo_stamp "#6 Turn on UART"
|
||||||
# Temporary solution
|
# Temporary solution
|
||||||
# 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_hw 0
|
/usr/bin/raspi-config nonint do_serial 1
|
||||||
/usr/bin/raspi-config nonint do_serial_cons 1
|
/usr/bin/raspi-config nonint set_config_var enable_uart 1 /boot/config.txt
|
||||||
|
echo dtoverlay=pi3-disable-bt >> /boot/config.txt
|
||||||
echo dtoverlay=pi3-disable-bt >> /boot/firmware/config.txt
|
|
||||||
systemctl disable hciuart.service
|
systemctl disable hciuart.service
|
||||||
|
|
||||||
echo "--- Enable v4l2 driver"
|
# After adding to Raspbian OS
|
||||||
# http://robocraft.ru/blog/electronics/3158.html
|
# https://github.com/RPi-Distro/raspi-config/commit/d6d9ecc0d9cbe4aaa9744ae733b9cb239e79c116
|
||||||
|
#/usr/bin/raspi-config nonint do_serial 2
|
||||||
|
|
||||||
|
# 7. Enable V4L driver http://robocraft.ru/blog/electronics/3158.html
|
||||||
#echo "bcm2835-v4l2" >> /etc/modules
|
#echo "bcm2835-v4l2" >> /etc/modules
|
||||||
|
echo_stamp "#7 Turn on v4l2 driver"
|
||||||
if ! grep -q "^bcm2835-v4l2" /etc/modules;
|
if ! grep -q "^bcm2835-v4l2" /etc/modules;
|
||||||
then printf "bcm2835-v4l2\n" >> /etc/modules
|
then printf "bcm2835-v4l2\n" >> /etc/modules
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo_stamp "#8 End of configure hardware interfaces"
|
||||||
|
|||||||
@@ -13,31 +13,63 @@
|
|||||||
# copies or substantial portions of the Software.
|
# copies or substantial portions of the Software.
|
||||||
#
|
#
|
||||||
|
|
||||||
echo "--- Fix home directory permissions"
|
set -e # Exit immidiately on non-zero result
|
||||||
chmod +rx /home/pi
|
|
||||||
|
echo_stamp() {
|
||||||
|
# TEMPLATE: echo_stamp <TEXT> <TYPE>
|
||||||
|
# TYPE: SUCCESS, ERROR, INFO
|
||||||
|
|
||||||
|
# More info there https://www.shellhacks.com/ru/bash-colors/
|
||||||
|
|
||||||
|
TEXT="$(date '+[%Y-%m-%d %H:%M:%S]') $1"
|
||||||
|
TEXT="\e[1m$TEXT\e[0m" # BOLD
|
||||||
|
|
||||||
|
case "$2" in
|
||||||
|
SUCCESS)
|
||||||
|
TEXT="\e[32m${TEXT}\e[0m";; # GREEN
|
||||||
|
ERROR)
|
||||||
|
TEXT="\e[31m${TEXT}\e[0m";; # RED
|
||||||
|
*)
|
||||||
|
TEXT="\e[34m${TEXT}\e[0m";; # BLUE
|
||||||
|
esac
|
||||||
|
echo -e ${TEXT}
|
||||||
|
}
|
||||||
|
|
||||||
NEW_SSID='clover-'$(head -c 100 /dev/urandom | xxd -ps -c 100 | sed -e "s/[^0-9]//g" | cut -c 1-4)
|
NEW_SSID='clover-'$(head -c 100 /dev/urandom | xxd -ps -c 100 | sed -e "s/[^0-9]//g" | cut -c 1-4)
|
||||||
echo "--- Creating Wi-Fi AP with SSID=${NEW_SSID}"
|
echo_stamp "Setting SSID to ${NEW_SSID}"
|
||||||
nmcli con add type wifi ifname wlan0 mode ap con-name clover ssid $NEW_SSID autoconnect true \
|
# TODO: Use wpa_cli insted direct file edit
|
||||||
&& nmcli con modify clover 802-11-wireless.band bg \
|
# FIXME: We rely on raspberrypi-net-mods to copy our file to /etc/wpa_supplicant.
|
||||||
&& nmcli con modify clover ipv4.method shared ipv4.address 192.168.11.1/24 \
|
# This is not very reliable, but seems to fix our rfkill problem.
|
||||||
&& nmcli con modify clover ipv6.method disabled \
|
cat << EOF >> /boot/wpa_supplicant.conf
|
||||||
&& nmcli con modify clover wifi-sec.key-mgmt wpa-psk \
|
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
|
||||||
&& nmcli con modify clover wifi-sec.psk "cloverwifi" \
|
update_config=1
|
||||||
&& systemctl disable dnsmasq # disable dnsmasq to avoid conflicts with NetworkManager's dnsmasq
|
country=GB
|
||||||
|
network={
|
||||||
|
ssid="${NEW_SSID}"
|
||||||
|
psk="cloverwifi"
|
||||||
|
mode=2
|
||||||
|
proto=WPA RSN
|
||||||
|
key_mgmt=WPA-PSK
|
||||||
|
pairwise=CCMP
|
||||||
|
group=CCMP
|
||||||
|
auth_alg=OPEN
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
NEW_HOSTNAME=$(echo ${NEW_SSID} | tr '[:upper:]' '[:lower:]')
|
NEW_HOSTNAME=$(echo ${NEW_SSID} | tr '[:upper:]' '[:lower:]')
|
||||||
echo "--- Setting hostname to $NEW_HOSTNAME"
|
echo_stamp "Setting hostname to $NEW_HOSTNAME"
|
||||||
hostnamectl set-hostname $NEW_HOSTNAME \
|
hostnamectl set-hostname $NEW_HOSTNAME
|
||||||
&& sed -i 's/127\.0\.1\.1.*/127.0.1.1\t'${NEW_HOSTNAME}' '${NEW_HOSTNAME}'.local/g' /etc/hosts
|
sed -i 's/127\.0\.1\.1.*/127.0.1.1\t'${NEW_HOSTNAME}' '${NEW_HOSTNAME}'.local/g' /etc/hosts
|
||||||
# .local (mdns) hostname added to make it accesable when wlan and ethernet interfaces are down
|
# .local (mdns) hostname added to make it accesable when wlan and ethernet interfaces are down
|
||||||
|
|
||||||
echo "--- Enable ROS services"
|
echo_stamp "Enable ROS services"
|
||||||
systemctl enable roscore
|
systemctl enable roscore
|
||||||
systemctl enable clover
|
systemctl enable clover
|
||||||
|
|
||||||
echo "--- Harware setup"
|
echo_stamp "Harware setup"
|
||||||
/root/hardware_setup.sh
|
/root/hardware_setup.sh
|
||||||
|
|
||||||
echo "--- Remove init scripts"
|
echo_stamp "Remove init scripts"
|
||||||
rm /root/init_rpi.sh /root/hardware_setup.sh
|
rm /root/init_rpi.sh /root/hardware_setup.sh
|
||||||
|
|
||||||
|
echo_stamp "End of initialization of the image"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,122 +0,0 @@
|
|||||||
#! /usr/bin/env bash
|
|
||||||
|
|
||||||
#
|
|
||||||
# Script for building ROS packages from scratch
|
|
||||||
#
|
|
||||||
# Copyright (C) 2022 Copter Express Technologies
|
|
||||||
#
|
|
||||||
# Author: Oleg Kalachev <okalachev@gmail.com>
|
|
||||||
#
|
|
||||||
# Distributed under MIT License (available at https://opensource.org/licenses/MIT).
|
|
||||||
# The above copyright notice and this permission notice shall be included in all
|
|
||||||
# copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
|
|
||||||
set -ex # exit on error, echo commands
|
|
||||||
|
|
||||||
# http://wiki.ros.org/Installation/Source
|
|
||||||
|
|
||||||
export ROS_DISTRO=noetic
|
|
||||||
. /etc/os-release # set $VERSION_CODENAME to Debian release code name
|
|
||||||
export ROS_OS_OVERRIDE=debian:$VERSION_CODENAME
|
|
||||||
export ROS_PYTHON_VERSION=3
|
|
||||||
export CLOVER_DEPS="tf tf2 tf2_ros tf2_geometry_msgs geometry_msgs sensor_msgs visualization_msgs libgeographiclib-dev mavros mavros_extras cv_camera cv_bridge rosbridge_server web_video_server tf2_web_republisher libxml2 libxslt python3-lxml dynamic_reconfigure image_transport image_proc image_geometry python-pymavlink ros_pytest"
|
|
||||||
export CLOVER_DEPS="$CLOVER_DEPS rostest python3-docopt image_publisher"
|
|
||||||
|
|
||||||
echo "=== Building ROS from scratch"
|
|
||||||
|
|
||||||
#echo "--- Adding sources"
|
|
||||||
# echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list
|
|
||||||
# curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -
|
|
||||||
|
|
||||||
#cp /etc/apt/trusted.gpg /etc/apt/trusted.gpg.d # https://askubuntu.com/a/1408456
|
|
||||||
apt-get update
|
|
||||||
apt-get install -y python3-distutils build-essential cmake git python3-pip python3-rosinstall-generator python3-vcstools python3-empy libpoco-dev
|
|
||||||
|
|
||||||
# install vcstool using pip
|
|
||||||
# curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && python3 get-pip.py && rm get-pip.py
|
|
||||||
pip3 install -U --break-system-packages vcstool rosdep rosinstall-generator catkin-pkg future
|
|
||||||
|
|
||||||
# sudo rosdep init
|
|
||||||
# rm /etc/ros/rosdep/sources.list.d/20-default.list
|
|
||||||
rosdep init
|
|
||||||
rosdep update --os=debian:bullseye
|
|
||||||
|
|
||||||
# rm /etc/ros/rosdep/sources.list.d/20-default.list && rosdep init
|
|
||||||
# rosdep --os=debian:$VERSION_CODENAME update
|
|
||||||
|
|
||||||
echo "--- Create Catkin workspace to build ROS package"
|
|
||||||
mkdir ~/ros_catkin_ws
|
|
||||||
cd ~/ros_catkin_ws
|
|
||||||
|
|
||||||
echo "--- Download ROS sources"
|
|
||||||
rosinstall_generator ros_base $CLOVER_DEPS --rosdistro $ROS_DISTRO --deps --tar > noetic.rosinstall
|
|
||||||
mkdir ./src
|
|
||||||
vcs import --input noetic.rosinstall ./src
|
|
||||||
|
|
||||||
# https://answers.ros.org/question/343367/catkin-package-dependencies-issue-when-installing-ros-melodic-on-raspberry-pi-4/
|
|
||||||
#sudo apt remove python-rospkg
|
|
||||||
#sudo apt remove python-catkin-pkg
|
|
||||||
##sudo apt --fix-broken install
|
|
||||||
#sudo apt-get autoremove
|
|
||||||
|
|
||||||
#echo "--- Install catkin_pkg"
|
|
||||||
#cd
|
|
||||||
#git clone https://github.com/ros-infrastructure/catkin_pkg.git
|
|
||||||
#cd catkin_pkg
|
|
||||||
#python3 setup.py install
|
|
||||||
#cd ~/ros_catkin_ws
|
|
||||||
|
|
||||||
echo "--- Resolve dependencies"
|
|
||||||
rosdep install --from-paths ./src --ignore-packages-from-source --rosdistro $ROS_DISTRO -y --os=debian:bullseye --skip-keys="python3-catkin-pkg-modules libboost-thread python3-rosdep-modules" || true
|
|
||||||
|
|
||||||
echo "--- Install missing dependencies"
|
|
||||||
apt-get install -y liborocos-kdl1.5 geographiclib-tools libgeographiclib-dev
|
|
||||||
|
|
||||||
echo "-- Install geographiclib datasets"
|
|
||||||
wget https://raw.githubusercontent.com/mavlink/mavros/master/mavros/scripts/install_geographiclib_datasets.sh
|
|
||||||
chmod +x install_geographiclib_datasets.sh
|
|
||||||
./install_geographiclib_datasets.sh
|
|
||||||
|
|
||||||
echo "--- Apply patches"
|
|
||||||
wget https://github.com/ros/rosconsole/pull/58.patch
|
|
||||||
patch -p1 -d src/rosconsole < 58.patch
|
|
||||||
|
|
||||||
wget https://github.com/ros/ros_comm/pull/2353.patch
|
|
||||||
patch -p2 -d src/ros_comm < 2353.patch
|
|
||||||
|
|
||||||
wget https://github.com/AJahueyM/web_video_server/commit/5b722eb0822bcc3fe45fefe7b393b87bfe004417.patch
|
|
||||||
patch -p1 -d src/web_video_server < 5b722eb0822bcc3fe45fefe7b393b87bfe004417.patch
|
|
||||||
|
|
||||||
echo "--- Build ROS"
|
|
||||||
# https://github.com/ros/catkin/issues/863#issuecomment-290392074
|
|
||||||
./src/catkin/bin/catkin_make_isolated --install -DCMAKE_BUILD_TYPE=Release
|
|
||||||
# -DSETUPTOOLS_DEB_LAYOUT=OFF \
|
|
||||||
# --install-space=/opt/ros/$ROS_DISTRO
|
|
||||||
|
|
||||||
# source ~/ros_catkin_ws/install_isolated/setup.bash
|
|
||||||
#source /opt/ros/$ROS_DISTRO/setup.bash
|
|
||||||
#
|
|
||||||
#echo "--- List built ROS packages"
|
|
||||||
#set +x
|
|
||||||
#rospack list-names | while read line; do echo $line `rosversion $line`; done
|
|
||||||
#set -x
|
|
||||||
#
|
|
||||||
#echo "--- Build Debian packages"
|
|
||||||
#apt-get install -y python3-bloom debhelper dpkg-dev libtinyxml-dev
|
|
||||||
#
|
|
||||||
## add rosdep file to help bloom-generate resolve missing bookworm dependencies
|
|
||||||
#echo "yaml file:///etc/ros/rosdep/noetic-rosdep-clover.yaml" >> /etc/ros/rosdep/sources.list.d/20-default.list
|
|
||||||
#rosdep update
|
|
||||||
#
|
|
||||||
#pip3 install setuptools==45.2.0 # https://github.com/ros/catkin/issues/863#issuecomment-1000446018
|
|
||||||
#
|
|
||||||
#for file in `find . -name "package.xml" -not -path "*/debian/*"`; do
|
|
||||||
# cd $(dirname ${file})
|
|
||||||
# rm -rf debian
|
|
||||||
# bloom-generate rosdebian --os-name debian --os-version $VERSION_CODENAME --ros-distro $ROS_DISTRO --debug
|
|
||||||
# debian/rules binary # fakeroot is not needed as we are root
|
|
||||||
# cd -
|
|
||||||
#done
|
|
||||||
|
|
||||||
ls
|
|
||||||
@@ -13,22 +13,42 @@
|
|||||||
# copies or substantial portions of the Software.
|
# copies or substantial portions of the Software.
|
||||||
#
|
#
|
||||||
|
|
||||||
set -ex # exit on error, echo commands
|
set -e # Exit immidiately on non-zero result
|
||||||
|
|
||||||
# https://www.raspberrypi.org/software/operating-systems/#raspberry-pi-os-32-bit
|
# https://www.raspberrypi.org/software/operating-systems/#raspberry-pi-os-32-bit
|
||||||
SOURCE_IMAGE="https://downloads.raspberrypi.com/raspios_lite_armhf/images/raspios_lite_armhf-2024-03-15/2024-03-15-raspios-bookworm-armhf-lite.img.xz"
|
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'}
|
||||||
export LC_ALL=${LC_ALL:='C.UTF-8'}
|
export LC_ALL=${LC_ALL:='C.UTF-8'}
|
||||||
|
|
||||||
|
echo_stamp() {
|
||||||
|
# TEMPLATE: echo_stamp <TEXT> <TYPE>
|
||||||
|
# TYPE: SUCCESS, ERROR, INFO
|
||||||
|
|
||||||
|
# More info there https://www.shellhacks.com/ru/bash-colors/
|
||||||
|
|
||||||
|
TEXT="$(date '+[%Y-%m-%d %H:%M:%S]') $1"
|
||||||
|
TEXT="\e[1m$TEXT\e[0m" # BOLD
|
||||||
|
|
||||||
|
case "$2" in
|
||||||
|
SUCCESS)
|
||||||
|
TEXT="\e[32m${TEXT}\e[0m";; # GREEN
|
||||||
|
ERROR)
|
||||||
|
TEXT="\e[31m${TEXT}\e[0m";; # RED
|
||||||
|
*)
|
||||||
|
TEXT="\e[34m${TEXT}\e[0m";; # BLUE
|
||||||
|
esac
|
||||||
|
echo -e ${TEXT}
|
||||||
|
}
|
||||||
|
|
||||||
BUILDER_DIR="/builder"
|
BUILDER_DIR="/builder"
|
||||||
REPO_DIR="${BUILDER_DIR}/repo"
|
REPO_DIR="${BUILDER_DIR}/repo"
|
||||||
SCRIPTS_DIR="${REPO_DIR}/builder"
|
SCRIPTS_DIR="${REPO_DIR}/builder"
|
||||||
IMAGES_DIR="${REPO_DIR}/images"
|
IMAGES_DIR="${REPO_DIR}/images"
|
||||||
|
|
||||||
[[ ! -d ${SCRIPTS_DIR} ]] && (echo "Error: directory ${SCRIPTS_DIR} doesn't exist"; exit 1)
|
[[ ! -d ${SCRIPTS_DIR} ]] && (echo_stamp "Directory ${SCRIPTS_DIR} doesn't exist" "ERROR"; exit 1)
|
||||||
[[ ! -d ${IMAGES_DIR} ]] && mkdir ${IMAGES_DIR} && echo "Directory ${IMAGES_DIR} was created successful"
|
[[ ! -d ${IMAGES_DIR} ]] && mkdir ${IMAGES_DIR} && echo_stamp "Directory ${IMAGES_DIR} was created successful" "SUCCESS"
|
||||||
|
|
||||||
if [[ -z ${TRAVIS_TAG} ]]; then IMAGE_VERSION="$(cd ${REPO_DIR}; git log --format=%h -1)"; else IMAGE_VERSION="${TRAVIS_TAG}"; fi
|
if [[ -z ${TRAVIS_TAG} ]]; then IMAGE_VERSION="$(cd ${REPO_DIR}; git log --format=%h -1)"; else IMAGE_VERSION="${TRAVIS_TAG}"; fi
|
||||||
# IMAGE_VERSION="${TRAVIS_TAG:=$(cd ${REPO_DIR}; git log --format=%h -1)}"
|
# IMAGE_VERSION="${TRAVIS_TAG:=$(cd ${REPO_DIR}; git log --format=%h -1)}"
|
||||||
@@ -44,17 +64,15 @@ get_image() {
|
|||||||
local RPI_IMAGE_NAME=$(echo ${RPI_ZIP_NAME} | sed 's/zip/img/')
|
local RPI_IMAGE_NAME=$(echo ${RPI_ZIP_NAME} | sed 's/zip/img/')
|
||||||
|
|
||||||
if [ ! -e "${BUILD_DIR}/${RPI_ZIP_NAME}" ]; then
|
if [ ! -e "${BUILD_DIR}/${RPI_ZIP_NAME}" ]; then
|
||||||
echo "--- Downloading original Linux distribution"
|
echo_stamp "Downloading original Linux distribution"
|
||||||
wget --progress=dot:giga -O ${BUILD_DIR}/${RPI_ZIP_NAME} $2
|
wget --progress=dot:giga -O ${BUILD_DIR}/${RPI_ZIP_NAME} $2
|
||||||
echo "--- Downloading complete" "SUCCESS"
|
echo_stamp "Downloading complete" "SUCCESS" \
|
||||||
else
|
else echo_stamp "Linux distribution already donwloaded"; fi
|
||||||
echo "Linux distribution already downloaded"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "--- Unzipping Linux distribution image"
|
echo_stamp "Unzipping Linux distribution image" \
|
||||||
apt-get update --allow-releaseinfo-change
|
&& unzip -p ${BUILD_DIR}/${RPI_ZIP_NAME} ${RPI_IMAGE_NAME} > $1 \
|
||||||
apt-get install -y xz-utils
|
&& echo_stamp "Unzipping complete" "SUCCESS" \
|
||||||
unxz --stdout ${BUILD_DIR}/${RPI_ZIP_NAME} > $1
|
|| (echo_stamp "Unzipping was failed!" "ERROR"; exit 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
get_image ${IMAGE_PATH} ${SOURCE_IMAGE}
|
get_image ${IMAGE_PATH} ${SOURCE_IMAGE}
|
||||||
@@ -102,7 +120,6 @@ ${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/launch.
|
|||||||
# ${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/kinetic-ros-clover.rosinstall' '/home/pi/ros_catkin_ws/'
|
# ${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/kinetic-ros-clover.rosinstall' '/home/pi/ros_catkin_ws/'
|
||||||
# Add rename script
|
# Add rename script
|
||||||
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-ros.sh' ${REPO_URL} ${IMAGE_VERSION} false false ${NUMBER_THREADS}
|
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-ros.sh' ${REPO_URL} ${IMAGE_VERSION} false false ${NUMBER_THREADS}
|
||||||
#${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-build-ros.sh'
|
|
||||||
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-validate.sh'
|
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-validate.sh'
|
||||||
|
|
||||||
${BUILDER_DIR}/image-resize.sh ${IMAGE_PATH}
|
${BUILDER_DIR}/image-resize.sh ${IMAGE_PATH}
|
||||||
|
|||||||
@@ -12,33 +12,50 @@
|
|||||||
# copies or substantial portions of the Software.
|
# copies or substantial portions of the Software.
|
||||||
#
|
#
|
||||||
|
|
||||||
set -ex # exit on error, echo commands
|
set -e # Exit immidiately on non-zero result
|
||||||
|
|
||||||
echo "--- Move /etc/ld.so.preload out of the way"
|
echo_stamp() {
|
||||||
mv /etc/ld.so.preload /etc/ld.so.preload.disabled-for-build
|
# TEMPLATE: echo_stamp <TEXT> <TYPE>
|
||||||
|
# TYPE: SUCCESS, ERROR, INFO
|
||||||
|
|
||||||
echo "--- Create pi user"
|
# More info there https://www.shellhacks.com/ru/bash-colors/
|
||||||
echo 'pi:$6$c70VpvPsVNCG0YR5$l5vWWLsLko9Kj65gcQ8qvMkuOoRkEagI90qi3F/Y7rm8eNYZHW8CY6BOIKwMH7a3YYzZYL90zf304cAHLFaZE0' > /boot/userconf.txt
|
|
||||||
|
TEXT="$(date '+[%Y-%m-%d %H:%M:%S]') $1"
|
||||||
|
TEXT="\e[1m$TEXT\e[0m" # BOLD
|
||||||
|
|
||||||
|
case "$2" in
|
||||||
|
SUCCESS)
|
||||||
|
TEXT="\e[32m${TEXT}\e[0m";; # GREEN
|
||||||
|
ERROR)
|
||||||
|
TEXT="\e[31m${TEXT}\e[0m";; # RED
|
||||||
|
*)
|
||||||
|
TEXT="\e[34m${TEXT}\e[0m";; # BLUE
|
||||||
|
esac
|
||||||
|
echo -e ${TEXT}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo_stamp "Write Clover information"
|
||||||
|
|
||||||
echo "--- Write Clover information"
|
|
||||||
# Clover image version
|
# Clover image version
|
||||||
echo "$1" >> /etc/clover_version
|
echo "$1" >> /etc/clover_version
|
||||||
# Origin image file name
|
# Origin image file name
|
||||||
echo "${2%.*}" >> /etc/clover_origin
|
echo "${2%.*}" >> /etc/clover_origin
|
||||||
|
|
||||||
echo "--- Write magic script to /etc/rc.local"
|
echo_stamp "Write magic script to /etc/rc.local"
|
||||||
MAGIC_SCRIPT="sudo /root/init_rpi.sh; sudo sed -i '/sudo \\\/root\\\/init_rpi.sh/d' /etc/rc.local && sudo reboot"
|
MAGIC_SCRIPT="sudo /root/init_rpi.sh; sudo sed -i '/sudo \\\/root\\\/init_rpi.sh/d' /etc/rc.local && sudo reboot"
|
||||||
sed -i "19a${MAGIC_SCRIPT}" /etc/rc.local
|
sed -i "19a${MAGIC_SCRIPT}" /etc/rc.local
|
||||||
# TODO: remake to oneshot systemd service
|
|
||||||
|
|
||||||
# It needs for autosizer.sh & maybe that is correct
|
# It needs for autosizer.sh & maybe that is correct
|
||||||
echo "--- Change boot partition"
|
echo_stamp "Change boot partition"
|
||||||
sed -i 's/root=[^ ]*/root=\/dev\/mmcblk0p2/' /boot/cmdline.txt
|
sed -i 's/root=[^ ]*/root=\/dev\/mmcblk0p2/' /boot/cmdline.txt
|
||||||
sed -i 's/.* \/boot\/firmware vfat defaults 0 2$/\/dev\/mmcblk0p1 \/boot\/firmware vfat defaults 0 2/' /etc/fstab
|
sed -i 's/.* \/boot vfat defaults 0 2$/\/dev\/mmcblk0p1 \/boot vfat defaults 0 2/' /etc/fstab
|
||||||
sed -i 's/.* \/ ext4 defaults,noatime 0 1$/\/dev\/mmcblk0p2 \/ ext4 defaults,noatime 0 1/' /etc/fstab
|
sed -i 's/.* \/ ext4 defaults,noatime 0 1$/\/dev\/mmcblk0p2 \/ ext4 defaults,noatime 0 1/' /etc/fstab
|
||||||
cat /boot/cmdline.txt
|
|
||||||
cat /etc/fstab
|
|
||||||
|
|
||||||
echo "--- Set max space for syslogs"
|
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"
|
||||||
|
|||||||
@@ -12,20 +12,43 @@
|
|||||||
# copies or substantial portions of the Software.
|
# copies or substantial portions of the Software.
|
||||||
#
|
#
|
||||||
|
|
||||||
set -ex # exit on error, echo commands
|
set -e # Exit immidiately on non-zero result
|
||||||
|
|
||||||
|
echo_stamp() {
|
||||||
|
# TEMPLATE: echo_stamp <TEXT> <TYPE>
|
||||||
|
# TYPE: SUCCESS, ERROR, INFO
|
||||||
|
|
||||||
|
# More info there https://www.shellhacks.com/ru/bash-colors/
|
||||||
|
|
||||||
|
TEXT="$(date '+[%Y-%m-%d %H:%M:%S]') $1"
|
||||||
|
TEXT="\e[1m$TEXT\e[0m" # BOLD
|
||||||
|
|
||||||
|
case "$2" in
|
||||||
|
SUCCESS)
|
||||||
|
TEXT="\e[32m${TEXT}\e[0m";; # GREEN
|
||||||
|
ERROR)
|
||||||
|
TEXT="\e[31m${TEXT}\e[0m";; # RED
|
||||||
|
*)
|
||||||
|
TEXT="\e[34m${TEXT}\e[0m";; # BLUE
|
||||||
|
esac
|
||||||
|
echo -e ${TEXT}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo_stamp "#1 Write STATIC to /etc/dhcpcd.conf"
|
||||||
|
|
||||||
echo "--- Write static to /etc/dhcpcd.conf"
|
|
||||||
cat << EOF >> /etc/dhcpcd.conf
|
cat << EOF >> /etc/dhcpcd.conf
|
||||||
interface wlan0
|
interface wlan0
|
||||||
static ip_address=192.168.11.1/24
|
static ip_address=192.168.11.1/24
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
echo "--- Set wpa_supplicant country"
|
echo_stamp "#2 Set wpa_supplicant country"
|
||||||
|
|
||||||
cat << EOF >> /etc/wpa_supplicant/wpa_supplicant.conf
|
cat << EOF >> /etc/wpa_supplicant/wpa_supplicant.conf
|
||||||
country=GB
|
country=GB
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
echo "--- Write dhcp-config to /etc/dnsmasq.conf"
|
echo_stamp "#3 Write dhcp-config to /etc/dnsmasq.conf"
|
||||||
|
|
||||||
cat << EOF >> /etc/dnsmasq.conf
|
cat << EOF >> /etc/dnsmasq.conf
|
||||||
interface=wlan0
|
interface=wlan0
|
||||||
address=/clover/coex/192.168.11.1
|
address=/clover/coex/192.168.11.1
|
||||||
@@ -36,3 +59,5 @@ bogus-priv
|
|||||||
domain-needed
|
domain-needed
|
||||||
quiet-dhcp6
|
quiet-dhcp6
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
echo_stamp "#4 End of network installation"
|
||||||
|
|||||||
@@ -15,10 +15,34 @@
|
|||||||
|
|
||||||
set -ex # exit on error, echo commands
|
set -ex # exit on error, echo commands
|
||||||
|
|
||||||
|
REPO=$1
|
||||||
|
REF=$2
|
||||||
|
INSTALL_ROS_PACK_SOURCES=$3
|
||||||
|
DISCOVER_ROS_PACK=$4
|
||||||
|
NUMBER_THREADS=$5
|
||||||
|
|
||||||
# Current ROS distribution
|
# Current ROS distribution
|
||||||
ROS_DISTRO=noetic
|
ROS_DISTRO=noetic
|
||||||
. /etc/os-release # set $VERSION_CODENAME to Debian release code name
|
|
||||||
export ROS_OS_OVERRIDE=debian:$VERSION_CODENAME
|
echo_stamp() {
|
||||||
|
# TEMPLATE: echo_stamp <TEXT> <TYPE>
|
||||||
|
# TYPE: SUCCESS, ERROR, INFO
|
||||||
|
|
||||||
|
# More info there https://www.shellhacks.com/ru/bash-colors/
|
||||||
|
|
||||||
|
TEXT="$(date '+[%Y-%m-%d %H:%M:%S]') $1"
|
||||||
|
TEXT="\e[1m$TEXT\e[0m" # BOLD
|
||||||
|
|
||||||
|
case "$2" in
|
||||||
|
SUCCESS)
|
||||||
|
TEXT="\e[32m${TEXT}\e[0m";; # GREEN
|
||||||
|
ERROR)
|
||||||
|
TEXT="\e[31m${TEXT}\e[0m";; # RED
|
||||||
|
*)
|
||||||
|
TEXT="\e[34m${TEXT}\e[0m";; # BLUE
|
||||||
|
esac
|
||||||
|
echo -e ${TEXT}
|
||||||
|
}
|
||||||
|
|
||||||
# https://gist.github.com/letmaik/caa0f6cc4375cbfcc1ff26bd4530c2a3
|
# https://gist.github.com/letmaik/caa0f6cc4375cbfcc1ff26bd4530c2a3
|
||||||
# https://github.com/travis-ci/travis-build/blob/master/lib/travis/build/templates/header.sh
|
# https://github.com/travis-ci/travis-build/blob/master/lib/travis/build/templates/header.sh
|
||||||
@@ -28,7 +52,7 @@ my_travis_retry() {
|
|||||||
local max_count=5
|
local max_count=5
|
||||||
while [ $count -le $max_count ]; do
|
while [ $count -le $max_count ]; do
|
||||||
[ $result -ne 0 ] && {
|
[ $result -ne 0 ] && {
|
||||||
echo -e "\nThe command \"$*\" failed. Retrying, $count of $max_count.\n" >&2
|
echo -e "\nThe command \"$@\" failed. Retrying, $count of $max_count.\n" >&2
|
||||||
}
|
}
|
||||||
# ! { } ignores set -e, see https://stackoverflow.com/a/4073372
|
# ! { } ignores set -e, see https://stackoverflow.com/a/4073372
|
||||||
! { "$@"; result=$?; }
|
! { "$@"; result=$?; }
|
||||||
@@ -38,66 +62,65 @@ my_travis_retry() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
[ $count -gt $max_count ] && {
|
[ $count -gt $max_count ] && {
|
||||||
echo -e "\nThe command \"$*\" failed $max_count times.\n" >&2
|
echo -e "\nThe command \"$@\" failed $max_count times.\n" >&2
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result
|
return $result
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "--- Install rosdep"
|
|
||||||
my_travis_retry pip3 install -U rosdep
|
|
||||||
|
|
||||||
# TODO: 'kinetic-rosdep-clover.yaml' should add only if we use our repo?
|
# TODO: 'kinetic-rosdep-clover.yaml' should add only if we use our repo?
|
||||||
echo "--- Init rosdep"
|
echo_stamp "Init rosdep"
|
||||||
my_travis_retry rosdep init
|
my_travis_retry rosdep init
|
||||||
|
# FIXME: Re-add this after missing packages are built
|
||||||
echo "--- Update rosdep"
|
|
||||||
echo "yaml file:///etc/ros/rosdep/${ROS_DISTRO}-rosdep-clover.yaml" >> /etc/ros/rosdep/sources.list.d/10-clover.list
|
echo "yaml file:///etc/ros/rosdep/${ROS_DISTRO}-rosdep-clover.yaml" >> /etc/ros/rosdep/sources.list.d/10-clover.list
|
||||||
my_travis_retry rosdep update
|
my_travis_retry rosdep update
|
||||||
|
|
||||||
echo "--- Populate rosdep for ROS user"
|
echo_stamp "Populate rosdep for ROS user"
|
||||||
my_travis_retry sudo -u pi ROS_OS_OVERRIDE=debian:$VERSION_CODENAME rosdep update
|
my_travis_retry sudo -u pi rosdep update
|
||||||
|
|
||||||
# echo "Reconfiguring Clover repository for simplier unshallowing"
|
export ROS_IP='127.0.0.1' # needed for running tests
|
||||||
|
|
||||||
|
# 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/*"
|
||||||
|
|
||||||
# This is sort of a hack to force "custom" packages to be installed - the ones built by COEX, linked against OpenCV 4.2
|
# This is sort of a hack to force "custom" packages to be installed - the ones built by COEX, linked against OpenCV 4.2
|
||||||
# I **wish** OpenCV would not be such a mess, but, well, here we are.
|
# I **wish** OpenCV would not be such a mess, but, well, here we are.
|
||||||
# echo "--- Installing OpenCV 4.2-compatible ROS packages"
|
echo_stamp "Installing OpenCV 4.2-compatible ROS packages"
|
||||||
# apt install -y --no-install-recommends \
|
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.1-0buster \
|
ros-${ROS_DISTRO}-cv-camera=0.5.1-0buster \
|
||||||
# ros-${ROS_DISTRO}-image-publisher=1.15.3-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 \
|
||||||
# ros-${ROS_DISTRO}-cv-bridge \
|
ros-${ROS_DISTRO}-cv-bridge \
|
||||||
# ros-${ROS_DISTRO}-cv-camera \
|
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 "--- Installing libboost-dev" # https://travis-ci.org/github/CopterExpress/clover/jobs/766318908#L6536
|
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
|
my_travis_retry apt-get install -y --no-install-recommends libboost-dev libboost-all-dev
|
||||||
|
|
||||||
echo "--- 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
|
||||||
my_travis_retry rosdep install -y --from-paths src --ignore-src --rosdistro ${ROS_DISTRO} --os=debian:$VERSION_CODENAME \
|
my_travis_retry rosdep install -y --from-paths src --ignore-src --rosdistro ${ROS_DISTRO} --os=debian:buster \
|
||||||
--skip-keys="gazebo_ros gazebo_plugins"
|
--skip-keys=gazebo_ros --skip-keys=gazebo_plugins
|
||||||
my_travis_retry pip3 install wheel
|
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
|
||||||
catkin_make -j2 -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
catkin_make -j2 -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||||
source devel/setup.bash
|
source devel/setup.bash
|
||||||
|
|
||||||
echo "--- 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
|
||||||
./setup.py install
|
./setup.py install
|
||||||
rm -rf build # remove build artifacts
|
rm -rf build # remove build artifacts
|
||||||
|
|
||||||
echo "--- Build Clover documentation"
|
echo_stamp "Build Clover documentation"
|
||||||
cd /home/pi/catkin_ws/src/clover
|
cd /home/pi/catkin_ws/src/clover
|
||||||
builder/assets/install_gitbook.sh
|
builder/assets/install_gitbook.sh
|
||||||
gitbook install
|
gitbook install
|
||||||
@@ -105,69 +128,66 @@ gitbook build
|
|||||||
# replace assets copy to assets symlink to save space
|
# replace assets copy to assets symlink to save space
|
||||||
rm -rf _book/assets && ln -s ../docs/assets _book/assets
|
rm -rf _book/assets && ln -s ../docs/assets _book/assets
|
||||||
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
|
||||||
npm cache clean --force
|
|
||||||
|
|
||||||
echo "--- Installing additional ROS packages"
|
echo_stamp "Installing additional ROS packages"
|
||||||
my_travis_retry apt-get install -y --no-install-recommends \
|
my_travis_retry apt-get install -y --no-install-recommends \
|
||||||
ros-${ROS_DISTRO}-rosbridge-suite \
|
ros-${ROS_DISTRO}-rosbridge-suite \
|
||||||
ros-${ROS_DISTRO}-rosserial \
|
ros-${ROS_DISTRO}-rosserial \
|
||||||
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}-libcamera-ros \
|
|
||||||
ros-${ROS_DISTRO}-rosshow \
|
ros-${ROS_DISTRO}-rosshow \
|
||||||
ros-${ROS_DISTRO}-cmake-modules \
|
ros-${ROS_DISTRO}-cmake-modules \
|
||||||
ros-${ROS_DISTRO}-image-view \
|
ros-${ROS_DISTRO}-image-view \
|
||||||
ros-${ROS_DISTRO}-nodelet-topic-tools \
|
ros-${ROS_DISTRO}-nodelet-topic-tools \
|
||||||
ros-${ROS_DISTRO}-stereo-msgs \
|
ros-${ROS_DISTRO}-stereo-msgs \
|
||||||
ros-${ROS_DISTRO}-vision-msgs
|
ros-${ROS_DISTRO}-vision-msgs \
|
||||||
|
ros-${ROS_DISTRO}-angles
|
||||||
|
|
||||||
# TODO move GeographicLib datasets to Mavros debian package
|
# TODO move GeographicLib datasets to Mavros debian package
|
||||||
echo "--- Install GeographicLib datasets (needed for mavros)" \
|
echo_stamp "Install GeographicLib datasets (needed for mavros)" \
|
||||||
&& wget -qO- https://raw.githubusercontent.com/mavlink/mavros/master/mavros/scripts/install_geographiclib_datasets.sh | bash
|
&& wget -qO- https://raw.githubusercontent.com/mavlink/mavros/master/mavros/scripts/install_geographiclib_datasets.sh | bash
|
||||||
|
|
||||||
echo "--- Running tests"
|
echo_stamp "Running tests"
|
||||||
export ROS_IP='127.0.0.1' # needed for running tests
|
|
||||||
cd /home/pi/catkin_ws
|
cd /home/pi/catkin_ws
|
||||||
# FIXME: Investigate failing tests
|
# FIXME: Investigate failing tests
|
||||||
catkin_make run_tests #&& catkin_test_results
|
catkin_make run_tests #&& catkin_test_results
|
||||||
|
|
||||||
echo "--- 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 "--- Update www"
|
echo_stamp "Update www"
|
||||||
sudo -u pi sh -c ". devel/setup.sh && rosrun clover www"
|
sudo -u pi sh -c ". devel/setup.sh && rosrun clover www"
|
||||||
|
|
||||||
echo "--- Make \$HOME/examples symlink"
|
echo_stamp "Make \$HOME/examples symlink"
|
||||||
ln -s "$(catkin_find clover examples --first-only)" /home/pi
|
ln -s "$(catkin_find clover examples --first-only)" /home/pi
|
||||||
chown -Rf pi:pi /home/pi/examples
|
chown -Rf pi:pi /home/pi/examples
|
||||||
|
|
||||||
echo "--- Make systemd services symlinks"
|
echo_stamp "Make systemd services symlinks"
|
||||||
ln -s /home/pi/catkin_ws/src/clover/builder/assets/clover.service /lib/systemd/system/
|
ln -s /home/pi/catkin_ws/src/clover/builder/assets/clover.service /lib/systemd/system/
|
||||||
ln -s /home/pi/catkin_ws/src/clover/builder/assets/roscore.service /lib/systemd/system/
|
ln -s /home/pi/catkin_ws/src/clover/builder/assets/roscore.service /lib/systemd/system/
|
||||||
# validate
|
# validate
|
||||||
[ -f /lib/systemd/system/clover.service ]
|
[ -f /lib/systemd/system/clover.service ]
|
||||||
[ -f /lib/systemd/system/roscore.service ]
|
[ -f /lib/systemd/system/roscore.service ]
|
||||||
|
|
||||||
echo "--- Make udev rules symlink"
|
echo_stamp "Make udev rules symlink"
|
||||||
ln -s "$(catkin_find clover udev --first-only)"/* /lib/udev/rules.d/
|
ln -s "$(catkin_find clover udev --first-only)"/* /lib/udev/rules.d/
|
||||||
|
|
||||||
echo "--- 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'
|
||||||
LC_ALL='C.UTF-8'
|
LC_ALL='C.UTF-8'
|
||||||
export ROS_HOSTNAME=\`hostname\`.local
|
export ROS_HOSTNAME=\`hostname\`.local
|
||||||
export ROS_OS_OVERRIDE=debian:bookworm
|
|
||||||
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
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
echo "--- Cleanup apt"
|
#echo_stamp "Removing local apt mirror"
|
||||||
apt-get autoremove --purge -y
|
# Restore original sources.list
|
||||||
apt-get clean
|
#mv /var/sources.list.bak /etc/apt/sources.list
|
||||||
|
# Clean apt cache
|
||||||
|
apt-get clean -qq > /dev/null
|
||||||
|
# Remove local mirror repository key
|
||||||
|
#apt-key del COEX-MIRROR
|
||||||
|
|
||||||
echo "--- Cleanup pip"
|
echo_stamp "END of ROS INSTALLATION"
|
||||||
pip3 cache purge
|
|
||||||
|
|
||||||
echo "--- Cleanup /tmp"
|
|
||||||
rm -rf /tmp/*
|
|
||||||
|
|||||||
@@ -12,9 +12,27 @@
|
|||||||
# copies or substantial portions of the Software.
|
# copies or substantial portions of the Software.
|
||||||
#
|
#
|
||||||
|
|
||||||
set -ex # exit on error, echo commands
|
set -e # Exit immidiately on non-zero result
|
||||||
|
|
||||||
. /etc/os-release # set $VERSION_CODENAME to Debian release code name
|
echo_stamp() {
|
||||||
|
# TEMPLATE: echo_stamp <TEXT> <TYPE>
|
||||||
|
# TYPE: SUCCESS, ERROR, INFO
|
||||||
|
|
||||||
|
# More info there https://www.shellhacks.com/ru/bash-colors/
|
||||||
|
|
||||||
|
TEXT="$(date '+[%Y-%m-%d %H:%M:%S]') $1"
|
||||||
|
TEXT="\e[1m${TEXT}\e[0m" # BOLD
|
||||||
|
|
||||||
|
case "$2" in
|
||||||
|
SUCCESS)
|
||||||
|
TEXT="\e[32m${TEXT}\e[0m";; # GREEN
|
||||||
|
ERROR)
|
||||||
|
TEXT="\e[31m${TEXT}\e[0m";; # RED
|
||||||
|
*)
|
||||||
|
TEXT="\e[34m${TEXT}\e[0m";; # BLUE
|
||||||
|
esac
|
||||||
|
echo -e ${TEXT}
|
||||||
|
}
|
||||||
|
|
||||||
# https://gist.github.com/letmaik/caa0f6cc4375cbfcc1ff26bd4530c2a3
|
# https://gist.github.com/letmaik/caa0f6cc4375cbfcc1ff26bd4530c2a3
|
||||||
# https://github.com/travis-ci/travis-build/blob/master/lib/travis/build/templates/header.sh
|
# https://github.com/travis-ci/travis-build/blob/master/lib/travis/build/templates/header.sh
|
||||||
@@ -23,7 +41,7 @@ my_travis_retry() {
|
|||||||
local count=1
|
local count=1
|
||||||
while [ $count -le 3 ]; do
|
while [ $count -le 3 ]; do
|
||||||
[ $result -ne 0 ] && {
|
[ $result -ne 0 ] && {
|
||||||
echo -e "\n${ANSI_RED}The command \"$*\" failed. Retrying, $count of 3.${ANSI_RESET}\n" >&2
|
echo -e "\n${ANSI_RED}The command \"$@\" failed. Retrying, $count of 3.${ANSI_RESET}\n" >&2
|
||||||
}
|
}
|
||||||
# ! { } ignores set -e, see https://stackoverflow.com/a/4073372
|
# ! { } ignores set -e, see https://stackoverflow.com/a/4073372
|
||||||
! { "$@"; result=$?; }
|
! { "$@"; result=$?; }
|
||||||
@@ -33,39 +51,41 @@ my_travis_retry() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
[ $count -gt 3 ] && {
|
[ $count -gt 3 ] && {
|
||||||
echo -e "\n${ANSI_RED}The command \"$*\" failed 3 times.${ANSI_RESET}\n" >&2
|
echo -e "\n${ANSI_RED}The command \"$@\" failed 3 times.${ANSI_RESET}\n" >&2
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result
|
return $result
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "--- Increase apt retries"
|
echo_stamp "Increase apt retries"
|
||||||
|
|
||||||
echo "APT::Acquire::Retries \"3\";" > /etc/apt/apt.conf.d/80-retries
|
echo "APT::Acquire::Retries \"3\";" > /etc/apt/apt.conf.d/80-retries
|
||||||
|
|
||||||
echo "--- Install apt keys & repos"
|
echo_stamp "Install apt keys & repos"
|
||||||
|
|
||||||
# TODO: This STDOUT consist 'OK'
|
# TODO: This STDOUT consist 'OK'
|
||||||
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
|
||||||
|
|
||||||
wget -O - 'http://packages.coex.tech/key.asc' | apt-key add -
|
wget -O - 'http://packages.coex.tech/key.asc' | apt-key add -
|
||||||
echo "deb http://packages.coex.tech $VERSION_CODENAME main" >> /etc/apt/sources.list
|
echo 'deb http://packages.coex.tech buster main' >> /etc/apt/sources.list
|
||||||
|
|
||||||
echo "--- Update apt cache"
|
echo_stamp "Update apt cache"
|
||||||
|
|
||||||
# TODO: FIX ERROR: /usr/bin/apt-key: 596: /usr/bin/apt-key: cannot create /dev/null: Permission denied
|
# TODO: FIX ERROR: /usr/bin/apt-key: 596: /usr/bin/apt-key: cannot create /dev/null: Permission denied
|
||||||
apt-get update
|
apt-get update
|
||||||
# && apt upgrade -y
|
# && apt upgrade -y
|
||||||
|
|
||||||
# Let's retry fetching those packages several times, just in case
|
# Let's retry fetching those packages several times, just in case
|
||||||
echo "--- Install software"
|
echo_stamp "Software installing"
|
||||||
my_travis_retry apt-get install --no-install-recommends -y cmake-data cmake
|
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 \
|
||||||
|
ipython \
|
||||||
ipython3 \
|
ipython3 \
|
||||||
screen \
|
screen \
|
||||||
byobu \
|
byobu \
|
||||||
@@ -76,57 +96,64 @@ dnsmasq \
|
|||||||
tmux \
|
tmux \
|
||||||
tree \
|
tree \
|
||||||
vim \
|
vim \
|
||||||
|
libjpeg8 \
|
||||||
tcpdump \
|
tcpdump \
|
||||||
libpoco-dev \
|
libpoco-dev \
|
||||||
libzbar0 \
|
libzbar0 \
|
||||||
|
python3-rosdep \
|
||||||
python3-rosinstall-generator \
|
python3-rosinstall-generator \
|
||||||
python3-wstool \
|
python3-wstool \
|
||||||
python3-rosinstall \
|
python3-rosinstall \
|
||||||
build-essential \
|
build-essential \
|
||||||
libffi-dev \
|
libffi-dev \
|
||||||
monkey \
|
monkey \
|
||||||
pigpio python3-pigpio \
|
pigpio python-pigpio python3-pigpio \
|
||||||
i2c-tools \
|
i2c-tools \
|
||||||
espeak espeak-data python3-espeak \
|
espeak espeak-data python-espeak python3-espeak \
|
||||||
ntpdate \
|
ntpdate \
|
||||||
mjpg-streamer \
|
python-dev \
|
||||||
xxd \
|
|
||||||
python3-dev \
|
python3-dev \
|
||||||
python3-systemd \
|
python-systemd \
|
||||||
python3-opencv \
|
mjpg-streamer \
|
||||||
python3-pip
|
python3-opencv
|
||||||
#libjpeg8 \
|
|
||||||
|
|
||||||
# Deny byobu to check available updates
|
# Deny byobu to check available updates
|
||||||
sed -i "s/updates_available//" /usr/share/byobu/status/status
|
sed -i "s/updates_available//" /usr/share/byobu/status/status
|
||||||
# sed -i "s/updates_available//" /home/pi/.byobu/status
|
# sed -i "s/updates_available//" /home/pi/.byobu/status
|
||||||
|
|
||||||
echo "--- Make sure pip is installed"
|
echo_stamp "Installing pip"
|
||||||
|
curl https://bootstrap.pypa.io/pip/3.7/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
|
||||||
|
python get-pip2.py
|
||||||
|
rm get-pip.py get-pip2.py
|
||||||
|
#my_travis_retry pip install --upgrade pip
|
||||||
|
#my_travis_retry pip3 install --upgrade pip
|
||||||
|
|
||||||
|
echo_stamp "Make sure both pip and pip3 are installed"
|
||||||
pip --version
|
pip --version
|
||||||
pip3 --version
|
pip3 --version
|
||||||
|
|
||||||
echo "--- Enable installing packages with pip"
|
echo_stamp "Install and enable Butterfly (web terminal)"
|
||||||
mv /usr/lib/python3.11/EXTERNALLY-MANAGED /usr/lib/python3.11/EXTERNALLY-MANAGED.old
|
echo_stamp "Workaround for tornado >= 6.0 breaking butterfly"
|
||||||
|
|
||||||
echo "--- Install and enable Butterfly (web terminal)"
|
|
||||||
export CRYPTOGRAPHY_DONT_BUILD_RUST=1
|
export CRYPTOGRAPHY_DONT_BUILD_RUST=1
|
||||||
my_travis_retry pip3 install cryptography==3.4.6 # https://stackoverflow.com/a/68472128/6850197
|
my_travis_retry pip3 install cryptography==3.4.6 # https://stackoverflow.com/a/68472128/6850197
|
||||||
#my_travis_retry pip3 install pyOpenSSL==20.0.1
|
my_travis_retry pip3 install pyOpenSSL==20.0.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]
|
||||||
systemctl enable butterfly.socket
|
systemctl enable butterfly.socket
|
||||||
|
|
||||||
echo "--- Install ws281x library"
|
echo_stamp "Install ws281x library"
|
||||||
my_travis_retry pip3 install --prefer-binary rpi_ws281x
|
my_travis_retry pip3 install --prefer-binary rpi_ws281x
|
||||||
|
|
||||||
echo "--- 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
|
sed -i 's/SymLink Off/SymLink On/' /etc/monkey/monkey.conf
|
||||||
systemctl enable monkey.service
|
systemctl enable monkey.service
|
||||||
|
|
||||||
echo "--- Install Node.js"
|
echo_stamp "Install Node.js"
|
||||||
cd /home/pi
|
cd /home/pi
|
||||||
wget --no-verbose https://nodejs.org/dist/v10.15.0/node-v10.15.0-linux-armv6l.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-armv6l.tar.gz
|
tar -xzf node-v10.15.0-linux-armv6l.tar.gz
|
||||||
@@ -134,24 +161,28 @@ cp -R node-v10.15.0-linux-armv6l/* /usr/local/
|
|||||||
rm -rf node-v10.15.0-linux-armv6l/
|
rm -rf node-v10.15.0-linux-armv6l/
|
||||||
rm node-v10.15.0-linux-armv6l.tar.gz
|
rm node-v10.15.0-linux-armv6l.tar.gz
|
||||||
|
|
||||||
echo "--- Installing debugpy"
|
echo_stamp "Installing ptvsd"
|
||||||
my_travis_retry pip3 install debugpy
|
my_travis_retry pip install ptvsd
|
||||||
|
my_travis_retry pip3 install ptvsd
|
||||||
|
|
||||||
echo "--- Installing pyzbar"
|
echo_stamp "Installing pyzbar"
|
||||||
|
my_travis_retry pip install pyzbar
|
||||||
my_travis_retry pip3 install pyzbar
|
my_travis_retry pip3 install pyzbar
|
||||||
|
|
||||||
echo "--- Add .vimrc"
|
echo_stamp "Add .vimrc"
|
||||||
cat << EOF > /home/pi/.vimrc
|
cat << EOF > /home/pi/.vimrc
|
||||||
set mouse-=a
|
set mouse-=a
|
||||||
syntax on
|
syntax on
|
||||||
autocmd BufNewFile,BufRead *.launch set syntax=xml
|
autocmd BufNewFile,BufRead *.launch set syntax=xml
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
echo "--- Change default keyboard layout to US"
|
echo_stamp "Change default keyboard layout to US"
|
||||||
sed -i 's/XKBLAYOUT="gb"/XKBLAYOUT="us"/g' /etc/default/keyboard
|
sed -i 's/XKBLAYOUT="gb"/XKBLAYOUT="us"/g' /etc/default/keyboard
|
||||||
|
|
||||||
echo "--- Attempting to kill dirmngr"
|
echo_stamp "Attempting to kill dirmngr"
|
||||||
gpgconf --kill dirmngr
|
gpgconf --kill dirmngr
|
||||||
# dirmngr is only used by apt-key, so we can safely kill it.
|
# dirmngr is only used by apt-key, so we can safely kill it.
|
||||||
# We ignore pkill's exit value as well.
|
# We ignore pkill's exit value as well.
|
||||||
pkill -9 -f dirmngr || true
|
pkill -9 -f dirmngr || true
|
||||||
|
|
||||||
|
echo_stamp "End of software installation"
|
||||||
|
|||||||
@@ -12,33 +12,32 @@
|
|||||||
# copies or substantial portions of the Software.
|
# copies or substantial portions of the Software.
|
||||||
#
|
#
|
||||||
|
|
||||||
set -ex # exit on error, echo commands
|
set -ex
|
||||||
|
|
||||||
|
echo "Run image tests"
|
||||||
echo "--- Run image tests"
|
|
||||||
|
|
||||||
export ROS_DISTRO='noetic'
|
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
|
||||||
[[ $(./test_qr.py) == "Found QRCODE with data Проверка Unicode with center at x=66.0, y=66.0" ]]
|
[[ $(./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
|
||||||
|
|
||||||
# check documented packages available
|
# check documented packages available
|
||||||
apt-cache show gst-rtsp-launch
|
apt-cache show gst-rtsp-launch
|
||||||
apt-cache show openvpn
|
apt-cache show openvpn
|
||||||
|
|
||||||
|
echo "Move /etc/ld.so.preload back to its original position"
|
||||||
|
mv /etc/ld.so.preload.disabled-for-build /etc/ld.so.preload
|
||||||
|
|
||||||
echo "Largest packages installed"
|
echo "Largest packages installed"
|
||||||
sudo -E sh -c 'apt-get install -y debian-goodies'
|
sudo -E sh -c 'apt-get install -y debian-goodies'
|
||||||
dpigs -H -n 100
|
dpigs -H -n 100
|
||||||
|
|
||||||
echo "Cleanup apt"
|
|
||||||
apt-get autoremove --purge -y
|
|
||||||
apt-get clean
|
|
||||||
|
|
||||||
echo "Move /etc/ld.so.preload back to its original position"
|
|
||||||
mv /etc/ld.so.preload.disabled-for-build /etc/ld.so.preload
|
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ import os
|
|||||||
import rospy
|
import rospy
|
||||||
from geometry_msgs.msg import PoseStamped
|
from geometry_msgs.msg import PoseStamped
|
||||||
from sensor_msgs.msg import Range, BatteryState
|
from sensor_msgs.msg import Range, BatteryState
|
||||||
|
from vision_msgs.msg import BoundingBox2D, BoundingBox2DArray, BoundingBox3D, BoundingBox3DArray, \
|
||||||
|
Classification2D, Classification3D, Detection2D, Detection2DArray, Detection3D, Detection3DArray, \
|
||||||
|
ObjectHypothesis, ObjectHypothesisWithPose, VisionInfo
|
||||||
|
import angles
|
||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
import cv2.aruco
|
import cv2.aruco
|
||||||
@@ -23,10 +27,6 @@ from clover.srv import GetTelemetry, Navigate, NavigateGlobal, SetPosition, SetV
|
|||||||
from led_msgs.srv import SetLEDs
|
from led_msgs.srv import SetLEDs
|
||||||
from led_msgs.msg import LEDStateArray, LEDState
|
from led_msgs.msg import LEDStateArray, LEDState
|
||||||
from aruco_pose.msg import Marker, MarkerArray, Point2D
|
from aruco_pose.msg import Marker, MarkerArray, Point2D
|
||||||
from vision_msgs.msg import BoundingBox2D, BoundingBox2DArray, BoundingBox3D, BoundingBox3DArray, \
|
|
||||||
Classification2D, Classification3D, Detection2D, Detection2DArray, Detection3D, Detection3DArray, \
|
|
||||||
ObjectHypothesis, ObjectHypothesisWithPose, VisionInfo
|
|
||||||
|
|
||||||
from clover import long_callback
|
from clover import long_callback
|
||||||
|
|
||||||
import dynamic_reconfigure.client
|
import dynamic_reconfigure.client
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -ex # exit on error, echo commands
|
set -ex
|
||||||
|
|
||||||
# TODO: validate versions
|
# TODO: validate versions
|
||||||
|
|
||||||
# validate required software is installed
|
# validate required software is installed
|
||||||
|
|
||||||
|
python2 --version
|
||||||
python3 --version
|
python3 --version
|
||||||
ipython3 --version
|
ipython3 --version
|
||||||
|
|
||||||
@@ -21,28 +22,30 @@ pip --version
|
|||||||
pip3 --version
|
pip3 --version
|
||||||
tcpdump --version
|
tcpdump --version
|
||||||
monkey --version
|
monkey --version
|
||||||
espeak --version
|
# espeak --version
|
||||||
xxd --version
|
|
||||||
systemctl --version
|
systemctl --version
|
||||||
|
|
||||||
if [ -z $VM ]; then
|
if [ -z $VM ]; then
|
||||||
# rpi only software
|
# rpi only software
|
||||||
python --version
|
python --version
|
||||||
[[ $(python -c 'import sys;print(sys.version_info.major)') == "3" ]]
|
ipython --version
|
||||||
|
pip2 --version
|
||||||
|
# `python` is python2 for now
|
||||||
|
[[ $(python -c 'import sys;print(sys.version_info.major)') == "2" ]]
|
||||||
|
|
||||||
python -m debugpy --version
|
# ptvsd does not have a stand-alone binary
|
||||||
python3 -m debugpy --version
|
python -m ptvsd --version
|
||||||
|
python3 -m ptvsd --version
|
||||||
|
|
||||||
pigpiod -v
|
pigpiod -v
|
||||||
i2cdetect -V
|
i2cdetect -V
|
||||||
/usr/local/bin/butterfly.server.py --help
|
butterfly -h
|
||||||
mjpg_streamer --version
|
mjpg_streamer --version
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ros stuff
|
# ros stuff
|
||||||
|
|
||||||
roscore -h
|
roscore -h
|
||||||
catkin_find
|
|
||||||
rosversion clover
|
rosversion clover
|
||||||
rosversion aruco_pose
|
rosversion aruco_pose
|
||||||
rosversion mavros
|
rosversion mavros
|
||||||
@@ -57,15 +60,18 @@ rosversion cv_camera
|
|||||||
rosversion web_video_server
|
rosversion web_video_server
|
||||||
rosversion nodelet
|
rosversion nodelet
|
||||||
rosversion image_view
|
rosversion image_view
|
||||||
|
rosversion stereo_msgs
|
||||||
|
rosversion vision_msgs
|
||||||
|
rosversion angles
|
||||||
|
|
||||||
[[ $(rosversion ws281x) == "0.0.15" ]]
|
[[ $(rosversion ws281x) == "0.0.13" ]]
|
||||||
|
|
||||||
if [ -z $VM ]; then
|
if [ -z $VM ]; then
|
||||||
# rosversion compressed_image_transport
|
rosversion compressed_image_transport
|
||||||
rosversion rosshow
|
rosversion rosshow
|
||||||
rosversion vl53l1x
|
rosversion vl53l1x
|
||||||
rosversion rosserial
|
rosversion rosserial
|
||||||
[[ $(rosversion cv_camera) == "0.6.1" ]] # patched version with init fix
|
[[ $(rosversion cv_camera) == "0.5.1" ]] # patched version with init fix
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# determine user home directory
|
# determine user home directory
|
||||||
|
|||||||
8
builder/test/tests_py3.py
Executable file
8
builder/test/tests_py3.py
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Make sure our Python 3 software is installed
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
from pyzbar import pyzbar
|
||||||
|
|
||||||
|
print(cv2.getBuildInformation())
|
||||||
@@ -2,6 +2,52 @@
|
|||||||
Changelog for package clover
|
Changelog for package clover
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
0.25 (2024-07-28)
|
||||||
|
-----------------
|
||||||
|
* Optimize displaying newlines in the topic viewer, add width and indent parameters.
|
||||||
|
* Link assets instead of copying in documentation to save space.
|
||||||
|
* Install image_geometry and dynamic_reconfigure as clover dependencies.
|
||||||
|
* Add dictionary parameter to aruco.launch.
|
||||||
|
* Solve the issue with aruco_detect not running when aruco_map is not enabled.
|
||||||
|
* Documentation improvements.
|
||||||
|
* Rest changes.
|
||||||
|
|
||||||
|
0.24 (2023-10-11)
|
||||||
|
-----------------
|
||||||
|
* Significant update to autonomous flights API.
|
||||||
|
* Updates to selfcheck.py.
|
||||||
|
* Support PX4 v1.14 parameters.
|
||||||
|
* Added scripts for automatic testing of autonomous flights.
|
||||||
|
* Added new examples for working with the camera, including a red circle model and its recognition and following.
|
||||||
|
* Implemented long_callback Python decorator to address the issue #218.
|
||||||
|
* Implemented optical_flow/enabled dynamic parameter.
|
||||||
|
* Updated LED strip native library to support RPi 4 rev. 1.5.
|
||||||
|
* Show number of messages received in web topic viewer.
|
||||||
|
* Run main_camera/image_raw_throttled topic by default.
|
||||||
|
* Added rectify argument to main_camera.launch
|
||||||
|
* Added udev rules for all supported autopilots by PX4.
|
||||||
|
* Various changes.
|
||||||
|
|
||||||
|
0.23 (2022-02-10)
|
||||||
|
-----------------
|
||||||
|
* Web tool for topics monitoring.
|
||||||
|
* Publish optical flow when local position is not available.
|
||||||
|
* Force estimator init.
|
||||||
|
* Web viewer for Clover logs.
|
||||||
|
* selfcheck.py improvements.
|
||||||
|
* Various changes.
|
||||||
|
|
||||||
|
0.22 (2021-06-07)
|
||||||
|
-----------------
|
||||||
|
* Move to ROS Noetic and Python 3.
|
||||||
|
* aruco.launch: add placement, length and map arguments.
|
||||||
|
* Web: add link for viewing the error log.
|
||||||
|
* LED: add error/ignore parameter to not flash on some errors.
|
||||||
|
* Wait for FC and camera devices before launching mavros and camera driver.
|
||||||
|
* clover.launch: disable rc node by default.
|
||||||
|
* optical_flow: publish debug image even when calc_flow_gyro failed.
|
||||||
|
* Various changes.
|
||||||
|
|
||||||
0.21.1 (2020-11-17)
|
0.21.1 (2020-11-17)
|
||||||
-------------------
|
-------------------
|
||||||
* First release of clover package to ROS
|
* First release of clover package to ROS
|
||||||
|
|||||||
@@ -50,6 +50,6 @@ To start connection to the flight controller, use:
|
|||||||
roslaunch clover clover.launch
|
roslaunch clover clover.launch
|
||||||
```
|
```
|
||||||
|
|
||||||
For the simulation information see the [corresponding article](https://clover.coex.tech/en/simulation.html).
|
For the simulation information see the [corresponding article](https://clovercoex.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,65 +0,0 @@
|
|||||||
# Generated from fisheye_cam.yaml by rescale_camera_info.py
|
|
||||||
camera_matrix:
|
|
||||||
cols: 3
|
|
||||||
data:
|
|
||||||
- 415.5985593268293
|
|
||||||
- 0.0
|
|
||||||
- 400.0
|
|
||||||
- 0.0
|
|
||||||
- 312.35267324512984
|
|
||||||
- 225.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 1.0
|
|
||||||
rows: 3
|
|
||||||
camera_name: main_camera_optical
|
|
||||||
distortion_coefficients:
|
|
||||||
cols: 8
|
|
||||||
data:
|
|
||||||
- 0.215356885
|
|
||||||
- -0.117472846
|
|
||||||
- -0.000306197672
|
|
||||||
- -0.000109444025
|
|
||||||
- -0.00453657258
|
|
||||||
- 0.573090623
|
|
||||||
- -0.127574577
|
|
||||||
- -0.0286125589
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
rows: 1
|
|
||||||
distortion_model: plumb_bob
|
|
||||||
image_height: 720
|
|
||||||
image_width: 1280
|
|
||||||
projection_matrix:
|
|
||||||
cols: 4
|
|
||||||
data:
|
|
||||||
- 415.5985593268293
|
|
||||||
- 0.0
|
|
||||||
- 405.4752811707317
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 312.35267324512984
|
|
||||||
- 205.91677004464282
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 1.0
|
|
||||||
- 0.0
|
|
||||||
rows: 3
|
|
||||||
rectification_matrix:
|
|
||||||
cols: 3
|
|
||||||
data:
|
|
||||||
- 1
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 1
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 1
|
|
||||||
rows: 3
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
# Generated from fisheye_cam.yaml by rescale_camera_info.py
|
|
||||||
camera_matrix:
|
|
||||||
cols: 3
|
|
||||||
data:
|
|
||||||
- 1246.7956779804879
|
|
||||||
- 0.0
|
|
||||||
- 1200.0
|
|
||||||
- 0.0
|
|
||||||
- 702.7935148015422
|
|
||||||
- 506.25
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 1.0
|
|
||||||
rows: 3
|
|
||||||
camera_name: main_camera_optical
|
|
||||||
distortion_coefficients:
|
|
||||||
cols: 8
|
|
||||||
data:
|
|
||||||
- 0.215356885
|
|
||||||
- -0.117472846
|
|
||||||
- -0.000306197672
|
|
||||||
- -0.000109444025
|
|
||||||
- -0.00453657258
|
|
||||||
- 0.573090623
|
|
||||||
- -0.127574577
|
|
||||||
- -0.0286125589
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
rows: 1
|
|
||||||
distortion_model: plumb_bob
|
|
||||||
image_height: 1080
|
|
||||||
image_width: 1920
|
|
||||||
projection_matrix:
|
|
||||||
cols: 4
|
|
||||||
data:
|
|
||||||
- 1246.7956779804879
|
|
||||||
- 0.0
|
|
||||||
- 1216.4258435121951
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 702.7935148015422
|
|
||||||
- 463.31273260044634
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 1.0
|
|
||||||
- 0.0
|
|
||||||
rows: 3
|
|
||||||
rectification_matrix:
|
|
||||||
cols: 3
|
|
||||||
data:
|
|
||||||
- 1
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 1
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 1
|
|
||||||
rows: 3
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
# Generated from fisheye_cam.yaml by rescale_camera_info.py
|
|
||||||
camera_matrix:
|
|
||||||
cols: 3
|
|
||||||
data:
|
|
||||||
- 5049.522495820976
|
|
||||||
- 0.0
|
|
||||||
- 4860.0
|
|
||||||
- 0.0
|
|
||||||
- 2846.313734946246
|
|
||||||
- 2050.3125
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 1.0
|
|
||||||
rows: 3
|
|
||||||
camera_name: main_camera_optical
|
|
||||||
distortion_coefficients:
|
|
||||||
cols: 8
|
|
||||||
data:
|
|
||||||
- 0.215356885
|
|
||||||
- -0.117472846
|
|
||||||
- -0.000306197672
|
|
||||||
- -0.000109444025
|
|
||||||
- -0.00453657258
|
|
||||||
- 0.573090623
|
|
||||||
- -0.127574577
|
|
||||||
- -0.0286125589
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
rows: 1
|
|
||||||
distortion_model: plumb_bob
|
|
||||||
image_height: 1944
|
|
||||||
image_width: 2592
|
|
||||||
projection_matrix:
|
|
||||||
cols: 4
|
|
||||||
data:
|
|
||||||
- 5049.522495820976
|
|
||||||
- 0.0
|
|
||||||
- 4926.52466622439
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 2846.313734946246
|
|
||||||
- 1876.4165670318075
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 1.0
|
|
||||||
- 0.0
|
|
||||||
rows: 3
|
|
||||||
rectification_matrix:
|
|
||||||
cols: 3
|
|
||||||
data:
|
|
||||||
- 1
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 1
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 1
|
|
||||||
rows: 3
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
# Generated from fisheye_cam.yaml by rescale_camera_info.py
|
|
||||||
camera_matrix:
|
|
||||||
cols: 3
|
|
||||||
data:
|
|
||||||
- 166.23942373073172
|
|
||||||
- 0.0
|
|
||||||
- 160.0
|
|
||||||
- 0.0
|
|
||||||
- 166.5880923974026
|
|
||||||
- 120.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 1.0
|
|
||||||
rows: 3
|
|
||||||
camera_name: main_camera_optical
|
|
||||||
distortion_coefficients:
|
|
||||||
cols: 8
|
|
||||||
data:
|
|
||||||
- 0.215356885
|
|
||||||
- -0.117472846
|
|
||||||
- -0.000306197672
|
|
||||||
- -0.000109444025
|
|
||||||
- -0.00453657258
|
|
||||||
- 0.573090623
|
|
||||||
- -0.127574577
|
|
||||||
- -0.0286125589
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
rows: 1
|
|
||||||
distortion_model: plumb_bob
|
|
||||||
image_height: 240
|
|
||||||
image_width: 320
|
|
||||||
projection_matrix:
|
|
||||||
cols: 4
|
|
||||||
data:
|
|
||||||
- 166.23942373073172
|
|
||||||
- 0.0
|
|
||||||
- 162.19011246829268
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 166.5880923974026
|
|
||||||
- 109.82227735714285
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 1.0
|
|
||||||
- 0.0
|
|
||||||
rows: 3
|
|
||||||
rectification_matrix:
|
|
||||||
cols: 3
|
|
||||||
data:
|
|
||||||
- 1
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 1
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 1
|
|
||||||
rows: 3
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
# Generated from fisheye_cam.yaml by rescale_camera_info.py
|
|
||||||
camera_matrix:
|
|
||||||
cols: 3
|
|
||||||
data:
|
|
||||||
- 30297.13497492585
|
|
||||||
- 0.0
|
|
||||||
- 29160.0
|
|
||||||
- 0.0
|
|
||||||
- 12808.411807258106
|
|
||||||
- 9226.40625
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 1.0
|
|
||||||
rows: 3
|
|
||||||
camera_name: main_camera_optical
|
|
||||||
distortion_coefficients:
|
|
||||||
cols: 8
|
|
||||||
data:
|
|
||||||
- 0.215356885
|
|
||||||
- -0.117472846
|
|
||||||
- -0.000306197672
|
|
||||||
- -0.000109444025
|
|
||||||
- -0.00453657258
|
|
||||||
- 0.573090623
|
|
||||||
- -0.127574577
|
|
||||||
- -0.0286125589
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
rows: 1
|
|
||||||
distortion_model: plumb_bob
|
|
||||||
image_height: 2160
|
|
||||||
image_width: 3840
|
|
||||||
projection_matrix:
|
|
||||||
cols: 4
|
|
||||||
data:
|
|
||||||
- 30297.13497492585
|
|
||||||
- 0.0
|
|
||||||
- 29559.14799734634
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 12808.411807258106
|
|
||||||
- 8443.874551643134
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 1.0
|
|
||||||
- 0.0
|
|
||||||
rows: 3
|
|
||||||
rectification_matrix:
|
|
||||||
cols: 3
|
|
||||||
data:
|
|
||||||
- 1
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 1
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 1
|
|
||||||
rows: 3
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
# Generated from fisheye_cam.yaml by rescale_camera_info.py
|
|
||||||
camera_matrix:
|
|
||||||
cols: 3
|
|
||||||
data:
|
|
||||||
- 192008.0929035926
|
|
||||||
- 0.0
|
|
||||||
- 184801.5
|
|
||||||
- 0.0
|
|
||||||
- 81119.941445968
|
|
||||||
- 58433.90625
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 1.0
|
|
||||||
rows: 3
|
|
||||||
camera_name: main_camera_optical
|
|
||||||
distortion_coefficients:
|
|
||||||
cols: 8
|
|
||||||
data:
|
|
||||||
- 0.215356885
|
|
||||||
- -0.117472846
|
|
||||||
- -0.000306197672
|
|
||||||
- -0.000109444025
|
|
||||||
- -0.00453657258
|
|
||||||
- 0.573090623
|
|
||||||
- -0.127574577
|
|
||||||
- -0.0286125589
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
rows: 1
|
|
||||||
distortion_model: plumb_bob
|
|
||||||
image_height: 3040
|
|
||||||
image_width: 4056
|
|
||||||
projection_matrix:
|
|
||||||
cols: 4
|
|
||||||
data:
|
|
||||||
- 192008.0929035926
|
|
||||||
- 0.0
|
|
||||||
- 187331.10043318244
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 81119.941445968
|
|
||||||
- 53477.87216040651
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 1.0
|
|
||||||
- 0.0
|
|
||||||
rows: 3
|
|
||||||
rectification_matrix:
|
|
||||||
cols: 3
|
|
||||||
data:
|
|
||||||
- 1
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 1
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 1
|
|
||||||
rows: 3
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
# Generated from fisheye_cam.yaml by rescale_camera_info.py
|
|
||||||
camera_matrix:
|
|
||||||
cols: 3
|
|
||||||
data:
|
|
||||||
- 166.23942373073172
|
|
||||||
- 0.0
|
|
||||||
- 160.0
|
|
||||||
- 0.0
|
|
||||||
- 166.5880923974026
|
|
||||||
- 120.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 1.0
|
|
||||||
rows: 3
|
|
||||||
camera_name: main_camera_optical
|
|
||||||
distortion_coefficients:
|
|
||||||
cols: 8
|
|
||||||
data:
|
|
||||||
- 0.215356885
|
|
||||||
- -0.117472846
|
|
||||||
- -0.000306197672
|
|
||||||
- -0.000109444025
|
|
||||||
- -0.00453657258
|
|
||||||
- 0.573090623
|
|
||||||
- -0.127574577
|
|
||||||
- -0.0286125589
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
rows: 1
|
|
||||||
distortion_model: plumb_bob
|
|
||||||
image_height: 480
|
|
||||||
image_width: 640
|
|
||||||
projection_matrix:
|
|
||||||
cols: 4
|
|
||||||
data:
|
|
||||||
- 166.23942373073172
|
|
||||||
- 0.0
|
|
||||||
- 162.19011246829268
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 166.5880923974026
|
|
||||||
- 109.82227735714285
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 1.0
|
|
||||||
- 0.0
|
|
||||||
rows: 3
|
|
||||||
rectification_matrix:
|
|
||||||
cols: 3
|
|
||||||
data:
|
|
||||||
- 1
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 1
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 1
|
|
||||||
rows: 3
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
# Generated from fisheye_cam.yaml by rescale_camera_info.py
|
|
||||||
camera_matrix:
|
|
||||||
cols: 3
|
|
||||||
data:
|
|
||||||
- 207.79927966341464
|
|
||||||
- 0.0
|
|
||||||
- 200.0
|
|
||||||
- 0.0
|
|
||||||
- 208.23511549675322
|
|
||||||
- 150.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 1.0
|
|
||||||
rows: 3
|
|
||||||
camera_name: main_camera_optical
|
|
||||||
distortion_coefficients:
|
|
||||||
cols: 8
|
|
||||||
data:
|
|
||||||
- 0.215356885
|
|
||||||
- -0.117472846
|
|
||||||
- -0.000306197672
|
|
||||||
- -0.000109444025
|
|
||||||
- -0.00453657258
|
|
||||||
- 0.573090623
|
|
||||||
- -0.127574577
|
|
||||||
- -0.0286125589
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
rows: 1
|
|
||||||
distortion_model: plumb_bob
|
|
||||||
image_height: 600
|
|
||||||
image_width: 800
|
|
||||||
projection_matrix:
|
|
||||||
cols: 4
|
|
||||||
data:
|
|
||||||
- 207.79927966341464
|
|
||||||
- 0.0
|
|
||||||
- 202.73764058536585
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 208.23511549675322
|
|
||||||
- 137.27784669642855
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 0.0
|
|
||||||
- 1.0
|
|
||||||
- 0.0
|
|
||||||
rows: 3
|
|
||||||
rectification_matrix:
|
|
||||||
cols: 3
|
|
||||||
data:
|
|
||||||
- 1
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 1
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 1
|
|
||||||
rows: 3
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# Information: https://clover.coex.tech/camera
|
# Information: https://clovercoex.tech/camera
|
||||||
|
|
||||||
# Example on basic working with the camera and image processing:
|
# Example on basic working with the camera and image processing:
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Information: https://clover.coex.tech/programming
|
# Information: https://clovercoex.tech/programming
|
||||||
|
|
||||||
import rospy
|
import rospy
|
||||||
from clover import srv
|
from clover import srv
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Information: https://clover.coex.tech/aruco
|
# Information: https://clovercoex.tech/aruco
|
||||||
|
|
||||||
import rospy
|
import rospy
|
||||||
from clover import srv
|
from clover import srv
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Information: https://clover.coex.tech/en/simple_offboard.html#gettelemetry
|
# Information: https://clovercoex.tech/en/simple_offboard.html#gettelemetry
|
||||||
|
|
||||||
import rospy
|
import rospy
|
||||||
from clover import srv
|
from clover import srv
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Information: https://clover.coex.tech/en/simple_offboard.html#navigateglobal
|
# Information: https://clovercoex.tech/en/simple_offboard.html#navigateglobal
|
||||||
|
|
||||||
import rospy
|
import rospy
|
||||||
from clover import srv
|
from clover import srv
|
||||||
@@ -16,7 +16,7 @@ set_attitude = rospy.ServiceProxy('set_attitude', srv.SetAttitude)
|
|||||||
set_rates = rospy.ServiceProxy('set_rates', srv.SetRates)
|
set_rates = rospy.ServiceProxy('set_rates', srv.SetRates)
|
||||||
land = rospy.ServiceProxy('land', Trigger)
|
land = rospy.ServiceProxy('land', Trigger)
|
||||||
|
|
||||||
# https://clover.coex.tech/en/snippets.html#wait_arrival
|
# https://clovercoex.tech/en/snippets.html#wait_arrival
|
||||||
def wait_arrival(tolerance=0.2):
|
def wait_arrival(tolerance=0.2):
|
||||||
while not rospy.is_shutdown():
|
while not rospy.is_shutdown():
|
||||||
telem = get_telemetry(frame_id='navigate_target')
|
telem = get_telemetry(frame_id='navigate_target')
|
||||||
@@ -27,7 +27,7 @@ def wait_arrival(tolerance=0.2):
|
|||||||
start = get_telemetry()
|
start = get_telemetry()
|
||||||
|
|
||||||
if math.isnan(start.lat):
|
if math.isnan(start.lat):
|
||||||
raise Exception('No global position, install and configure GPS sensor: https://clover.coex.tech/gps')
|
raise Exception('No global position, install and configure GPS sensor: https://clovercoex.tech/gps')
|
||||||
|
|
||||||
print('Start point global position: lat={}, lon={}'.format(start.lat, start.lon))
|
print('Start point global position: lat={}, lon={}'.format(start.lat, start.lon))
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Information: https://clover.coex.tech/led
|
# Information: https://clovercoex.tech/led
|
||||||
|
|
||||||
import rospy
|
import rospy
|
||||||
from clover.srv import SetLEDEffect
|
from clover.srv import SetLEDEffect
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Information: https://clover.coex.tech/en/snippets.html#navigate_wait
|
# Information: https://clovercoex.tech/en/snippets.html#navigate_wait
|
||||||
|
|
||||||
import math
|
import math
|
||||||
import rospy
|
import rospy
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# This example makes the drone find and follow the red circle.
|
# This example makes the drone find and follow the red circle.
|
||||||
# To test in the simulator, place 'Red Circle' model on the floor.
|
# To test in the simulator, place 'Red Circle' model on the floor.
|
||||||
# More information: https://clover.coex.tech/red_circle
|
# More information: https://clovercoex.tech/red_circle
|
||||||
|
|
||||||
# Input topic: main_camera/image_raw (camera image)
|
# Input topic: main_camera/image_raw (camera image)
|
||||||
# Output topics:
|
# Output topics:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Information: https://clover.coex.tech/en/laser.html
|
# Information: https://clovercoex.tech/en/laser.html
|
||||||
|
|
||||||
import rospy
|
import rospy
|
||||||
from sensor_msgs.msg import Range
|
from sensor_msgs.msg import Range
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<arg name="length" default="0.22"/> <!-- not-in-map markers length, m -->
|
<arg name="length" default="0.22"/> <!-- not-in-map markers length, m -->
|
||||||
<arg name="map" default="map.txt"/> <!-- markers map file name -->
|
<arg name="map" default="map.txt"/> <!-- markers map file name -->
|
||||||
|
|
||||||
<!-- For additional help go to https://clover.coex.tech/aruco -->
|
<!-- For additional help go to https://clovercoex.tech/aruco -->
|
||||||
|
|
||||||
<arg name="force_init" default="false"/>
|
<arg name="force_init" default="false"/>
|
||||||
<arg name="disable" default="false"/> <!-- only force init -->
|
<arg name="disable" default="false"/> <!-- only force init -->
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<arg name="simulator" default="false"/>
|
<arg name="simulator" default="false"/>
|
||||||
|
|
||||||
<!-- For additional help go to https://clover.coex.tech/led -->
|
<!-- For additional help go to https://clovercoex.tech/led -->
|
||||||
|
|
||||||
<!-- ws281x led strip driver -->
|
<!-- ws281x led strip driver -->
|
||||||
<node pkg="ws281x" name="led" type="ws281x_node" clear_params="true" output="screen" if="$(eval ws281x and not simulator)">
|
<node pkg="ws281x" name="led" type="ws281x_node" clear_params="true" output="screen" if="$(eval ws281x and not simulator)">
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
<launch>
|
<launch>
|
||||||
<!-- article about camera setup: https://clover.coex.tech/camera_setup -->
|
<!-- article about camera setup: https://clovercoex.tech/camera_setup -->
|
||||||
|
|
||||||
<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="type" default="libcamera"/> <!-- camera interface: libcamera, v4l2 -->
|
<arg name="device" default="/dev/video0"/> <!-- v4l2 device -->
|
||||||
<arg name="camera_id" default="0"/> <!-- libcamera camera id -->
|
|
||||||
<arg name="device" default="/dev/video0"/> <!-- v4l2 device path -->
|
|
||||||
<arg name="width" default="320"/>
|
|
||||||
<arg name="height" default="240"/>
|
|
||||||
<arg name="fps" default="40"/>
|
|
||||||
<arg name="throttled_topic" default="true"/> <!-- enable throttled image topic -->
|
<arg name="throttled_topic" default="true"/> <!-- enable throttled image topic -->
|
||||||
<arg name="throttled_topic_rate" default="5.0"/> <!-- throttled image topic rate -->
|
<arg name="throttled_topic_rate" default="5.0"/> <!-- throttled image topic rate -->
|
||||||
<arg name="rectify" default="false"/> <!-- enable rectification -->
|
<arg name="rectify" default="false"/> <!-- enable rectification -->
|
||||||
@@ -31,34 +26,20 @@
|
|||||||
<param name="num_worker_threads" value="2"/>
|
<param name="num_worker_threads" value="2"/>
|
||||||
</node>
|
</node>
|
||||||
|
|
||||||
<!-- camera node using libcamera -->
|
<!-- camera node -->
|
||||||
<node pkg="nodelet" type="nodelet" name="main_camera" args="load libcamera_ros/LibcameraRos main_camera_nodelet_manager" output="screen" clear_params="true" if="$(eval not simulator and type == 'libcamera')" respawn="true">
|
<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="camera_name" value=""/>
|
|
||||||
<param name="camera_id" value="$(arg camera_id)"/>
|
|
||||||
<param name="frame_id" value="main_camera_optical"/>
|
|
||||||
<param name="calib_url" type="string" value="file://$(find clover)/camera_info/fisheye_cam_$(arg width)x$(arg height).yaml"/>
|
|
||||||
<param name="stream_role" value="still"/>
|
|
||||||
<param name="pixel_format" value="RGB888"/>
|
|
||||||
<param name="use_ros_time" value="true"/>
|
|
||||||
<param name="resolution/width" value="$(arg width)"/>
|
|
||||||
<param name="resolution/height" value="$(arg height)"/>
|
|
||||||
|
|
||||||
<!-- see: https://github.com/ctu-mrs/libcamera_ros/blob/b3645/config/param.yaml#L19 -->
|
|
||||||
<param name="control/fps" value="$(arg fps)"/>
|
|
||||||
</node>
|
|
||||||
|
|
||||||
<!-- old camera node for v4l2 (cv_camera) -->
|
|
||||||
<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" if="$(eval not simulator and type == 'v4l2')" respawn="true">
|
|
||||||
<param name="device_path" value="$(arg 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"/>
|
||||||
|
|
||||||
<param name="rate" value="100"/> <!-- poll rate -->
|
<param name="rate" value="100"/> <!-- poll rate -->
|
||||||
<param name="cv_cap_prop_fps" value="$(arg fps)"/> <!-- camera FPS -->
|
<param name="cv_cap_prop_fps" value="40"/> <!-- camera FPS -->
|
||||||
<param name="capture_delay" value="0.02"/> <!-- approximate delay on frame retrieving -->
|
<param name="capture_delay" value="0.02"/> <!-- approximate delay on frame retrieving -->
|
||||||
<param name="rescale_camera_info" value="true"/> <!-- automatically rescale camera calibration info -->
|
<param name="rescale_camera_info" value="true"/> <!-- automatically rescale camera calibration info -->
|
||||||
<param name="image_width" value="$(arg width)"/>
|
|
||||||
<param name="image_height" value="$(arg height)"/>
|
<!-- camera resolution -->
|
||||||
|
<param name="image_width" value="320"/>
|
||||||
|
<param name="image_height" value="240"/>
|
||||||
</node>
|
</node>
|
||||||
|
|
||||||
<!-- camera visualization markers -->
|
<!-- camera visualization markers -->
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<package format="3">
|
<package format="3">
|
||||||
<name>clover</name>
|
<name>clover</name>
|
||||||
<version>0.24.0</version>
|
<version>0.25.0</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>
|
||||||
<license>MIT</license>
|
<license>MIT</license>
|
||||||
|
|
||||||
<url type="website">https://clover.coex.tech/</url>
|
<url type="website">https://clovercoex.tech/</url>
|
||||||
<author email="okalachev@gmail.com">Oleg Kalachev</author>
|
<author email="okalachev@gmail.com">Oleg Kalachev</author>
|
||||||
<author email="urpylka@gmail.com">Artem Smirnov</author>
|
<author email="urpylka@gmail.com">Artem Smirnov</author>
|
||||||
|
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ def check_fcu():
|
|||||||
info(line[len('HW arch: '):])
|
info(line[len('HW arch: '):])
|
||||||
|
|
||||||
if not clover_fw:
|
if not clover_fw:
|
||||||
info('not Clover PX4 firmware, check https://clover.coex.tech/firmware')
|
info('not Clover PX4 firmware, check https://clovercoex.tech/firmware')
|
||||||
|
|
||||||
est = get_param('SYS_MC_EST_GROUP')
|
est = get_param('SYS_MC_EST_GROUP')
|
||||||
if est == 1:
|
if est == 1:
|
||||||
@@ -300,7 +300,7 @@ def check_fcu():
|
|||||||
try:
|
try:
|
||||||
battery = rospy.wait_for_message('mavros/battery', BatteryState, timeout=3)
|
battery = rospy.wait_for_message('mavros/battery', BatteryState, timeout=3)
|
||||||
if not battery.cell_voltage:
|
if not battery.cell_voltage:
|
||||||
failure('cell voltage is not available, https://clover.coex.tech/power')
|
failure('cell voltage is not available, https://clovercoex.tech/power')
|
||||||
else:
|
else:
|
||||||
cell = battery.cell_voltage[0]
|
cell = battery.cell_voltage[0]
|
||||||
# number of cells 1 means this is overall voltage
|
# number of cells 1 means this is overall voltage
|
||||||
@@ -312,7 +312,7 @@ def check_fcu():
|
|||||||
cell /= n_cells
|
cell /= n_cells
|
||||||
|
|
||||||
if cell > 4.3 or cell < 3.0:
|
if cell > 4.3 or cell < 3.0:
|
||||||
failure('incorrect cell voltage: %.2f V, https://clover.coex.tech/power', cell)
|
failure('incorrect cell voltage: %.2f V, https://clovercoex.tech/power', cell)
|
||||||
elif cell < 3.7:
|
elif cell < 3.7:
|
||||||
failure('critically low cell voltage: %.2f V, recharge battery', cell)
|
failure('critically low cell voltage: %.2f V, recharge battery', cell)
|
||||||
except rospy.ROSException:
|
except rospy.ROSException:
|
||||||
@@ -881,7 +881,7 @@ def check_network():
|
|||||||
if ros_hostname in parts:
|
if ros_hostname in parts:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
failure('not found %s in /etc/hosts, ROS will malfunction if network interfaces are down, https://clover.coex.tech/hostname', ros_hostname)
|
failure('not found %s in /etc/hosts, ROS will malfunction if network interfaces are down, https://clovercoex.tech/hostname', ros_hostname)
|
||||||
|
|
||||||
|
|
||||||
@check('RPi health')
|
@check('RPi health')
|
||||||
|
|||||||
@@ -646,7 +646,7 @@ inline void checkState()
|
|||||||
throw std::runtime_error("State timeout, check mavros settings");
|
throw std::runtime_error("State timeout, check mavros settings");
|
||||||
|
|
||||||
if (!state.connected)
|
if (!state.connected)
|
||||||
throw std::runtime_error("No connection to FCU, https://clover.coex.tech/connection");
|
throw std::runtime_error("No connection to FCU, https://clovercoex.tech/connection");
|
||||||
}
|
}
|
||||||
|
|
||||||
void publishState()
|
void publishState()
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
# Copyright (C) 2024 Copter Express Technologies
|
|
||||||
#
|
|
||||||
# Author: Oleg Kalachev <okalachev@gmail.com>
|
|
||||||
#
|
|
||||||
# Distributed under MIT License (available at https://opensource.org/licenses/MIT).
|
|
||||||
# The above copyright notice and this permission notice shall be included in all
|
|
||||||
# copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
"""Rescale camera info
|
|
||||||
|
|
||||||
Rescale camera info files for different resolutions.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
rescale_camera_info.py <camera_info_file>
|
|
||||||
rescale_camera_info.py (-h | --help)
|
|
||||||
|
|
||||||
Options:
|
|
||||||
<camera_info_file> Path to the source camera info file
|
|
||||||
|
|
||||||
Example:
|
|
||||||
rescale_camera_info.py camera_info.yaml
|
|
||||||
"""
|
|
||||||
|
|
||||||
from docopt import docopt
|
|
||||||
import yaml
|
|
||||||
|
|
||||||
arguments = docopt(__doc__)
|
|
||||||
|
|
||||||
camera_info = yaml.safe_load(open(arguments['<camera_info_file>']))
|
|
||||||
RESOLUTIONS = (
|
|
||||||
(320, 240), # QVGA
|
|
||||||
(640, 480), # VGA
|
|
||||||
(800, 600), # SVGA
|
|
||||||
(1280, 720), # HD
|
|
||||||
(1920, 1080), # FullHD
|
|
||||||
(2592, 1944), # 5MP
|
|
||||||
(3840, 2160), # 4K
|
|
||||||
(4056, 3040),
|
|
||||||
)
|
|
||||||
# TODO: retrieve resolutions list (v4l2-ctl --list-formats-ext)
|
|
||||||
|
|
||||||
for resolution in RESOLUTIONS:
|
|
||||||
width_k = resolution[0] / camera_info['image_width']
|
|
||||||
height_k = resolution[1] / camera_info['image_height']
|
|
||||||
|
|
||||||
camera_info_rescaled = camera_info.copy()
|
|
||||||
camera_info_rescaled['image_width'] = resolution[0]
|
|
||||||
camera_info_rescaled['image_height'] = resolution[1]
|
|
||||||
|
|
||||||
# See http://docs.ros.org/api/sensor_msgs/html/msg/CameraInfo.html for clarification
|
|
||||||
camera_info_rescaled['camera_matrix']['data'][0] *= width_k
|
|
||||||
camera_info_rescaled['camera_matrix']['data'][2] *= width_k
|
|
||||||
camera_info_rescaled['camera_matrix']['data'][4] *= height_k
|
|
||||||
camera_info_rescaled['camera_matrix']['data'][5] *= height_k
|
|
||||||
|
|
||||||
camera_info_rescaled['projection_matrix']['data'][0] *= width_k
|
|
||||||
camera_info_rescaled['projection_matrix']['data'][2] *= width_k
|
|
||||||
camera_info_rescaled['projection_matrix']['data'][5] *= height_k
|
|
||||||
camera_info_rescaled['projection_matrix']['data'][6] *= height_k
|
|
||||||
|
|
||||||
output_file = arguments['<camera_info_file>'].replace('.yaml', '_{}x{}.yaml'.format(resolution[0], resolution[1]))
|
|
||||||
with open(output_file, 'w') as f:
|
|
||||||
f.write('# Generated from {} by rescale_camera_info.py\n'.format(arguments['<camera_info_file>']))
|
|
||||||
yaml.dump(camera_info_rescaled, f)
|
|
||||||
|
|
||||||
print('Saved {}'.format(output_file))
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<h1>Clover Drone Kit Tools</h1>
|
<h1>Clover Drone Kit Tools</h1>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="docs">View documentation</a> (snapshot of <a href="https://clover.coex.tech">clover.coex.tech</a>)</li>
|
<li><a href="docs">View documentation</a> (snapshot of <a href="https://clovercoex.tech">clovercoex.tech</a>)</li>
|
||||||
<li><a href="topics.html">View topics</a></li>
|
<li><a href="topics.html">View topics</a></li>
|
||||||
<li><a href="" id="wvs">View image topics</a> (<code>web_video_server</code>)</li>
|
<li><a href="" id="wvs">View image topics</a> (<code>web_video_server</code>)</li>
|
||||||
<li><a href="" id="butterfly">Open web terminal</a> (<code>Butterfly</code>)</li>
|
<li><a href="" id="butterfly">Open web terminal</a> (<code>Butterfly</code>)</li>
|
||||||
|
|||||||
236
clover/www/js/json-to-pretty-yaml.js
vendored
236
clover/www/js/json-to-pretty-yaml.js
vendored
@@ -1,236 +0,0 @@
|
|||||||
// Browserified https://www.npmjs.com/package/json-to-pretty-yaml module
|
|
||||||
|
|
||||||
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|
||||||
(function() {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var typeOf = require('remedial').typeOf;
|
|
||||||
var trimWhitespace = require('remove-trailing-spaces');
|
|
||||||
|
|
||||||
function stringify(data) {
|
|
||||||
var handlers, indentLevel = '';
|
|
||||||
|
|
||||||
handlers = {
|
|
||||||
"undefined": function() {
|
|
||||||
// objects will not have `undefined` converted to `null`
|
|
||||||
// as this may have unintended consequences
|
|
||||||
// For arrays, however, this behavior seems appropriate
|
|
||||||
return 'null';
|
|
||||||
},
|
|
||||||
"null": function() {
|
|
||||||
return 'null';
|
|
||||||
},
|
|
||||||
"number": function(x) {
|
|
||||||
return x;
|
|
||||||
},
|
|
||||||
"boolean": function(x) {
|
|
||||||
return x ? 'true' : 'false';
|
|
||||||
},
|
|
||||||
"string": function(x) {
|
|
||||||
// to avoid the string "true" being confused with the
|
|
||||||
// the literal `true`, we always wrap strings in quotes
|
|
||||||
return JSON.stringify(x);
|
|
||||||
},
|
|
||||||
"array": function(x) {
|
|
||||||
var output = '';
|
|
||||||
|
|
||||||
if (0 === x.length) {
|
|
||||||
output += '[]';
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
indentLevel = indentLevel.replace(/$/, ' ');
|
|
||||||
x.forEach(function(y, i) {
|
|
||||||
// TODO how should `undefined` be handled?
|
|
||||||
var handler = handlers[typeOf(y)];
|
|
||||||
|
|
||||||
if (!handler) {
|
|
||||||
throw new Error('what the crap: ' + typeOf(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
output += '\n' + indentLevel + '- ' + handler(y, true);
|
|
||||||
|
|
||||||
});
|
|
||||||
indentLevel = indentLevel.replace(/ /, '');
|
|
||||||
|
|
||||||
return output;
|
|
||||||
},
|
|
||||||
"object": function(x, inArray, rootNode) {
|
|
||||||
var output = '';
|
|
||||||
|
|
||||||
if (0 === Object.keys(x).length) {
|
|
||||||
output += '{}';
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rootNode) {
|
|
||||||
indentLevel = indentLevel.replace(/$/, ' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.keys(x).forEach(function(k, i) {
|
|
||||||
var val = x[k],
|
|
||||||
handler = handlers[typeOf(val)];
|
|
||||||
|
|
||||||
if ('undefined' === typeof val) {
|
|
||||||
// the user should do
|
|
||||||
// delete obj.key
|
|
||||||
// and not
|
|
||||||
// obj.key = undefined
|
|
||||||
// but we'll error on the side of caution
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!handler) {
|
|
||||||
throw new Error('what the crap: ' + typeOf(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(inArray && i === 0)) {
|
|
||||||
output += '\n' + indentLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
output += k + ': ' + handler(val);
|
|
||||||
});
|
|
||||||
indentLevel = indentLevel.replace(/ /, '');
|
|
||||||
|
|
||||||
return output;
|
|
||||||
},
|
|
||||||
"function": function() {
|
|
||||||
// TODO this should throw or otherwise be ignored
|
|
||||||
return '[object Function]';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return trimWhitespace(handlers[typeOf(data)](data, true, true) + '\n');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
window.yamlStringify = stringify;
|
|
||||||
module.exports.stringify = stringify;
|
|
||||||
}());
|
|
||||||
|
|
||||||
},{"remedial":2,"remove-trailing-spaces":3}],2:[function(require,module,exports){
|
|
||||||
/*jslint onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true */
|
|
||||||
(function () {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var global = Function('return this')()
|
|
||||||
, classes = "Boolean Number String Function Array Date RegExp Object".split(" ")
|
|
||||||
, i
|
|
||||||
, name
|
|
||||||
, class2type = {}
|
|
||||||
;
|
|
||||||
|
|
||||||
for (i in classes) {
|
|
||||||
if (classes.hasOwnProperty(i)) {
|
|
||||||
name = classes[i];
|
|
||||||
class2type["[object " + name + "]"] = name.toLowerCase();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function typeOf(obj) {
|
|
||||||
return (null === obj || undefined === obj) ? String(obj) : class2type[Object.prototype.toString.call(obj)] || "object";
|
|
||||||
}
|
|
||||||
|
|
||||||
function isEmpty(o) {
|
|
||||||
var i, v;
|
|
||||||
if (typeOf(o) === 'object') {
|
|
||||||
for (i in o) { // fails jslint
|
|
||||||
v = o[i];
|
|
||||||
if (v !== undefined && typeOf(v) !== 'function') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!String.prototype.entityify) {
|
|
||||||
String.prototype.entityify = function () {
|
|
||||||
return this.replace(/&/g, "&").replace(/</g,
|
|
||||||
"<").replace(/>/g, ">");
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!String.prototype.quote) {
|
|
||||||
String.prototype.quote = function () {
|
|
||||||
var c, i, l = this.length, o = '"';
|
|
||||||
for (i = 0; i < l; i += 1) {
|
|
||||||
c = this.charAt(i);
|
|
||||||
if (c >= ' ') {
|
|
||||||
if (c === '\\' || c === '"') {
|
|
||||||
o += '\\';
|
|
||||||
}
|
|
||||||
o += c;
|
|
||||||
} else {
|
|
||||||
switch (c) {
|
|
||||||
case '\b':
|
|
||||||
o += '\\b';
|
|
||||||
break;
|
|
||||||
case '\f':
|
|
||||||
o += '\\f';
|
|
||||||
break;
|
|
||||||
case '\n':
|
|
||||||
o += '\\n';
|
|
||||||
break;
|
|
||||||
case '\r':
|
|
||||||
o += '\\r';
|
|
||||||
break;
|
|
||||||
case '\t':
|
|
||||||
o += '\\t';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c = c.charCodeAt();
|
|
||||||
o += '\\u00' + Math.floor(c / 16).toString(16) +
|
|
||||||
(c % 16).toString(16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return o + '"';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!String.prototype.supplant) {
|
|
||||||
String.prototype.supplant = function (o) {
|
|
||||||
return this.replace(/{([^{}]*)}/g,
|
|
||||||
function (a, b) {
|
|
||||||
var r = o[b];
|
|
||||||
return typeof r === 'string' || typeof r === 'number' ? r : a;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!String.prototype.trim) {
|
|
||||||
String.prototype.trim = function () {
|
|
||||||
return this.replace(/^\s*(\S*(?:\s+\S+)*)\s*$/, "$1");
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// CommonJS / npm / Ender.JS
|
|
||||||
module.exports = {
|
|
||||||
typeOf: typeOf,
|
|
||||||
isEmpty: isEmpty
|
|
||||||
};
|
|
||||||
global.typeOf = global.typeOf || typeOf;
|
|
||||||
global.isEmpty = global.isEmpty || isEmpty;
|
|
||||||
}());
|
|
||||||
|
|
||||||
},{}],3:[function(require,module,exports){
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* removeTrailingSpaces
|
|
||||||
* Remove the trailing spaces from a string.
|
|
||||||
*
|
|
||||||
* @name removeTrailingSpaces
|
|
||||||
* @function
|
|
||||||
* @param {String} input The input string.
|
|
||||||
* @returns {String} The output string.
|
|
||||||
*/
|
|
||||||
|
|
||||||
module.exports = function removeTrailingSpaces(input) {
|
|
||||||
// TODO If possible, use a regex
|
|
||||||
return input.split("\n").map(function (x) {
|
|
||||||
return x.trimRight();
|
|
||||||
}).join("\n");
|
|
||||||
};
|
|
||||||
},{}]},{},[1]);
|
|
||||||
@@ -64,8 +64,11 @@ function viewTopic(topic) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let txt = `<div class=counter>${counter} received</div>${yamlStringify(msg)}`; // JSON.stringify(msg, null, 4);
|
let width = Number(params.width) || 100;
|
||||||
topicMessage.innerHTML = txt;
|
let indent = Number(params.indent) || 2;
|
||||||
|
let txt = YAML.stringify(msg, { lineWidth: width, indent: indent });
|
||||||
|
let html = `<div class=counter>${counter} received</div>${txt}`; // JSON.stringify(msg, null, 4);
|
||||||
|
topicMessage.innerHTML = html;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
19
clover/www/js/yaml.js
Normal file
19
clover/www/js/yaml.js
Normal file
File diff suppressed because one or more lines are too long
@@ -4,7 +4,7 @@
|
|||||||
<script src="js/roslib.js"></script>
|
<script src="js/roslib.js"></script>
|
||||||
<link rel="icon" href="data:,"> <!-- make chrome don't request icon -->
|
<link rel="icon" href="data:,"> <!-- make chrome don't request icon -->
|
||||||
<script type="module" src="js/topics.js"></script>
|
<script type="module" src="js/topics.js"></script>
|
||||||
<script src="js/json-to-pretty-yaml.js"></script>
|
<script src="js/yaml.js"></script>
|
||||||
<style>
|
<style>
|
||||||
#topics { line-height: 1.2em; }
|
#topics { line-height: 1.2em; }
|
||||||
#topic-view {
|
#topic-view {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Blockly programming support for Clover.
|
|||||||
|
|
||||||
<img src="screenshot.png" width=700>
|
<img src="screenshot.png" width=700>
|
||||||
|
|
||||||
See user documentation at the [main Clover documentation site](https://clover.coex.tech/en/blocks.html).
|
See user documentation at the [main Clover documentation site](https://clovercoex.tech/en/blocks.html).
|
||||||
|
|
||||||
Internal package documentation is given below.
|
Internal package documentation is given below.
|
||||||
|
|
||||||
|
|||||||
@@ -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.24.0</version>
|
<version>0.25.0</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>
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ def load(req):
|
|||||||
return {'names': [], 'programs': [], 'message': str(e)}
|
return {'names': [], 'programs': [], 'message': str(e)}
|
||||||
|
|
||||||
|
|
||||||
name_regexp = re.compile(r'^[a-zA-Z-_.]{0,20}$')
|
name_regexp = re.compile(r'^[a-zA-Z1-9-_.]{0,30}$')
|
||||||
|
|
||||||
def store(req):
|
def store(req):
|
||||||
if not name_regexp.match(req.name):
|
if not name_regexp.match(req.name):
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const COLOR_FLIGHT = 293;
|
|||||||
const COLOR_STATE = 36;
|
const COLOR_STATE = 36;
|
||||||
const COLOR_LED = 143;
|
const COLOR_LED = 143;
|
||||||
const COLOR_GPIO = 200;
|
const COLOR_GPIO = 200;
|
||||||
const DOCS_URL = 'https://clover.coex.tech/en/blocks.html';
|
const DOCS_URL = 'https://clovercoex.tech/en/blocks.html';
|
||||||
|
|
||||||
var frameIds = [["body", "BODY"], ["markers map", "ARUCO_MAP"], ["marker", "ARUCO"], ["last navigate target", "NAVIGATE_TARGET"], ["map", "MAP"]];
|
var frameIds = [["body", "BODY"], ["markers map", "ARUCO_MAP"], ["marker", "ARUCO"], ["last navigate target", "NAVIGATE_TARGET"], ["map", "MAP"]];
|
||||||
var frameIdsWithTerrain = frameIds.concat([["terrain", "TERRAIN"]]);
|
var frameIdsWithTerrain = frameIds.concat([["terrain", "TERRAIN"]]);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<package format="2">
|
<package format="2">
|
||||||
<name>clover_description</name>
|
<name>clover_description</name>
|
||||||
<version>0.24.0</version>
|
<version>0.25.0</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>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<package format="3">
|
<package format="3">
|
||||||
<name>clover_simulation</name>
|
<name>clover_simulation</name>
|
||||||
<version>0.24.0</version>
|
<version>0.25.0</version>
|
||||||
<description>The clover_simulation package provides worlds and launch files for Gazebo.</description>
|
<description>The clover_simulation package provides worlds and launch files for Gazebo.</description>
|
||||||
|
|
||||||
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
||||||
|
|||||||
@@ -12,4 +12,4 @@ If you have studied the documentation but have not found an answer to your quest
|
|||||||
|
|
||||||
We also have a chat for programmers coding for PX4, autonomous navigation indoors, and drone swarms: [@DroneCode](tg://resolve?domain=DroneCode).
|
We also have a chat for programmers coding for PX4, autonomous navigation indoors, and drone swarms: [@DroneCode](tg://resolve?domain=DroneCode).
|
||||||
|
|
||||||
You can download [PDF-version](https://clover.coex.tech/clover_en.pdf) of this documentation.
|
You can download [PDF-version](https://clovercoex.tech/clover_en.pdf) of this documentation.
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ Main documentation: http://wiki.ros.org/roslaunch.
|
|||||||
|
|
||||||
The list of nodes / programs declared for running is specified in file `/home/pi/catkin_ws/src/clover/clover/launch/clover.launch`.
|
The list of nodes / programs declared for running is specified in file `/home/pi/catkin_ws/src/clover/clover/launch/clover.launch`.
|
||||||
|
|
||||||
You can add your own node to the list of automatically launched ones. To do this, place your executable file (e.g. `my_program.py`) into folder `/home/pi/catkin_ws/src/clover/clover/src`. Then add the start of your node to `clover.launch`, for example:
|
You can add your own node to the list of automatically launched ones. To do this, place your executable file (e.g. `my_program.py`) into folder `/home/pi/catkin_ws/src/clover/clover`. Then add the start of your node to `clover.launch`, for example:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<node name="my_program" pkg="clover" type="my_program.py" output="screen"/>
|
<node name="my_program" pkg="clover" type="my_program.py" output="screen"/>
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ Prepare your article and send it as a pull request to the [Clover repository](ht
|
|||||||
<img src="../assets/github-pull-request-create.png" alt="GitHub Create Pull">
|
<img src="../assets/github-pull-request-create.png" alt="GitHub Create Pull">
|
||||||
|
|
||||||
10. Wait for the review, be ready to make changes if needed.
|
10. Wait for the review, be ready to make changes if needed.
|
||||||
11. Look at your new and useful article at https://clover.coex.tech !
|
11. Look at your new and useful article at https://clovercoex.tech !
|
||||||
|
|
||||||
## Easy way
|
## Easy way
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ See all points by criteria in the [full table](https://docs.google.com/spreadshe
|
|||||||
Teams are welcome to dive into the development of the following company cases:
|
Teams are welcome to dive into the development of the following company cases:
|
||||||
|
|
||||||
1. Develop the Pixhawk FMUv6U flight controller board with the dimensions 55x40 mm and the compatibility of a Raspberry Pi CM 4 installation.
|
1. Develop the Pixhawk FMUv6U flight controller board with the dimensions 55x40 mm and the compatibility of a Raspberry Pi CM 4 installation.
|
||||||
2. Cloud platform for the [Clover simulator](https://clover.coex.tech/ru/simulation.html) similar as to/based on [ROS Development Studio](https://app.theconstructsim.com/).
|
2. Cloud platform for the [Clover simulator](https://clovercoex.tech/ru/simulation.html) similar as to/based on [ROS Development Studio](https://app.theconstructsim.com/).
|
||||||
|
|
||||||
The list of cases may be expanded in future.
|
The list of cases may be expanded in future.
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ The main goal of the contest is aerial robotics popularization and community de
|
|||||||
### Lecture requirements
|
### Lecture requirements
|
||||||
|
|
||||||
* The topic of the lecture is of free choice. Programmable quadcopter kit COEX Clover 4 and/or The Clover simulation environment should be used as the main tool in the lecture.
|
* The topic of the lecture is of free choice. Programmable quadcopter kit COEX Clover 4 and/or The Clover simulation environment should be used as the main tool in the lecture.
|
||||||
> **Note** *The version of COEX Clover is not earlier than [version 4](https://clover.coex.tech/en/assemble_4.html). The virtual machine image is not earlier than [version 1.0](https://github.com/CopterExpress/clover_vm/releases/tag/v1.0).
|
> **Note** *The version of COEX Clover is not earlier than [version 4](https://clovercoex.tech/en/assemble_4.html). The virtual machine image is not earlier than [version 1.0](https://github.com/CopterExpress/clover_vm/releases/tag/v1.0).
|
||||||
* The video is uploaded on YouTube or another public platform and is public accessible.
|
* The video is uploaded on YouTube or another public platform and is public accessible.
|
||||||
* The language of the lecture is any. The video contains subtitles in English in case the language is made neither of English nor Russian.
|
* The language of the lecture is any. The video contains subtitles in English in case the language is made neither of English nor Russian.
|
||||||
* The duration of the lecture is limited from 15 min. to 3 hours.
|
* The duration of the lecture is limited from 15 min. to 3 hours.
|
||||||
@@ -47,7 +47,7 @@ The main goal of the contest is aerial robotics popularization and community de
|
|||||||
### Lesson requirements
|
### Lesson requirements
|
||||||
|
|
||||||
* Programmable quadcopter kit COEX Clover 4 should be used as the main tool for the lesson.
|
* Programmable quadcopter kit COEX Clover 4 should be used as the main tool for the lesson.
|
||||||
> **Note** *The version of COEX Clover is not earlier than [version 4](https://clover.coex.tech/en/assemble_4.html).
|
> **Note** *The version of COEX Clover is not earlier than [version 4](https://clovercoex.tech/en/assemble_4.html).
|
||||||
* Integration of the quadcopter into any of the general education disciplines (physics, mathematics, computer science, etc.).
|
* Integration of the quadcopter into any of the general education disciplines (physics, mathematics, computer science, etc.).
|
||||||
* Practical use of the main tool in the lesson.
|
* Practical use of the main tool in the lesson.
|
||||||
* Grade - no restrictions (primary, high school).
|
* Grade - no restrictions (primary, high school).
|
||||||
@@ -88,7 +88,7 @@ The course is evaluated according to a separate, publicly available lesson submi
|
|||||||
|
|
||||||
* The course is related to the direction of Aerial robotics.
|
* The course is related to the direction of Aerial robotics.
|
||||||
* Programmable quadcopter kit COEX Clover 4 and/or The Clover simulation environment should be used as the main tool in the course;
|
* Programmable quadcopter kit COEX Clover 4 and/or The Clover simulation environment should be used as the main tool in the course;
|
||||||
> **Note** *The version of COEX Clover is not earlier than [version 4](https://clover.coex.tech/en/assemble_4.html). The virtual machine image is not earlier than [version 1.0](https://github.com/CopterExpress/clover_vm/releases/tag/v1.0).
|
> **Note** *The version of COEX Clover is not earlier than [version 4](https://clovercoex.tech/en/assemble_4.html). The virtual machine image is not earlier than [version 1.0](https://github.com/CopterExpress/clover_vm/releases/tag/v1.0).
|
||||||
* The course is located on a public platform (e.g., Coursera).
|
* The course is located on a public platform (e.g., Coursera).
|
||||||
* The course can be either paid or free of charge. One public lesson from the course is submitted for the competition;
|
* The course can be either paid or free of charge. One public lesson from the course is submitted for the competition;
|
||||||
* The lesson submitted for the contest should be publicly accessible.
|
* The lesson submitted for the contest should be publicly accessible.
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ Before you test it you need to install on your laptop:
|
|||||||
- Install Nodejs from [here](https://nodejs.org/en/download/). For [Ubuntu installation](https://tecadmin.net/install-latest-nodejs-npm-on-ubuntu/)
|
- Install Nodejs from [here](https://nodejs.org/en/download/). For [Ubuntu installation](https://tecadmin.net/install-latest-nodejs-npm-on-ubuntu/)
|
||||||
- Install Yarn package manager from [here](https://yarnpkg.com/lang/en/docs/install/). [Usual problem](https://github.com/yarnpkg/yarn/issues/3189) while installing and using yarn with Ubuntu.
|
- Install Yarn package manager from [here](https://yarnpkg.com/lang/en/docs/install/). [Usual problem](https://github.com/yarnpkg/yarn/issues/3189) while installing and using yarn with Ubuntu.
|
||||||
- Have an experience in manual control on the drone in case of any weird behavior happen.
|
- Have an experience in manual control on the drone in case of any weird behavior happen.
|
||||||
- Worked before with COEX drones, if this is your first time to work with COEX drones check [this](https://clover.coex.tech/en/).
|
- Worked before with COEX drones, if this is your first time to work with COEX drones check [this](https://clovercoex.tech/en/).
|
||||||
|
|
||||||
and you are ready to build and use the required codes.
|
and you are ready to build and use the required codes.
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ Animation is created by [this](https://justsketchme.web.app/)
|
|||||||
## References
|
## References
|
||||||
|
|
||||||
- [Human pose estimation guide](https://blog.nanonets.com/human-pose-estimation-2d-guide/)
|
- [Human pose estimation guide](https://blog.nanonets.com/human-pose-estimation-2d-guide/)
|
||||||
- [Clover drones tutorials](https://clover.coex.tech/en/)
|
- [Clover drones tutorials](https://clovercoex.tech/en/)
|
||||||
- [Posenet GitHub repo](https://github.com/tensorflow/tfjs-models/tree/master/posenet)
|
- [Posenet GitHub repo](https://github.com/tensorflow/tfjs-models/tree/master/posenet)
|
||||||
- [Posenet meduim article](https://medium.com/tensorflow/real-time-human-pose-estimation-in-the-browser-with-tensorflow-js-7dd0bc881cd5)
|
- [Posenet meduim article](https://medium.com/tensorflow/real-time-human-pose-estimation-in-the-browser-with-tensorflow-js-7dd0bc881cd5)
|
||||||
- [Tensorflow.js demos](https://www.tensorflow.org/js/demos)
|
- [Tensorflow.js demos](https://www.tensorflow.org/js/demos)
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ network={
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Inside the config file, general `wpa_supplicant` settings, and the settings for the adapter configuration are specified. The configuration file also contains `network` section with the basic settings of the Wi-Fi network, such as network SSID, password, adapter operating mode. There may be several `network` sections, but only the first valid one is used. For example, if the first section contains a connection to an unavailable network, the adapter will be configured according to a next valid section, if there is one. Read more about the syntax of `wpa_supplicant.conf` [TODO WIKI].
|
Inside the config file, general `wpa_supplicant` settings, and the settings for the adapter configuration are specified. The configuration file also contains `network` section with the basic settings of the Wi-Fi network, such as network SSID, password, adapter operating mode. There may be several `network` sections, but only the first valid one is used. For example, if the first section contains a connection to an unavailable network, the adapter will be configured according to a next valid section, if there is one. Read more about the syntax of `wpa_supplicant.conf` in the [Debian manual page](https://manpages.debian.org/buster/wpasupplicant/wpa_supplicant.conf.5.en.html).
|
||||||
|
|
||||||
#### wpa_passphrase
|
#### wpa_passphrase
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ The list of team members:
|
|||||||
|
|
||||||
<img src="https://github.com/den250400/potential-fields-obstacle-avoidance/raw/main/assets/avoidance_sim_demo.gif" class="center"/>
|
<img src="https://github.com/den250400/potential-fields-obstacle-avoidance/raw/main/assets/avoidance_sim_demo.gif" class="center"/>
|
||||||
|
|
||||||
[This](https://github.com/den250400/potential-fields-obstacle-avoidance) repository contains obstacle avoidance system for quadcopters with Raspberry Pi 4 onboard computer. The code in this repository is designed to work with [Clover Raspberry Pi image](https://clover.coex.tech/en/image.html) and [special PX4-based firmware](https://clover.coex.tech/en/firmware.html) modified for easier communication with Raspberry Pi.
|
[This](https://github.com/den250400/potential-fields-obstacle-avoidance) repository contains obstacle avoidance system for quadcopters with Raspberry Pi 4 onboard computer. The code in this repository is designed to work with [Clover Raspberry Pi image](https://clovercoex.tech/en/image.html) and [special PX4-based firmware](https://clovercoex.tech/en/firmware.html) modified for easier communication with Raspberry Pi.
|
||||||
|
|
||||||
Artificial potential fields method is based on considering quadcopter, obstacles and target point as electric-charged points. Quadcopter and obstacles have positive charge, and target point is assigned with negative charge. This results in quadcopter "attracting" itself to the target point, while being repelled by the same-signed charges of obstacles. Using this analogy, you can compute a safe, collision-free trajectory, which can be executed by the vehicle.
|
Artificial potential fields method is based on considering quadcopter, obstacles and target point as electric-charged points. Quadcopter and obstacles have positive charge, and target point is assigned with negative charge. This results in quadcopter "attracting" itself to the target point, while being repelled by the same-signed charges of obstacles. Using this analogy, you can compute a safe, collision-free trajectory, which can be executed by the vehicle.
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ It's obvious that you need some sort of geometrical information about the surrou
|
|||||||
|
|
||||||
This guide is intended to be used on Ubuntu 20.04. Python version is 3.8.10, but it's very likely that it will work on other versions like 3.7, 3.9, 3.10 without any changes.
|
This guide is intended to be used on Ubuntu 20.04. Python version is 3.8.10, but it's very likely that it will work on other versions like 3.7, 3.9, 3.10 without any changes.
|
||||||
|
|
||||||
1. Install the [Clover simulator](https://clover.coex.tech/en/simulation.html).
|
1. Install the [Clover simulator](https://clovercoex.tech/en/simulation.html).
|
||||||
2. Install [realsense_gazebo_plugin](https://github.com/issaiass/realsense_gazebo_plugin) and [realsense2_description](https://github.com/issaiass/realsense2_description):
|
2. Install [realsense_gazebo_plugin](https://github.com/issaiass/realsense_gazebo_plugin) and [realsense2_description](https://github.com/issaiass/realsense2_description):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -66,11 +66,11 @@ Flying forward for 1m:
|
|||||||
navigate(x=1.5, frame_id='body')
|
navigate(x=1.5, frame_id='body')
|
||||||
```
|
```
|
||||||
|
|
||||||
[Navigation using ArUco-markers](aruco_marker.md) and [using VPE] are available when using Optical Flow.
|
[Navigation using ArUco-markers](aruco_marker.md) and [using VPE](aruco_map.md) are available when using Optical Flow.
|
||||||
|
|
||||||
## Additional settings
|
## Additional settings
|
||||||
|
|
||||||
<!-- TODO: статья по пидам -->
|
For additional background on PID tuning, see the [PID tuning guide](calibratePID.md).
|
||||||
|
|
||||||
If the copter has an unstable position, try to increase the *P* coefficient of speed PID controller - parameters are `MPC_XY_VEL_P` and `MPC_Z_VEL_P`.
|
If the copter has an unstable position, try to increase the *P* coefficient of speed PID controller - parameters are `MPC_XY_VEL_P` and `MPC_Z_VEL_P`.
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ In case of using EKF2 (official firmware):
|
|||||||
|`EKF2_OF_N_MIN`|0.05||
|
|`EKF2_OF_N_MIN`|0.05||
|
||||||
|`EKF2_OF_N_MAX`|0.2||
|
|`EKF2_OF_N_MAX`|0.2||
|
||||||
|`EKF2_HGT_MODE`\*|3 (*Vision*)|If the [rangefinder](laser.md) is present and flying over horizontal floor – 2 (*Range sensor*)|
|
|`EKF2_HGT_MODE`\*|3 (*Vision*)|If the [rangefinder](laser.md) is present and flying over horizontal floor – 2 (*Range sensor*)|
|
||||||
|`EKF2_EVA_NOISE`|0.1||
|
|`EKF2_EVA_NOISE`|0.1 rad or 5 deg||
|
||||||
|`EKF2_EVP_NOISE`|0.1||
|
|`EKF2_EVP_NOISE`|0.1||
|
||||||
|`EKF2_EV_DELAY`|0||
|
|`EKF2_EV_DELAY`|0||
|
||||||
|`EKF2_MAG_TYPE`|5 (*None*)|Disabling usage of the magnetometer (when navigating indoor)|
|
|`EKF2_MAG_TYPE`|5 (*None*)|Disabling usage of the magnetometer (when navigating indoor)|
|
||||||
@@ -59,6 +59,7 @@ In case of using EKF2 (official firmware):
|
|||||||
|`EKF2_BARO_CTRL`|0 (*Disabled*)|Barometer is disabled|
|
|`EKF2_BARO_CTRL`|0 (*Disabled*)|Barometer is disabled|
|
||||||
|`EKF2_OF_CTRL`|1 (*Enabled*)|Optical flow is enabled|
|
|`EKF2_OF_CTRL`|1 (*Enabled*)|Optical flow is enabled|
|
||||||
|`EKF2_HGT_REF`|3 (*Vision*)|If the [rangefinder](laser.md) is present and flying over horizontal floor – 2 (*Range sensor*)|
|
|`EKF2_HGT_REF`|3 (*Vision*)|If the [rangefinder](laser.md) is present and flying over horizontal floor – 2 (*Range sensor*)|
|
||||||
|
|`EKF2_RNG_CTRL`|2 (*Enabled*)|Range sensor is enabled|
|
||||||
|
|
||||||
<!-- markdownlint-enable MD031 -->
|
<!-- markdownlint-enable MD031 -->
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,6 @@ The sticks on the screen of the application work just like real sticks. To arm t
|
|||||||
Malfunctions
|
Malfunctions
|
||||||
---
|
---
|
||||||
|
|
||||||
* If the interface of the transmitter displays a surely incorrect voltage (e.g., > 5 V), check that the value of PX4 parameter `BAT_N_CELLS` matches the actual number of battery cells. If the displayed voltage is still incorrect, calibrate the battery (TODO: link).
|
* If the interface of the transmitter displays a surely incorrect voltage (e.g., > 5 V), check that the value of PX4 parameter `BAT_N_CELLS` matches the actual number of battery cells. If the displayed voltage is still incorrect, calibrate the [power sensor](power.md).
|
||||||
|
|
||||||
* If instead of mode PX4, text "DISCONNECTED FROM FCU" is displayed, check [Raspberry Pi connection to Pixhawk](connection.md).
|
* If instead of mode PX4, text "DISCONNECTED FROM FCU" is displayed, check [Raspberry Pi connection to Pixhawk](connection.md).
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ Press the *Save* button to save the changed value to the flight controller. Chan
|
|||||||
* `MC_ROLLRATE_I` = 0.050
|
* `MC_ROLLRATE_I` = 0.050
|
||||||
* `MC_ROLLRATE_D` = 0.0025
|
* `MC_ROLLRATE_D` = 0.0025
|
||||||
|
|
||||||
> **Hint** Note that you should fine-tune the PID parameters for each drone individually. <!-- TODO: add PID article link -->
|
> **Hint** Note that you should fine-tune the PID parameters for each drone individually. See the [PID tuning guide](calibratePID.md).
|
||||||
|
|
||||||
#### Circuit breaker parameters
|
#### Circuit breaker parameters
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Autonomous flight
|
# Autonomous flight
|
||||||
|
|
||||||
> **Note** The following applies to the [image version **0.24**](https://github.com/CopterExpress/clover/releases/tag/v0.24), which is not yet released. Older documentation is still available for [for version **0.23**](https://github.com/CopterExpress/clover/blob/f78a03ec8943b596d5a99b893188a159d5319888/docs/en/simple_offboard.md).
|
> **Note** The following applies to [image versions](image.md) **0.24** and up. Older documentation is available for [for version **0.23**](https://github.com/CopterExpress/clover/blob/v0.23/docs/en/simple_offboard.md).
|
||||||
|
|
||||||
The `simple_offboard` module of the `clover` package is intended for simplified programming of the autonomous drone flight (`OFFBOARD` [flight mode](modes.md)). It allows setting the desired flight tasks, and automatically transforms [coordinates between frames](frames.md).
|
The `simple_offboard` module of the `clover` package is intended for simplified programming of the autonomous drone flight (`OFFBOARD` [flight mode](modes.md)). It allows setting the desired flight tasks, and automatically transforms [coordinates between frames](frames.md).
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ The recommended virtual machine hypervisor is [UTM app](https://mac.getutm.app/)
|
|||||||
|
|
||||||
<img src="../assets/simulation_ubuntu_account.png" width=400 class="center zoom">
|
<img src="../assets/simulation_ubuntu_account.png" width=400 class="center zoom">
|
||||||
|
|
||||||
6. Finish the installation and run the system.
|
6. Finish the installation and run the system (you need to eject the virtual CD or choose *Boot from next volume* in the boot menu).
|
||||||
7. Install the simulation using the [native setup manual](simulation_native.md).
|
7. Install the simulation using the [native setup manual](simulation_native.md).
|
||||||
|
|
||||||
### Troubleshooting
|
### Troubleshooting
|
||||||
|
|||||||
@@ -72,7 +72,11 @@ ln -s ~/PX4-Autopilot/Tools/sitl_gazebo ~/catkin_ws/src/
|
|||||||
ln -s ~/PX4-Autopilot/mavlink ~/catkin_ws/src/
|
ln -s ~/PX4-Autopilot/mavlink ~/catkin_ws/src/
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Hint** You may use more recent PX4 version, but there would be more risk of something would not be working.
|
> **Hint** You may use more recent PX4 version, but something may not work as expected in that case.
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
> **Note** If clone fails with network error (`fatal: fetch-pack: invalid index-pack output`), set HTTP version 1.1 using `git config --global http.version HTTP/1.1` command (don't forget to return it back after clone using `git config --global http.version HTTP/2`). Alternative solution is cloning the repository and submodules through SSH using `git config --global url."git@github.com:".insteadOf https://github.com/` command (requires setting up valid SSH key in GitHub profile settings).
|
||||||
|
|
||||||
## Install PX4 prerequisites
|
## Install PX4 prerequisites
|
||||||
|
|
||||||
@@ -115,10 +119,10 @@ Build your workspace:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/catkin_ws
|
cd ~/catkin_ws
|
||||||
catkin_make
|
catkin_make -j1
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note** If building fails with RAM issues (`c++: fatal error: Killed signal terminated program cc1plus`), reduce the number of parallel jobs using `-j` key. For example, to use only two parallel jobs use `catkin_make -j2` command.
|
> **Note** The `-j1` flag means that the build will not use parallel processes, as building with parallel processes on a virtual machine may run out of memory. If you have enough memory, you may not use this flag.
|
||||||
|
|
||||||
## Run the simulator
|
## Run the simulator
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ Swarm in Blocks is a CopterHack 2022 project. It's a high-level interface based
|
|||||||
<img width="500" src="https://raw.githubusercontent.com/Grupo-SEMEAR-USP/swarm_in_blocks/master/assets/intro/ring.gif" />
|
<img width="500" src="https://raw.githubusercontent.com/Grupo-SEMEAR-USP/swarm_in_blocks/master/assets/intro/ring.gif" />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
For more information on our project from last year, see our final article in [Swarm in Blocks 2022](https://clover.coex.tech/en/swarm_in_blocks.html). In addition, we also recommend watching our final video from last year, [Swarm in Blocks 2022 - Final Video](https://www.youtube.com/watch?v=5C-1rRnyiE8).
|
For more information on our project from last year, see our final article in [Swarm in Blocks 2022](https://clovercoex.tech/en/swarm_in_blocks.html). In addition, we also recommend watching our final video from last year, [Swarm in Blocks 2022 - Final Video](https://www.youtube.com/watch?v=5C-1rRnyiE8).
|
||||||
|
|
||||||
Even with the huge facilities that the block platform offers, we realized that this was just the *tip of the iceberg* when it comes to deploying real swarms. Several other operational and conceptual problems in validating a real swarm still haunted the general public. With that, this year's project comes precisely with the purpose of **tackling the main problems in validating a Swarm in a simple and polished way**.
|
Even with the huge facilities that the block platform offers, we realized that this was just the *tip of the iceberg* when it comes to deploying real swarms. Several other operational and conceptual problems in validating a real swarm still haunted the general public. With that, this year's project comes precisely with the purpose of **tackling the main problems in validating a Swarm in a simple and polished way**.
|
||||||
|
|
||||||
|
|||||||
@@ -14,4 +14,4 @@
|
|||||||
|
|
||||||
Чат по разработке самой платформы Клевера и образа для RPi: [@devclover](https://t.me/devclover).
|
Чат по разработке самой платформы Клевера и образа для RPi: [@devclover](https://t.me/devclover).
|
||||||
|
|
||||||
Вы можете скачать [PDF-версию](https://clover.coex.tech/clover_ru.pdf) этой документации. The English version of this documentation [is available](../en/).
|
Вы можете скачать [PDF-версию](https://clovercoex.tech/clover_ru.pdf) этой документации. The English version of this documentation [is available](../en/).
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
Разработка симулятора для Clover с возможностью создания workspace (окружения, позволяющие легко управлять и транспортировать файлы симулятора такие как: проекты, конфигурации, установленные пакеты).
|
Разработка симулятора для Clover с возможностью создания workspace (окружения, позволяющие легко управлять и транспортировать файлы симулятора такие как: проекты, конфигурации, установленные пакеты).
|
||||||
|
|
||||||
- Простой, быстрый и производительный способ запуска симулятора.
|
- Простой, быстрый и производительный способ запуска симулятора.
|
||||||
- Инструментарий для создания заданий (как на [IOR2020](https://clover.coex.tech/ru/innopolis_open_L22_AERO.html)).
|
- Инструментарий для создания заданий (как на [IOR2020](https://clovercoex.tech/ru/innopolis_open_L22_AERO.html)).
|
||||||
- Изоляция Gazebo и чекера заданий от Workspace пользователя и clover.
|
- Изоляция Gazebo и чекера заданий от Workspace пользователя и clover.
|
||||||
- Worker для проверки задач со степика.
|
- Worker для проверки задач со степика.
|
||||||
- Возможность запуска несколько коптеров каждый из которых имеет свой контейнер.
|
- Возможность запуска несколько коптеров каждый из которых имеет свой контейнер.
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ navigate(frame_id='aruco_5', x=0, y=0, z=1)
|
|||||||
|
|
||||||
## Дополнительные настройки
|
## Дополнительные настройки
|
||||||
|
|
||||||
<!-- TODO: статья по пидам -->
|
Дополнительную информацию по настройке PID см. в статье [Настройка коэффициентов PID](calibratePID.md).
|
||||||
|
|
||||||
Если коптер нестабильно удерживает позицию по VPE, попробуйте увеличить коэффициенты *P* PID-регулятора по скорости – параметры `MPC_XY_VEL_P` и `MPC_Z_VEL_P`.
|
Если коптер нестабильно удерживает позицию по VPE, попробуйте увеличить коэффициенты *P* PID-регулятора по скорости – параметры `MPC_XY_VEL_P` и `MPC_Z_VEL_P`.
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ roslaunch
|
|||||||
|
|
||||||
Список объявленных для запуска нод / программ указывается в файле `/home/pi/catkin_ws/src/clover/clover/launch/clover.launch`.
|
Список объявленных для запуска нод / программ указывается в файле `/home/pi/catkin_ws/src/clover/clover/launch/clover.launch`.
|
||||||
|
|
||||||
Вы можете добавить собственную ноду в список автозапускаемых. Для этого разместите ваш запускаемый файл (например, `my_program.py`) в каталог `/home/pi/catkin_ws/src/clover/clover/src`. Затем добавьте запуск вашей ноды в `clover.launch`, например:
|
Вы можете добавить собственную ноду в список автозапускаемых. Для этого разместите ваш запускаемый файл (например, `my_program.py`) в каталог `/home/pi/catkin_ws/src/clover/clover`. Затем добавьте запуск вашей ноды в `clover.launch`, например:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<node name="my_program" pkg="clover" type="my_program.py" output="screen"/>
|
<node name="my_program" pkg="clover" type="my_program.py" output="screen"/>
|
||||||
|
|||||||
@@ -91,7 +91,7 @@
|
|||||||
<img src="../assets/github-pull-request-create.png" alt="GitHub Create Pull">
|
<img src="../assets/github-pull-request-create.png" alt="GitHub Create Pull">
|
||||||
|
|
||||||
10. Дождитесь комментариев на свою статью, сделайте правки, если потребуется.
|
10. Дождитесь комментариев на свою статью, сделайте правки, если потребуется.
|
||||||
11. Порадуйтесь своей новой полезной статье, опубликованной на https://clover.coex.tech !
|
11. Порадуйтесь своей новой полезной статье, опубликованной на https://clovercoex.tech !
|
||||||
|
|
||||||
## Простой способ
|
## Простой способ
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ CopterHack 2022 — это международный конкурс по ра
|
|||||||
Команды приглашаются принять участие в работе над следующими кейсами компании:
|
Команды приглашаются принять участие в работе над следующими кейсами компании:
|
||||||
|
|
||||||
1. Разработка платы полетного контроллера Pixhawk FMUv6U размером 55*40 мм и возможностью установки Raspberry Pi CM4.
|
1. Разработка платы полетного контроллера Pixhawk FMUv6U размером 55*40 мм и возможностью установки Raspberry Pi CM4.
|
||||||
2. Облачная платформа для [симулятора Клевера](https://clover.coex.tech/ru/simulation.html) по аналогии или на основе [ROS Development Studio](https://app.theconstructsim.com/).
|
2. Облачная платформа для [симулятора Клевера](https://clovercoex.tech/ru/simulation.html) по аналогии или на основе [ROS Development Studio](https://app.theconstructsim.com/).
|
||||||
|
|
||||||
Список кейсов может быть расширен.
|
Список кейсов может быть расширен.
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
* Тематика лекции - открытая, на выбор участника (пример: сборка, настройка, программирование, лекция интегрированная в школьную программу и т.п.).
|
* Тематика лекции - открытая, на выбор участника (пример: сборка, настройка, программирование, лекция интегрированная в школьную программу и т.п.).
|
||||||
* Основной инструмент лекции - «Конструктор программируемого квадрокоптера «COEX Клевер 4» и/или «Симуляционная среда программируемого квадрокоптера Клевер».
|
* Основной инструмент лекции - «Конструктор программируемого квадрокоптера «COEX Клевер 4» и/или «Симуляционная среда программируемого квадрокоптера Клевер».
|
||||||
> **Note** *Версия «COEX Клевер» не ранее [4 версии](https://clover.coex.tech/ru/assemble_4.html). «Симуляционная среда программируемого квадрокоптера Клевер» - не ранее [версии 1.0](https://github.com/CopterExpress/clover_vm/releases/tag/v1.0).
|
> **Note** *Версия «COEX Клевер» не ранее [4 версии](https://clovercoex.tech/ru/assemble_4.html). «Симуляционная среда программируемого квадрокоптера Клевер» - не ранее [версии 1.0](https://github.com/CopterExpress/clover_vm/releases/tag/v1.0).
|
||||||
* Видео загружено на YouTube или иную общедоступную платформу, и находится в открытом доступе для любых пользователей;
|
* Видео загружено на YouTube или иную общедоступную платформу, и находится в открытом доступе для любых пользователей;
|
||||||
* Язык лекции - на выбор участника. Если язык лекции не русский/английский - наличие субтитров к видео на английском языке.
|
* Язык лекции - на выбор участника. Если язык лекции не русский/английский - наличие субтитров к видео на английском языке.
|
||||||
* Продолжительность лекции - от 15 мин. до 3 часов.
|
* Продолжительность лекции - от 15 мин. до 3 часов.
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
### Требования к уроку
|
### Требования к уроку
|
||||||
|
|
||||||
* Основной инструмент урока - «Конструктор программируемого квадрокоптера «COEX Клевер 4».
|
* Основной инструмент урока - «Конструктор программируемого квадрокоптера «COEX Клевер 4».
|
||||||
> **Note** *Версия «COEX Клевер» не ранее [4 версии](https://clover.coex.tech/ru/assemble_4.html).
|
> **Note** *Версия «COEX Клевер» не ранее [4 версии](https://clovercoex.tech/ru/assemble_4.html).
|
||||||
* Интеграция квадрокоптера в любую из общеобразовательных дисциплин (физика, математика, информатика, урок технологии и т.д.).
|
* Интеграция квадрокоптера в любую из общеобразовательных дисциплин (физика, математика, информатика, урок технологии и т.д.).
|
||||||
* Практическое использование основного инструмента на уроке.
|
* Практическое использование основного инструмента на уроке.
|
||||||
* Класс - без ограничений (начальная, основная школа).
|
* Класс - без ограничений (начальная, основная школа).
|
||||||
@@ -88,7 +88,7 @@
|
|||||||
|
|
||||||
* Направление курса - «Летающая робототехника».
|
* Направление курса - «Летающая робототехника».
|
||||||
* Основной инструмент курса - «Конструктор программируемого квадрокоптера «COEX Клевер 4» и/или «Симуляционная среда программируемого квадрокоптера Клевер».
|
* Основной инструмент курса - «Конструктор программируемого квадрокоптера «COEX Клевер 4» и/или «Симуляционная среда программируемого квадрокоптера Клевер».
|
||||||
> **Note** *Версия «COEX Клевер» не ранее [4 версии](https://clover.coex.tech/ru/assemble_4.html). «Симуляционная среда программируемого квадрокоптера Клевер» - не ранее [версии 1.0](https://github.com/CopterExpress/clover_vm/releases/tag/v1.0).
|
> **Note** *Версия «COEX Клевер» не ранее [4 версии](https://clovercoex.tech/ru/assemble_4.html). «Симуляционная среда программируемого квадрокоптера Клевер» - не ранее [версии 1.0](https://github.com/CopterExpress/clover_vm/releases/tag/v1.0).
|
||||||
* Курс расположен на общедоступной платформе (Stepik, Coursera и т.п.).
|
* Курс расположен на общедоступной платформе (Stepik, Coursera и т.п.).
|
||||||
* Доступ к курсу может быть как платный, так и бесплатный, на конкурс принимается один бесплатный и общедоступный урок заявленного курса.
|
* Доступ к курсу может быть как платный, так и бесплатный, на конкурс принимается один бесплатный и общедоступный урок заявленного курса.
|
||||||
* Заявленный на конкурс урок должен быть в открытом доступе.
|
* Заявленный на конкурс урок должен быть в открытом доступе.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
## Ссылки на литературу
|
## Ссылки на литературу
|
||||||
|
|
||||||
- [Руководство по оценке позы человека](https://blog.nanonets.com/human-pose-estimation-2d-guide/)
|
- [Руководство по оценке позы человека](https://blog.nanonets.com/human-pose-estimation-2d-guide/)
|
||||||
- [Умные беспилотники учебники](https://clover.coex.tech/en/)
|
- [Умные беспилотники учебники](https://clovercoex.tech/en/)
|
||||||
- [Posnet GitHub РЕПО](https://github.com/tensorflow/tfjs-models/tree/master/posenet)
|
- [Posnet GitHub РЕПО](https://github.com/tensorflow/tfjs-models/tree/master/posenet)
|
||||||
- [Posnet Medium артикул](https://medium.com/tensorflow/real-time-human-pose-estimation-in-the-browser-with-tensorflow-js-7dd0bc881cd5)
|
- [Posnet Medium артикул](https://medium.com/tensorflow/real-time-human-pose-estimation-in-the-browser-with-tensorflow-js-7dd0bc881cd5)
|
||||||
- [Tensorflow.js Демонстрация](https://www.tensorflow.org/js/demos)
|
- [Tensorflow.js Демонстрация](https://www.tensorflow.org/js/demos)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
* [Инструкция по сборке.](assemble_3.md)
|
* [Инструкция по сборке.](assemble_3.md)
|
||||||
* [Инструкция по настройке.](setup.md)
|
* [Инструкция по настройке.](setup.md)
|
||||||
* [Проверочные задания.](tests.md)
|
* [Проверочные задания.](tests.md)
|
||||||
* Информационные материалы на сайте https://clover.coex.tech.
|
* Информационные материалы на сайте https://clovercoex.tech.
|
||||||
|
|
||||||
## Промежуточный контроль
|
## Промежуточный контроль
|
||||||
|
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ network={
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Внутри конфига указываются общие настройки `wpa_supplicant` и параметры для настройки адаптера. Также конфигурационный файл содержит секции `network` – основные настройки Wi-Fi сети такие как SSID сети, пароль, режим работы адаптера. Таких блоков может быть несколько, но используется первый рабочий. Например, если вы указали в первом блоке подключение к некоторой недоступной сети, то адаптер будет настроен следующей удачной секцией, если такая есть. Подробнее о синтаксисе `wpa_supplicant.conf` [TODO WIKI].
|
Внутри конфига указываются общие настройки `wpa_supplicant` и параметры для настройки адаптера. Также конфигурационный файл содержит секции `network` – основные настройки Wi-Fi сети такие как SSID сети, пароль, режим работы адаптера. Таких блоков может быть несколько, но используется первый рабочий. Например, если вы указали в первом блоке подключение к некоторой недоступной сети, то адаптер будет настроен следующей удачной секцией, если такая есть. Подробнее о синтаксисе `wpa_supplicant.conf` см. в [man-странице Debian](https://manpages.debian.org/buster/wpasupplicant/wpa_supplicant.conf.5.en.html).
|
||||||
|
|
||||||
#### wpa_passphrase
|
#### wpa_passphrase
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ navigate(x=-1, frame_id='navigate_target')
|
|||||||
|
|
||||||
## Дополнительные настройки
|
## Дополнительные настройки
|
||||||
|
|
||||||
<!-- TODO: статья по пидам -->
|
Дополнительную информацию по настройке PID см. в статье [Настройка коэффициентов PID](calibratePID.md).
|
||||||
|
|
||||||
Если коптер нестабильно удерживает позицию, попробуйте увеличить коэффициенты *P* PID-регулятора по скорости – параметры `MPC_XY_VEL_P` и `MPC_Z_VEL_P`.
|
Если коптер нестабильно удерживает позицию, попробуйте увеличить коэффициенты *P* PID-регулятора по скорости – параметры `MPC_XY_VEL_P` и `MPC_Z_VEL_P`.
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
|`EKF2_OF_N_MIN`|0.05||
|
|`EKF2_OF_N_MIN`|0.05||
|
||||||
|`EKF2_OF_N_MAX`|0.2||
|
|`EKF2_OF_N_MAX`|0.2||
|
||||||
|`EKF2_HGT_MODE`\*|3 (*Vision*)|При наличии [дальномера](laser.md) и полете над ровным полом — 2 (*Range sensor*)|
|
|`EKF2_HGT_MODE`\*|3 (*Vision*)|При наличии [дальномера](laser.md) и полете над ровным полом — 2 (*Range sensor*)|
|
||||||
|`EKF2_EVA_NOISE`|0.1||
|
|`EKF2_EVA_NOISE`|0.1 rad или 5 deg||
|
||||||
|`EKF2_EVP_NOISE`|0.1||
|
|`EKF2_EVP_NOISE`|0.1||
|
||||||
|`EKF2_EV_DELAY`|0||
|
|`EKF2_EV_DELAY`|0||
|
||||||
|`EKF2_MAG_TYPE`|5 (*None*)|Выключение магнитометра (при навигации внутри помещения)|
|
|`EKF2_MAG_TYPE`|5 (*None*)|Выключение магнитометра (при навигации внутри помещения)|
|
||||||
@@ -59,6 +59,7 @@
|
|||||||
|`EKF2_BARO_CTRL`|0 (*Disabled*)|Барометр отключен|
|
|`EKF2_BARO_CTRL`|0 (*Disabled*)|Барометр отключен|
|
||||||
|`EKF2_OF_CTRL`|1 (*Enabled*)|Optical flow включен|
|
|`EKF2_OF_CTRL`|1 (*Enabled*)|Optical flow включен|
|
||||||
|`EKF2_HGT_REF`|3 (*Vision*)|При наличии [дальномера](laser.md) и полете над ровным полом — 2 (*Range sensor*)|
|
|`EKF2_HGT_REF`|3 (*Vision*)|При наличии [дальномера](laser.md) и полете над ровным полом — 2 (*Range sensor*)|
|
||||||
|
|`EKF2_RNG_CTRL`|2 (*Enabled*)|Дальномер включен|
|
||||||
|
|
||||||
<!-- markdownlint-enable MD031 -->
|
<!-- markdownlint-enable MD031 -->
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,6 @@ sudo systemctl restart clover
|
|||||||
Неисправности
|
Неисправности
|
||||||
---
|
---
|
||||||
|
|
||||||
* Если интерфейс пульта отображает явно неправильное напряжение (напр. > 5 V), проверьте, что значение PX4-параметра `BAT_N_CELLS` соответствует реальному количество элементов батареи. Если отображаемое напряжение все равно неверно, откалибруйте батарею (TODO: ссылка).
|
* Если интерфейс пульта отображает явно неправильное напряжение (напр. > 5 V), проверьте, что значение PX4-параметра `BAT_N_CELLS` соответствует реальному количеству элементов батареи. Если отображаемое напряжение все равно неверно, откалибруйте [датчик питания](power.md).
|
||||||
|
|
||||||
* Если вместо режима PX4 отображается текст "DISCONNECTED FROM FCU", проверьте [подключение Raspberry Pi к Pixhawk](connection.md).
|
* Если вместо режима PX4 отображается текст "DISCONNECTED FROM FCU", проверьте [подключение Raspberry Pi к Pixhawk](connection.md).
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
## Настройка Clover OS
|
## Настройка Clover OS
|
||||||
|
|
||||||
Настройка включает в себя переключение Raspberry из режима точки доступа в режим клиента. На начало работы была установлена [следующая операционная система](https://github.com/CopterExpress/clover). После установки можно было приступить непосредственно к настройкам системы. Как перевести Raspberry Pi в режим клиента, рассказывается в статье: [Настройка Wi-Fi](https://clover.coex.tech/ru/network.html). После того, как была произведена данная настройка Raspberry будет автоматически подключаться к Wi-Fi, после можно подключаться к Raspberry по SSH, также в дальнейшем подключение к Wi-Fi пригодится для подключения к серверу и передачи данных между клиентом и серверу (в разрабатываемой мной системе клиентом является квадрокоптер и сервером – компьютер).
|
Настройка включает в себя переключение Raspberry из режима точки доступа в режим клиента. На начало работы была установлена [следующая операционная система](https://github.com/CopterExpress/clover). После установки можно было приступить непосредственно к настройкам системы. Как перевести Raspberry Pi в режим клиента, рассказывается в статье: [Настройка Wi-Fi](https://clovercoex.tech/ru/network.html). После того, как была произведена данная настройка Raspberry будет автоматически подключаться к Wi-Fi, после можно подключаться к Raspberry по SSH, также в дальнейшем подключение к Wi-Fi пригодится для подключения к серверу и передачи данных между клиентом и серверу (в разрабатываемой мной системе клиентом является квадрокоптер и сервером – компьютер).
|
||||||
|
|
||||||
## Подключение и проверка подключения
|
## Подключение и проверка подключения
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Автономный полет
|
# Автономный полет
|
||||||
|
|
||||||
> **Note** Эта статья описывает работу с [образом версии **0.24**](https://github.com/CopterExpress/clover/releases/tag/v0.24), который пока находится в стадии тестирования. Для версии **0.23** доступна [более старая документация](https://github.com/CopterExpress/clover/blob/f78a03ec8943b596d5a99b893188a159d5319888/docs/ru/simple_offboard.md).
|
> **Note** Документация для версий [образа](image.md), начиная с версии **0.24**. Для более ранних версий см. [документацию для версии **0.23**](https://github.com/CopterExpress/clover/blob/v0.23/docs/ru/simple_offboard.md).
|
||||||
|
|
||||||
Модуль `simple_offboard` пакета `clover` предназначен для упрощенного программирования автономного полета дрона ([режим](modes.md) `OFFBOARD`). Он позволяет устанавливать желаемые полетные задачи и автоматически трансформирует [систему координат](frames.md).
|
Модуль `simple_offboard` пакета `clover` предназначен для упрощенного программирования автономного полета дрона ([режим](modes.md) `OFFBOARD`). Он позволяет устанавливать желаемые полетные задачи и автоматически трансформирует [систему координат](frames.md).
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
<img src="../assets/simulation_ubuntu_account.png" width=400 class="center zoom">
|
<img src="../assets/simulation_ubuntu_account.png" width=400 class="center zoom">
|
||||||
|
|
||||||
6. Завершите установку и запустите установленную систему.
|
6. Завершите установку и запустите установленную систему (для этого потребуется извлечь виртуальный CD-диск или выбрать *Boot from next volume* в меню загрузки).
|
||||||
7. Установите симулятор согласно [инструкции по сборке симулятора на собственной машине](simulation_native.md).
|
7. Установите симулятор согласно [инструкции по сборке симулятора на собственной машине](simulation_native.md).
|
||||||
|
|
||||||
### Возможные проблемы при установке
|
### Возможные проблемы при установке
|
||||||
|
|||||||
@@ -72,7 +72,11 @@ ln -s ~/PX4-Autopilot/Tools/sitl_gazebo ~/catkin_ws/src/
|
|||||||
ln -s ~/PX4-Autopilot/mavlink ~/catkin_ws/src/
|
ln -s ~/PX4-Autopilot/mavlink ~/catkin_ws/src/
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Hint** Вы можете использовать более позднюю версию PX4 с большим риском, что что-то не заработает.
|
> **Hint** Симулятор пока не поддерживает более поздние версии PX4, и при их использовании могут возникнуть ошибки.
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
> **Note** Если процесс клонирования завершится с ошибкой сети (`fatal: fetch-pack: invalid index-pack output`), используйте версию HTTP 1.1 `git config --global http.version HTTP/1.1` (после клонирования верните 2 версию командой `git config --global http.version HTTP/2`). Альтернативным решением будет принудительное клонирование репозитория и субмодулей через SSH командой `git config --global url."git@github.com:".insteadOf https://github.com/` (требует генерации и установки SSH ключа в настройках профиля GitHub).
|
||||||
|
|
||||||
## Установка зависимостей PX4
|
## Установка зависимостей PX4
|
||||||
|
|
||||||
@@ -115,10 +119,10 @@ sudo /opt/ros/noetic/lib/mavros/install_geographiclib_datasets.sh
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/catkin_ws
|
cd ~/catkin_ws
|
||||||
catkin_make
|
catkin_make -j1
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note** Если процесс сборки завершится с ошибкой, связанной с недостатком памяти (`c++: fatal error: Killed signal terminated program cc1plus`), уменьшите количество параллельно исполняемых процессов используя ключ `-j`. Например, чтобы использовать только два параллельных процесса используйте команду `catkin_make -j2`.
|
> **Note** Флаг `-j1` означает, что сборка не будет использовать параллельные процессы, так как при сборке с параллельными процессами на виртуальной машине может не хватить оперативной памяти. Если у вас достаточно памяти, вы можете не использовать этот флаг.
|
||||||
|
|
||||||
## Запуск симулятора
|
## Запуск симулятора
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<package format="2">
|
<package format="2">
|
||||||
<name>roswww_static</name>
|
<name>roswww_static</name>
|
||||||
<version>0.24.0</version>
|
<version>0.25.0</version>
|
||||||
<description>Static web pages for ROS packages</description>
|
<description>Static web pages for ROS packages</description>
|
||||||
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
||||||
<license>MIT</license>
|
<license>MIT</license>
|
||||||
|
|||||||
Reference in New Issue
Block a user