Compare commits

..

17 Commits

Author SHA1 Message Date
Oleg Kalachev
28e89704e6 Update changelog and versions in package.xml 2024-08-08 04:42:35 +03:00
Oleg Kalachev
23da41247f Use pip installer for Python 3.7 2024-08-04 09:18:16 +03:00
Oleg Kalachev
1e45ec143c Add angles package 2024-08-04 07:41:07 +03:00
Oleg Kalachev
26ec42f1e6 Add vision_msgs package 2024-06-18 04:24:24 +03:00
Oleg Kalachev
3edb2f48e0 Add missing stereo_msgs presence test 2024-06-18 04:24:02 +03:00
Oleg Kalachev
3a08085c69 Add width and indent parameters for topic viewer 2024-06-17 05:03:18 +03:00
Oleg Kalachev
4e4dfc1f07 Update checkout action to v4
checkout@v2 is deprecated
2024-06-12 03:37:28 +03:00
Oleg Kalachev
6b0ed144e3 Update editorconfig exceptions 2024-06-09 21:49:41 +03:00
Oleg Kalachev
91bb9d6e38 Change the library for YAML encode in topic viewer
To support displaying newlines in long strings
2024-06-09 21:35:17 +03:00
Oleg Kalachev
e1ff92ee1f Change the recommended directory for autolaunch scripts
Workaround to the issue with importing clover.srv inside the clover/src
directory, as it attempts to import from clover/srv/clover/__init__.py.
2024-06-09 16:16:34 +03:00
Oleg Kalachev
4d2b685b06 blocks: allow using numbers in programs name
Additionally increase maximum program name size
2024-05-25 08:07:56 +03:00
Oleg Kalachev
14c41b21b6 docs: add EKF2_RNG_CTRL parameter value 2024-05-17 23:03:48 +03:00
Oleg Kalachev
70439f172d selfcheck.py: address situation when individual cells voltage is unknown
When length of cell_voltage array is 1, it means that cell voltage is
unknown and overall voltage is reported instead. Consider this situation
gathering the number of cells from PX4 parameters.
2024-04-25 22:20:01 +03:00
Oleg Kalachev
dacaa8ebde docs: minor fixes 2024-04-25 11:12:29 +03:00
Oleg Kalachev
a5309765f1 Some changes to markdownlint config 2024-04-25 11:04:55 +03:00
Oleg Kalachev
2e86ed199a Implement possibility to upload image from repo not named clover 2024-04-25 10:50:02 +03:00
Oleg Kalachev
ad14822684 Fix running aruco_detect without aruco_map enabled
use_map_markers parameter blocked aruco_detect from running
2024-04-25 10:48:20 +03:00
36 changed files with 364 additions and 340 deletions

View File

@@ -13,18 +13,18 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Build image
run: |
docker run --privileged --rm -v /dev:/dev -v $(pwd):/builder/repo -e TRAVIS_TAG="${{ github.event.release.tag_name }}" sfalexrog/img-tool:qemu-update
- name: Compress image
run: |
cd images && sudo chmod -R 777 . && zip -9 $(echo clover_*).zip clover_* && ls -l . && unzip -l clover_*.zip
cd images && sudo chmod -R 777 . && zip -9 $(echo *_*).zip *_* && ls -l . && unzip -l *_*.zip
- name: Upload image
uses: softprops/action-gh-release@v1
if: ${{ github.event_name == 'release' }}
with:
files: images/clover_*.zip
files: images/*_*.zip
prerelease: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -11,7 +11,7 @@ jobs:
# melodic:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v2
# - uses: actions/checkout@v4
# - name: Native Melodic build
# run: |
# docker run --rm -v $(pwd):/root/catkin_ws/src/clover ros:melodic-ros-base /root/catkin_ws/src/clover/builder/standalone-install.sh
@@ -23,7 +23,7 @@ jobs:
working-directory: catkin_ws
shell: bash
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
path: catkin_ws/src/clover
- name: Install requirements

View File

@@ -20,7 +20,7 @@ jobs:
docs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v1
with: { node-version: '10' }

View File

@@ -11,9 +11,9 @@ jobs:
editorconfig:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: .editorconfig Linter
run: |
wget --no-verbose https://github.com/okalachev/editorconfig-checker/releases/download/1.2.1-disable-spaces-amount/ec-linux-amd64
chmod +x ec-linux-amd64
./ec-linux-amd64 -spaces-after-tabs -e "roslib.js|ros3d.js|eventemitter2.js|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"

View File

@@ -113,7 +113,9 @@
"VMware",
"DuoCam"
],
"code_blocks": false
"code_blocks": false,
"html_elements": false
},
"MD045": false
"MD045": false,
"MD051": false
}

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<package format="3">
<name>aruco_pose</name>
<version>0.24.0</version>
<version>0.25.0</version>
<description>Positioning with ArUco markers</description>
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>

View File

@@ -15,26 +15,52 @@
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
##################################################
echo "--- Enable sshd"
# 1. Enable sshd
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
echo "--- Enable SPI"
# 4. Enable SPI
echo_stamp "#4 Turn on SPI"
/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
echo "--- Enable UART"
# 6. Enable hardware UART
echo_stamp "#6 Turn on UART"
# Temporary solution
# https://github.com/RPi-Distro/raspi-config/pull/75
/usr/bin/raspi-config nonint do_serial 1
@@ -46,9 +72,11 @@ systemctl disable hciuart.service
# https://github.com/RPi-Distro/raspi-config/commit/d6d9ecc0d9cbe4aaa9744ae733b9cb239e79c116
#/usr/bin/raspi-config nonint do_serial 2
echo "--- Enable v4l2 driver"
# http://robocraft.ru/blog/electronics/3158.html
# 7. Enable V4L driver http://robocraft.ru/blog/electronics/3158.html
#echo "bcm2835-v4l2" >> /etc/modules
echo_stamp "#7 Turn on v4l2 driver"
if ! grep -q "^bcm2835-v4l2" /etc/modules;
then printf "bcm2835-v4l2\n" >> /etc/modules
fi
echo_stamp "#8 End of configure hardware interfaces"

View File

@@ -15,8 +15,28 @@
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}
}
NEW_SSID='clover-'$(head -c 100 /dev/urandom | xxd -ps -c 100 | sed -e "s/[^0-9]//g" | cut -c 1-4)
echo "--- Setting SSID to ${NEW_SSID}"
echo_stamp "Setting SSID to ${NEW_SSID}"
# TODO: Use wpa_cli insted direct file edit
# FIXME: We rely on raspberrypi-net-mods to copy our file to /etc/wpa_supplicant.
# This is not very reliable, but seems to fix our rfkill problem.
@@ -37,17 +57,19 @@ network={
EOF
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
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
echo "--- Enable ROS services"
echo_stamp "Enable ROS services"
systemctl enable roscore
systemctl enable clover
echo "--- Harware setup"
echo_stamp "Harware setup"
/root/hardware_setup.sh
echo "--- Remove init scripts"
echo_stamp "Remove init scripts"
rm /root/init_rpi.sh /root/hardware_setup.sh
echo_stamp "End of initialization of the image"

View File

@@ -13,7 +13,7 @@
# 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
SOURCE_IMAGE="https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2021-05-28/2021-05-07-raspios-buster-armhf-lite.zip"
@@ -22,13 +22,33 @@ export DEBIAN_FRONTEND=${DEBIAN_FRONTEND:='noninteractive'}
export LANG=${LANG:='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"
REPO_DIR="${BUILDER_DIR}/repo"
SCRIPTS_DIR="${REPO_DIR}/builder"
IMAGES_DIR="${REPO_DIR}/images"
[[ ! -d ${SCRIPTS_DIR} ]] && (echo "Error: directory ${SCRIPTS_DIR} doesn't exist"; exit 1)
[[ ! -d ${IMAGES_DIR} ]] && mkdir ${IMAGES_DIR} && echo "Directory ${IMAGES_DIR} was created successful"
[[ ! -d ${SCRIPTS_DIR} ]] && (echo_stamp "Directory ${SCRIPTS_DIR} doesn't exist" "ERROR"; exit 1)
[[ ! -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
# IMAGE_VERSION="${TRAVIS_TAG:=$(cd ${REPO_DIR}; git log --format=%h -1)}"
@@ -44,15 +64,15 @@ get_image() {
local RPI_IMAGE_NAME=$(echo ${RPI_ZIP_NAME} | sed 's/zip/img/')
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
echo "--- Downloading complete" "SUCCESS"
else
echo "Linux distribution already downloaded"
fi
echo_stamp "Downloading complete" "SUCCESS" \
else echo_stamp "Linux distribution already donwloaded"; fi
echo "--- Unzipping Linux distribution image"
unzip -p ${BUILD_DIR}/${RPI_ZIP_NAME} ${RPI_IMAGE_NAME} > $1
echo_stamp "Unzipping Linux distribution image" \
&& unzip -p ${BUILD_DIR}/${RPI_ZIP_NAME} ${RPI_IMAGE_NAME} > $1 \
&& echo_stamp "Unzipping complete" "SUCCESS" \
|| (echo_stamp "Unzipping was failed!" "ERROR"; exit 1)
}
get_image ${IMAGE_PATH} ${SOURCE_IMAGE}

View File

@@ -12,29 +12,50 @@
# 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 "Write Clover information"
echo "--- Write Clover information"
# Clover image version
echo "$1" >> /etc/clover_version
# Origin image file name
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"
sed -i "19a${MAGIC_SCRIPT}" /etc/rc.local
# 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/.* \/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
echo "--- Set max space for syslogs"
echo_stamp "Set max space for syslogs"
# https://unix.stackexchange.com/questions/139513/how-to-clear-journalctl
sed -i 's/#SystemMaxUse=/SystemMaxUse=200M/' /etc/systemd/journald.conf
echo "--- Move /etc/ld.so.preload out of the way"
echo_stamp "Move /etc/ld.so.preload out of the way"
mv /etc/ld.so.preload /etc/ld.so.preload.disabled-for-build
echo "--- End of init image"
echo_stamp "End of init image"

View File

@@ -12,20 +12,43 @@
# 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
interface wlan0
static ip_address=192.168.11.1/24
EOF
echo "--- Set wpa_supplicant country"
echo_stamp "#2 Set wpa_supplicant country"
cat << EOF >> /etc/wpa_supplicant/wpa_supplicant.conf
country=GB
EOF
echo "--- Write dhcp-config to /etc/dnsmasq.conf"
echo_stamp "#3 Write dhcp-config to /etc/dnsmasq.conf"
cat << EOF >> /etc/dnsmasq.conf
interface=wlan0
address=/clover/coex/192.168.11.1
@@ -36,3 +59,5 @@ bogus-priv
domain-needed
quiet-dhcp6
EOF
echo_stamp "#4 End of network installation"

View File

@@ -15,9 +15,35 @@
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
ROS_DISTRO=noetic
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://github.com/travis-ci/travis-build/blob/master/lib/travis/build/templates/header.sh
my_travis_retry() {
@@ -43,24 +69,24 @@ my_travis_retry() {
}
# 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
# FIXME: Re-add this after missing packages are built
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
echo "--- Populate rosdep for ROS user"
echo_stamp "Populate rosdep for ROS user"
my_travis_retry sudo -u pi rosdep update
export ROS_IP='127.0.0.1' # needed for running tests
# echo "Reconfiguring Clover repository for simplier unshallowing"
# echo_stamp "Reconfiguring Clover repository for simplier unshallowing"
cd /home/pi/catkin_ws/src/clover
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
# 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 \
ros-${ROS_DISTRO}-compressed-image-transport=1.14.0-0buster \
ros-${ROS_DISTRO}-cv-bridge=1.15.0-0buster \
@@ -74,10 +100,10 @@ ros-${ROS_DISTRO}-cv-camera \
ros-${ROS_DISTRO}-image-publisher \
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
echo "--- Build and install Clover"
echo_stamp "Build and install Clover"
cd /home/pi/catkin_ws
# Don't try to install gazebo_ros
my_travis_retry rosdep install -y --from-paths src --ignore-src --rosdistro ${ROS_DISTRO} --os=debian:buster \
@@ -89,12 +115,12 @@ source /opt/ros/${ROS_DISTRO}/setup.bash
catkin_make -j2 -DCMAKE_BUILD_TYPE=RelWithDebInfo
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
./setup.py install
rm -rf build # remove build artifacts
echo "--- Build Clover documentation"
echo_stamp "Build Clover documentation"
cd /home/pi/catkin_ws/src/clover
builder/assets/install_gitbook.sh
gitbook install
@@ -103,7 +129,7 @@ gitbook build
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
echo "--- Installing additional ROS packages"
echo_stamp "Installing additional ROS packages"
my_travis_retry apt-get install -y --no-install-recommends \
ros-${ROS_DISTRO}-rosbridge-suite \
ros-${ROS_DISTRO}-rosserial \
@@ -114,38 +140,40 @@ my_travis_retry apt-get install -y --no-install-recommends \
ros-${ROS_DISTRO}-cmake-modules \
ros-${ROS_DISTRO}-image-view \
ros-${ROS_DISTRO}-nodelet-topic-tools \
ros-${ROS_DISTRO}-stereo-msgs
ros-${ROS_DISTRO}-stereo-msgs \
ros-${ROS_DISTRO}-vision-msgs \
ros-${ROS_DISTRO}-angles
# 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
echo "--- Running tests"
echo_stamp "Running tests"
cd /home/pi/catkin_ws
# FIXME: Investigate failing tests
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
echo "--- Update www"
echo_stamp "Update 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
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/roscore.service /lib/systemd/system/
# validate
[ -f /lib/systemd/system/clover.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/
echo "--- Setup ROS environment"
echo_stamp "Setup ROS environment"
cat << EOF >> /home/pi/.bashrc
LANG='C.UTF-8'
LC_ALL='C.UTF-8'
@@ -154,5 +182,12 @@ source /opt/ros/${ROS_DISTRO}/setup.bash
source /home/pi/catkin_ws/devel/setup.bash
EOF
echo "--- Clean apt cache"
#echo_stamp "Removing local apt mirror"
# Restore original sources.list
#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_stamp "END of ROS INSTALLATION"

View File

@@ -12,7 +12,27 @@
# 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}
}
# https://gist.github.com/letmaik/caa0f6cc4375cbfcc1ff26bd4530c2a3
# https://github.com/travis-ci/travis-build/blob/master/lib/travis/build/templates/header.sh
@@ -37,10 +57,11 @@ my_travis_retry() {
return $result
}
echo "--- Increase apt retries"
echo_stamp "Increase apt 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'
apt-get update \
@@ -49,17 +70,17 @@ apt-get update \
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 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
apt-get update
# && apt upgrade -y
# 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=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 \
unzip \
@@ -100,8 +121,8 @@ python3-opencv
sed -i "s/updates_available//" /usr/share/byobu/status/status
# sed -i "s/updates_available//" /home/pi/.byobu/status
echo "--- Installing pip"
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
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
@@ -109,12 +130,12 @@ rm get-pip.py get-pip2.py
#my_travis_retry pip install --upgrade pip
#my_travis_retry pip3 install --upgrade pip
echo "--- Make sure both pip and pip3 are installed"
echo_stamp "Make sure both pip and pip3 are installed"
pip --version
pip3 --version
echo "--- Install and enable Butterfly (web terminal)"
echo "Workaround for tornado >= 6.0 breaking butterfly"
echo_stamp "Install and enable Butterfly (web terminal)"
echo_stamp "Workaround for tornado >= 6.0 breaking butterfly"
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 pyOpenSSL==20.0.1
@@ -123,16 +144,16 @@ my_travis_retry pip3 install butterfly
my_travis_retry pip3 install butterfly[systemd]
systemctl enable butterfly.socket
echo "--- Install ws281x library"
echo_stamp "Install ws281x library"
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 /root/monkey /etc/monkey/sites/default
sed -i 's/SymLink Off/SymLink On/' /etc/monkey/monkey.conf
systemctl enable monkey.service
echo "--- Install Node.js"
echo_stamp "Install Node.js"
cd /home/pi
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
@@ -140,26 +161,28 @@ cp -R node-v10.15.0-linux-armv6l/* /usr/local/
rm -rf node-v10.15.0-linux-armv6l/
rm node-v10.15.0-linux-armv6l.tar.gz
echo "--- Installing ptvsd"
echo_stamp "Installing ptvsd"
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
echo "--- Add .vimrc"
echo_stamp "Add .vimrc"
cat << EOF > /home/pi/.vimrc
set mouse-=a
syntax on
autocmd BufNewFile,BufRead *.launch set syntax=xml
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
echo "--- Attempting to kill dirmngr"
echo_stamp "Attempting to kill dirmngr"
gpgconf --kill dirmngr
# dirmngr is only used by apt-key, so we can safely kill it.
# We ignore pkill's exit value as well.
pkill -9 -f dirmngr || true
echo_stamp "End of software installation"

View File

@@ -12,10 +12,9 @@
# 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_IP='127.0.0.1'
@@ -36,9 +35,9 @@ systemctl stop roscore
apt-cache show gst-rtsp-launch
apt-cache show openvpn
echo "--- Move /etc/ld.so.preload back to its original position"
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'
dpigs -H -n 100

View File

@@ -6,6 +6,10 @@ import os
import rospy
from geometry_msgs.msg import PoseStamped
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.aruco

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
set -ex # exit on error, echo commands
set -ex
# TODO: validate versions
@@ -60,6 +60,9 @@ rosversion cv_camera
rosversion web_video_server
rosversion nodelet
rosversion image_view
rosversion stereo_msgs
rosversion vision_msgs
rosversion angles
[[ $(rosversion ws281x) == "0.0.13" ]]

View File

@@ -2,6 +2,52 @@
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)
-------------------
* First release of clover package to ROS

View File

@@ -19,7 +19,7 @@
<param name="dictionary" value="2"/> <!-- DICT_4X4_250 -->
<param name="estimate_poses" value="true"/>
<param name="send_tf" value="true"/>
<param name="use_map_markers" value="true"/>
<param name="use_map_markers" value="$(arg aruco_map)"/>
<param name="known_vertical" value="map" if="$(eval placement == 'floor' or placement == 'ceiling')"/>
<param name="flip_vertical" value="true" if="$(eval placement == 'ceiling')"/>
<param name="length" value="$(arg length)"/>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<package format="3">
<name>clover</name>
<version>0.24.0</version>
<version>0.25.0</version>
<description>The Clover package</description>
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>

View File

@@ -303,6 +303,14 @@ def check_fcu():
failure('cell voltage is not available, https://clover.coex.tech/power')
else:
cell = battery.cell_voltage[0]
# number of cells 1 means this is overall voltage
if len(battery.cell_voltage) == 1:
n_cells = get_param('BAT1_N_CELLS', strict=False)
if n_cells is None:
# older PX4
n_cells = get_param('BAT_N_CELLS', strict=True)
cell /= n_cells
if cell > 4.3 or cell < 3.0:
failure('incorrect cell voltage: %.2f V, https://clover.coex.tech/power', cell)
elif cell < 3.7:

View File

@@ -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, "&amp;").replace(/</g,
"&lt;").replace(/>/g, "&gt;");
};
}
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]);

View File

@@ -64,8 +64,11 @@ function viewTopic(topic) {
}
}
let txt = `<div class=counter>${counter} received</div>${yamlStringify(msg)}`; // JSON.stringify(msg, null, 4);
topicMessage.innerHTML = txt;
let width = Number(params.width) || 100;
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

File diff suppressed because one or more lines are too long

View File

@@ -4,7 +4,7 @@
<script src="js/roslib.js"></script>
<link rel="icon" href="data:,"> <!-- make chrome don't request icon -->
<script type="module" src="js/topics.js"></script>
<script src="js/json-to-pretty-yaml.js"></script>
<script src="js/yaml.js"></script>
<style>
#topics { line-height: 1.2em; }
#topic-view {

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<package format="2">
<name>clover_blocks</name>
<version>0.24.0</version>
<version>0.25.0</version>
<description>Blockly programming support for Clover</description>
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
<license>MIT</license>

View File

@@ -166,7 +166,7 @@ def load(req):
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):
if not name_regexp.match(req.name):

View File

@@ -1,6 +1,6 @@
<package format="2">
<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>
<maintainer email="sfalexrog@gmail.com">Alexey Rogachevskiy</maintainer>

View File

@@ -1,6 +1,6 @@
<package format="3">
<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>
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>

View File

@@ -136,7 +136,7 @@ navigate(x=2, y=2, z=2, speed=1, frame_id='aruco_map')
### Using a specific marker frame
Starting with the [image](image.md) version 0.18, the drone also can fly relative to a marker in the map, even if it is not currently visible. Like with [single-marker navigation](aruco_marker.md#working-with-detected-markers), this works by setting the frame_id parameter to aruco_ID, where ID is the desired marker number.
Starting with the [image](image.md) version 0.18, the drone also can fly relative to a marker in the map, even if it is not currently visible. Like with [single-marker navigation](aruco_marker.md#working-with-detected-markers), this works by setting the frame_id parameter to `aruco_ID`, where ID is the desired marker number.
The following code will move the drone to the point 1 meter above the center of marker 5:

View File

@@ -210,7 +210,7 @@ Most of the parameters for autonomous flight are located in the following direct
<arg name="aruco_vpe" default="true"/>`
```
- Generate the ArUco markers field. See the article [Map-based navigation with ArUco markers] (aruco_map.md # marker map settings) for details. To generate markers, you need to enter a command with specific values.
- Generate the ArUco markers field. See the article [Map-based navigation with ArUco markers](aruco_map.md#marker-map-definition) for details. To generate markers, you need to enter a command with specific values.
Here is the example generating command where:

View File

@@ -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`.
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
<node name="my_program" pkg="clover" type="my_program.py" output="screen"/>

View File

@@ -59,6 +59,7 @@ In case of using EKF2 (official firmware):
|`EKF2_BARO_CTRL`|0 (*Disabled*)|Barometer is disabled|
|`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_RNG_CTRL`|2 (*Enabled*)|Range sensor is enabled|
<!-- markdownlint-enable MD031 -->

View File

@@ -136,7 +136,7 @@ navigate(x=2, y=2, z=2, speed=1, frame_id='aruco_map') # полет в коор
### Полет в координаты по ID маркера
Начиная с версии [образа](image.md) 0.18, доступны также полёты относительно отдельного маркера в карте, даже если дрон его не видит. По аналогии с [навигацией по отдельным маркерам](aruco_marker.md#навигация-по-маркерам) при настройке карты маркеров дрон сможет лететь в координаты относительно отдельного маркера, используя фрейм aruco_ID с соответствующим ID маркера.
Начиная с версии [образа](image.md) 0.18, доступны также полёты относительно отдельного маркера в карте, даже если дрон его не видит. По аналогии с [навигацией по отдельным маркерам](aruco_marker.md#навигация-по-маркерам) при настройке карты маркеров дрон сможет лететь в координаты относительно отдельного маркера, используя фрейм `aruco_ID` с соответствующим ID маркера.
Полет в точку над маркером 5 на высоту 1 метр:

View File

@@ -42,7 +42,7 @@ roslaunch
Список объявленных для запуска нод / программ указывается в файле `/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
<node name="my_program" pkg="clover" type="my_program.py" output="screen"/>

View File

@@ -59,6 +59,7 @@
|`EKF2_BARO_CTRL`|0 (*Disabled*)|Барометр отключен|
|`EKF2_OF_CTRL`|1 (*Enabled*)|Optical flow включен|
|`EKF2_HGT_REF`|3 (*Vision*)|При наличии [дальномера](laser.md) и полете над ровным полом — 2 (*Range sensor*)|
|`EKF2_RNG_CTRL`|2 (*Enabled*)|Дальномер включен|
<!-- markdownlint-enable MD031 -->

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<package format="2">
<name>roswww_static</name>
<version>0.24.0</version>
<version>0.25.0</version>
<description>Static web pages for ROS packages</description>
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
<license>MIT</license>