Compare commits

...

318 Commits

Author SHA1 Message Date
Oleg Kalachev
621b70711d Typo 2024-06-18 00:52:59 +03:00
Oleg Kalachev
2a2fbe3bed Add vision_msgs package 2024-06-18 00:52:30 +03:00
Oleg Kalachev
add15ac2fe Remove libcamera_ros from dependencies as this package is not commonly available 2024-06-16 13:15:49 +03:00
Oleg Kalachev
abe6f5cf0f Add rosdep key for libcamera_ros package 2024-06-16 12:22:27 +03:00
Oleg Kalachev
b04d8311bd Add tool for rescaling camera info file
Generate fisheye_cam camera info for all the
different resolutions
2024-06-16 08:33:25 +03:00
Oleg Kalachev
b7e8acefb4 Use libcamera_ros camera driver
v4l2 doesn't work on Bookworm with RPi camera
2024-06-16 08:32:44 +03:00
Oleg Kalachev
caa974b71c Fix running rosbridge_suite adding ROS_OV_OVERRIDE env variable
It gives error 'Could not detect OS' (from roslib) on Bookworm without that
2024-05-22 14:17:59 +03:00
Oleg Kalachev
3f00001d9a Merge branch 'master' into bookworm 2024-05-09 20:40:34 +03:00
Oleg Kalachev
1a9e689b8c Disable exiting on error in init scripts 2024-05-08 20:09:09 +03:00
Oleg Kalachev
1e2f92f165 Fix Wi-Fi creation 2024-05-08 20:07:10 +03:00
Oleg Kalachev
d087d1c953 Try to fix 2024-05-07 22:26:25 +03:00
Oleg Kalachev
01c495597b Upload image to artifacts if this is not master 2024-05-07 21:39:42 +03:00
Oleg Kalachev
8c8fdcda54 Try to fix Butterfly installation 2024-05-07 21:33:06 +03:00
Oleg Kalachev
fbe353b767 Bring back CRYPTOGRAPHY_DONT_BUILD_RUST while installing Butterfly 2024-05-07 02:24:48 +03:00
Oleg Kalachev
4748d34fa2 Fix pi home directory permissions to make Monkey work 2024-05-07 01:53:01 +03:00
Oleg Kalachev
afe46ab7e5 Clean initial scripts, fix UART setup 2024-05-07 01:01:40 +03:00
Oleg Kalachev
d7e8d22bf6 Fix ws281x version checks as it was updated 2024-04-28 22:15:09 +03:00
Oleg Kalachev
ee4165ea26 Use 7z image archive to reduce size 2024-04-28 00:06:36 +03:00
Oleg Kalachev
0a265db50e Update upload-artifact action version 2024-04-28 00:06:21 +03:00
Oleg Kalachev
04d4dcaa1c Compress image to zip using 7z with ultra level to reduce archive size 2024-04-27 22:14:45 +03:00
Oleg Kalachev
6adfc038a2 Print size of image archive in human style 2024-04-27 22:08:09 +03:00
Oleg Kalachev
5877235e9a Fix adding pi user 2024-04-27 16:19:15 +03:00
Oleg Kalachev
b70c4387f7 Fix 2024-04-27 11:26:51 +03:00
Oleg Kalachev
00fb98c0c2 Create Wi-Fi AP using NetworkManager 2024-04-27 00:55:11 +03:00
Oleg Kalachev
249800bc87 Fix config.txt path to the new 2024-04-27 00:54:43 +03:00
Oleg Kalachev
465bdd743b Enable ssh using raspi-config 2024-04-27 00:54:18 +03:00
Oleg Kalachev
028d1ecd82 Create pi user which is not created by default now 2024-04-27 00:54:06 +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
Oleg Kalachev
4517cdf595 Merge branch 'cleanup-build' into bookworm 2024-04-18 07:46:34 +03:00
Oleg Kalachev
dc2293e960 More build scripts cleanup 2024-04-18 06:51:11 +03:00
Oleg Kalachev
1b191d9cf0 Major build scripts cleanup
Including removing echo_stamp, which is not needed
2024-04-18 06:49:46 +03:00
Oleg Kalachev
41b6311d9e Enable echo in image-init, move disabling ld preload to the top 2024-04-18 06:17:31 +03:00
Oleg Kalachev
b39fa10ba9 One more fix to working with fstab 2024-04-18 06:13:12 +03:00
Oleg Kalachev
2c62fa3583 Fix work with fstab 2024-04-18 06:08:50 +03:00
Oleg Kalachev
8dcdae1259 Remove editing /boot/firmware/cmdline.txt 2024-04-18 05:36:19 +03:00
Oleg Kalachev
be27a6d3a3 Correct cmdline.txt and fstab editing for the new OS version 2024-04-18 05:04:43 +03:00
Oleg Kalachev
d8c26c114e Add installation of xxd which is needed for generating SSID 2024-04-18 05:04:12 +03:00
Oleg Kalachev
ef43b04a8b Update Raspberry Pi OS to 2024-03-15 2024-04-17 08:27:27 +03:00
Oleg Kalachev
960a105cba Disable full remove of apt cache 2024-04-17 06:48:59 +03:00
Oleg Kalachev
4fcd0eaf2f Cleanup apt including all caches in the end of the build 2024-04-16 04:06:30 +03:00
Oleg Kalachev
f9026fa0e3 Cleanup /tmp in image build 2024-04-15 07:04:41 +03:00
Oleg Kalachev
cd5a9d1176 Cleanup pip cache in image build 2024-04-15 07:03:59 +03:00
Oleg Kalachev
cfe430676b Clean npm cache after building docs 2024-04-15 07:02:36 +03:00
Oleg Kalachev
3bccfd8c06 Do apt-get clean after autoremove 2024-04-15 06:45:59 +03:00
Oleg Kalachev
fef8a3299e Try to use autoremove to reduce image size 2024-04-14 04:12:14 +03:00
Oleg Kalachev
63deabe01d Code cleanup 2024-04-14 04:11:21 +03:00
Oleg Kalachev
b021afff7e Make apt-get clean verbose 2024-04-14 04:10:45 +03:00
Oleg Kalachev
b3d28723d7 Upload image artifact on on manual workflow run 2024-04-14 04:08:03 +03:00
Oleg Kalachev
22c9d238d4 Don't install boost explicitly 2024-04-14 01:42:28 +03:00
Oleg Kalachev
eb1a6f4349 Upload image to artifacts 2024-04-14 01:42:06 +03:00
Oleg Kalachev
a41004d294 Merge remote-tracking branch 'origin/master' into bookworm 2024-04-13 23:56:50 +03:00
Oleg Kalachev
e788bf3d4d Merge noetic-bookworm into noetic-rosdep-clover, remove noetic-bullseye 2024-04-13 23:54:40 +03:00
Oleg Kalachev
6e8a0d14b3 Disable back catkin_test_results, cleanup 2024-04-13 23:29:33 +03:00
Oleg Kalachev
78465fc93f Replace ptvsd with debugpy
ptvsd is deprecated
2024-04-13 22:43:57 +03:00
Oleg Kalachev
bf8482a6ce Enable catkin_test_results call 2024-04-13 22:39:27 +03:00
Oleg Kalachev
4659772d40 Cleanup 2024-04-13 22:38:52 +03:00
Oleg Kalachev
62cade7404 Add correct librocos resolve to rosdep 2024-04-13 22:38:35 +03:00
Oleg Kalachev
fa7a05bdb1 Bring back printing largest installed packages 2024-04-13 22:36:48 +03:00
Oleg Kalachev
936efa985d Make clover rosdep file more priority to fix build 2024-04-13 21:32:55 +03:00
Oleg Kalachev
5580bd754c Don't run roscore in image validate script 2024-04-13 21:31:38 +03:00
Oleg Kalachev
50c295ed3e Wait until roscore is terminated before script end 2024-04-13 20:10:12 +03:00
Oleg Kalachev
0f76999214 Stop roscore using killall before ending the validate script 2024-04-13 20:08:55 +03:00
Oleg Kalachev
f7ae2c21a4 Add some sleep to try to fix busy error 2024-04-13 19:16:36 +03:00
Oleg Kalachev
c55e0cb7e1 Fix geographiclib dependency 2024-04-13 19:06:44 +03:00
Oleg Kalachev
b8344dbb84 Add dictionary parameter to aruco.launch 2024-04-13 16:57:29 +03:00
Oleg Kalachev
fae431c890 Disable printing largest packages 2024-04-13 03:55:41 +03:00
Oleg Kalachev
fdbd989d0e Move recovering ld.so.preload file at the end of the build 2024-04-13 03:55:09 +03:00
Oleg Kalachev
649e596479 Disable compressed_image_transport 2024-04-12 23:50:38 +03:00
Oleg Kalachev
d9d85f5979 Skip python3-catkin-pkg-modules and python3-rosdep-modules via rosdep file 2024-04-12 20:54:18 +03:00
Oleg Kalachev
bcf355acf9 Ignore python3-rosdep-modules dependency 2024-04-12 20:23:36 +03:00
Oleg Kalachev
89912c67b8 Ignore python3-catkin-pkg-modules dependency 2024-04-12 20:20:53 +03:00
Oleg Kalachev
05c773b297 Bring back rosdep init 2024-04-12 19:39:28 +03:00
Oleg Kalachev
51d6d78b3d Fix 2024-04-12 17:29:54 +03:00
Oleg Kalachev
dd5dff7922 Bring back installing rosdep with pip 2024-04-12 16:44:04 +03:00
Oleg Kalachev
94c102b5e0 Install catkin before sourcing setup.bash 2024-04-12 01:33:32 +03:00
Oleg Kalachev
70026fef74 Disable rosdep init 2024-04-12 01:16:43 +03:00
Oleg Kalachev
41f81f35e6 Don't install rosdep using pip 2024-04-12 00:25:52 +03:00
Oleg Kalachev
e7ae321b54 Add ros-base installation 2024-04-11 22:56:50 +03:00
Oleg Kalachev
5b35df41b1 Print out environment variables right after setup.bash call 2024-04-11 22:21:53 +03:00
Oleg Kalachev
51af09bde8 Print out environment variables for debug 2024-04-11 21:06:06 +03:00
Oleg Kalachev
3d17433ba8 Print catkin_ws contents for debug 2024-04-11 19:42:48 +03:00
Oleg Kalachev
2e174b2bc0 Print out caktin path 2024-04-11 16:42:57 +03:00
Oleg Kalachev
9bff8b47dc Start roscore directly instead of using systemd 2024-04-11 16:41:52 +03:00
Oleg Kalachev
cceb62cfc4 Remove butterfly installation workarounds 2024-04-11 05:45:14 +03:00
Oleg Kalachev
4e111fa299 Check butterfly installation via butterfly.server.py 2024-04-11 04:03:45 +03:00
Oleg Kalachev
ba7f15b1d7 Allow pip usage globally 2024-04-11 03:03:34 +03:00
Oleg Kalachev
30e9d111ec Fix pip installation check 2024-04-11 03:01:14 +03:00
Oleg Kalachev
8087bb26c9 Re-arrange installed software list 2024-04-11 03:00:27 +03:00
Oleg Kalachev
3ef0065ab2 Bring back Monkey setup 2024-04-11 02:57:27 +03:00
Oleg Kalachev
d0fa541d13 Validate espeak is installed 2024-04-11 02:50:34 +03:00
Oleg Kalachev
31dde130b4 Update cv_camera version for check 2024-04-11 02:49:27 +03:00
Oleg Kalachev
bced762f77 Bring back ipython 2024-04-11 02:49:15 +03:00
Oleg Kalachev
2d8ac74f8d Remove Python 2 tests 2024-04-11 01:55:30 +03:00
Oleg Kalachev
0e2f1b9ac1 Bring back rosbridge-suite 2024-04-11 01:02:55 +03:00
Oleg Kalachev
f4733e7209 Remove not existing wno rosbridge-suite package installation 2024-04-11 00:58:13 +03:00
Oleg Kalachev
2cfdf36768 Bring mjpeg-streamer installation back 2024-04-11 00:29:06 +03:00
Oleg Kalachev
24961393a5 Add missing pluginlib dependency to aruco_pose 2024-04-10 21:21:33 +03:00
Oleg Kalachev
f16273c1ae Add rosserial_server to noetic-bookworm.yaml 2024-04-10 21:21:22 +03:00
Oleg Kalachev
9f20448831 Fix shellcheck errors 2024-04-10 21:21:09 +03:00
Oleg Kalachev
343a09a242 Remove printing out /opt/ros 2024-04-10 01:11:05 +03:00
Oleg Kalachev
9355790333 Print out /opt/ros contents 2024-04-05 19:42:25 +03:00
Oleg Kalachev
d07a55334f Change a bit the way of enabling pip packages installation 2024-04-05 19:42:17 +03:00
Oleg Kalachev
72197392fa Enable installing packages with pip 2024-04-05 19:14:55 +03:00
Oleg Kalachev
c91da69552 Add some correct dependencies resolves for bookworm 2024-04-05 18:47:22 +03:00
Oleg Kalachev
8e09a1243a Bring back monkey 2024-04-05 18:47:01 +03:00
Oleg Kalachev
f6594dee62 Try to fix rosdep update another way 2024-04-05 16:00:19 +03:00
Oleg Kalachev
a3fad60aae Try to fix rosdep update from pi: enable preserve-env 2024-04-05 15:31:47 +03:00
Oleg Kalachev
e548cade90 Try to fix rosdep update from pi 2024-04-05 14:54:54 +03:00
Oleg Kalachev
407ab40614 Bring back installation python's pigpio, systemd, espeak, and python3-dev 2024-04-05 14:37:45 +03:00
Oleg Kalachev
90d447734d Set ROS_OS_OVERRIDE 2024-04-05 14:33:37 +03:00
Oleg Kalachev
f5a7dc2b94 Disable packages.ros.org and install rosdep using pip3 2024-04-05 14:21:24 +03:00
Oleg Kalachev
2085b68cec Bring back ws281x 2024-04-05 02:39:21 +03:00
Oleg Kalachev
c5bf88d858 Don't install ws281 for now 2024-04-05 00:39:35 +03:00
Oleg Kalachev
5cf42ee650 Disable monkey 2024-04-04 23:35:48 +03:00
Oleg Kalachev
a5a87f8590 Disable mjpeg-streamer installation 2024-04-04 23:21:28 +03:00
Oleg Kalachev
8c119b8bc9 Use packages.ros.org/ros/ubuntu buster 2024-04-04 23:11:39 +03:00
Oleg Kalachev
b1f36bf966 Disable package.ros.org 2024-04-04 23:06:48 +03:00
Oleg Kalachev
100eca7210 Correctly add coex package source considering Debian release 2024-04-04 23:02:57 +03:00
Oleg Kalachev
3a53b86707 Install liboost-all-dev 2024-04-04 21:51:37 +03:00
Oleg Kalachev
ed623c2e97 Correct debian version codename 2024-04-04 21:16:27 +03:00
Oleg Kalachev
956490b9bc Disable holding opencv 4.2 compatible packages 2024-04-04 21:01:09 +03:00
Oleg Kalachev
5790d4de01 Fix used rosdep file 2024-04-04 20:44:47 +03:00
Oleg Kalachev
bea3149ac5 Fix 2024-04-04 20:29:39 +03:00
Oleg Kalachev
8c56da44fd --break-system-packages 2024-04-04 20:17:17 +03:00
Oleg Kalachev
26bff21253 Don't install Python 2's pip 2024-04-04 19:54:31 +03:00
Oleg Kalachev
eedb028232 Install pip using apt 2024-04-04 19:36:52 +03:00
Oleg Kalachev
c1a7fc7765 Echo commands while installing software 2024-04-04 19:18:01 +03:00
Oleg Kalachev
4ccd5003ad Disable python-pigpio installation 2024-04-03 00:48:39 +03:00
Oleg Kalachev
9dde4d0c51 Disable libjpeg8 install 2024-04-03 00:43:00 +03:00
Oleg Kalachev
23c795f21f Disable ipython installation 2024-04-02 23:52:40 +03:00
Oleg Kalachev
05fc8ff626 Disable some missing packages installation 2024-04-02 23:46:00 +03:00
Oleg Kalachev
380b395c72 Remove cmake=3.13.4-1 installation 2024-04-02 23:08:21 +03:00
Oleg Kalachev
b01f090453 Switch to use prebuilt packages 2024-04-02 23:00:40 +03:00
Qandra Si
3b7242f3d6 docs: Add advanced SSH article (SSH keys) (#503)
---------

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2024-03-12 19:33:55 +03:00
Oleg Kalachev
f1e9e50617 Install future python module 2024-03-08 05:03:37 +03:00
Oleg Kalachev
f0048f804a Set ROS_PYTHON_VERSION to 3 2024-03-08 04:35:42 +03:00
Oleg Kalachev
857d134919 Install cmake 2024-03-08 04:07:20 +03:00
Oleg Kalachev
8f47a26a1b Add Poco library 2024-03-08 03:23:53 +03:00
Oleg Kalachev
77b195c203 Merge branch 'master' into bookworm 2024-03-08 03:22:53 +03:00
Oleg Kalachev
cfeff0c74d Use installed GeographicLib CMake file
As it's done in mavros https://github.com/mavlink/mavros/pull/1775
2024-03-08 02:45:28 +03:00
Oleg Kalachev
bd99923f6b Install python3-empy 2024-03-04 22:13:10 +03:00
Oleg Kalachev
521c248c90 Fix 2024-03-04 21:27:33 +03:00
Oleg Kalachev
7a4f611e47 Fix running install_geographiclib_datasets script 2024-03-04 21:10:27 +03:00
Oleg Kalachev
39cd8d5827 Fix ROS build 2024-03-04 20:47:00 +03:00
Qandra Si
7d022a5af1 docs: improve UART connection to FC section (#502)
* добавил схему подключения fc-uart-rpi, дополнил и уточнил настройки для старой версии px4 (в списке рекомендуемых всё ещё 1.8.2), поправил мелкие опечатки и формулировки в eng-версии, вставил (для общности) изображение не только для fc-uart-rpi, но и для fc-usb-rpi, проверил работоспособность инструкции на своём комплекте с PX4 и прошивкой v1.8.2 (работает с rpi v2.22, и v2.23, и последней v2.24)

---------

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2024-03-04 19:42:04 +03:00
Oleg Kalachev
6fa9442963 Replace libgeographic-dev dependency as suggested 2024-03-01 03:25:27 +03:00
Oleg Kalachev
ce4d84d8c1 Build most of the Clover dependency packages 2024-03-01 01:25:49 +03:00
Oleg Kalachev
ebd9c03251 docs: fix broken image in Flysky RC article 2024-02-23 23:17:10 +03:00
Oleg Kalachev
0356133ab7 Merge branch 'master' into bookworm 2024-02-21 15:07:29 +03:00
Oleg Kalachev
5755300d3a Install image_geometry and dynamic_reconfigure as clover dependencies 2024-02-21 15:04:56 +03:00
Oleg Kalachev
147d6238d5 Fix patching 2024-02-21 00:19:26 +03:00
Oleg Kalachev
9576141376 Apply needed patches 2024-02-20 23:22:27 +03:00
Oleg Kalachev
39f0be296e Set OS to bullseye when doing rosdep update and install
Disable building packages
2024-02-20 21:04:05 +03:00
Oleg Kalachev
8c5551b00b docs: fix anchor link in snippets 2024-02-13 19:22:02 +03:00
Oleg Kalachev
42c26aa645 docs: add a snippet for moving objects in Gazebo 2024-02-13 15:45:27 +03:00
Qandra Si
f91dc4df71 docs: warnings about usage of v1.10- firmwares and QGC (#500)
* сведения о совместимости QGC v4.2.0 / v4.3.0 и прошивок до /после v1.8, v1.0 и готовящейся к выпуску v1.15

* Remove unintended change

* Edit and shorten warnings

---------

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2024-02-08 19:15:03 +03:00
Oleg Kalachev
cf6f8f3488 Install Catkin using pip 2024-02-06 23:09:38 +03:00
Oleg Kalachev
4b059f3145 Skip log4cxx in rosdep 2024-02-06 21:55:01 +03:00
Oleg Kalachev
ce3b6c0cc7 Fix 2024-02-06 21:44:28 +03:00
Oleg Kalachev
9d0499159a Add --break-system-packages flag to pip 2024-02-06 21:34:31 +03:00
Oleg Kalachev
3906bc0318 Install pip using apt 2024-02-06 21:05:14 +03:00
Oleg Kalachev
ee9b3d8fe7 Use --break-system-packages flag for pip 2024-02-06 20:47:07 +03:00
Oleg Kalachev
aac5b25c60 Install rosdep and rosinstall-generator using pip 2024-02-06 20:26:09 +03:00
Oleg Kalachev
5211630542 Uncomment add ROS apt sources 2024-02-06 16:49:43 +03:00
Oleg Kalachev
bb2afd5e9d Fix 2024-02-06 16:38:19 +03:00
Oleg Kalachev
88668897f9 Fix 2024-02-06 16:26:08 +03:00
Oleg Kalachev
36daaddfb2 Correct RPI_IMAGE_NAME 2024-02-06 16:16:51 +03:00
Oleg Kalachev
b5e2073007 Add --allow-releaseinfo-change flag 2024-02-06 16:11:21 +03:00
Oleg Kalachev
1154969af2 Merge branch 'master' into bookworm 2024-02-06 16:09:52 +03:00
Oleg Kalachev
225d8e85ff Foo 2024-02-06 16:08:21 +03:00
Oleg Kalachev
bf29e87cea Use unxz to unarchive image 2024-02-06 16:06:51 +03:00
Oleg Kalachev
24c15f6e65 Decompress image using xz 2024-02-06 16:03:54 +03:00
Oleg Kalachev
d6acb0a202 Base Debian version is update to bookworm 2024-02-06 15:48:25 +03:00
Oleg Kalachev
6defbea453 Update Raspberry Pi OS to 2023-12-11 2024-02-06 15:46:51 +03:00
Oleg Kalachev
e31b69a790 Add possibility to trigger workflows manually 2024-01-22 01:35:52 +03:00
Oleg Kalachev
7251a76315 image: symlink assets instead of copying in documentation to save space 2023-11-04 01:28:00 +03:00
Oleg Kalachev
921e09c392 docs: minor fixes 2023-11-02 17:27:06 +03:00
Oleg Kalachev
9e69bdb01b docs: fix building by new assets size excludes 2023-11-02 06:57:02 +03:00
Oleg Kalachev
50495a9de9 docs: publish mechanical gripper model 2023-11-02 06:52:18 +03:00
Oleg Kalachev
12ccd919a2 docs: fix camera orientation setup example 2023-10-29 14:51:39 +03:00
Oleg Kalachev
f0eacfc0f7 aruco_pose: make dynamic reconfigure generator work with newer versions of OpenCV (#495) 2023-10-14 17:28:37 +03:00
Oleg Kalachev
742d0535c3 docs: add information about EKF2 parameter in PX4 1.14+ 2023-10-11 10:27:05 +03:00
Oleg Kalachev
af1b993e64 led_effect: add led parameter to specify led namespace
When using ROS namespace, subscription to mavros topics is broken
2023-10-11 10:06:18 +03:00
Oleg Kalachev
d3bda9df48 docs: add some additional tests to testing list 2023-10-11 08:30:00 +03:00
Oleg Kalachev
939086362a Run rectify nodelet in tests 2023-10-11 06:40:50 +03:00
Oleg Kalachev
7cf14373b0 main_camera.launch: argument for running image rectification nodelet 2023-10-11 00:51:02 +03:00
Oleg Kalachev
f428dfdb50 image: install stereo-msgs package 2023-10-10 08:46:03 +03:00
Oleg Kalachev
76982dc198 image: install nodelet-topic-tools package 2023-10-10 08:43:20 +03:00
Oleg Kalachev
29f01c25e0 selfcheck.py: support PX4 v1.14 EKF2 aiding parameters change
EKF2_AID_MASK has been split (EKF2_EV_CTRL, EKF2_GPS_CTRL, EKF2_OF_CTRL)
EKF2_HGT_MODE renamed to EKF2_HGT_REF
EKF2_RNG_AID is removed
2023-10-10 08:25:27 +03:00
Oleg Kalachev
7ca0ede1d7 selfcheck.py: cast parameter to int when performing bitwise operations 2023-10-10 07:47:52 +03:00
Oleg Kalachev
c3d87b1608 Update udev rules using data from PX4 sources
Adding Cube Orange, Holybro 6X and many more popular boards
2023-10-10 07:35:42 +03:00
Oleg Kalachev
47901dcff2 selfcheck.py: check udev rules presence and give more useful hint if no mavros state 2023-10-10 06:45:47 +03:00
Oleg Kalachev
9404d4be6d Use image_geometry library in red circle following example 2023-09-20 02:44:26 +03:00
Oleg Kalachev
ad51d86464 docs: add terrain frame to frames list 2023-09-19 15:54:20 +03:00
Oleg Kalachev
9a713057b6 image: add image_geometry package 2023-08-15 17:49:55 +07:00
Oleg Kalachev
7b591d350c aruco_map: fix publishing detected markers count 2023-08-01 17:09:10 +07:00
Oleg Kalachev
2f8915ce31 aruco_map: add ability to pass number of detected markers to Pose covariance field 2023-07-30 14:04:59 +07:00
Oleg Kalachev
6fb84ae584 Remove unneeded line 2023-07-22 13:36:14 +03:00
Oleg Kalachev
bf4f680164 aruco_detect: don't convert image to bgr8 as this is not needed 2023-07-18 17:47:13 +03:00
Oleg Kalachev
c0baf30c96 Move rangefinder frame node out of mavros.launch 2023-07-15 22:05:24 +03:00
Oleg Kalachev
8f2c3b2e55 vpe_publisher: fix code aligning 2023-07-15 20:04:27 +03:00
Oleg Kalachev
6423eb91a2 vpe_publisher: fix calculating the offset in topic mode 2023-07-15 19:15:31 +03:00
Oleg Kalachev
22d7236a47 docs: publish CopterHack-2023 results 2023-05-28 10:05:04 +03:00
Oleg Kalachev
91d33a5961 docs: minor fixes 2023-05-28 09:59:27 +03:00
Oleg Kalachev
2997951371 docs: fix Atena article links to gitbook 2023-05-27 06:26:27 +03:00
Oleg Kalachev
a2ffcf381c docs: workaround for inter-lingual links inarticle 2023-05-27 05:46:49 +03:00
Oleg Kalachev
9aab324f60 docs: enable markdownlint for Atena CopterHack-2023 article 2023-05-23 00:28:54 +03:00
José Carlos Andrade do Nascimento
984fb39b85 docs: Swarm in Blocks 2 (Atena) (CopterHack 2023) (#471)
* Create swarm_in_blocks2.md

* Delete swarm_in_blocks2.md

* Create swarm_in_blocks_2.md

* markdown fixed

* Update swarm_in_blocks_2.md

* markdown first version

* Update swarm_in_blocks_2.md

* markdown fixed

* changing images

* Update swarm_in_blocks_2.md

* Lowercase asset file extension

* Some editing

* linking asstes

* docs: team image link fixed

* removing raw assets from pr

* docs: removing all unused assets

* docs: doc checking unused files

* Reduce logo image size

* Lowercase logo image file

* Rename logo directory

* Fix external images urls, some fix to whitespace

* Add link to CopterHack page in the header

* Add article to summary and CopterHack page

---------

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2023-05-22 23:55:28 +03:00
Oleg Kalachev
3a1a9d486c docs: fix some issues with CopterHack-2023 articles 2023-05-20 08:26:40 +03:00
Oleg Kalachev
55297696d6 docs: add CopterHack articles to summary 2023-05-20 07:49:46 +03:00
Oleg Kalachev
371f244228 docs: update CopterHack teams table 2023-05-20 07:16:49 +03:00
Juli-Shvetsova
ab3e7ac951 docs: CH2023 - Liceu128 (CopterHack-2023) (#473)
* Create liceu128.md

* Update liceu128.md

* Update liceu128.md

* Update liceu128.md

* Edit article

* final liceu128.md

* Edit article

---------

Co-authored-by: микемка <mikemka@vk.com>
Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2023-05-20 07:05:52 +03:00
Max
cdd6195f0b docs: Advanced clover simulation platform (CopterHack-2023) (#472)
* Create advanced_clover_simulator_platform.md

* Write better description

* AdvancedClover article finished

* Some editing

* Reduce images size

---------

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2023-05-20 07:04:55 +03:00
ssmith-81
c9b015148f docs: MoCap-Clover (CopterHack-2023) (#470)
* Create MoCap-Clover

* Rename MoCap-Clover to mocap_clover.md

* Create mocap_logo

* Add files via upload

* Update mocap_clover.md

* Update mocap_clover.md

update

* Update mocap_clover.md

* Update mocap_clover.md

* Add files via upload

* Update mocap_clover.md

* Update mocap_clover.md

* Add files via upload

* Update mocap_clover.md

* Update mocap_clover.md

* Update mocap_clover.md

* Update mocap_clover.md

* Add files via upload

* Update mocap_clover.md

* Add files via upload

* Update mocap_clover.md

* Add files via upload

* Update mocap_clover.md

* Update mocap_clover.md

* Update mocap_clover.md

* Edit article

* Remove unneeded asset

* Reduce sizes of some assets

* Update mocap_clover.md

* Update mocap_clover.md

* Delete docs/assets/mocap_clover directory

* Fix again headers anchors

* Create test

* Add files via upload

* Update mocap_clover.md

* Add files via upload

* Delete test

* Update mocap_clover.md

---------

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2023-05-20 07:00:39 +03:00
Lukerrr
2054472c23 docs: C305: Radio-Navigation System (CopterHack-2023) (#468)
* Create nav-beacon

* Update and rename article

* Fixed article issues

* Update nav-beacon.md

* Update nav-beacon.md

* Update nav-beacon.md

* Update nav-beacon.md

* Update nav-beacon.md

* Update nav-beacon.md

* Edit article

---------

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2023-05-20 06:58:51 +03:00
DJS Phoenix
b1084f99b9 docs: DJS PHOENIX (CopterHack-2023) (#462)
* Create djs_phoenix_chetak.md

* Update djs_phoenix_chetak.md

* Update djs_phoenix_chetak.md

* Update djs_phoenix_chetak.md

* Edit article

* Move English article to en/ subfolder

---------

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2023-05-20 06:58:11 +03:00
Mikhail Kuznetsov
c5f405c4d9 docs: Clover Cloud Platform CopterHack 2023 (#455)
* Create clover-cloud-platform.md

* md fix

* fix link to repositories

* Update clover-cloud-platform.md

* Editing

---------

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2023-05-20 06:57:23 +03:00
Oleg Kalachev
099d39d42d docs: some updates to version warnings 2023-05-20 04:43:32 +03:00
Oleg Kalachev
c9035790f2 image: loose required Python libraries versions, add missing validation 2023-04-17 22:54:18 +03:00
Oleg Kalachev
95da57fea1 docs: fix obsolete link to Ubuntu Focal desktop image 2023-04-12 21:32:38 +03:00
Oleg Kalachev
ad0138cd26 Merge pull request #488 from CopterExpress/v0.24-release
V0.24 release changes
2023-04-12 02:04:59 +03:00
Oleg Kalachev
d6101dc0a3 ci: add secret variable to temporarily freeze updating docs website 2023-04-12 01:34:34 +03:00
Oleg Kalachev
cbba62d165 blocks: add block for reading RC values 2023-04-11 19:35:00 +03:00
Oleg Kalachev
28ddbbcdf9 docs: add version warnings to camera articles 2023-04-11 19:21:53 +03:00
Oleg Kalachev
cac6b59a56 Set the version to 0.24.0 in ROS packages 2023-04-11 15:28:38 +03:00
Oleg Kalachev
c82490a0c1 Set terrain_frame_mode to range by default addressing CopterExpress/clover_vm#14 2023-04-11 15:27:39 +03:00
Oleg Kalachev
808726b4b7 Try to tix the build 2023-04-11 13:33:35 +03:00
Oleg Kalachev
19fde7095f simple_offboard: add test for land service 2023-04-11 01:40:58 +03:00
Oleg Kalachev
5e9f442996 simple_offboard: add terrain_frame_mode parameter, CopterExpress/clover_vm#14
`altitude` mode takes the current altitude from the estimator
`range` mode takes the current altitude from a simple range topic
2023-04-11 01:28:38 +03:00
Oleg Kalachev
68903373b0 simple_offboard: reset stored setpoint on auto_arm only if needed to be armed
CopterExpress/clover_vm#13
2023-04-11 00:57:43 +03:00
Oleg Kalachev
ae05710a37 blocks: fix set_yaw block implementation (#487) 2023-03-27 19:18:21 +03:00
Oleg Kalachev
4c576ba5d4 builder: print largest installed packages 2023-02-22 00:42:06 +03:00
Oleg Kalachev
ffd8b98e53 Merge branch 'master' into v0.24-release 2023-02-07 10:06:27 +03:00
Oleg Kalachev
69deeae32f blocks: document ~print topic of the main node 2023-02-07 10:06:09 +03:00
Oleg Kalachev
df66deb32c docs: add running flight autotests to testing plan 2023-02-07 10:03:41 +03:00
Oleg Kalachev
87a51221bc docs: update documentation for autonomous flights 2023-02-07 10:02:02 +03:00
Oleg Kalachev
08bda736e9 aruco_detect: fix drawing markers axis 2023-01-26 18:16:24 +03:00
Oleg Kalachev
cb2850b1d4 docs: update CopterHack-2023 project link 2023-01-12 00:45:27 +03:00
Oleg Kalachev
9e8470a3cb Install TinyXML 2022-10-11 16:05:47 +06:00
Oleg Kalachev
e9cd3d917c Try to fix --install-layout not recognized issue 2022-10-08 19:54:19 +06:00
Oleg Kalachev
373cefb01c Remove fakeroot as we are root 2022-10-07 22:51:34 +06:00
Oleg Kalachev
d0039ea23f Typo 2022-10-07 20:44:20 +06:00
Oleg Kalachev
bd25818aa7 Add rosdep file to help bloom-generate resolve Bullseye dependencies 2022-10-07 14:34:30 +06:00
Oleg Kalachev
a73457c5c5 Debug 2022-10-07 14:08:10 +06:00
Oleg Kalachev
c8a4d49577 Try to build from catkin workdspace 2022-10-06 23:24:12 +06:00
Oleg Kalachev
123379b60e Fix 2022-10-06 23:23:21 +06:00
Oleg Kalachev
71d3144691 fix 2022-10-06 15:18:14 +06:00
Oleg Kalachev
d306a9d96d Try 2022-10-05 17:45:49 +06:00
Oleg Kalachev
1d514cf5ca Merge branch 'master' into bullseye 2022-10-05 17:42:06 +06:00
Oleg Kalachev
96adadeae9 Put Debian build log to file 2022-09-24 18:14:44 +03:00
Oleg Kalachev
a1061ff32c Add ls 2022-09-24 13:46:34 +03:00
Oleg Kalachev
e9d13b865c Build Debian packages 2022-09-24 12:58:56 +03:00
Oleg Kalachev
b655a4274e List built ROS packages 2022-09-23 23:10:20 +03:00
Oleg Kalachev
d58a59afab Fix 2022-09-23 22:48:19 +03:00
Oleg Kalachev
d0fabd8b3e Fix 2022-09-23 19:40:06 +03:00
Oleg Kalachev
b50207e5e9 Install ROS to /opt/ros/ 2022-09-23 18:44:18 +03:00
Oleg Kalachev
97797a9178 Fix 2022-09-23 15:53:20 +03:00
Oleg Kalachev
1e8569b664 Fix 2022-09-23 15:35:23 +03:00
Oleg Kalachev
21cc47eecb Fix 2022-09-23 15:20:09 +03:00
Oleg Kalachev
4c56adafb2 Fix 2022-09-23 03:17:30 +03:00
Oleg Kalachev
8a524a8aa5 Fix 2022-09-23 03:11:47 +03:00
Oleg Kalachev
5493445747 Manually install catkin_pkg 2022-09-23 03:04:30 +03:00
Oleg Kalachev
0ef26334dc Fix 2022-09-23 02:45:52 +03:00
Oleg Kalachev
8d83e8faa3 Add ROS sources for Ubuntu 2022-09-23 02:36:01 +03:00
Oleg Kalachev
9b90214d9d Try to fix 2022-09-23 01:53:56 +03:00
Oleg Kalachev
224f6cee27 Fix 2022-09-23 01:38:59 +03:00
Oleg Kalachev
ff04b2fb75 Fix 2022-09-23 01:21:12 +03:00
Oleg Kalachev
473444ae33 Fix 2022-09-23 01:13:41 +03:00
Oleg Kalachev
168734ad8c Remove sources list before rosdep init 2022-09-23 00:56:49 +03:00
Oleg Kalachev
4e7b2e379a Restore rosdep init 2022-09-23 00:50:29 +03:00
Oleg Kalachev
ad1d51fd9e Fix 2022-09-23 00:42:20 +03:00
Oleg Kalachev
57c415db22 Add os flag to rosdep update 2022-09-23 00:32:35 +03:00
Oleg Kalachev
568386a758 Install GeographicLib datasets in build workflow 2022-09-23 00:31:21 +03:00
Oleg Kalachev
55f8f4fa1a aruco_detect: check for duplicates in marker transforms, send all transforms in one message 2022-09-23 00:31:19 +03:00
Oleg Kalachev
dd0dd6b5c1 aruco_pose: add duplicate test to CMakeLists.txt 2022-09-23 00:31:19 +03:00
Oleg Kalachev
4c40bea226 aruco_pose: implement test for TF_REPEATED_DATA when multiple markers with the same ID 2022-09-23 00:31:18 +03:00
Oleg Kalachev
6b3f5c3690 Simplify script for testing native Noetic build 2022-09-23 00:31:18 +03:00
Oleg Kalachev
63067823ee Show number of messages received in topic viewer 2022-09-23 00:31:17 +03:00
Oleg Kalachev
880f67c3bc Fix error when viewing messages without header in topic viewer 2022-09-23 00:31:17 +03:00
Oleg Kalachev
839aeb6a26 clover.launch: make force_init argument overridable externally 2022-09-23 00:31:16 +03:00
Oleg Kalachev
b123585756 mavros.launch: fix fcu_url for hitl connection 2022-09-23 00:31:16 +03:00
Oleg Kalachev
fa4757a4c8 mavros.launch: add hitl option for fcu_conn argument 2022-09-23 00:31:15 +03:00
Oleg Kalachev
28d77aea33 selfcheck.py: skip boot duration check on not Clover image 2022-09-23 00:31:15 +03:00
Oleg Kalachev
0425e1da24 optical_flow: timeout for previous frame
For cases when optical flow is dynamically disabled and enabled back
2022-09-23 00:31:14 +03:00
Oleg Kalachev
692d424a0b Remove obsolete note from readme 2022-09-23 00:31:14 +03:00
Oleg Kalachev
1c9fd7b126 docs: remove some obsolete notes about renaming 2022-09-23 00:31:13 +03:00
oponfil
a1752c1642 docs: update connection article (en) (#363)
* Add instructions on how to connect FMU to Raspberry Pi by UART

* Remove sitl connection section

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2022-09-23 00:31:13 +03:00
oponfil
0dbd2d1048 docs: update connection article (#362)
* Add instructions on how to connect FMU to Raspberry Pi by UART

* Remove inactual sitl connection

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2022-09-23 00:31:12 +03:00
oponfil
79408861a2 docs: docs: correction in mavros article on global setpoints (en) (#358)
Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2022-09-23 00:31:12 +03:00
oponfil
063f2c3c13 docs: correction in mavros article on global setpoints (#357)
Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2022-09-23 00:31:10 +03:00
Oleg Kalachev
68819bbd34 docs: update PX4 to v1.12.3 in native simulation installation article 2022-09-23 00:31:10 +03:00
Oleg Kalachev
3a5c3d5bb4 docs: comment out link to install_software.sh in simulation installation manual
The link confuses users so they often try to run it
2022-09-23 00:31:09 +03:00
Oleg Kalachev
032eb52a88 Fix python-pymavlink installation adding some lxml dependencies
Otherwise installation falls with:
Error: Please make sure the libxml2 and libxslt development packages are installed
2022-09-23 00:31:09 +03:00
Oleg Kalachev
7dc24437cf vpe_publisher: fix reading map and base link frame_id from mavros 2022-09-23 00:31:08 +03:00
Oleg Kalachev
1ccb756931 Update docs job runner to ubuntu 22.04
https://github.com/actions/runner-images/issues/6002
2022-09-23 00:31:08 +03:00
Oleg Kalachev
b5268a7b62 Deploy docs using build artifacts instead of gh-pages branch (#452)
https://github.blog/changelog/2021-12-16-github-pages-using-github-actions-for-builds-and-deployments-for-public-repositories/
2022-09-23 00:31:07 +03:00
Elena Seliverstova
a0663d6b36 Update the contact link in Telegram 2022-09-23 00:31:07 +03:00
Elena Seliverstova
26f2c966ff Update the contact link in Telegram 2022-09-23 00:31:06 +03:00
Elena Seliverstova
4517186862 docs: add new articles about CopterHack2023 (#450) 2022-09-23 00:31:06 +03:00
Oleg Kalachev
5236afe035 Make PX4 node required in the sim 2022-09-23 00:31:05 +03:00
Oleg Kalachev
fe1707d0c3 simulator: change COM_RCL_EXCEPT param to enable offboard flights without RC on PX4 v1.13 2022-09-23 00:31:05 +03:00
Oleg Kalachev
03854d2589 Implement dynamic reconfiguration for aruco_map (#448) 2022-09-23 00:31:04 +03:00
Niels Hoppe
28339e65af Add missing dependency 2022-09-23 00:31:04 +03:00
Oleg Kalachev
e11f0cf054 Minor whitespace fix 2022-09-23 00:31:03 +03:00
Oleg Kalachev
c1045cd11e Add shortcut launch-file to run the simulation 2022-09-23 00:31:03 +03:00
Oleg Kalachev
aa3373da58 docs: redirect for blocks programming article 2022-09-23 00:31:01 +03:00
Oleg Kalachev
a4ad408228 Restore rosdep update 2022-09-23 00:09:09 +03:00
Oleg Kalachev
0d436637cd Trigger build 2022-09-22 23:59:23 +03:00
Oleg Kalachev
18daff1044 Fix 2022-06-18 00:11:51 +03:00
Oleg Kalachev
b96d17a746 Fix 2022-06-18 00:00:47 +03:00
Oleg Kalachev
1506d3fd96 Fix 2022-06-17 23:55:15 +03:00
Oleg Kalachev
eec0833707 Merge branch 'master' into bullseye 2022-06-17 22:14:41 +03:00
Oleg Kalachev
f9883baa87 builder: script to build ROS from scratch 2022-02-09 19:42:18 +03:00
Oleg Kalachev
3bebecf91e Update Raspberry Pi OS to 2022-01-28 (bullseye) 2022-02-05 19:40:06 +03:00
119 changed files with 3889 additions and 629 deletions

View File

@@ -7,6 +7,7 @@ on:
branches: [ master ]
release:
types: [ created ]
workflow_dispatch:
jobs:
build:
@@ -16,14 +17,24 @@ jobs:
- 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
# - 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: |
cd images && sudo chmod -R 777 . && zip -9 $(echo clover_*).zip clover_* && ls -l . && unzip -l clover_*.zip
cd images && sudo chmod -R 777 . && 7z a -mx=9 $(echo *_*).7z *_* && ls -lh . && 7z l *_*.7z
- 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 }}
- 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

View File

@@ -5,6 +5,7 @@ on:
branches: [ '*' ]
pull_request:
branches: [ master ]
workflow_dispatch:
jobs:
# melodic:

View File

@@ -5,6 +5,7 @@ on:
branches: [ '*' ]
pull_request:
branches: [ '*' ]
workflow_dispatch:
permissions:
contents: read
@@ -81,5 +82,8 @@ jobs:
needs: docs
steps:
- name: Deploy to GitHub Pages
env:
FREEZE_DOCS: ${{ secrets.FREEZE_DOCS }}
if: ${{ !env.FREEZE_DOCS }}
id: deployment
uses: actions/deploy-pages@v1

View File

@@ -5,6 +5,7 @@ on:
branches: [ '*' ]
pull_request:
branches: [ master ]
workflow_dispatch:
jobs:
editorconfig:

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

@@ -4,7 +4,10 @@ PACKAGE = "aruco_pose"
from dynamic_reconfigure.parameter_generator_catkin import *
import cv2.aruco
p = cv2.aruco.DetectorParameters_create()
try:
p = cv2.aruco.DetectorParameters_create()
except AttributeError:
p = cv2.aruco.DetectorParameters()
gen = ParameterGenerator()

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<package format="3">
<name>aruco_pose</name>
<version>0.23.0</version>
<version>0.24.0</version>
<description>Positioning with ArUco markers</description>
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
@@ -28,6 +28,7 @@
<depend>sensor_msgs</depend>
<depend>rostest</depend>
<depend>dynamic_reconfigure</depend>
<depend>pluginlib</depend>
<depend condition="$ROS_PYTHON_VERSION == 2">python-docopt</depend>
<depend condition="$ROS_PYTHON_VERSION == 3">python3-docopt</depend>

View File

@@ -50,6 +50,7 @@
#include <aruco_pose/DetectorConfig.h>
#include <aruco_pose/SetMarkers.h>
#include "draw.h"
#include "utils.h"
#include <memory>
#include <functional>
@@ -139,7 +140,7 @@ private:
if (!enabled_) return;
if (waiting_for_map_) return;
Mat image = cv_bridge::toCvShare(msg, "bgr8")->image;
Mat image = cv_bridge::toCvShare(msg)->image;
vector<int> ids;
vector<vector<cv::Point2f>> corners, rejected;
@@ -264,8 +265,7 @@ private:
cv::aruco::drawDetectedMarkers(debug, corners, ids); // draw markers
if (estimate_poses_)
for (unsigned int i = 0; i < ids.size(); i++)
cv::aruco::drawAxis(debug, camera_matrix_, dist_coeffs_,
rvecs[i], tvecs[i], getMarkerLength(ids[i]));
_drawAxis(debug, camera_matrix_, dist_coeffs_, rvecs[i], tvecs[i], getMarkerLength(ids[i]));
cv_bridge::CvImage out_msg;
out_msg.header.frame_id = msg->header.frame_id;

View File

@@ -83,7 +83,7 @@ private:
visualization_msgs::MarkerArray vis_array_;
std::string known_vertical_, map_, markers_frame_, markers_parent_frame_;
int image_width_, image_height_, image_margin_;
bool flip_vertical_, auto_flip_, image_axis_;
bool flip_vertical_, auto_flip_, image_axis_, put_markers_count_to_covariance_;
public:
virtual void onInit()
@@ -111,6 +111,7 @@ public:
image_height_ = nh_priv_.param("image_height", 2000);
image_margin_ = nh_priv_.param("image_margin", 200);
image_axis_ = nh_priv_.param("image_axis", true);
put_markers_count_to_covariance_ = nh_priv_.param("put_markers_count_to_covariance", false);
markers_parent_frame_ = nh_priv_.param<std::string>("markers/frame_id", transform_.child_frame_id);
markers_frame_ = nh_priv_.param<std::string>("markers/child_frame_id_prefix", "");
@@ -178,6 +179,20 @@ public:
corners.push_back(marker_corners);
}
if (put_markers_count_to_covariance_) {
// HACK: pass markers count using covariance field
int valid_markers = 0;
for (auto const &marker : markers->markers) {
for (auto const &board_marker : board_->ids) {
if (board_marker == marker.id) {
valid_markers++;
break;
}
}
}
pose_.pose.covariance[0] = valid_markers;
}
if (known_vertical_.empty()) {
// simple estimation
valid = cv::aruco::estimatePoseBoard(corners, ids, board_, camera_matrix_, dist_coeffs_,

View File

@@ -5,7 +5,7 @@ Requires=roscore.service
[Service]
User=pi
ExecStart=/bin/bash -c ". /home/pi/catkin_ws/devel/setup.sh; \
ROS_HOSTNAME=`hostname`.local exec stdbuf -o L roslaunch clover clover.launch --wait --screen --skip-log-check \
ROS_HOSTNAME=`hostname`.local ROS_OS_OVERRIDE=debian:bookworm exec stdbuf -o L roslaunch clover clover.launch --wait --screen --skip-log-check \
2> >(tee /tmp/clover.err)"
ExecStartPre=+rm /var/log/clover.log

View File

@@ -13,70 +13,38 @@
# copies or substantial portions of the Software.
#
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://www.raspberrypi.com/documentation/computers/configuration.html
##################################################
# Configure hardware interfaces
##################################################
# 1. Enable sshd
echo_stamp "#1 Turn on sshd"
touch /boot/ssh
# /usr/bin/raspi-config nonint do_ssh 0
echo "--- Enable sshd"
/usr/bin/raspi-config nonint do_ssh 0
# 2. Enable GPIO
echo_stamp "#2 GPIO enabled by default"
echo "--- GPIO enabled by default"
# 3. Enable I2C
echo_stamp "#3 Turn on I2C"
echo "--- Enable I2C"
/usr/bin/raspi-config nonint do_i2c 0
# 4. Enable SPI
echo_stamp "#4 Turn on SPI"
echo "--- Enable SPI"
/usr/bin/raspi-config nonint do_spi 0
# 5. Enable raspicam
echo_stamp "#5 Turn on raspicam"
echo "--- Enable raspicam"
/usr/bin/raspi-config nonint do_camera 0
# 6. Enable hardware UART
echo_stamp "#6 Turn on UART"
echo "--- Setup UART"
# Temporary solution
# https://github.com/RPi-Distro/raspi-config/pull/75
/usr/bin/raspi-config nonint do_serial 1
/usr/bin/raspi-config nonint set_config_var enable_uart 1 /boot/config.txt
echo dtoverlay=pi3-disable-bt >> /boot/config.txt
/usr/bin/raspi-config nonint do_serial_hw 0
/usr/bin/raspi-config nonint do_serial_cons 1
echo dtoverlay=pi3-disable-bt >> /boot/firmware/config.txt
systemctl disable hciuart.service
# After adding to Raspbian OS
# 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 "--- Enable v4l2 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

@@ -13,63 +13,31 @@
# copies or substantial portions of the Software.
#
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 "--- Fix home directory permissions"
chmod +rx /home/pi
NEW_SSID='clover-'$(head -c 100 /dev/urandom | xxd -ps -c 100 | sed -e "s/[^0-9]//g" | cut -c 1-4)
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.
cat << EOF >> /boot/wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
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
echo "--- Creating Wi-Fi AP with SSID=${NEW_SSID}"
nmcli con add type wifi ifname wlan0 mode ap con-name clover ssid $NEW_SSID autoconnect true \
&& nmcli con modify clover 802-11-wireless.band bg \
&& nmcli con modify clover ipv4.method shared ipv4.address 192.168.11.1/24 \
&& nmcli con modify clover ipv6.method disabled \
&& nmcli con modify clover wifi-sec.key-mgmt wpa-psk \
&& nmcli con modify clover wifi-sec.psk "cloverwifi" \
&& systemctl disable dnsmasq # disable dnsmasq to avoid conflicts with NetworkManager's dnsmasq
NEW_HOSTNAME=$(echo ${NEW_SSID} | tr '[:upper:]' '[:lower:]')
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
echo "--- 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_stamp "Enable ROS services"
echo "--- Enable ROS services"
systemctl enable roscore
systemctl enable clover
echo_stamp "Harware setup"
echo "--- Harware setup"
/root/hardware_setup.sh
echo_stamp "Remove init scripts"
echo "--- Remove init scripts"
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

122
builder/image-build-ros.sh Executable file
View File

@@ -0,0 +1,122 @@
#! /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

View File

@@ -13,42 +13,22 @@
# copies or substantial portions of the Software.
#
set -e # Exit immidiately on non-zero result
set -ex # exit on error, echo commands
# 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"
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"
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_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"
[[ ! -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"
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)}"
@@ -64,15 +44,17 @@ get_image() {
local RPI_IMAGE_NAME=$(echo ${RPI_ZIP_NAME} | sed 's/zip/img/')
if [ ! -e "${BUILD_DIR}/${RPI_ZIP_NAME}" ]; then
echo_stamp "Downloading original Linux distribution"
echo "--- Downloading original Linux distribution"
wget --progress=dot:giga -O ${BUILD_DIR}/${RPI_ZIP_NAME} $2
echo_stamp "Downloading complete" "SUCCESS" \
else echo_stamp "Linux distribution already donwloaded"; fi
echo "--- Downloading complete" "SUCCESS"
else
echo "Linux distribution already downloaded"
fi
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)
echo "--- Unzipping Linux distribution image"
apt-get update --allow-releaseinfo-change
apt-get install -y xz-utils
unxz --stdout ${BUILD_DIR}/${RPI_ZIP_NAME} > $1
}
get_image ${IMAGE_PATH} ${SOURCE_IMAGE}
@@ -120,6 +102,7 @@ ${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/'
# 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-build-ros.sh'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-validate.sh'
${BUILDER_DIR}/image-resize.sh ${IMAGE_PATH}

View File

@@ -12,50 +12,33 @@
# copies or substantial portions of the Software.
#
set -e # Exit immidiately on non-zero result
set -ex # exit on error, echo commands
echo_stamp() {
# TEMPLATE: echo_stamp <TEXT> <TYPE>
# TYPE: SUCCESS, ERROR, INFO
echo "--- Move /etc/ld.so.preload out of the way"
mv /etc/ld.so.preload /etc/ld.so.preload.disabled-for-build
# 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 "--- Create pi user"
echo 'pi:$6$c70VpvPsVNCG0YR5$l5vWWLsLko9Kj65gcQ8qvMkuOoRkEagI90qi3F/Y7rm8eNYZHW8CY6BOIKwMH7a3YYzZYL90zf304cAHLFaZE0' > /boot/userconf.txt
echo "--- Write Clover information"
# Clover image version
echo "$1" >> /etc/clover_version
# Origin image file name
echo "${2%.*}" >> /etc/clover_origin
echo_stamp "Write magic script to /etc/rc.local"
echo "--- 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
# TODO: remake to oneshot systemd service
# It needs for autosizer.sh & maybe that is correct
echo_stamp "Change boot partition"
echo "--- 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/.* \/boot\/firmware vfat defaults 0 2$/\/dev\/mmcblk0p1 \/boot\/firmware vfat defaults 0 2/' /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_stamp "Set max space for syslogs"
echo "--- 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_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"

View File

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

View File

@@ -15,44 +15,20 @@
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}
}
. /etc/os-release # set $VERSION_CODENAME to Debian release code name
export ROS_OS_OVERRIDE=debian:$VERSION_CODENAME
# https://gist.github.com/letmaik/caa0f6cc4375cbfcc1ff26bd4530c2a3
# https://github.com/travis-ci/travis-build/blob/master/lib/travis/build/templates/header.sh
my_travis_retry() {
local result=0
local count=1
local max_count=50
local max_count=5
while [ $count -le $max_count ]; do
[ $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
! { "$@"; result=$?; }
@@ -62,127 +38,136 @@ my_travis_retry() {
done
[ $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
}
echo "--- Install rosdep"
my_travis_retry pip3 install -U rosdep
# TODO: 'kinetic-rosdep-clover.yaml' should add only if we use our repo?
echo_stamp "Init rosdep"
echo "--- 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/20-default.list
echo "--- Update rosdep"
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_stamp "Populate rosdep for ROS user"
my_travis_retry sudo -u pi rosdep update
echo "--- Populate rosdep for ROS user"
my_travis_retry sudo -u pi ROS_OS_OVERRIDE=debian:$VERSION_CODENAME rosdep update
export ROS_IP='127.0.0.1' # needed for running tests
# echo_stamp "Reconfiguring Clover repository for simplier unshallowing"
# echo "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_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 \
ros-${ROS_DISTRO}-cv-camera=0.5.1-0buster \
ros-${ROS_DISTRO}-image-publisher=1.15.3-0buster \
ros-${ROS_DISTRO}-web-video-server=0.2.1-0buster
apt-mark hold \
ros-${ROS_DISTRO}-compressed-image-transport \
ros-${ROS_DISTRO}-cv-bridge \
ros-${ROS_DISTRO}-cv-camera \
ros-${ROS_DISTRO}-image-publisher \
ros-${ROS_DISTRO}-web-video-server
# echo "--- 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 \
# ros-${ROS_DISTRO}-cv-camera=0.5.1-0buster \
# ros-${ROS_DISTRO}-image-publisher=1.15.3-0buster \
# ros-${ROS_DISTRO}-web-video-server=0.2.1-0buster
# apt-mark hold \
# ros-${ROS_DISTRO}-compressed-image-transport \
# ros-${ROS_DISTRO}-cv-bridge \
# ros-${ROS_DISTRO}-cv-camera \
# ros-${ROS_DISTRO}-image-publisher \
# ros-${ROS_DISTRO}-web-video-server
echo_stamp "Installing libboost-dev" # https://travis-ci.org/github/CopterExpress/clover/jobs/766318908#L6536
my_travis_retry apt-get install -y --no-install-recommends libboost-dev libboost-all-dev
#echo "--- Installing libboost-dev" # https://travis-ci.org/github/CopterExpress/clover/jobs/766318908#L6536
#my_travis_retry apt-get install -y --no-install-recommends libboost-dev libboost-all-dev
echo_stamp "Build and install Clover"
echo "--- 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 \
--skip-keys=gazebo_ros --skip-keys=gazebo_plugins
my_travis_retry rosdep install -y --from-paths src --ignore-src --rosdistro ${ROS_DISTRO} --os=debian:$VERSION_CODENAME \
--skip-keys="gazebo_ros gazebo_plugins"
my_travis_retry pip3 install wheel
my_travis_retry pip3 install -r /home/pi/catkin_ws/src/clover/clover/requirements.txt
source /opt/ros/${ROS_DISTRO}/setup.bash
# Don't build simulation plugins for actual drone
catkin_make -j2 -DCMAKE_BUILD_TYPE=RelWithDebInfo
source devel/setup.bash
echo_stamp "Install clever package (for backwards compatibility)"
echo "--- 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_stamp "Build Clover documentation"
echo "--- Build Clover documentation"
cd /home/pi/catkin_ws/src/clover
builder/assets/install_gitbook.sh
gitbook install
gitbook build
# replace assets copy to assets symlink to save space
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
npm cache clean --force
echo_stamp "Installing additional ROS packages"
echo "--- Installing additional ROS packages"
my_travis_retry apt-get install -y --no-install-recommends \
ros-${ROS_DISTRO}-dynamic-reconfigure \
ros-${ROS_DISTRO}-rosbridge-suite \
ros-${ROS_DISTRO}-rosserial \
ros-${ROS_DISTRO}-usb-cam \
ros-${ROS_DISTRO}-vl53l1x \
ros-${ROS_DISTRO}-ws281x \
ros-${ROS_DISTRO}-libcamera-ros \
ros-${ROS_DISTRO}-rosshow \
ros-${ROS_DISTRO}-cmake-modules \
ros-${ROS_DISTRO}-image-view
ros-${ROS_DISTRO}-image-view \
ros-${ROS_DISTRO}-nodelet-topic-tools \
ros-${ROS_DISTRO}-stereo-msgs \
ros-${ROS_DISTRO}-vision-msgs
# TODO move GeographicLib datasets to Mavros debian package
echo_stamp "Install GeographicLib datasets (needed for mavros)" \
echo "--- Install GeographicLib datasets (needed for mavros)" \
&& wget -qO- https://raw.githubusercontent.com/mavlink/mavros/master/mavros/scripts/install_geographiclib_datasets.sh | bash
echo_stamp "Running tests"
echo "--- Running tests"
export ROS_IP='127.0.0.1' # needed for running tests
cd /home/pi/catkin_ws
# FIXME: Investigate failing tests
catkin_make run_tests #&& catkin_test_results
echo_stamp "Change permissions for catkin_ws"
echo "--- Change permissions for catkin_ws"
chown -Rf pi:pi /home/pi/catkin_ws
echo_stamp "Update www"
echo "--- Update www"
sudo -u pi sh -c ". devel/setup.sh && rosrun clover www"
echo_stamp "Make \$HOME/examples symlink"
echo "--- Make \$HOME/examples symlink"
ln -s "$(catkin_find clover examples --first-only)" /home/pi
chown -Rf pi:pi /home/pi/examples
echo_stamp "Make systemd services symlinks"
echo "--- 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_stamp "Make udev rules symlink"
echo "--- Make udev rules symlink"
ln -s "$(catkin_find clover udev --first-only)"/* /lib/udev/rules.d/
echo_stamp "Setup ROS environment"
echo "--- Setup ROS environment"
cat << EOF >> /home/pi/.bashrc
LANG='C.UTF-8'
LC_ALL='C.UTF-8'
export ROS_HOSTNAME=\`hostname\`.local
export ROS_OS_OVERRIDE=debian:bookworm
source /opt/ros/${ROS_DISTRO}/setup.bash
source /home/pi/catkin_ws/devel/setup.bash
EOF
#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 "--- Cleanup apt"
apt-get autoremove --purge -y
apt-get clean
echo_stamp "END of ROS INSTALLATION"
echo "--- Cleanup pip"
pip3 cache purge
echo "--- Cleanup /tmp"
rm -rf /tmp/*

View File

@@ -12,27 +12,9 @@
# copies or substantial portions of the Software.
#
set -e # Exit immidiately on non-zero result
set -ex # exit on error, echo commands
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}
}
. /etc/os-release # set $VERSION_CODENAME to Debian release code name
# https://gist.github.com/letmaik/caa0f6cc4375cbfcc1ff26bd4530c2a3
# https://github.com/travis-ci/travis-build/blob/master/lib/travis/build/templates/header.sh
@@ -41,7 +23,7 @@ my_travis_retry() {
local count=1
while [ $count -le 3 ]; do
[ $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
! { "$@"; result=$?; }
@@ -51,41 +33,39 @@ my_travis_retry() {
done
[ $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
}
echo_stamp "Increase apt retries"
echo "--- Increase apt retries"
echo "APT::Acquire::Retries \"3\";" > /etc/apt/apt.conf.d/80-retries
echo_stamp "Install apt keys & repos"
echo "--- Install apt keys & repos"
# TODO: This STDOUT consist 'OK'
apt-get update \
&& apt-get install --no-install-recommends -y dirmngr > /dev/null \
&& 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 -
echo 'deb http://packages.coex.tech buster main' >> /etc/apt/sources.list
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_stamp "Update apt cache"
echo "--- 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_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
echo "--- Install software"
my_travis_retry apt-get install --no-install-recommends -y cmake-data cmake
my_travis_retry apt-get install --no-install-recommends -y \
unzip \
zip \
ipython \
ipython3 \
screen \
byobu \
@@ -96,64 +76,57 @@ dnsmasq \
tmux \
tree \
vim \
libjpeg8 \
tcpdump \
libpoco-dev \
libzbar0 \
python3-rosdep \
python3-rosinstall-generator \
python3-wstool \
python3-rosinstall \
build-essential \
libffi-dev \
monkey \
pigpio python-pigpio python3-pigpio \
pigpio python3-pigpio \
i2c-tools \
espeak espeak-data python-espeak python3-espeak \
espeak espeak-data python3-espeak \
ntpdate \
python-dev \
python3-dev \
python-systemd \
mjpg-streamer \
python3-opencv
xxd \
python3-dev \
python3-systemd \
python3-opencv \
python3-pip
#libjpeg8 \
# Deny byobu to check available updates
sed -i "s/updates_available//" /usr/share/byobu/status/status
# sed -i "s/updates_available//" /home/pi/.byobu/status
echo_stamp "Installing pip"
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip2.py
python3 get-pip.py
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"
echo "--- Make sure pip is installed"
pip --version
pip3 --version
echo_stamp "Install and enable Butterfly (web terminal)"
echo_stamp "Workaround for tornado >= 6.0 breaking butterfly"
echo "--- Enable installing packages with pip"
mv /usr/lib/python3.11/EXTERNALLY-MANAGED /usr/lib/python3.11/EXTERNALLY-MANAGED.old
echo "--- Install and enable Butterfly (web terminal)"
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
my_travis_retry pip3 install tornado==5.1.1
#my_travis_retry pip3 install pyOpenSSL==20.0.1
#my_travis_retry pip3 install tornado==5.1.1
my_travis_retry pip3 install butterfly
my_travis_retry pip3 install butterfly[systemd]
systemctl enable butterfly.socket
echo_stamp "Install ws281x library"
echo "--- Install ws281x library"
my_travis_retry pip3 install --prefer-binary rpi_ws281x
echo_stamp "Setup Monkey"
echo "--- 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_stamp "Install Node.js"
echo "--- 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
@@ -161,28 +134,24 @@ 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_stamp "Installing ptvsd"
my_travis_retry pip install ptvsd
my_travis_retry pip3 install ptvsd
echo "--- Installing debugpy"
my_travis_retry pip3 install debugpy
echo_stamp "Installing pyzbar"
my_travis_retry pip install pyzbar
echo "--- Installing pyzbar"
my_travis_retry pip3 install pyzbar
echo_stamp "Add .vimrc"
echo "--- Add .vimrc"
cat << EOF > /home/pi/.vimrc
set mouse-=a
syntax on
autocmd BufNewFile,BufRead *.launch set syntax=xml
EOF
echo_stamp "Change default keyboard layout to US"
echo "--- Change default keyboard layout to US"
sed -i 's/XKBLAYOUT="gb"/XKBLAYOUT="us"/g' /etc/default/keyboard
echo_stamp "Attempting to kill dirmngr"
echo "--- 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,28 +12,33 @@
# copies or substantial portions of the Software.
#
set -ex
set -ex # exit on error, echo commands
echo "Run image tests"
echo "--- Run image tests"
export ROS_DISTRO='noetic'
export ROS_IP='127.0.0.1'
source /opt/ros/${ROS_DISTRO}/setup.bash
source /home/pi/catkin_ws/devel/setup.bash
systemctl start roscore
cd /home/pi/catkin_ws/src/clover/builder/test/
./tests.sh
./tests.py
./tests_py3.py
[[ $(./test_qr.py) == "Found QRCODE with data Проверка Unicode with center at x=66.0, y=66.0" ]]
[[ $(./tests_clever.py) == "Warning: clever package is renamed to clover" ]] # test backwards compatibility
systemctl stop roscore
# check documented packages available
apt-cache show gst-rtsp-launch
apt-cache show openvpn
echo "Largest packages installed"
sudo -E sh -c 'apt-get install -y debian-goodies'
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

View File

@@ -23,6 +23,10 @@ from clover.srv import GetTelemetry, Navigate, NavigateGlobal, SetPosition, SetV
from led_msgs.srv import SetLEDs
from led_msgs.msg import LEDStateArray, LEDState
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
import dynamic_reconfigure.client
@@ -33,9 +37,12 @@ import tf2_geometry_msgs
import VL53L1X
import pymavlink
from pymavlink import mavutil
from image_geometry import PinholeCameraModel, StereoCameraModel
# from espeak import espeak
from pyzbar import pyzbar
import docopt
import geopy
import flask
print(cv2.getBuildInformation())

View File

@@ -1,12 +1,11 @@
#!/usr/bin/env bash
set -ex
set -ex # exit on error, echo commands
# TODO: validate versions
# validate required software is installed
python2 --version
python3 --version
ipython3 --version
@@ -22,30 +21,28 @@ pip --version
pip3 --version
tcpdump --version
monkey --version
# espeak --version
espeak --version
xxd --version
systemctl --version
if [ -z $VM ]; then
# rpi only software
python --version
ipython --version
pip2 --version
# `python` is python2 for now
[[ $(python -c 'import sys;print(sys.version_info.major)') == "2" ]]
[[ $(python -c 'import sys;print(sys.version_info.major)') == "3" ]]
# ptvsd does not have a stand-alone binary
python -m ptvsd --version
python3 -m ptvsd --version
python -m debugpy --version
python3 -m debugpy --version
pigpiod -v
i2cdetect -V
butterfly -h
/usr/local/bin/butterfly.server.py --help
mjpg_streamer --version
fi
# ros stuff
roscore -h
catkin_find
rosversion clover
rosversion aruco_pose
rosversion mavros
@@ -61,14 +58,14 @@ rosversion web_video_server
rosversion nodelet
rosversion image_view
[[ $(rosversion ws281x) == "0.0.13" ]]
[[ $(rosversion ws281x) == "0.0.15" ]]
if [ -z $VM ]; then
rosversion compressed_image_transport
# rosversion compressed_image_transport
rosversion rosshow
rosversion vl53l1x
rosversion rosserial
[[ $(rosversion cv_camera) == "0.5.1" ]] # patched version with init fix
[[ $(rosversion cv_camera) == "0.6.1" ]] # patched version with init fix
fi
# determine user home directory

View File

@@ -1,8 +0,0 @@
#!/usr/bin/env python3
# Make sure our Python 3 software is installed
import cv2
from pyzbar import pyzbar
print(cv2.getBuildInformation())

View File

@@ -18,7 +18,7 @@ EXCLUDE = 'rviz.png', 'ssid.png', 'sitl_docker_demo.png', 'qgc-params.png', 'but
'qgc-battery.png', 'qgc-radio.png', 'qgc-cal-acc.png', 'qgc-esc.png', 'qgc-cal-compass.png', \
'qgc.png', 'qgc-parameters.png', 'clever4-front-white-large.png', 'qgc-modes.png', \
'qgc-requires-setup.png', 'clever4-front-white.png', 'clever4-kit-white.png', '26_1.png', 'battery_holder.stl', \
'camera_case.stl', 'camera_mount.stl'
'camera_case.stl', 'camera_mount.stl', 'grip_right.stl', 'grip_left.stl'
code = 0

View File

@@ -30,6 +30,8 @@ find_package(catkin REQUIRED COMPONENTS
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
# https://github.com/mavlink/mavros/blob/7f1a8/mavros/CMakeLists.txt#L42
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};/usr/share/cmake/geographiclib")
find_package(GeographicLib REQUIRED)
# Workaround for OpenCV 3/4 support

View File

@@ -0,0 +1,65 @@
# 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

View File

@@ -0,0 +1,65 @@
# 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

View File

@@ -0,0 +1,65 @@
# 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

View File

@@ -0,0 +1,65 @@
# 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

View File

@@ -0,0 +1,65 @@
# 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

View File

@@ -0,0 +1,65 @@
# 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

View File

@@ -0,0 +1,65 @@
# 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

View File

@@ -0,0 +1,65 @@
# 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

View File

@@ -1,18 +0,0 @@
# taken from: https://github.com/mavlink/mavros/blob/master/libmavconn/cmake/Modules/FindGeographicLib.cmake
# Look for GeographicLib
#
# Set
# GEOGRAPHICLIB_FOUND = TRUE
# GeographicLib_INCLUDE_DIRS = /usr/local/include
# GeographicLib_LIBRARIES = /usr/local/lib/libGeographic.so
# GeographicLib_LIBRARY_DIRS = /usr/local/lib
find_path (GeographicLib_INCLUDE_DIRS NAMES GeographicLib/Config.h)
find_library (GeographicLib_LIBRARIES NAMES Geographic)
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (GeographicLib DEFAULT_MSG
GeographicLib_LIBRARIES GeographicLib_INCLUDE_DIRS)
mark_as_advanced (GeographicLib_LIBRARIES GeographicLib_INCLUDE_DIRS)

View File

@@ -17,6 +17,7 @@ from cv_bridge import CvBridge
from clover import long_callback, srv
import tf2_ros
import tf2_geometry_msgs
import image_geometry
rospy.init_node('cv', disable_signals=True) # disable signals to allow interrupting with ctrl+c
@@ -32,21 +33,14 @@ mask_pub = rospy.Publisher('~mask', Image, queue_size=1)
point_pub = rospy.Publisher('~red_circle', PointStamped, queue_size=1)
# read camera info
camera_info = rospy.wait_for_message('main_camera/camera_info', CameraInfo)
camera_matrix = np.float64(camera_info.K).reshape(3, 3)
distortion = np.float64(camera_info.D).flatten()
camera_model = image_geometry.PinholeCameraModel()
camera_model.fromCameraInfo(rospy.wait_for_message('main_camera/camera_info', CameraInfo))
def img_xy_to_point(xy, dist):
xy = cv2.undistortPoints(xy, camera_matrix, distortion, P=camera_matrix)[0][0]
# Shift points to center
xy -= camera_info.width // 2, camera_info.height // 2
fx = camera_matrix[0, 0]
fy = camera_matrix[1, 1]
return Point(x=xy[0] * dist / fx, y=xy[1] * dist / fy, z=dist)
xy_rect = camera_model.rectifyPoint(xy)
ray = camera_model.projectPixelTo3dRay(xy_rect)
return Point(x=ray[0] * dist, y=ray[1] * dist, z=dist)
def get_center_of_mass(mask):
M = cv2.moments(mask)

View File

@@ -16,9 +16,10 @@
<remap from="image_raw" to="main_camera/image_raw"/>
<remap from="camera_info" to="main_camera/camera_info"/>
<remap from="map_markers" to="aruco_map/map"/>
<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

@@ -51,6 +51,7 @@
<!-- simplified offboard control -->
<node name="simple_offboard" pkg="clover" type="simple_offboard" output="screen" clear_params="true">
<param name="reference_frames/main_camera_optical" value="map"/>
<param name="terrain_frame_mode" value="range"/>
</node>
<!-- main camera -->
@@ -71,6 +72,9 @@
<param name="pass_statuses" type="yaml" value="[0, 6, 7, 11]"/>
</node>
<!-- rangefinder's frame -->
<node pkg="tf2_ros" type="static_transform_publisher" name="rangefinder_frame" args="0 0 -0.05 0 1.5707963268 0 base_link rangefinder" if="$(arg rangefinder_vl53l1x)"/>
<!-- led strip -->
<include file="$(find clover)/launch/led.launch" if="$(arg led)">
<arg name="simulator" value="$(arg simulator)"/>

View File

@@ -21,7 +21,8 @@
</node>
<!-- high level led effects control, events notification with leds -->
<node pkg="clover" name="led_effect" type="led" ns="led" clear_params="true" output="screen" if="$(arg led_effect)">
<node pkg="clover" name="led_effect" type="led" clear_params="true" output="screen" if="$(arg led_effect)">
<param name="led" value="led"/>
<param name="blink_rate" value="2"/>
<param name="fade_period" value="0.5"/>
<param name="rainbow_period" value="5"/>

View File

@@ -3,9 +3,15 @@
<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="device" default="/dev/video0"/> <!-- v4l2 device -->
<arg name="type" default="libcamera"/> <!-- camera interface: libcamera, v4l2 -->
<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_rate" default="5.0"/> <!-- throttled image topic rate -->
<arg name="rectify" default="false"/> <!-- enable rectification -->
<arg name="simulator" default="false"/>
<node if="$(eval direction_z == 'down' and direction_y == 'backward')" pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 -0.07 -1.5707963 0 3.1415926 base_link main_camera_optical"/>
@@ -25,20 +31,34 @@
<param name="num_worker_threads" value="2"/>
</node>
<!-- camera node -->
<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">
<!-- camera node using libcamera -->
<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">
<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="frame_id" value="main_camera_optical"/>
<param name="camera_info_url" value="file://$(find clover)/camera_info/fisheye_cam.yaml"/>
<param name="rate" value="100"/> <!-- poll rate -->
<param name="cv_cap_prop_fps" value="40"/> <!-- camera FPS -->
<param name="cv_cap_prop_fps" value="$(arg fps)"/> <!-- camera FPS -->
<param name="capture_delay" value="0.02"/> <!-- approximate delay on frame retrieving -->
<param name="rescale_camera_info" value="true"/> <!-- automatically rescale camera calibration info -->
<!-- camera resolution -->
<param name="image_width" value="320"/>
<param name="image_height" value="240"/>
<param name="image_width" value="$(arg width)"/>
<param name="image_height" value="$(arg height)"/>
</node>
<!-- camera visualization markers -->
@@ -49,4 +69,11 @@
<!-- image topic throttled -->
<node pkg="topic_tools" name="main_camera_throttle" type="throttle" ns="main_camera"
args="messages image_raw $(arg throttled_topic_rate) image_raw_throttled" if="$(arg throttled_topic)"/>
<!-- rectified image topic -->
<node pkg="nodelet" type="nodelet" name="rectify" args="load image_proc/rectify main_camera_nodelet_manager" if="$(arg rectify)">
<remap from="image_mono" to="main_camera/image_raw"/>
<remap from="camera_info" to="main_camera/camera_info"/>
<remap from="image_rect" to="main_camera/image_rect"/>
</node>
</launch>

View File

@@ -77,9 +77,6 @@
covariance: 1 # cm
</rosparam>
<!-- Rangefinders frame -->
<node pkg="tf2_ros" type="static_transform_publisher" name="rangefinder_frame" args="0 0 -0.05 0 1.5707963268 0 base_link rangefinder"/>
<!-- Copter visualization -->
<node name="visualization" pkg="mavros_extras" type="visualization" if="$(arg viz)">
<remap to="mavros/local_position/pose" from="local_position"/>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<package format="3">
<name>clover</name>
<version>0.23.0</version>
<version>0.24.0</version>
<description>The Clover package</description>
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
@@ -42,6 +42,8 @@
<depend condition="$ROS_PYTHON_VERSION == 2">python-lxml</depend>
<depend condition="$ROS_PYTHON_VERSION == 3">python3-lxml</depend>
<depend>dynamic_reconfigure</depend>
<depend>image_proc</depend>
<depend>image_geometry</depend>
<exec_depend>python-pymavlink</exec_depend>
<test_depend>ros_pytest</test_depend>

View File

@@ -1,4 +1,4 @@
flask==1.1.1
geopy==1.11.0
smbus2==0.3.0
VL53L1X==0.0.5
flask
geopy
smbus2
VL53L1X

View File

@@ -309,15 +309,19 @@ int main(int argc, char **argv)
nh_priv.param("notify/low_battery/threshold", low_battery_threshold, 3.7);
nh_priv.param("notify/error/ignore", error_ignore, {});
ros::service::waitForService("set_leds"); // cannot work without set_leds service
set_leds_srv = nh.serviceClient<led_msgs::SetLEDs>("set_leds", true);
std::string led; // led namespace
nh_priv.param("led", led, std::string("led"));
if (!led.empty()) led += "/";
ros::service::waitForService(led + "set_leds"); // cannot work without set_leds service
set_leds_srv = nh.serviceClient<led_msgs::SetLEDs>(led + "set_leds", true);
// wait for leds count info
handleState(*ros::topic::waitForMessage<led_msgs::LEDStateArray>("state", nh));
handleState(*ros::topic::waitForMessage<led_msgs::LEDStateArray>(led + "state", nh));
auto state_sub = nh.subscribe("state", 1, &handleState);
auto state_sub = nh.subscribe(led + "state", 1, &handleState);
auto set_effect = nh.advertiseService("set_effect", &setEffect);
auto set_effect = nh.advertiseService(led + "set_effect", &setEffect);
auto mavros_state_sub = nh.subscribe("mavros/state", 1, &handleMavrosState);
auto battery_sub = nh.subscribe("mavros/battery", 1, &handleBattery);

View File

@@ -107,7 +107,7 @@ def ff(value, precision=2):
param_get = rospy.ServiceProxy('mavros/param/get', ParamGet)
def get_param(name, default=None):
def get_param(name, default=None, strict=True):
try:
res = param_get(param_id=name)
except rospy.ServiceException as e:
@@ -115,7 +115,8 @@ def get_param(name, default=None):
return None
if not res.success:
failure('unable to retrieve PX4 parameter %s', name)
if strict:
failure('unable to retrieve PX4 parameter %s', name)
return default
else:
if res.value.integer != 0:
@@ -263,7 +264,7 @@ def check_fcu():
est = get_param('SYS_MC_EST_GROUP')
if est == 1:
info('selected estimator: LPE')
fuse = get_param('LPE_FUSION')
fuse = int(get_param('LPE_FUSION'))
if fuse & (1 << 4):
info('LPE_FUSION: land detector fusion is enabled')
else:
@@ -302,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:
@@ -316,7 +325,13 @@ def check_fcu():
failure('cannot read time sync offset')
except rospy.ROSException:
failure('no MAVROS state (check wiring)')
failure('no MAVROS state')
fcu_url = rospy.get_param('mavros/fcu_url', '?')
if fcu_url == '/dev/px4fmu':
if not os.path.exists('/lib/udev/rules.d/99-px4fmu.rules'):
info('udev rules are not installed, install udev rules or change usb_device to /dev/ttyACM0 in mavros.launch')
else:
info('udev did\'t recognize px4fmu device, check wiring or change usb_device to /dev/ttyACM0 in mavros.launch')
info('fcu_url = %s', rospy.get_param('mavros/fcu_url', '?'))
@@ -487,7 +502,7 @@ def check_vpe():
failure('vision yaw weight is zero, change ATT_W_EXT_HDG parameter')
else:
info('vision yaw weight: %s', ff(vision_yaw_w))
fuse = get_param('LPE_FUSION')
fuse = int(get_param('LPE_FUSION'))
if not fuse & (1 << 2):
failure('vision position fusion is disabled, change LPE_FUSION parameter')
delay = get_param('LPE_VIS_DELAY')
@@ -495,11 +510,22 @@ def check_vpe():
failure('LPE_VIS_DELAY = %s, but it should be zero', delay)
info('LPE_VIS_XY = %s m, LPE_VIS_Z = %s m', get_paramf('LPE_VIS_XY'), get_paramf('LPE_VIS_Z'))
elif est == 2:
fuse = get_param('EKF2_AID_MASK')
if not fuse & (1 << 3):
failure('vision position fusion is disabled, change EKF2_AID_MASK parameter')
if not fuse & (1 << 4):
failure('vision yaw fusion is disabled, change EKF2_AID_MASK parameter')
ev_ctrl = get_param('EKF2_EV_CTRL', strict=False)
if ev_ctrl is not None: # PX4 after v1.14
ev_ctrl = int(ev_ctrl)
if not ev_ctrl & (1 << 0):
failure('vision horizontal position fusion is disabled, change EKF2_EV_CTRL parameter')
if not ev_ctrl & (1 << 1):
failure('vision vertical position fusion is disabled, change EKF2_EV_CTRL parameter')
if not ev_ctrl & (1 << 3):
failure('vision yaw fusion is disabled, change EKF2_EV_CTRL parameter')
else: # PX4 before v1.14
fuse = int(get_param('EKF2_AID_MASK'))
if not fuse & (1 << 3):
failure('vision position fusion is disabled, change EKF2_AID_MASK parameter')
if not fuse & (1 << 4):
failure('vision yaw fusion is disabled, change EKF2_AID_MASK parameter')
delay = get_param('EKF2_EV_DELAY')
if delay != 0:
failure('EKF2_EV_DELAY = %.2f, but it should be zero', delay)
@@ -606,8 +632,14 @@ def check_global_position():
rospy.wait_for_message('mavros/global_position/global', NavSatFix, timeout=0.8)
except rospy.ROSException:
info('no global position')
if get_param('SYS_MC_EST_GROUP') == 2 and (get_param('EKF2_AID_MASK', 0) & (1 << 0)):
failure('enabled GPS fusion may suppress vision position aiding')
if get_param('SYS_MC_EST_GROUP') == 2:
gps_ctrl = get_param('EKF2_GPS_CTRL', strict=False)
if gps_ctrl is not None: # PX4 after v1.14
if int(gps_ctrl) & (1 << 0):
failure('GPS fusion enabled may suppress vision position aiding, change EKF2_GPS_CTRL')
else: # PX4 before v1.14
if int(get_param('EKF2_AID_MASK', 0)) & (1 << 0):
failure('GPS fusion enabled may suppress vision position aiding, change EKF2_AID_MASK')
@check('Optical flow')
@@ -626,7 +658,7 @@ def check_optical_flow():
failure('SENS_FLOW_ROT = %s, but it should be zero', rot)
est = get_param('SYS_MC_EST_GROUP')
if est == 1:
fuse = get_param('LPE_FUSION')
fuse = int(get_param('LPE_FUSION'))
if not fuse & (1 << 1):
failure('optical flow fusion is disabled, change LPE_FUSION parameter')
if not fuse & (1 << 1):
@@ -640,9 +672,14 @@ def check_optical_flow():
get_paramf('LPE_FLW_R', 4),
get_paramf('LPE_FLW_RR', 4))
elif est == 2:
fuse = get_param('EKF2_AID_MASK', 0)
if not fuse & (1 << 1):
failure('optical flow fusion is disabled, change EKF2_AID_MASK parameter')
of_ctrl = get_param('EKF2_OF_CTRL', strict=False)
if of_ctrl is not None: # PX4 after v1.14
if of_ctrl == 0:
failure('optical flow fusion is disabled, change EKF2_OF_CTRL')
else: # PX4 before v1.14
fuse = int(get_param('EKF2_AID_MASK', 0))
if not fuse & (1 << 1):
failure('optical flow fusion is disabled, change EKF2_AID_MASK parameter')
delay = get_param('EKF2_OF_DELAY', 0)
if delay != 0:
failure('EKF2_OF_DELAY = %.2f, but it should be zero', delay)
@@ -684,23 +721,26 @@ def check_rangefinder():
est = get_param('SYS_MC_EST_GROUP')
if est == 1:
fuse = get_param('LPE_FUSION', 0)
fuse = int(get_param('LPE_FUSION', 0))
if not fuse & (1 << 5):
info('"pub agl as lpos down" in LPE_FUSION is disabled, NOT operating over flat surface')
else:
info('"pub agl as lpos down" in LPE_FUSION is enabled, operating over flat surface')
elif est == 2:
hgt = get_param('EKF2_HGT_MODE')
hgt = get_param('EKF2_HGT_REF', strict=False)
if hgt is None: # PX4 before v1.14
hgt = get_param('EKF2_HGT_MODE')
if hgt != 2:
info('EKF2_HGT_MODE != Range sensor, NOT operating over flat surface')
else:
info('EKF2_HGT_MODE = Range sensor, operating over flat surface')
aid = get_param('EKF2_RNG_AID')
if aid != 1:
info('EKF2_RNG_AID != 1, range sensor aiding disabled')
else:
info('EKF2_RNG_AID = 1, range sensor aiding enabled')
aid = get_param('EKF2_RNG_AID', strict=False)
if aid is not None: # PX4 before v1.14
if aid != 1:
info('EKF2_RNG_AID != 1, range sensor aiding disabled')
else:
info('EKF2_RNG_AID = 1, range sensor aiding enabled')
@check('Boot duration')

View File

@@ -30,6 +30,7 @@
#include <geometry_msgs/QuaternionStamped.h>
#include <sensor_msgs/NavSatFix.h>
#include <sensor_msgs/BatteryState.h>
#include <sensor_msgs/Range.h>
#include <mavros_msgs/CommandBool.h>
#include <mavros_msgs/SetMode.h>
#include <mavros_msgs/PositionTarget.h>
@@ -86,6 +87,7 @@ float default_speed;
bool auto_release;
bool land_only_in_offboard, nav_from_sp, check_kill_switch;
std::map<string, string> reference_frames;
string terrain_frame_mode;
// Publishers
ros::Publisher attitude_pub, attitude_raw_pub, position_pub, position_raw_pub, rates_pub, thrust_pub, state_pub;
@@ -205,18 +207,27 @@ inline bool waitTransform(const string& target, const string& source,
return false;
}
void publishTerrain(const double distance, const ros::Time& stamp)
{
if (!waitTransform(local_frame, body.child_frame_id, stamp, ros::Duration(0.1))) return;
auto t = tf_buffer.lookupTransform(local_frame, body.child_frame_id, stamp);
t.child_frame_id = terrain.child_frame_id;
t.transform.translation.z -= distance;
static_transform_broadcaster->sendTransform(t);
}
void handleAltitude(const Altitude& alt)
{
// publish terrain frame
if (!std::isfinite(alt.bottom_clearance)) return;
// terrain.header.stamp = alt.header.stamp;
publishTerrain(alt.bottom_clearance, alt.header.stamp);
}
if (!waitTransform(local_frame, body.child_frame_id, alt.header.stamp, ros::Duration(0.1))) return;
auto t = tf_buffer.lookupTransform(local_frame, body.child_frame_id, alt.header.stamp);
t.child_frame_id = terrain.child_frame_id;
t.transform.translation.z -= alt.bottom_clearance;
static_transform_broadcaster->sendTransform(t);
void handleRange(const Range& range)
{
if (!std::isfinite(range.range)) return;
// TODO: check it's facing down
publishTerrain(range.range, range.header.stamp);
}
#define TIMEOUT(msg, timeout) (msg.header.stamp.isZero() || (ros::Time::now() - msg.header.stamp > timeout))
@@ -800,7 +811,8 @@ bool serve(enum setpoint_type_t sp_type, float x, float y, float z, float vx, fl
nav_from_sp_flag = false;
}
if (auto_arm || setpoint_type == VELOCITY || setpoint_type == ATTITUDE || setpoint_type == RATES) {
bool to_auto_arm = auto_arm && (state.mode != "OFFBOARD" || !state.armed);
if (to_auto_arm || setpoint_type == VELOCITY || setpoint_type == ATTITUDE || setpoint_type == RATES) {
// invalidate position setpoint
setpoint_position.header.frame_id = "";
setpoint_altitude.header.frame_id = "";
@@ -1100,6 +1112,7 @@ int main(int argc, char **argv)
nh_priv.param("default_speed", default_speed, 0.5f);
nh_priv.param<string>("body_frame", body.child_frame_id, "body");
nh_priv.param<string>("terrain_frame", terrain.child_frame_id, "terrain");
nh_priv.param<string>("terrain_frame_mode", terrain_frame_mode, "altitude");
nh_priv.getParam("reference_frames", reference_frames);
// Default reference frames
@@ -1138,7 +1151,15 @@ int main(int argc, char **argv)
ros::Subscriber altitude_sub;
if (!body.child_frame_id.empty() && !terrain.child_frame_id.empty()) {
terrain.header.frame_id = local_frame;
altitude_sub = nh.subscribe(mavros + "/altitude", 1, &handleAltitude);
if (terrain_frame_mode == "altitude") {
altitude_sub = nh.subscribe(mavros + "/altitude", 1, &handleAltitude);
} else if (terrain_frame_mode == "range") {
string range_topic = nh_priv.param("range_topic", string("rangefinder/range"));
altitude_sub = nh.subscribe(range_topic, 1, &handleRange);
} else {
ROS_FATAL("Unknown terrain_frame_mode: %s, valid values: altitude, range", terrain_frame_mode.c_str());
ros::shutdown();
}
}
// Setpoint publishers

View File

@@ -11,12 +11,14 @@
#include <string>
#include <ros/ros.h>
#include <tf/transform_datatypes.h>
#include <tf2/transform_datatypes.h>
#include <tf2_ros/buffer.h>
#include <tf2_ros/transform_listener.h>
#include <tf2_ros/static_transform_broadcaster.h>
#include <tf2_geometry_msgs/tf2_geometry_msgs.h>
#include <geometry_msgs/TransformStamped.h>
#include <geometry_msgs/Quaternion.h>
#include <geometry_msgs/PoseStamped.h>
#include <geometry_msgs/PoseWithCovarianceStamped.h>
#include <std_srvs/Trigger.h>
@@ -66,6 +68,13 @@ inline Pose getPose(const PoseStampedConstPtr& pose) { return pose->pose; }
inline Pose getPose(const PoseWithCovarianceStampedConstPtr& pose) { return pose->pose.pose; }
inline void keepYaw(Quaternion& quaternion)
{
tf::Quaternion q;
q.setRPY(0, 0, tf::getYaw(quaternion));
tf::quaternionTFToMsg(q, quaternion);
}
template <typename T>
void callback(const T& msg)
{
@@ -88,10 +97,29 @@ void callback(const T& msg)
if (!offset_frame_id.empty()) {
if (reset_flag || msg->header.stamp - vpe.header.stamp > offset_timeout) {
// calculate the offset
offset = tf_buffer.lookupTransform(local_frame_id, frame_id,
msg->header.stamp, ros::Duration(0.02));
// offset.header.frame_id = vpe.header.frame_id;
offset.child_frame_id = offset_frame_id;
if (!frame_id.empty()) {
// calculate from TF
offset = tf_buffer.lookupTransform(local_frame_id, frame_id,
msg->header.stamp, ros::Duration(0.02));
// offset.header.frame_id = vpe.header.frame_id;
offset.child_frame_id = offset_frame_id;
} else {
// calculate transform between pose in vpe frame and pose in local frame
TransformStamped local_pose = tf_buffer.lookupTransform(local_frame_id, child_frame_id,
msg->header.stamp, ros::Duration(0.02));
keepYaw(local_pose.transform.rotation);
tf::Transform vpeTransform, poseTransform;
tf::poseMsgToTF(vpe.pose, vpeTransform);
tf::transformMsgToTF(local_pose.transform, poseTransform);
tf::Transform offset_tf = vpeTransform.inverseTimes(poseTransform);
tf::transformTFToMsg(offset_tf, offset.transform);
offset.header.frame_id = local_frame_id;
offset.header.stamp = msg->header.stamp;
offset.child_frame_id = offset_frame_id;
}
br.sendTransform(offset);
reset_flag = false;
ROS_INFO("offset reset");
@@ -122,8 +150,9 @@ int main(int argc, char **argv) {
tf2_ros::TransformListener tf_listener(tf_buffer);
nh_priv.param<string>("frame_id", frame_id, "");
nh_priv.param<string>("offset_frame_id", offset_frame_id, "");
nh_priv.param<string>("frame_id", frame_id, ""); // name for used visual pose frame
nh_priv.param<string>("offset_frame_id", offset_frame_id, ""); // name for published offset frame
nh.param<string>("mavros/local_position/frame_id", local_frame_id, "map");
nh.param<string>("mavros/local_position/tf/child_frame_id", child_frame_id, "base_link");
offset_timeout = ros::Duration(nh_priv.param("offset_timeout", 3.0));

View File

@@ -40,6 +40,16 @@
<node pkg="topic_tools" name="main_camera_throttle" type="throttle" ns="main_camera"
args="messages image_raw 5.0 image_raw_throttled" required="true"/>
<node pkg="nodelet" type="nodelet" name="main_camera_nodelet_manager" args="manager" output="screen" required="true">
<param name="num_worker_threads" value="2"/>
</node>
<node pkg="nodelet" type="nodelet" name="rectify" args="load image_proc/rectify main_camera_nodelet_manager" required="true">
<remap from="image_mono" to="main_camera/image_raw"/>
<remap from="camera_info" to="main_camera/camera_info"/>
<remap from="image_rect" to="main_camera/image_rect"/>
</node>
<param name="test_module" value="$(find clover)/test/basic.py"/>
<test test-name="basic_test" pkg="ros_pytest" type="ros_pytest_runner"/>
</launch>

View File

@@ -3,9 +3,11 @@ import pytest
from pytest import approx
import threading
import mavros_msgs.msg
from mavros_msgs.srv import SetMode
from geometry_msgs.msg import PoseStamped
from clover import srv
from clover.msg import State
from std_srvs.srv import Trigger
from math import nan, inf
import tf2_ros
import tf2_geometry_msgs
@@ -38,6 +40,8 @@ def test_offboard(node, tf_buffer):
set_attitude = rospy.ServiceProxy('set_attitude', srv.SetAttitude)
set_rates = rospy.ServiceProxy('set_rates', srv.SetRates)
get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry)
land = rospy.ServiceProxy('land', Trigger)
res = navigate()
assert res.success == False
assert res.message.startswith('State timeout')
@@ -45,6 +49,7 @@ def test_offboard(node, tf_buffer):
telem = get_telemetry()
assert telem.connected == False
# mocked state publisher
state_pub = rospy.Publisher('/mavros/state', mavros_msgs.msg.State, latch=True, queue_size=1)
state_msg = mavros_msgs.msg.State(mode='OFFBOARD', armed=True)
@@ -59,6 +64,13 @@ def test_offboard(node, tf_buffer):
threading.Thread(target=publish_state, daemon=True).start()
rospy.sleep(0.5)
# set_mode service mock
def set_mode(req):
state_msg.mode = req.custom_mode # set mocked mode to requested
return True,
rospy.Service('/mavros/set_mode', SetMode, set_mode)
telem = get_telemetry()
assert telem.connected == False
@@ -157,7 +169,23 @@ def test_offboard(node, tf_buffer):
assert state.z_frame_id == 'map'
assert state.yaw_frame_id == 'test'
# auto_arm should invalidate the setpoint
# auto_arm should not invalidate the setpoint if not effective
res = navigate(x=nan, y=nan, z=1, frame_id='map', auto_arm=True)
assert res.success == True
state = get_state()
assert state.mode == State.MODE_NAVIGATE
assert state.yaw_mode == State.YAW_MODE_YAW
assert state.x == 1
assert state.y == 2
assert state.z == 1
assert state.yaw == 0
assert state.xy_frame_id == 'test'
assert state.z_frame_id == 'map'
assert state.yaw_frame_id == 'map'
# auto_arm should invalidate the setpoint if effective
state_msg.mode = 'STABILIZED' # pretend we are not in OFFBOARD mode
rospy.sleep(1)
res = navigate(x=nan, y=nan, z=1, frame_id='map', auto_arm=True)
assert res.success == True
state = get_state()
@@ -170,6 +198,8 @@ def test_offboard(node, tf_buffer):
assert state.xy_frame_id == 'map'
assert state.z_frame_id == 'map'
assert state.yaw_frame_id == 'map'
state_msg.mode = 'OFFBOARD'
rospy.sleep(1)
# set_attitude should invalidate the setpoint
res = set_attitude()
@@ -400,3 +430,8 @@ def test_offboard(node, tf_buffer):
res = set_rates(roll_rate=inf)
assert res.success == False
assert res.message == 'roll_rate argument cannot be Inf'
# test land service
res = land()
assert res.success == True
assert state_msg.mode == 'AUTO.LAND' # check that the mode was set correctly

View File

@@ -0,0 +1,68 @@
#!/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))

View File

@@ -1,17 +1,54 @@
# PixHawk (px4fmu-v2), px4fmu-v3
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0011", ATTRS{product}=="PX4 FMU v2.x", SYMLINK+="px4fmu"
# PixRacer (px4fmu-v4)
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0012", ATTRS{product}=="PX4 FMU v4.x", SYMLINK+="px4fmu"
# px4fmu-v5
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0032", ATTRS{product}=="PX4 FMU v5.x", SYMLINK+="px4fmu"
# auav
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0021", ATTRS{product}=="PX4 AUAV x2.1", SYMLINK+="px4fmu"
# crazyflie
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0016", ATTRS{product}=="PX4 Crazyflie v2.0", SYMLINK+="px4fmu"
# px4fmu-v4pro
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0013", ATTRS{product}=="PX4 FMU v4.x PRO", SYMLINK+="px4fmu"
# Omnibus
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0001", ATTRS{product}=="PX4 OmnibusF4SD", SYMLINK+="px4fmu"
# CUAV X7 Pro
SUBSYSTEM=="tty", ATTRS{idVendor}=="3163", ATTRS{idProduct}=="004c", ATTRS{product}=="PX4 CUAV X7Pro", SYMLINK+="px4fmu"
# Source files: PX4-Autopilot/boards/**/nuttx-config/nsh/defconfig
# Additional info:
# https://docs.px4.io/main/en/flight_controller/
# https://github.com/mavlink/qgroundcontrol/blob/master/src/comm/USBBoardInfo.json
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0001", ATTRS{product}=="PX4 GNF405", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0001", ATTRS{product}=="PX4 OmnibusF4SD", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0016", ATTRS{product}=="PX4 Crazyflie v2.0", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="1FC9", ATTRS{idProduct}=="001c", ATTRS{product}=="PX4 FMUK66 v3.x", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="1FC9", ATTRS{idProduct}=="001c", ATTRS{product}=="PX4 FMUK66 E", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="1FC9", ATTRS{idProduct}=="001d", ATTRS{product}=="PX4 FMURT1062 v1.x", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0001", ATTRS{product}=="DiatoneMambaF405 MK2", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a32f", ATTRS{product}=="PX4 FMU ModalAI FCv1", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a330", ATTRS{product}=="PX4 FMU ModalAI FCv2", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0012", ATTRS{product}=="PX4 FMU UVify Core", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="3162", ATTRS{idProduct}=="0050", ATTRS{product}=="PX4 KakuteH7", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="3162", ATTRS{idProduct}=="0050", ATTRS{product}=="PX4 KakuteH7v2", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="3162", ATTRS{idProduct}=="004b", ATTRS{product}=="PX4 DurandalV1", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0050", ATTRS{product}=="PX4 KakuteF7", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="3162", ATTRS{idProduct}=="0050", ATTRS{product}=="PX4 KakuteH7Mini-nand", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="3162", ATTRS{idProduct}=="004E", ATTRS{product}=="PX4 PIX32V5", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0061", ATTRS{product}=="PX4 ATL Mantis-EDU", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="3163", ATTRS{idProduct}=="004c", ATTRS{product}=="PX4 CUAV Nora", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="3163", ATTRS{idProduct}=="004c", ATTRS{product}=="PX4 CUAV X7Pro", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="1B8C", ATTRS{idProduct}=="0036", ATTRS{product}=="MatekH743-mini", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="1B8C", ATTRS{idProduct}=="0036", ATTRS{product}=="MatekH743", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="120A", ATTRS{idProduct}=="1004", ATTRS{product}=="Matekgnssm9nf4", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="1013", ATTRS{product}=="MatekH743", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="0037", ATTRS{product}=="PX4 FMU SmartAP AIRLink", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="2DAE", ATTRS{idProduct}=="1058", ATTRS{product}=="CubeOrange+", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="2DAE", ATTRS{idProduct}=="1012", ATTRS{product}=="CubeYellow", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="2DAE", ATTRS{idProduct}=="1016", ATTRS{product}=="CubeOrange", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="3185", ATTRS{idProduct}=="0035", ATTRS{product}=="PX4 FMU v6X.x", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="3185", ATTRS{idProduct}=="0038", ATTRS{product}=="PX4 FMU v6C.x", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="3185", ATTRS{idProduct}=="0033", ATTRS{product}=="PX4 FMU v5X.x", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="1B8C", ATTRS{idProduct}=="0036", ATTRS{product}=="PX4 FMU v6U.x", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0013", ATTRS{product}=="PX4 FMU v4.x PRO", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0011", ATTRS{product}=="PX4 FMU v2.x", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0012", ATTRS{product}=="PX4 FMU v4.x", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0032", ATTRS{product}=="PX4 FMU v5.x", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="3162", ATTRS{idProduct}=="004b", ATTRS{product}=="PX4 SP RACING H7 EXTREME", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0030", ATTRS{product}=="MindPX FMU v2.x", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="3185", ATTRS{idProduct}=="0039", ATTRS{product}=="ARK FMU v6X.x", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0016", ATTRS{product}=="PX4 FreeFly RTK GPS", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="1024", ATTRS{product}=="mRoControlZeroH7 OEM", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="1017", ATTRS{product}=="mRoPixracerPro", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="1023", ATTRS{product}=="mRoControlZeroH7", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="008D", ATTRS{product}=="mRoControlZeroF7", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0021", ATTRS{product}=="PX4 AUAV X2.1", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="1022", ATTRS{product}=="mRoControlZero Classic", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0088", ATTRS{product}=="mRo x2.1-777", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="35a7", ATTRS{idProduct}=="0002", ATTRS{product}=="FCC-R1", SYMLINK+="px4fmu"
SUBSYSTEM=="tty", ATTRS{idVendor}=="35a7", ATTRS{idProduct}=="0001", ATTRS{product}=="FCC-K1", SYMLINK+="px4fmu"

View File

@@ -47,6 +47,7 @@ http://<hostname>/clover_blocks/?navigate_tolerance=0.5&sleep_time=0.1
* `~running` ([*std_msgs/Bool*](http://docs.ros.org/noetic/api/std_msgs/html/msg/Bool.html)) indicates if the program is currently running.
* `~block` ([*std_msgs/String*](http://docs.ros.org/noetic/api/std_msgs/html/msg/String.html)) current executing block (maximum topic rate is limited).
* `~print` ([*std_msgs/String*](http://docs.ros.org/noetic/api/std_msgs/html/msg/String.html)) user program output messages (published in *print* blocks).
* `~error` ([*std_msgs/String*](http://docs.ros.org/noetic/api/std_msgs/html/msg/String.html))  user program errors and exceptions.
* `~prompt` ([*clover_blocks/Prompt*](msg/Prompt.msg)) user input request (includes random request ID string).

View File

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

View File

@@ -269,6 +269,19 @@ Blockly.Blocks['voltage'] = {
}
};
Blockly.Blocks['get_rc'] = {
init: function () {
this.appendDummyInput()
.appendField("RC channel")
this.appendValueInput("CHANNEL")
.setCheck("Number");
this.setInputsInline(true);
this.setOutput(true, "Number");
this.setColour(COLOR_STATE);
this.setTooltip("Returns current RC channel value.");
this.setHelpUrl(DOCS_URL + '#' + this.type);
}
}
Blockly.Blocks['armed'] = {
init: function () {

View File

@@ -100,6 +100,9 @@
<block type="mode"></block>
<block type="armed"></block>
<block type="voltage"></block>
<block type="get_rc">
<value name="CHANNEL"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
</block>
</category>
<category name="LED" colour="#02d754">
<block type="set_effect">

View File

@@ -83,6 +83,9 @@ function generateROSDefinitions() {
if (rosDefinitions.navigateGlobal) {
code += `navigate_global = rospy.ServiceProxy('navigate_global', srv.NavigateGlobal)\n`;
}
if (rosDefinitions.setYaw) {
code += `set_yaw = rospy.ServiceProxy('set_yaw', srv.SetYaw)\n`;
}
if (rosDefinitions.setVelocity) {
code += `set_velocity = rospy.ServiceProxy('set_velocity', srv.SetVelocity)\n`;
}
@@ -399,6 +402,12 @@ Blockly.Python.voltage = function(block) {
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
}
Blockly.Python.get_rc = function(block) {
Blockly.Python.definitions_['import_rcin'] = 'from mavros_msgs.msg import RCIn';
var channel = Blockly.Python.valueToCode(block, 'CHANNEL', Blockly.Python.ORDER_NONE);
return [`rospy.wait_for_message('mavros/rc/in', RCIn).channels[${channel}]`, Blockly.Python.ORDER_FUNCTION_CALL]
}
function parseColor(color) {
return {
r: parseInt(color.substr(2, 2), 16),

View File

@@ -1,6 +1,6 @@
<package format="2">
<name>clover_description</name>
<version>0.23.0</version>
<version>0.24.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.23.0</version>
<version>0.24.0</version>
<description>The clover_simulation package provides worlds and launch files for Gazebo.</description>
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 KiB

View File

@@ -57,6 +57,7 @@
* [COEX Pix](coex_pix.md)
* [COEX PDB](coex_pdb.md)
* [COEX GPS](coex_gps.md)
* [Using SSH keys](ssh_keys.md)
* [Guide on autonomous flight](auto_setup.md)
* [Hostname](hostname.md)
* [PX4 Simulation](sitl.md)
@@ -105,6 +106,12 @@
* [Video contest](video_contest.md)
* [Educational contests](educational_contests.md)
* [Clover-based projects](projects.md)
* [Clover Cloud Platform](clover-cloud-platform.md)
* [Autonomous Racing Drone](djs_phoenix_chetak.md)
* [Motion Capture System](mocap_clover.md)
* [Swarm in Blocks 2](swarm_in_blocks_2.md)
* [Advanced Clover 2](advanced_clover_simulator_platform.md)
* [Network of charging stations](liceu128.md)
* [Swarm-in-blocks](swarm_in_blocks.md)
* [Obstacle avoidance using artificial potential fields method](obstacle-avoidance-potential-fields.md)
* [The Clover Rescue Project](clover-rescue-team.md)

View File

@@ -0,0 +1,161 @@
# Advanced Clover 3: The Platform
[CopterHack-2023](copterhack2023.md), team **FTL**.
## Team Information
```cpp
#include "veryInterestingCommandDescription.h"
```
Team members:
- Maxim Ramanouski, [@max8rr8](https://t.me/max8rr8).
Country: Belarus.
## Project Description
Last year at CopterHack 2022, we created a [project](../ru/advanced_clover_simulator.html) that simplified the simulation of Clover, and in 2021, we created a [project](../ru/advanced_clover.html) that simplified the development of products for Clover (IDE and library for writing). The time has come to combine them and achieve unlimited power.
### Project Idea
The idea of the project is to combine CloverIDE and CloverSim (a tool for running Clover simulations). Thus, a platform is planned that allows developing products based on Clover using a simulator and an advanced IDE. The platform will include the following features:
- Add a web interface that allows using CloverSim without touching the command line.
- Work both in the browser (without installing anything) and from CLI.
- Have a course that covers different aspects of clover.
- Simplify installation, especially in WSL.
- Running a simulation on a remote device (more powerful computer or cloud).
### Project videos
Video presentation of the project: [link](https://www.youtube.com/watch?v=T4RU9sfxsSI).
Live presentation at CopterHack: TBD.
CLI demonstration: [link](https://www.youtube.com/watch?v=Ao-ukR58sSQ).
## Installation
Installation process is described in the [project documentation](https://ftl-team.github.io/clover_sim/#/?id=installation).
## Usage
The CloverSim platform offers a seamless workflow for users:
1. Users can effortlessly select or create a workspace and task and
launch them with ease.
![Step 1 screenshot](../assets/ftl/acp_workflow1.png)
2. After launching the simulation, users are presented with CloverSim WebUI that
provides them with an intuitive way to view their scores and progress,
control the simulator, and access task descriptions and scoring information.
From it users can open terminal, gzweb and more importantly they can easily
access the CloverSim IDE to solve task.
![Step 2 screenshot](../assets/ftl/acp_workflow2.png)
3. The IDE provides a full suite of tools and features for writing and
debugging code. One example is autocompletion to help streamline the
development process, making it more efficient and effective.
![Step 3 screenshot](../assets/ftl/acp_workflow3.png)
4. Users can launch their programs with ease and monitor its progress via
the GZWeb, CopterStatus, and SimulatorStatus views of the IDE.
![Step 4 screenshot](../assets/ftl/acp_workflow4.png)
5. Users can track their progress and scores in real-time and effortlessly
restart the simulator if necessary. Additionally, different randomization
seed can be set to check various inputs and outcomes.
We also have video demonstration/tutorial: [link](https://www.youtube.com/watch?v=aPOPHD3M3ZM).
## More features
- Easy installation process.
- Efficient simulation launch, surpassing traditional virtual machines.
- Generation of dynamic Gazebo worlds with randomization based on seed.
- Real-time task completion verification and score presentation.
- Execution with security in isolated containers.
- Multiple project capability without the need for multiple virtual machine images.
- WebUI for ease of use, removing the need to use the command line.
- IDE similar to VSCode with support for C++ and Python, including autocompletion and autoformatting.
- Custom-patched GZWeb with bug fixes and additional features, including the display of the Clover LED strip.
- GZWeb provides a follow-objects feature superior to that of Gazebo.
- IDE includes tools to interact with ROS, such as topic visualization, service calling, and image topic visualization.
- IDE also includes Copter Status, displaying most of the drone's information, including position, camera, and LED strip, in one view.
- IDE integrates with the simulator by providing control from it, viewing task descriptions, and opening GZWeb.
We also have developed a learning course based on CloverSim: [link](https://github.com/FTL-team/CloverSim_course). It currently has the following tasks:
- 1_thesquare - First task of CloverSim course with goal to fly square.
- 2_iseeall - Task that teaches how to interact with camera.
- 3_landmid - Find and land onto randomly positioned object.
- 4_flybyline - Flying along the line.
- 5_posknown - Find position of objects relative to ArUco map.
## More details
At this point, our platform consists of four major parts:
- [CloverSim](https://github.com/FTL-team/clover_sim) - tool that manages simulation.
- [CloverSim Basefs](https://github.com/FTL-team/clover_sim_basefs) - container image that is used in simulator.
- [Clover IDE](https://github.com/FTL-team/cloverIDE) - clover ide tools and theia.
- [CloverSim course](https://github.com/FTL-team/CloverSim_course) - course with tasks based on our platform.
### CloverSim
The simulation architecture is a continuation of work from CopterHack 2022, but while 2022 version was closer to Proof-of-Concept, the updated version is more robust.
There are three major difference in simulator architecture
- Replacement of `systemd-nspawn` with `runc` provides us higher degree of container control and seemingless support of non-systemd systems, for example WSL.
- Migration to squash fs images, which greatly reduced size of installed CloverSim from 13 gigabytes to just 3.5 gigabytes.
- Tasks are now mounted instead of being copied and also build before starting.
Because of the way catkin_make works, it is incredibly slow when new packages are added (whole cmake configuration is rerun for all packages). catkin_make provides a way to build only some packages, but it caches this packages and to reset this cache you need to recompile whole catkin_make. But we have found a solution: `catkin_make -DCATKIN_WHITELIST_PACKAGES="task;CloverSim" --build build_CloverSim` This command, builds only CloverSim and task package in separate build directory, this drastically reduces time that catkin_make takes, and keeps expected behavior of catkin_make without arguments.
There are also differences in tool that launches simulation:
- Client-server architecture allows us to create web UI and run CloverSim on server.
- More robust error handling improves user experience.
- Rewritten in rust, better reliability and development experience.
### CloverSim basefs
Version 2 integrates CloverIDE into system. We also updated clover in simulator to v0.23 and added web terminal. Basefs is now squashed and doesn't require additional installation. It also uses patched(by us) version of gzweb that is more suitable for our use-case:
- Unlike original GZWeb assets can be dynamically loaded, which is required to support dynamically generated tasks.
- It also implements multiple bugfixes for rendering, UI.
- Fixed performance, original gzweb had two constantly running loops that used 200% of cpu. We fixed this by instead using synchronization primitives.
- Clover LED strip is rendered, our gzweb connects to ROS and pulls LED data from there to render LED strip like Gazebo does.
- Users can now follow-objects like in Gazebo better actually.
- Reconnect on disconnect, when simulator is restarted gzweb looses connection and it now can automatically reconnect.
Patched gzweb available there: [FTL-team/gzweb](https://github.com/FTL-team/gzweb).
### CloverIDE
CloverIDE got some updates too:
- We have updated theia and extensions used.
- Better C++ support via clangd.
- Clover IDE tools can now reconnect after simulator restart.
- Copter Status now displays LED strip status.
- Tools ui has better support for different themes.
But the most important change is CloverSim integration, there are new tools (task description, simulator control and gzweb). While gzweb tool is just an iframe (though it's very cool to have it in IDE).
Task description and simulator control are more interesting as they have to interact with both IDE and CloverSim, to maintain different versions support we use quite interesting trick, extension webview after being initialized dynamically loads JavaScript from CloverSim. That provides better integration between two.
### CloverSim course
CloverSim course is a new part of our platform. It uses robust task API of CloverSim to create practical learning course. It currently teaches different aspects of clover development that i encountered during my participation in different contests involving clover. But we are happy to accpet suggestions about other aspects we should teach in out course.
## Conclusion
This project is a final (or maybe there is more?) project of our advanced clover saga. AdvancedClover is a project that is easy to use and greatly improves experience during learning about clover, participating in clover based competitions and development clover based projects. We thank COEX team for their support and look forward to further cooperation.

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

@@ -72,12 +72,6 @@ Sample code to fly to a point 1 metre to the left and 2 metres above marker with
navigate(frame_id='aruco_7', x=-1, y=0, z=2)
```
Sample code to rotate counterclockwise while hovering 1.5 metres above marker id 10:
```python
navigate(frame_id='aruco_10', x=0, y=0, z=1.5, yaw_rate=0.5)
```
Note that if the required marker isn't detected for 0.5 seconds after the `navigate` command, the command will be ignored.
These frames may also be used in other services that accept TF frames (like `get_telemetry`). The following code will get the drone's position relative to the marker with id 3:

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

@@ -2,7 +2,7 @@
<img src="../assets/blocks/blockly.svg" width=200 align="right">
Visual blocks programming feature has been added to the [RPi image](image.md), starting with the version **0.21**. Blocks programming is implemented using [Google Blockly](https://developers.google.com/blockly) platform. Blocks programming integration can lower the entry barrier to a minimum.
Visual blocks programming feature has been added to the [RPi image](image.md), starting with the version **0.21**. Blocks programming is implemented using [Google Blockly](https://developers.google.com/blockly) library. Blocks programming integration can lower the entry barrier to a minimum.
## Configuration

View File

@@ -1,5 +1,7 @@
# Working with the camera
> **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/camera.md).
Make sure the camera is enabled in the `~/catkin_ws/src/clover/clover/launch/clover.launch` file:
```xml

View File

@@ -30,6 +30,16 @@ Print path to the current directory:
pwd
```
Go to the user's home directory:
```bash
# all three commands are equivalent, where the tilde character (~) is an abbreviated
# path entry to the home directory, and the $HOME variable stores this path
cd
cd ~
cd $HOME
```
Print contents of the `file.py` file:
```bash

View File

@@ -0,0 +1,93 @@
# Clover Cloud Platform
[CopterHack-2023](copterhack2023.md), team **Clover Cloud Team**.
The list of our team members:
* Кирилл Лещинский / Kirill Leshchinskiy, [@k_leshchinskiy](https://t.me/k_leshchinskiy) - Team Lead.
* Кузнецов Михаил / Mikhail Kuznetsov, [@bruhfloppa](https://t.me/bruhfloppa) - Frontend Developer.
* Даниил Валишин / Daniil Valishin, [@Astel_1](https://t.me/Astel_1) - Backend Developer.
## Table of contents
* [Introduction](#introduction)
* [Usability](#usability)
* [How to work with our platform?](#how-to-work-with-our-platform)
* [About the development of the platform](#about-the-development-of-the-platform)
* [Conclusion](#conclusion)
## Video demonstration
<p align="center">
<a href="https://www.youtube.com/watch?v=FZPl2LOMgi4"><img img width="560" height="315" src="https://img.youtube.com/vi/FZPl2LOMgi4/maxresdefault.jpg" /></a>
</p>
## Introduction
Clover Cloud Platform is an innovative platform that enables users to access COEX Clover drone simulation online, without the need to download any programs or virtual machines.
> **Note** Visit our [documentation](https://docs.clovercloud.software) to learn all about the platform, its development and how to use it.
## Unleash Your Coding Power: Develop Autonomous Flight Code at Lightning Speed on Clover Cloud Platform
If you're a developer working on autonomous flight projects, you know how time-consuming and distracting all of the routine activities can be. Between managing your hardware, debugging, and configuring your environment, it can feel like the real work of coding gets lost in the shuffle.
That's where our platform comes in. Our streamlined interface and powerful tools make it easy to tackle all of those essential tasks so you can focus on what really matters: developing flawless, high-performance code for your autonomous flight project.
So why wait to unleash your coding power? Sign up for our platform today and discover the difference it can make in the speed, quality, and focus of your autonomous flight coding work.
## Usability
Our platform is incredibly user-friendly and provides seamless access to the simulation in just a few clicks. Together with a simulator that displays simulation data accurately and without delay, there is a map editor allows users to edit the ArUco marker map and add or modify other objects on the scene directly within the simulation window. Additionally, users can create pre-configured workspaces complete with autonomous flight code and simulation scene configuration. Each user can also create their templates or apply a pre-made one to their workspace in just a few clicks. In addition to its other features, Clover Cloud Platform provides users with a convenient code editor for autonomous flight coding. Users can write code in the built-in editor and run it directly from the editor, viewing program output in real-time in the terminal. The platform also includes a file manager that simplifies file manipulation tasks, further enhancing the user's overall experience. With these tools at your fingertips, Clover Cloud Platform delivers an unparalleled level of accessibility and convenience for autonomous flight simulation.
<p align="center">
<img src="https://raw.githubusercontent.com/Clover-Cloud-Platform/clover-cloud-platform-frontend/master/docs/workspace.png" alt="Workspace screenshot">
</p>
## The CodeSandbox for COEX Clover
You can describe the usability and relevance of our platform in another way. Have you heard of CodeSandbox? Our platform offers the same convenience, flexibility, and accessibility as CodeSandbox, but is specifically designed to work with the COEX Clover drone simulation.
## How to work with our platform?
Let's dive into the sea of functionality that our platform offers. Detailed description of each feature is available in our [documentation](https://docs.clovercloud.software), here we will provide a general overview of the platform.
### Creating an account
First, you should create an account on our site. You can do this by clicking on this [link](https://clovercloud.software/signup).
### Instance management
After creating an account, you will be taken to the [dashboard](https://clovercloud.software/instances). Here you can create, start, stop and delete workspaces.
>Workspaces are containers with Gazebo simulator and our software that provide data flow for simulation visualization, as well as handle requests from file manager, code editor and terminal.
<p align="center">
<img src="https://raw.githubusercontent.com/Clover-Cloud-Platform/clover-cloud-platform-frontend/master/docs/instances.gif" alt="Instance management">
</p>
### Workspace overview
In the workspace, in addition to the simulator, you have a file manager, code editor and terminal. There is also an editing mode in the simulator - one of the key features of our project. It allows you to quickly and conveniently edit the simulation scene, namely: move ArUco markers, change their size, change id of the marker, load instead of marker picture, add new markers or delete them. You can also add 3d objects to the scene and change their position, size and color. Below is an example of working with our workspace.
<p align="center">
<img src="https://github.com/Clover-Cloud-Platform/clover-cloud-platform-frontend/raw/master/docs/workspace.gif" alt="Workspace overview">
</p>
### Templates
Templates are another key feature of our platform.Is there something you can't do and you want to see how to properly perform a task? Look for the right template with ready-made code in the Template Browser and apply it to your workspace! Each user can create a template with an autonomous flight code and simulator configuration and share it.
## About the development of the platform
Our team has worked tirelessly to develop a simple yet multifunctional platform. We utilized the most modern standards and tools and implemented numerous optimization methods to ensure seamless performance and error-free operation. The frontend programming language chosen was JavaScript with the React framework, as a design system we utilizing Material Design style for an elegant and intuitive user interface. With the help of GitHub Actions the website is being built and deployed to Firebase hosting. The platform's backend is written in Python and contains multiple simultaneously running scripts. User data is secured and stored in a MongoDB database. Communication between the server and site is enabled through web sockets and the socket.io library, guaranteeing lightning-fast data transfer with minimal lag.
You can view the source code of our platform by clicking on the links below:
[Repository with the frontend-side code](https://github.com/Clover-Cloud-Platform/clover-cloud-platform-frontend)
[Repository with the backend-side code](https://github.com/Clover-Cloud-Platform/clover-cloud-platform-backend)
## Conclusion
In conclusion, we have successfully created a truly convenient and useful platform, suitable for both novice and advanced COEX Clover drone users. Beginners can test their first autonomous flight code without the need for demanding simulator installation or virtual machines. They can also explore all of the drone's functions and capabilities without editing any configuration files. Advanced users benefit from access to their workspace from anywhere in the world and on any device, along with a convenient code-sharing system. In the future, we plan to add more new features to our platform, scale our network to serve a greater number of users, and collaborate with COEX to integrate their Clover quadcopter documentation into our platform, offering users a very simple and user-friendly way to learn to program autonomous drone flight. We also want to express gratitude to the COEX customer support team for their assistance in resolving complex issues that arose during development.

View File

@@ -6,37 +6,59 @@ In order to program [autonomous flights](simple_offboard.md), [work with Pixhawk
USB connection is the preferred way to connect to the flight controller.
<img src="../assets/assembling_clever4/usb_connection_1.png" alt="USB connection" height=400 class="zoom border center">
1. Connect your FCU to the Raspberry Pi using a microUSB to USB cable.
2. [Connect to the Raspberry Pi over SSH](ssh.md).
3. Make sure the connection is working by [running the following command on the Raspberry Pi](ssh.md):
3. Make sure that the connection is working properly by [running the following command on the Raspberry Pi](cli.md):
```bash
rostopic echo /mavros/state
```
The `connected` field should have the `True` value.s
The `connected` field should have the `True` value.
> **Hint** You need to set the `CBRK_USB_CHK` [parameter](parameters.md) to 197848 for the USB connection to work.
## UART connection
<!-- TODO: Connection scheme -->
UART connection is another way for the Raspberry Pi and FCU to communicate.
<img src="../assets/raspberry-uart-telemetry2.png" alt="UART connection via TELEM2" height=400 class="zoom border center">
If the pin marked GND is occupied, you can use any other ground pin (look at the [pinout](https://pinout.xyz) for reference).
1. Connect the TELEM 2 port on the flight controller using a UART cable to the Raspberry Pi pins following this instruction: the black cable (*GND*) to Ground, the green cable (*UART_RX*) to *GPIO14*, the yellow cable (*UART_TX*) to *GPIO15*. Do not connect the red cable (*5V*).
2. Set the PX4 parameters: `MAV_1_CONFIG` to TELEM 2, `SER_TEL2_BAUND` to 921600 8N1. In PX4 of version prior to v1.10.0 the parameter `SYS_COMPANION` should be set to 921600.
2. In PX4 of version v1.9.0 or higher, set parameter values: `MAV_1_CONFIG` to TELEM 2, `SER_TEL2_BAUND` to 921600 8N1. In PX4 of version [prior to v1.9.0](https://github.com/mavlink/qgroundcontrol/issues/6905#issuecomment-464549610) the parameter `SYS_COMPANION` should be set to `Companion Link (921600 baud, 8N1)`, to set it correctly use the old version of QGC [v3.3.1](https://github.com/mavlink/qgroundcontrol/releases/tag/v3.3.1).
3. [Connect to the Raspberry Pi over SSH](ssh.md).
4. Change the connection type in `~/catkin_ws/src/clover/clover/launch/clover.launch` to UART:
4. Check the presence of the parameters `enable_uart=1` and `dtoverlay=pi 3-disable-bt` in the file `/boot/config.txt` by [running the following command on the Raspberry Pi](cli.md):
```bash
cat /boot/config.txt | grep -E "^enable_uart=.|^dtoverlay=pi3-disable-bt"
```
If the parameters in the file are different or missing, then edit the file and restart the Raspberry Pi.
5. Change the connection type from `usb` to `uart` in the Clover' launch file `~/catkin_ws/src/clover/clover/launch/clover.launch`:
```xml
<arg name="fcu_conn" default="uart"/>
```
Be sure to restart the `clover` service after editing the .launch file:
If you change the launch file, you need to restart the `clover' service:
```bash
sudo systemctl restart clover
```
6. Make sure that the connection is working properly by running the following command:
```bash
rostopic echo -n1 /mavros/state
```
The `connected` field should have the `True` value.
Read more in the PX4 docs: https://docs.px4.io/main/en/peripherals/serial_configuration.html.
**Next**: [Using QGroundControl over Wi-Fi](gcs_bridge.md)

View File

@@ -8,27 +8,35 @@ To learn more about the articles of the CopterHack finalist teams follow the lin
The proposed projects are supposed to be open-source and be compatible with the Clover quadcopter platform. Teams-participants are supposed to work on their projects throughout the competition, bringing them closer to the state of the finished product while being assisted by industry experts through lectures and regular feedback.
Final of the CopterHack 2022 was held on May 27, 2023. The winner team was the team 🇷🇺 **[Clover Cloud Platform](clover-cloud-platform.md)**.
## Full stream of the final
<iframe width="560" height="315" src="https://www.youtube.com/embed/Hdl6Sah7nkE" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
## Projects of the contest's participants {#participants}
|Place|Team|Project|Points|
|:-:|-|-|-|
||🇷🇺 Clover Cloud Team|[Clover Cloud Platform](https://github.com/DevMBS/clover/blob/clover-cloud-platform/docs/en/clover-cloud-platform.md)||
||🇰🇬 Zavarka|[Система обмена грузами с помощью конвейера](https://github.com/aiurobotics/clover/blob/conveyance/docs/ru/conveyance.md)||
||🇮🇳 DJS PHOENIX|[Autonomous Racing Drone](https://github.com/DJSPhoenix/clover/blob/DJSPhoenix_chetak/docs/ru/djs_phoenix_chetak.md)||
||🇷🇺 FSOTM|[Drone Interceptor](https://github.com/deadln/clover/blob/interceptor/docs/ru/interceptor.md)||
||🇰🇬 Homelesses|[Trash Collector](https://github.com/Isa-jesus/clover/blob/trash-collector/docs/ru/trash-collector.md)||
||🇷🇺 Digital otters|[Digital otters](https://github.com/Mentalsupernova/clover_cool/blob/new-article.md/docs/ru/new-article.md)||
||🇷🇺 Light Flight|[Сопровождение БПЛА при посадке](https://github.com/SirSerow/clover_inertial_ns/blob/inertial-1/Description.md)||
||🇰🇬 LiveSavers|[LiveSavers](https://github.com/Sarvar00/clover/blob/livesavers/docs/ru/livesaver.md)||
||🇷🇺 C305|[Система радио-навигации](https://github.com/Lukerrr/clover-c305/blob/nav_beacon/docs/ru/nav-beacon.md)||
||🇷🇺 XenCOM|[Bound by fate](https://github.com/xenkek/clover/blob/xenkek-patch-1/docs/ru/bound_by_fate.md)||
||🇨🇦 Clover with Motion Capture System|[Clover with Motion Capture System](https://github.com/ssmith-81/clover/blob/MoCap_Clover/docs/en/mocap_clover.md)||
||🇧🇷 Atena|[Swarm in Blocks 2](https://github.com/Grupo-SEMEAR-USP/clover/blob/swarm_in_blocks_2/docs/en/swarm_in_blocks_2.md)||
||🇧🇾 FTL|[Advanced Clover 2](https://github.com/FTL-team/clover/blob/FTL-advancedClover3/docs/ru/advanced_clover_simulator_platform.md)||
||🇷🇺 Лицей №128|[Платформа для зарядки квадрокоптера](https://github.com/Juli-Shvetsova/clover/blob/liceu128-1/docs/ru/liceu128.md)||
||🇷🇺 Ava_Clover|[DoubleClover](https://github.com/bessiaka/clover/blob/Ava_Clover/docs/ru/soosocta.md)||
||🇷🇺 TPU_1|[Совместная транспортировка груза](https://github.com/shamoleg/clover/blob/tpu_1/docs/ru/tpu_1.md)||
||🇷🇺 TPU_2|[Алгоритм полета сквозь лесную местность](https://github.com/shamoleg/clover/blob/tpu_2/docs/ru/tpu_2.md)|&nbsp;|
|1|🇷🇺 Clover Cloud Team|[Clover Cloud Platform](clover-cloud-platform.md)|21.7|
|2|🇧🇾 FTL|[Advanced Clover 2](advanced_clover_simulator_platform.md)|21|
|3|🇨🇦 Clover with Motion Capture System|[Clover with Motion Capture System](mocap_clover.md)|20.5|
|4|🇧🇷 Atena|[Swarm in Blocks 2](swarm_in_blocks_2.md)|20.3|
|5|🇷🇺 C305|[Система радио-навигации](../ru/nav-beacon.html)|17.5|
|6|🇮🇳 DJS PHOENIX|[Autonomous Racing Drone](djs_phoenix_chetak.md)|14.6|
|7|🇷🇺 Lyceum №128|[Network of Clover charging stations](liceu128.md)|13.7|
||🇰🇬 Zavarka|[Система обмена грузами с помощью конвейера](https://github.com/aiurobotics/clover/blob/conveyance/docs/ru/conveyance.md)||
||🇷🇺 FSOTM|[Drone Interceptor](https://github.com/deadln/clover/blob/interceptor/docs/ru/interceptor.md)||
|✕|🇰🇬 Homelesses|[Trash Collector](https://github.com/Isa-jesus/clover/blob/trash-collector/docs/ru/show_maker.md)||
|✕|🇷🇺 Digital otters|[Digital otters](https://github.com/Mentalsupernova/clover_cool/blob/new-article.md/docs/ru/new-article.md)||
|✕|🇷🇺 Light Flight|[Сопровождение БПЛА при посадке](https://github.com/SirSerow/clover_inertial_ns/blob/inertial-1/Description.md)||
|✕|🇰🇬 LiveSavers|[LiveSavers](https://github.com/Sarvar00/clover/blob/livesavers/docs/ru/livesaver.md)||
||🇷🇺 XenCOM|[Bound by fate](https://github.com/xenkek/clover/blob/xenkek-patch-1/docs/ru/bound_by_fate.md)||
||🇷🇺 Ava_Clover|[DoubleClover](https://github.com/bessiaka/clover/blob/Ava_Clover/docs/ru/soosocta.md)||
||🇷🇺 TPU_1|[Совместная транспортировка груза](https://github.com/shamoleg/clover/blob/tpu_1/docs/ru/tpu_1.md)||
||🇷🇺 TPU_2|[Алгоритм полета сквозь лесную местность](https://github.com/shamoleg/clover/blob/tpu_2/docs/ru/tpu_2.md)|&nbsp;|
See all points by criteria in the [full table](https://docs.google.com/spreadsheets/d/1qTpW8zFVdSEGnbtOvMgQD6DcYwu8URFt1RKOCeUaOe8).
## CopterHack 2023 stages

View File

@@ -0,0 +1,55 @@
# Autonomous Racing Drone: CHETAK
[CopterHack-2023](copterhack2023.md), team **DJS PHOENIX**.
## Team Information
![Without bg](https://user-images.githubusercontent.com/93365067/195974501-0acef6b7-e4ea-4c47-bd7a-615caf73a625.png)
We are the DJS Phoenix, the official drone team of Dwarkadas. J. Sanghvi College of Engineering
The list of team members:
* Shubham Mehta, @Just_me_05, Mentor.
* Harshal Warde, @kryptonisinert, Mechanical.
* Parth Sawjiyani, @Non_Active, Mechanical.
* Soham Dalvi, @devilsfootprint_1973, Mechanical.
* Vedant Patel, @VedantMP, Mechanical.
* Harsh Shah, @harssshhhhh, Mechanical.
* Lisha Mehta, @lishamehta, Mechanical.
* Shubh Pokarne, @Shubhpokarne, Electronics.
* Tushar Nagda, @tushar_n11, Electronics.
* Deep Tank, @Kraven, Electronics.
* Khushi Sanghvi, @Cryptoknigghtt, Programmer.
* Harshil Shah, @divine_fossil, Programmer.
* Omkar Parab, @Omkar_parab21, Programmer.
* Madhura Korgaonkar, @Madhura221, Programmer.
* Shruti Shah, @Shrutishah22, Programmer.
* Aditi Dubey, @aditi_0503, Marketing.
* Krisha Lakhani, @krishalakhani, Marketing.
## Project Description
This year, our team DJS Phoenix, presents to you a fully Autonomous Racing Drone. The drone scans for ArUco tags on the gates and passes through them.
### Project Idea
This project proposes to develop an autonomous racing drone that can navigate through complex courses at high speeds while avoiding obstacles and detecting changes in the environment. In racing competitions, autonomous drones can compete in high-speed, precision races that challenge their agility, speed, and accuracy. These competitions could be held in indoor arenas or outdoor tracks, and they could attract enthusiasts and spectators from all over the world. With their advanced capabilities, autonomous racing drones could usher in a new era of racing events that are more exciting and challenging than ever before. From racing competitions to search and rescue operations, the autonomous racing drone can be used in a wide range of applications that benefit individuals, businesses, and society as a whole.
## Potential Outcome
### Problem
In many industries and applications, there is a need for fast, efficient, and safe movement of goods and information. Drones have become an increasingly popular tool for a wide range of applications, from aerial photography to surveying and monitoring. However, operating a drone requires a certain level of skill and experience, which can be a barrier for individuals or businesses who want to take advantage of this technology. Additionally, traditional drones can be expensive and time-consuming to operate, limiting their accessibility and effectiveness. Therefore, there is a need for a more user-friendly and affordable solution that can expand the use of drones to new audiences and applications.
### Solution
The solution to the above problem statement is an autonomous racing drone. An autonomous racing drone is equipped with a camera that scans the ArUco tags for gate detection which is supported by software used in autonomous flights that enable it to navigate through a predetermined course while avoiding obstacles and achieving high speeds. Unlike traditional drones, an autonomous racing drone does not require manual control, making it an ideal solution for those who do not have the skills or experience to operate a drone.Its autonomous capabilities make it a more accessible and user-friendly solution than traditional drones, enabling individuals or businesses to take advantage of this technology without requiring extensive training or expertise.
![image](https://user-images.githubusercontent.com/93365067/235303281-f63e379d-c156-45ad-b554-2c84bd82781d.png)
### Additional Information
In 2017, a student committee for DJS Phoenix was formed. In India, our team has participated in a number of contests, including IDRL-IIT GandhiNagar (sixth rank), IDRL-SVPCET Nagpur(second rank) and TECHNOXIAN (second place out of 50 national teams). In CopterHack-2021, our team participated, and we placed eighth internationally. We are back with improved concepts after learning from the previous season.
For more information checkout gitbook: https://djs-phoenix.gitbook.io/chetak-faster-than-you-can-imagine/.

View File

@@ -17,6 +17,8 @@ It is advisable to use a specialized build of PX4 with the necessary fixes and b
</ul>
</div>
> **Warning** If you are using the firmware version older than *v1.10* (for example, `v1.8.2-clover.13`), then in order to avoid configuration errors, use [QGroundControl version *v4.2.0*](https://github.com/mavlink/qgroundcontrol/releases/tag/v4.2.0) (or older). See [detailed information](https://docs.px4.io/v1.11/en/config/battery.html#parameter-migration-notes) about changes in the firmware parameters that cause errors in newer versions of QGroundControl.
<script type="text/javascript">
// get latest release from GitHub
fetch('https://api.github.com/repos/CopterExpress/Firmware/releases').then(function(res) {

View File

@@ -9,6 +9,7 @@ Main frames in the `clover` package:
* `base_link` is rigidly bound to the drone. It is shown by the simplified drone model on the image above;
* `body` is bound to the drone, but its Z axis points up regardless of the drone's pitch and roll. It is shown by the red, blue and green lines in the illustration;
* <a name="navigate_target"></a>`navigate_target` is bound to the current navigation target (as set by the [navigate](simple_offboard.md#navigate) service);
* `terrain` is bound to the floor at the current drone position (see the [set_altitude](simple_offboard.md#set_altitude) service);
* `setpoint` is current position setpoint;
* `main_camera_optical` is the coordinate system, [linked to the main camera](camera_setup.md#frame);

45
docs/en/liceu128.md Normal file
View File

@@ -0,0 +1,45 @@
# "QCS" - the network of Clover charging stations
[CopterHack-2023](copterhack2023.md), team **Lyceum 128**.
## Network realisation
Our charging stations use Python web server created with Django framework. On that server we storage information about charging stations:
- Position (GPS + ArUco marker).
- Possibility to drone landing.
- Drone info (If it's on it).
To connect to server we use API with special personal key for every drone and station. It can be regenerated if secured key became public.
If you want to test station without drone you can use API Debug page. You must be in your account to open it.
### Electronics in the station
There are Arduino Mega and Wemos D1 on the station.
![scheme](https://github.com/Juli-Shvetsova/clover/assets/78372613/3ab05a79-0046-463b-83dd-4db06115909b)
Wemos D1 connect with server to collect information, do tasks. Arduino Mega receive signals from Wemos and make physical updates such as moving landing platform, LED indication and other more.
After completing mission Wemos send request to a server to confirm updates on the server.
## Clover flight
We're using recursive landing algorithm to achieve success landing. Small ArUco marker is on the landing platform. Camera can use this marker on the ~25cm height. Next drone use standard landing.
## Visit our landing and API page
[https://qcs.pythonanywhere.com/](https://qcs.pythonanywhere.com/)
## Source code
Of that project is in our [GitHub page](https://github.com/qcs-charge/).
## Team
CH2023, Lyceum 128.
- Mikhail Konstantinov, [@mikemka](https://t.me/mikemka/), programmer.
- Julia Shvecova, [@Juli_Phil](https://t.me/Juli_Phil/), science adviser.
- Oleg Sherstobitov, [@kulumuluu](https://t.me/kulumuluu/), constructor.

200
docs/en/mocap_clover.md Normal file
View File

@@ -0,0 +1,200 @@
# Project Video
[CopterHack-2023](copterhack2023.md), team **Clover with Motion Capture System**. Click logo for project video.
<div align="center">
<a href="https://www.youtube.com/watch?v=jOovjo0aBpQ&t=4s&ab_channel=SeanSmith"><img src="../assets/mocap_clover/semi_logo_small.jpg" width="70%" height="70%" alt="IMAGE ALT TEXT"></a>
</div>
## Table of Contents
* [Team Information](#item-one)
* [Educational Document](#item-two)
* [Introduction](#item-three)
* [Project Description](#item-four)
* [Hardware](#item-hardware)
* [Data Transfer](#item-transfer)
* [Examples](#item-examples)
* [Trajectory Tracking](#item-figure8)
* [Auto-Tuning](#item-auto)
* [Conclusion](#item-last)
## Team Information {#item-one}
The list of team members:
* Sean Smith, @ssmith_81, roboticist and developer: [GitHub](https://github.com/ssmith-81), [Linkedin](https://www.linkedin.com/in/sean-smith-61920915a/).
## Educational Document {#item-two}
**My Gitbook, with detailed step by step analysis of the proposed project during the CopterHack 2023 competition can be found:**
[MoCap Clover Gitbook](https://0406hockey.gitbook.io/mocap-clover/).
This page gives a broad overview on the motivation and purpose behind this project, it also provides research and industry based knowledge around UAV application that the reader may find interesting. If the user is interested in the technical details and implementation then refer to the educational Gitbook document.
## Introduction {#item-three}
Aerial robotics has become a common focus in research and industry over the past few decades. Many technical developments in research require a controlled test environment to isolate certain characteristics of the system for analysis. This typically takes place indoors to eliminate unwanted disturbances allowing results to be more predictable. Removing localization and pose feedback concerns can be accomplished with motion capture (MoCap) systems that track unmanned aerial vehicles (UAVs) pose with high precision as stated:
"OptiTracks drone and ground robot tracking systems consistently produce positional error less than 0.3mm and rotational error less than 0.05°" [[reference](https://optitrack.com/applications/robotics/#:~:text=Exceptional%203D%20precision%20and%20accuracy&text=OptiTrack's%20drone%20and%20ground%20robot,error%20less%20than%200.05%C2%B0)].
<!-- markdownlint-disable MD044 -->
This enables researchers to study the dynamics and behavior of UAVs in different environments, evaluate their performance, and develop advanced control algorithms for improved flight stability, autonomy, and safety. Research facilities around the world tend to built research drones from the ground up using off-the-shelf components with open source platforms such as PX4. While the end goal is the same: transferring pose feedback to the flight controller along with high level commands, the platforms and methods can vary significantly depending on factors such as onboard and offboard computing frameworks and data transfer methods. Many developers have a detailed background and understanding of the theoretical components of their research, however, adapting hardware configurations to their own platform such as sensor feedback and sensor fusion is not obvious. The purpose of this project is to provide detailed documentation on integrating the Clover platform with the MoCap system along with examples to familiarize users with the hardware, sensor fusion, high and low level controller development, and trajectory tracking.
<!-- markdownlint-enable MD044 -->
## Project Description {#item-four}
In this article, we will provide an overview of MoCap systems for tracking UAV pose in research applications, highlighting their significance, advantages, and potential impacts in the field of UAV controller development.
## Document structure
The Motion Capture System educational document is divided into three main sections outside of the Introduction and Conclusion. Each section and its purpose is listed:
### Hardware {#item-hardware}
The main goal in this section is to educate the reader on the MoCap system hardware and software. This can be further divided into several steps including camera placement, marker placement, and system calibration. A summary of the process is provided:
| Task | Description |
| --------- | ----------- |
| Camera Placement | Position the motion capture cameras in strategic locations around the area where the UAV will be flying. The number of cameras and their placement will depend on the size of the area and the desired capture volume. Typically, cameras are placed on tripods or mounted on walls or ceilings at specific heights and angles to capture the UAV's movements from different perspectives. **A simple 4-camera setup example is provided in the educational document**. |
| Marker Placement | Attach OptiTrack markers to the UAV in specific locations. OptiTrack markers are small reflective spheres that are used as reference points for the motion capture system to track the UAV's position and movements. **An example placement on the Clover is shown in the educational document**.
| System Calibration | Perform system calibration to establish the spatial relationship between the cameras and the markers. This involves capturing a calibration sequence, during which a known pattern or object is moved in the capture volume. The system uses this data to calculate the precise positions and orientations of the cameras and markers in 3D space, which is crucial for accurate motion capture. |
With these components completed correctly, you are well on your way to commanding indoor autonomous missions like this:
<p align="center">
<img title="Figure-8" alt="Alt text" src="../assets/mocap_clover/drone_approach_small.jpg" width="60%" height="50%">
</p>
<!--
- Testing and Validation: After setting up the cameras and markers, perform test flights with the UAV to validate the accuracy of the MoCap system. Analyze the captured data to ensure that the UAV's movements are accurately captured and that the system is functioning correctly.
- Fine-tuning: Fine-tune the motion capture system as needed based on the test results. This may involve adjusting camera angles, marker placements, or calibration settings to improve the accuracy and reliability of the system.
- Data Collection: Once the motion capture system is properly set up and calibrated, you can start collecting data for your UAV research. The system will continuously track the positions and movements of the markers on the UAV in real-time, providing precise data that can be used for various analyses and experiments.
- Data Analysis: Analyze the captured data using appropriate software to extract relevant information for your UAV research. This may involve tracking the UAV's position, velocity, acceleration, orientation, and other parameters, and analyzing how they change over time or in response to different conditions or inputs.
-->
Overall, configuring a motion capture system for UAV research requires careful planning, precise marker placement, accurate system calibration, and thorough validation to ensure accurate and reliable data collection for your research purposes. For more information, refer to the [informative documentation](https://0406hockey.gitbook.io/mocap-clover/hardware/motion-capture-setup-optitrack).
### Data Transfer {#item-transfer}
With the data acquired from the MoCap system, the main goal in this section is to transfer it to the Raspberry Pi onboard the Clover and remap it to the flight controller/PX4 for control. A summary of the steps are listed:
<p align="center">
<img title="Figure-8" alt="Alt text" src="https://drive.google.com/uc?export=view&id=1B0OMIGveFZNyE1_UHpmBOukeFVgl-bTV" width="50%" height="50%">
</p>
* Data Acquisition: The motion capture system continuously tracks the position and orientation (pose) of the UAV using markers attached to the UAV and cameras positioned in the capture volume. The system calculates the 3D pose of the UAV in real-time and can be viewed through the motive software.
* Data Transmission: The pose data is transmitted from the motion capture system to a Raspberry Pi using VRPN and a ROS network. While this works, I have implemented a strictly UDP data transmission method where highlighting the setup process and ease of use will be a future development, both configurations can be seen in the below figures. The Raspberry Pi acts as an intermediary for processing and relaying the data to the flight controller onboard the UAV using MAVROS. The connection can be established using USB or UART, I chose UART in my setups.
<p align="center">
<img src="../assets/mocap_clover/block_ROS.jpg" width="49%" alt="ROS Block"/>
<img src="../assets/mocap_clover/block_udp.jpg" width="49%" alt="ROS Block"/>
<em>Fig.1(a) - Left figure: ROS network experimental setup topology. Legend: Black dotted line is the provided local network; Blue solid line is the Clover pose transmission where the final transmission from laptop to Pi is over a ROS network; Red line is hardware connections; MAVLink arrow is communication via a MAVLink protocol. .</em> <br>
<em>Fig.1(b) - Right figure: UDP transmission experimental setup topology. Legend: Black dotted line is the provided local network; Black solid line is the UDP client-server drone pose transmission; Light blue line is the pose data transmission; Red line is hardware connections; Purple line is communication via secure shell protocol and ROS network communication; MAVLink arrow is communication via a MAVLink protocol. .</em>
</p>
* Data Processing: The Raspberry Pi receives the pose data from the motion capture system over a ROS network on a VRPN ROS topic, this was initially parsed from the sensor readings into position and attitude.
* Data Remapping: Once the pose data is processed, the Raspberry Pi maps it to the to a gateway/MAVROS topic sending it to the flight controller onboard the UAV. All coordinate transformations (ENU->NED) are taken care of with MAVROS.
* Flight Control Update: The flight controller onboard the UAV receives the remapped pose data and uses it to update the UAV's flight control algorithms. The updated pose information can be used to adjust the UAV's flight trajectory, orientation, or other control parameters to achieve the desired flight behavior or control objectives based on the motion capture system feedback.
* Closed-Loop Control: The flight controller continuously receives pose feedback from the motion capture system via the Raspberry Pi, and uses it to update the UAV's flight control commands in a closed-loop fashion (PX4 uses a cascaded PID control system with more details provided in the educational document). This allows the UAV to maintain precise position and orientation control based on the real-time pose data provided by the motion capture system.
Overall, sending pose feedback from a motion capture system to a Raspberry Pi and remapping the data to the flight controller onboard a UAV involves acquiring, processing, and transmitting the pose data in a compatible format to enable real-time closed-loop control of the UAV based on the motion capture system's feedback.
### Examples {#item-examples}
This section provides two practical examples to help the user better understand the Clover platform, sensor fusion, UAV applications such as trajectory tracking, high level commands, and low level control. The reader will become familiar with an abundance of state-of-the-art open source UAV platforms/technologies such as:
| Platform | Description |
| ----------- | ----------- |
| PX4 | PX4 is an open-source flight control software for drones and other unmanned vehicles used on the Clover. It supports a wide range of platforms and sensors and is used in commercial and research applications. |
| Robot Operating System (ROS) |ROS is an open-source software framework for building robotic systems. It provides a set of libraries and tools for developing and managing robot software and is widely used in drone and robotics research. |
| MAVLink| MAVLink is a lightweight messaging protocol for communicating with unmanned systems. It is widely used in drone and robotics applications and provides a flexible and extensible communication framework.|
|QGroundControl (QGC)| QGC is an open-source ground control station software for drones and other unmanned vehicles. It provides a user-friendly interface for managing and monitoring drone flights and is widely used in commercial and research applications. |
<a id="item-figure8"></a>
1. **A figure-8 high-level trajectory generation**: this example is outlined for both Software in the Loop (SITL) simulations and hardware testing with the Clover platform. Check out this interesting example from my [trajectory tracking section](https://0406hockey.gitbook.io/mocap-clover/examples/flight-tests/complex-trajectory-tracking)!
<p align="center">
<img title="Figure-8" alt="Alt text" src="https://drive.google.com/uc?export=view&id=1imlqhaUl-v6JuEiOFA4BPvO1N174NWgY">
</p>
<p align = "center">
<em>Fig.2 - Lemniscate of Bernoulli [<a href="https://upload.wikimedia.org/wikipedia/commons/f/f1/Lemniscate_of_Bernoulli.gif">reference</a>].</em>
</p>
Here's a summary of the importance of trajectory tracking for UAV applications:
* *Navigation and Path Planning*: Trajectory tracking allows UAVs to follow pre-defined paths or trajectories, which is essential for tasks such as aerial mapping, surveying, inspection, and monitoring.
* *Precision and Safety*: Trajectory tracking enables precise control of the UAV's position, velocity, and orientation, which is crucial for maintaining safe and stable flight operations. Precise trajectory tracking allows UAVs to avoid obstacles, maintain safe distances from other objects or aircraft, and operate in confined or complex environments with high precision, reducing the risk of collisions or accidents.
* *Autonomy and Scalability*: Trajectory tracking enables UAV autonomy, allowing them to operate independently without constant operator intervention. This enables UAVs to perform repetitive or complex tasks autonomously, freeing up human operators to focus on higher-level decision-making or supervisory roles. Trajectory tracking also facilitates scalable operations, where multiple UAVs can follow coordinated trajectories to perform collaborative tasks, such as swarm operations or coordinated data collection.
* *Flexibility and Adaptability*: Trajectory tracking allows UAVs to adapt their flight paths or trajectories in real-time based on changing conditions or objectives. UAVs can dynamically adjust their trajectories to accommodate changes in environmental conditions, mission requirements, or operational constraints, allowing for flexible and adaptive operations in dynamic or unpredictable environments.
In summary, trajectory tracking is crucial for UAV applications as it enables precise navigation, safety, efficiency, autonomy, and scalability, while optimizing payload performance and adaptability to changing conditions. It plays a fundamental role in ensuring that UAVs can accomplish their missions effectively and safely, making it a critical component of UAV operations in various industries and domains.
<a id="item-auto"></a>
1. **Clover adaptive auto-tuning**: The second example shows the user how to implement the adaptive auto-tune module provided by PX4 to tune the low-level controllers or attitude control module. You can take a look into how this is accomplished with the Clover platform in the [auto-tuning section](https://0406hockey.gitbook.io/mocap-clover/examples/auto-tuning).
<p align="center">
<img title="Figure-8" alt="Alt text" src="../assets/mocap_clover/px4_control_structure.jpg" width="80%" height="80%">
</p>
<p align = "center">
<em>Fig.3 - Cascaded PX4 control system [<a href="https://docs.px4.io/v1.12/en/flight_stack/controller_diagrams.html#multicopter-control-architecture">reference</a>].</em>
</p>
This is a much faster and easier way to tune a real drone and provides good tuning for most air frames. Manual tuning is recommended when auto-tuning dos not work, or when fine-tuning is essential. However, the process is tedious and not easy especially for users with limited control background and experience. The Clover airframe provides sufficient base settings where auto-tuning can further improve performance depending on the Clover being used.
Here's a summary of the importance of low-level controller performance for UAV applications:
* *Flight Stability and Safety*: The low-level controller, typically implemented as a PID (Proportional-Integral-Derivative) or similar control algorithm, governs the UAV's attitude and position control. Properly tuning the low-level controller ensures that the UAV remains stable during flight, with accurate and responsive control inputs. This is essential for safe and reliable UAV operations, as it helps prevent undesired oscillations, overshooting, or instability that can lead to crashes or accidents.
* *Control Precision and Responsiveness*: Accurate control is crucial for achieving precise and responsive UAV maneuvers, such as smooth trajectory tracking, precise hovering, or dynamic maneuvers. Proper tuning of the low-level controller allows for precise control of the UAV's attitude, position, and velocity, enabling it to accurately follow desired flight trajectories, respond to changing conditions or commands, and perform complex flight maneuvers with high precision.
* *Adaptability and Robustness*: UAV operations can be subject to varying environmental conditions, payload configurations, or operational requirements. Proper low-level controller tuning allows for adaptability and robustness, enabling the UAV to perform reliably and accurately across a wide range of conditions or mission requirements. Tuning the controller parameters can help account for changes in payload mass, wind conditions, or other external factors, ensuring stable and responsive flight performance.
<p align="center">
<img title="Figure-8" alt="Alt text" src="https://drive.google.com/uc?export=view&id=1ech31B2JvYLcW9c7W67IguuQT-S53AFF" width="50%" height="50%">
</p>
In summary, low-level controller tuning is crucial for UAV applications as it directly affects flight stability, control precision, payload performance, energy efficiency, adaptability, and compliance with safety and regulatory requirements. It is an essential step in optimizing the performance and safety of UAV operations, ensuring reliable and effective flight control for various applications across different industries and domains.
## Conclusion {#item-last}
Over the course of this project I was able to extend my knowledge in robotic applications while enduring many ups and downs along the way. This greatly helped me with my research when testing controller development was required. The motivation behind this documentation is to improve this experience for other researchers, robotic developers, or hobbyists that have a desire to learn fundamental robotic application which is beginning to shape the world we know today. These details can be explored in a [GitBook](https://0406hockey.gitbook.io/mocap-clover/) for those who are interested.
I provided many details on the interworking components required to achieve an indoor autonomous flight setup with the COEX Clover platform. With an extensive background in UAV control, I tried to provide a basic understanding of this for the readers benefit. There are many more sections I would like to include along with improving upon the existing ones. A few examples include firmware testing with hardware in the loop simulations, advanced trajectory generation, and an extensive list of flight examples for the Gazebo simulator with application to hardware.
Lastly, I would like to thank the entire COEX team that made this project possible by providing a wonderful platform with support. I would like to give a special thanks to [Oleg Kalachev](https://github.com/okalachev) for helping me debug and succeed through applied learning. With that being said, I hope you all enjoy the resourceful content provided, and I plan on releasing more detailed documents on other interesting topics as I progress through my research and development.
<!--
## Project description
This project is an educational reference and detailed tutorial on how to setup the OptiTrack Motion Capture (MoCap) system with the COEX Clover platform.
It gives brief descriptions on the camera and motive software setup with many resourceful links, but it assumes the user has a basic understanding on how to
setup the cameras and motive computer software. MoCap markers allow the MoCap to stream positional data of the Clover therefore marker placement is discussed.
From there details on how to stream position data from the MoCap to the Clover along with how to configure the Clover; specifically, the Raspberry Pi and PX4
firmware parameters are discussed. The overall network will be provided as it is the most important part.
At the end, I will provide an interesting example such as a tracking a complex trajectory that any user can implement.
### Project idea
In many research applications highly precise position feedback is required and that is why a MoCap system is popular in this field of robotics. Research papers
are published detailed around certain topics such as control, path planning, obstacle avoidance and many more although the details surrounding certain hardware
setups such as with the MoCap system are not provided. There are a few sources that provide help with setting up the MoCap system with PX4 and other specific
systems but with limited knowledge of how and why steps are made one might not be able to adapt it to their own setup such as with the Clover. That is why this
project has been created; so that a student or user can follow this tutorial with the COEX Clover and have a working setup with the MoCap and Clover even with
a limited understanding of software and hardware. The article also provides descriptions on why certain things are done to allow the user the better understand
the system setup.
I currently have the setup running but now working well. The Clover is unable to follow setpoints with any precision
therefore working through network and software issues seems to be the current stage (I am not sure what exactly is causing this issue actually). I am hoping to
receive guidance in this area from this project so I can have it working as desired.
### Using Clover platform
The COEX Clover 4.2 kit is used where the MoCap system setup is specific for the Clover platform. It provides useful information for all robotics users interested in
implementing external sensor feedback although it is specific for Clover owners.
### Additional information at the request of participants
I am a masters student looking to implement this project in my research.
-->

View File

@@ -198,6 +198,15 @@ This page contains models and drawings of some of the drone parts. They can be u
</tr>
</table>
### 3D print
#### Mechanical gripper
* **Left claw**: [`grip_left.stl`](https://github.com/CopterExpress/clover/raw/master/docs/assets/stl/grip_left.stl).
* **Right claw**: [`grip_right.stl`](https://github.com/CopterExpress/clover/raw/master/docs/assets/stl/grip_right.stl).
Material: SBS Glass. Infill: 100%. Quantity: 1 pcs.
## Clover 4
### 3D print

View File

@@ -39,17 +39,27 @@ In case of using EKF2 (official firmware):
|Parameter|Value|Comment|
|-|-|-|
|`EKF2_AID_MASK`|26|Checkboxes: *flow* + *vision position* + *vision yaw*.<br>Details: [Optical Flow](optical_flow.md), [ArUco markers](aruco_map.md), [GPS](gps.md).|
|`EKF2_AID_MASK`\*|26|Checkboxes: *flow* + *vision position* + *vision yaw*.<br>Details: [Optical Flow](optical_flow.md), [ArUco markers](aruco_map.md), [GPS](gps.md).|
|`EKF2_OF_DELAY`|0||
|`EKF2_OF_QMIN`|10||
|`EKF2_OF_N_MIN`|0.05||
|`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_EVP_NOISE`|0.1||
|`EKF2_EV_DELAY`|0||
|`EKF2_MAG_TYPE`|5 (*None*)|Disabling usage of the magnetometer (when navigating indoor)|
\* — starting from PX4 version 1.14, the parameters marked with an asterisk are replaced with the following:
|Parameter|Value|Comment|
|-|-|-|
|`EKF2_EV_CTRL`|11|Checkboxes: *Horizontal position* + *Vertical position* + *Yaw*|
|`EKF2_GPS_CTRL`|0|All checkboxes are disabled|
|`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*)|
<!-- markdownlint-enable MD031 -->
> **Info** See also: list of default parameters of the [Clover simulator](simulation.md): https://github.com/CopterExpress/clover/blob/master/clover_simulation/airframes/4500_clover.

View File

@@ -67,7 +67,7 @@ Connect your receiver to the RC IN port on your flight controller:
</div>
> **Hint** Double check that you're using the RC IN port on the COEX Pix:
<img src="../assets/coexpix-bottom.jpg" width=300 class="zoom border center" alt="coex pix pinout">
<img src="../assets/coex_pix/coexpix-bottom.jpg" width=300 class="zoom border center" alt="coex pix pinout">
## Binding your transmitter {#rc_bind}

View File

@@ -1,5 +1,7 @@
# 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).
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).
`simple_offboard` is a high level system for interacting with the flight controller. For a more low level system, see [mavros](mavros.md).
@@ -20,6 +22,9 @@ rospy.init_node('flight') # 'flight' is name of your ROS node
get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry)
navigate = rospy.ServiceProxy('navigate', srv.Navigate)
navigate_global = rospy.ServiceProxy('navigate_global', srv.NavigateGlobal)
set_altitude = rospy.ServiceProxy('set_altitude', srv.SetAltitude)
set_yaw = rospy.ServiceProxy('set_yaw', srv.SetYaw)
set_yaw_rate = rospy.ServiceProxy('set_yaw_rate', srv.SetYawRate)
set_position = rospy.ServiceProxy('set_position', srv.SetPosition)
set_velocity = rospy.ServiceProxy('set_velocity', srv.SetVelocity)
set_attitude = rospy.ServiceProxy('set_attitude', srv.SetAttitude)
@@ -100,7 +105,6 @@ Parameters:
* `x`, `y`, `z` — coordinates *(m)*;
* `yaw` — yaw angle *(radians)*;
* `yaw_rate` angular yaw velocity (will be used if yaw is set to `NaN`) *(rad/s)*;
* `speed` flight speed (setpoint speed) *(m/s)*;
* `auto_arm` switch the drone to `OFFBOARD` mode and arm automatically (**the drone will take off**);
* `frame_id` [coordinate system](frames.md) for values `x`, `y`, `z` and `yaw`. Example: `map`, `body`, `aruco_map`. Default value: `map`.
@@ -119,7 +123,7 @@ Flying in a straight line to point 5:0 (altitude 2) in the local system of coord
navigate(x=5, y=0, z=3, speed=0.8)
```
Flying to point 5:0 without changing the yaw angle (`yaw` = `NaN`, `yaw_rate` = 0):
Flying to point 5:0 without changing the yaw angle:
```python
navigate(x=5, y=0, z=3, speed=0.8, yaw=float('nan'))
@@ -149,22 +153,10 @@ Flying to point 3:2 (with the altitude of 2 m) in the [ArUco map](aruco.md) coor
navigate(x=3, y=2, z=2, speed=1, frame_id='aruco_map')
```
Rotating on the spot at the speed of 0.5 rad/s (counterclockwise):
```python
navigate(x=0, y=0, z=0, yaw=float('nan'), yaw_rate=0.5, frame_id='body')
```
Flying 3 meters forwards at the speed of 0.5 m/s, yaw-rotating at the speed of 0.2 rad/s:
```python
navigate(x=3, y=0, z=0, speed=0.5, yaw=float('nan'), yaw_rate=0.2, frame_id='body')
```
Ascending to the altitude of 2 m (command line):
```(bash)
rosservice call /navigate "{x: 0.0, y: 0.0, z: 2, yaw: 0.0, yaw_rate: 0.0, speed: 0.5, frame_id: 'body', auto_arm: true}"
rosservice call /navigate "{x: 0.0, y: 0.0, z: 2, yaw: 0.0, speed: 0.5, frame_id: 'body', auto_arm: true}"
```
> **Note** Consider using the `navigate_target` frame instead of `body` for missions that primarily use relative movements forward/back/left/right. This negates inaccuracies in relative point calculations.
@@ -178,7 +170,6 @@ Parameters:
* `lat`, `lon` — latitude and longitude *(degrees)*;
* `z` — altitude *(m)*;
* `yaw` — yaw angle *(radians)*;
* `yaw_rate` angular yaw velocity (used for setting the yaw to `NaN`) *(rad/s)*;
* `speed` flight speed (setpoint speed) *(m/s)*;
* `auto_arm` switch the drone to `OFFBOARD` and arm automatically (**the drone will take off**);
* `frame_id` [coordinate system](frames.md) for `z` and `yaw` (Default value: `map`).
@@ -191,7 +182,7 @@ Flying to a global point at the speed of 5 m/s, while maintaining current altitu
navigate_global(lat=55.707033, lon=37.725010, z=0, speed=5, frame_id='body')
```
Flying to a global point without changing the yaw angle (`yaw` = `NaN`, `yaw_rate` = 0):
Flying to a global point without changing the yaw angle:
```python
navigate_global(lat=55.707033, lon=37.725010, z=0, speed=5, yaw=float('nan'), frame_id='body')
@@ -200,7 +191,71 @@ navigate_global(lat=55.707033, lon=37.725010, z=0, speed=5, yaw=float('nan'), fr
Flying to a global point (command line):
```bash
rosservice call /navigate_global "{lat: 55.707033, lon: 37.725010, z: 0.0, yaw: 0.0, yaw_rate: 0.0, speed: 5.0, frame_id: 'body', auto_arm: false}"
rosservice call /navigate_global "{lat: 55.707033, lon: 37.725010, z: 0.0, yaw: 0.0, speed: 5.0, frame_id: 'body', auto_arm: false}"
```
### set_altitude
Change the desired flight altitude. The service is used to set the altitude and its coordinate system independently, after calling [`navigate`](#navigate) or [`set_position`](#setposition).
Parameters:
* `z` flight altitude *(m)*;
* `frame_id` [coordinate system](frames.md) for computing the altitude.
Set the desired altitude to 2 m relative to the floor:
```python
set_altitude(z=2, frame_id='terrain')
```
Set the desired altitude to 1 m relative to [the ArUco map](aruco.md):
```python
set_altitude(z=1, frame_id='aruco_map')
```
### set_yaw
Change the desired yaw angle (and its coordinate system), keeping the previous command in effect.
Parameters:
* `yaw` — yaw angle *(radians)*;
* `frame_id` [coordinate system](frames.md) for computing the yaw.
Rotate by 90 degrees clockwise (the previous command continues):
```python
set_yaw(yaw=math.radians(-90), frame_id='body')
```
Set the desired yaw angle to zero relative to [the ArUco map](aruco.md):
```python
set_yaw(yaw=0, frame_id='aruco_map')
```
Stop yaw rotation (caused by [`set_yaw_rate`](#setyawrate) call):
```python
set_yaw(yaw=float('nan'))
```
### set_yaw_rate
The the desired angular yaw velocity, keeping the previous command in effect.
Parameters:
* `yaw_rate` angular yaw velocity *(rad/s)*;
The positive direction of `yaw_rate` rotation (when viewed from the top) is counterclockwise.
Start yaw rotation at 0.5 rad/s (the previous command continues):
```python
set_yaw_rate(yaw_rate=0.5)
```
### set_position
@@ -213,7 +268,6 @@ Parameters:
* `x`, `y`, `z` — point coordinates *(m)*;
* `yaw` — yaw angle *(radians)*;
* `yaw_rate` angular yaw velocity (used for setting the yaw to NaN) *(rad/s)*;
* `auto_arm` switch the drone to `OFFBOARD` and arm automatically (**the drone will take off**);
* `frame_id` [coordinate system](frames.md) for `x`, `y`, `z` and `yaw` parameters (Default value: `map`).
@@ -235,19 +289,12 @@ Assigning the target point 1 m ahead of the current position:
set_position(x=1, y=0, z=0, frame_id='body')
```
Rotating on the spot at the speed of 0.5 rad/s:
```python
set_position(x=0, y=0, z=0, frame_id='body', yaw=float('nan'), yaw_rate=0.5)
```
### set_velocity
Set speed and yaw setpoints.
* `vx`, `vy`, `vz` flight speed *(m/s)*;
* `yaw` — yaw angle *(radians)*;
* `yaw_rate` angular yaw velocity (used for setting the yaw to NaN) *(rad/s)*;
* `auto_arm` switch the drone to `OFFBOARD` and arm automatically (**the drone will take off**);
* `frame_id` [coordinate system](frames.md) for `vx`, `vy`, `vz` and `yaw` (Default value: `map`).
@@ -280,7 +327,7 @@ Parameters:
* `thrust` — throttle level, ranges from 0 (no throttle, propellers are stopped) to 1 (full throttle).
* `auto_arm` switch the drone to `OFFBOARD` and arm automatically (**the drone will take off**);
The positive direction of `yaw_rate` rotation (when viewed from the top) is counterclockwise,`pitch_rate` rotation is forward, `roll_rate` rotation is to the left.
The positive direction of `yaw_rate` rotation (when viewed from the top) is counterclockwise, `pitch_rate` rotation is forward, `roll_rate` rotation is to the left.
### land

View File

@@ -9,7 +9,7 @@ The recommended virtual machine hypervisor is [UTM app](https://mac.getutm.app/)
<img src="../assets/simulation_utm.png" width=500 class="center zoom">
1. Download UTM App from the official site [mac.getutm.app](https://mac.getutm.app/) and install it.
2. Download Ubuntu Linux 20.04 installation iso-file for ARM64 architecture using the link: https://cdimage.ubuntu.com/focal/daily-live/current/focal-desktop-arm64.iso.
2. Download Ubuntu Linux 20.04 installation iso-file for ARM64 architecture using the link: https://clovervm.ams3.digitaloceanspaces.com/focal-desktop-arm64.iso.
3. Create a new virtual machine in UTM, using the following settings:
* **Type**: Virtualize.

View File

@@ -488,3 +488,23 @@ Check, if the code is running inside a [Gazebo simulation](simulation.md):
```python
is_simulation = rospy.get_param('/use_sim_time', False)
```
### # {#simulator-interaction}
You can move a physical object (link) in Gazebo (as well as change its velocity) using the `gazebo/set_link_state` service (of the type [`SetLinkState`](http://docs.ros.org/en/api/gazebo_msgs/html/srv/SetLinkState.html)). For example, if you add a cube to the world (link `unit_box::link`), you can move it to the point (1, 2, 3):
```python
import rospy
from geometry_msgs.msg import Point, Pose, Quaternion
from gazebo_msgs.srv import SetLinkState
from gazebo_msgs.msg import LinkState
rospy.init_node('flight')
set_link_state = rospy.ServiceProxy('gazebo/set_link_state', SetLinkState)
# Change link's position
set_link_state(LinkState(link_name='unit_box::link', pose=Pose(position=Point(1, 2, 3), orientation=Quaternion(0, 0, 0, 1))))
```
> **Info** Simple object animation in Gazebo can be implemented [using actors](http://classic.gazebosim.org/tutorials?tut=actor&cat=build_robot).

View File

@@ -1,14 +1,14 @@
# Working with the ultrasonic distance gage
# Working with the ultrasonic distance sensor
Ultrasonic distance gage (*"sonar"*) is a distance gage based on the principle of measuring the time of a sound wave (about 40 kHz) propagation to the obstacle and back. The sonar can measure the distance up to 1.5 3 m with the accuracy of several centimeters.
Ultrasonic distance sensor (*"sonar"*) is a distance sensor based on the principle of measuring the time of a sound wave (about 40 kHz) propagation to the obstacle and back. The sonar can measure the distance up to 1.5 3 m with the accuracy of several centimeters.
## Distance gage HC-SR04
## HC-SR04 distance sensor
<img src="../assets/hc-sr04.jpg" alt="hc-sr04" width=200>
## Installation
The distance gage is attached to the body using double-sided tape. For obtaining acceptable results, the use of vibro-insulation is required. A piece of PU foam may be used for vibro-insulation.
The distance sensor is attached to the body using double-sided tape. For obtaining acceptable results, the use of vibro-insulation is required. A piece of PU foam may be used for vibro-insulation.
### Connection
@@ -24,17 +24,17 @@ Connect HC-SR04 to Raspberry Pi according to the connection diagram. Use 1.0 and
### Reading the data
To read the data from distance gage HC-SR04 library for working with <abbr title="General-Purpose Input/Output">GPIO</abbr> is used [`pigpio`](http://abyz.me.uk/rpi/pigpio/index.html). This library is pre-installed in the [Clover image](image.md), starting with version **v0.14**. For older versions of the image, use [an installation guide](http://abyz.me.uk/rpi/pigpio/download.html).
To read the data from distance sensor HC-SR04 library for working with <abbr title="General-Purpose Input/Output">GPIO</abbr> is used [`pigpio`](http://abyz.me.uk/rpi/pigpio/index.html). This library is pre-installed in the [Clover image](image.md), starting with version **v0.14**. For older versions of the image, use [an installation guide](http://abyz.me.uk/rpi/pigpio/download.html).
To work with `pigpio`, start appropriate daemon:
```(bash)
```bash
sudo systemctl start pigpiod.service
```
You can also enable `pigpiod` auto launch on system startup:
```(bash)
```bash
sudo systemctl enable pigpiod.service
```
@@ -113,15 +113,15 @@ An example of charts of initial and filtered data:
The source code of the ROS-node used for building the chart can be found [on Gist](https://gist.github.com/okalachev/feb2d7235f5c9636802c3cda43add253).
## Distance gage RCW-0001
## RCW-0001 distance sensor
<img src="../assets/rcw-0001.jpg" width=200>
Ultrasonic distance gage RCW-0001 is compatible with distance gage HC-SR04. Use the instruction above to connect and work with it.
The RCW-0001 distance sensor is compatible with distance sensor HC-SR04. Use the instruction above to connect and work with it.
## Flight
An example of a flight program with the use of [simple_offboard](simple_offboard.md), which makes the copter fly forward until the connected ultrasonic distance gage detects an obstacle:
An example of a flight program with the use of [simple_offboard](simple_offboard.md), which makes the copter fly forward until the connected ultrasonic distance sensor detects an obstacle:
```python
set_velocity(vx=0.5, frame_id='body', auto_arm=True) # flying forward at the velocity of 0.5 mps

View File

@@ -13,9 +13,9 @@ ssh pi@192.168.11.1
Password: `raspberry`.
For SSH access from Windows, you may use [PuTTY](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html).
For SSH access from Windows, you may use [PuTTY](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html). You can also gain SSH access from your smartphone using the [Termius](https://www.termius.com) app.
You can also gain SSH access from your smart-phone using the [Termius](https://www.termius.com) app.
> **Hint** To avoid entering the password each time you connect via SSH, see [the article on using SSH keys](ssh_keys.md).
Read more: https://www.raspberrypi.org/documentation/remote-access/ssh/README.md

180
docs/en/ssh_keys.md Normal file
View File

@@ -0,0 +1,180 @@
# Connecting to Raspberry Pi using SSH keys
*This instruction will allow you to quickly connect to the Raspberry Pi. In just one second. Without entering a password.*
Basic information on working with SSH can be found in the section [SSH access to Raspberry Pi](ssh.md). In this section you will find advanced information on using SSH, as well as a number of recommendations on using SSH when working with Clover.
## General information
SSH (*secure shell*) is a network protocol that allows you to remotely control the operating system on the computer you are connected to. It is similar to a protocol such as *telnet*, but allows you to encrypt network traffic during interaction. Thus, the transfer of passwords and other secret information is hidden. The Raspberry Pi operating system supports SSH communication, like many other common Linux-based systems.
SSH allows you not only to organize work in the command shell, but also to transfer files, as well as tunnel transmitted data from other protocols, such as information from a video camera or telemetry. In addition, SSH supports several authentication modes (that is, verification of the connecting user), with its help it is possible to connect to the Clover not only using a password, but also password-free access (authentication by a key pair, i.e. SSH keys).
## Password authentication
Authentication [by password](ssh.md) on the image of RPi for Clover is enabled by default and the password can be used to enter into the command shell of the minicomputer. On computers with Linux operating systems (and primarily on servers connected to the Internet), the ability to login with a password is usually disabled, since there is a more secure authentication method.
> **Hint** It is not recommended to disable logging into Clover by password, since you can completely lose access to the command shell over the network.
When connecting to RPi for the first time, you will see the notification with a suggestion to save a unique *fingerprint*. The stored information is accumulated on computers from which SSH login to RPi is performed, and is checked for sudden substitution.
On Linux and Unix (Mac OS) the first SSH-connection to the RPi looks like this:
```bash
ssh pi@192.168.11.1
# The authenticity of host '192.168.11.1 (192.168.11.1)' can't be established.
# ED25519 key fingerprint is SHA256:4w/7MqTgrtsqPwKnVAMISpouaOJNqzUew2NkJjldMWI.
# This key is not known by any other names
# Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
# Warning: Permanently added '192.168.11.1' (ED25519) to the list of known hosts.
# pi@192.168.11.1's password: *********
# Linux clover-3270 5.10.17-v7l+ #1414 SMP Fri Apr 30 13:20:47 BST 2021 armv7l
whoami
# pi
exit
```
In graphical programs in Windows, you will periodically see window with similar warnings.
<img src="../assets/ssh-keys-known_hosts-fingerprint.png" alt="Сохранение отпечатка в Windows" class="border center">
> **Hint** Windows 10 has a built-in SSH client that can be run from the command line, see the Microsoft usage guide [at this link](https://learn.microsoft.com/ru-ru/windows-server/administration/openssh/openssh_install_firstuse).
## Authentication using SSH keys
SSH keys are a convenient, fast alternative way to connect to the Raspberry Pi, which does not require entering a password. In particular, when operating with Clover, this method is convenient because it saves time, and therefore battery power, and the time limit allocated for events in flight zones. In addition, using SSH keys opens up opportunities for convenient use of other programs that you would hardly use if you needed to type a password every time.
The SSH key is divided into two parts: the pair consists of a so-called *private* and *public* key. The key is generated once. One part of the key (open) is transferred once to the remote computer to which the connection will be made, the second part of the key (private) is stored on the computer that will connect, the private part of the key is not transferred anywhere.
> **Hint** The public key is copied once to the Raspberry Pi, and the private key is stored in the laptop as a file.
### Preparation
In order for a key pair to appear, it must be generated. In Linux and Unix (Mac OS), there is a program `ssh-keygen` with which we will get the key pair we need (**attention!** commands are executed not in Raspberry Pi, and not in the virtual machine of the Gazebo simulator, but in the command shell of the laptop from which you will connect to the Clover):
Before using the keys, you need to perform a number of actions to configure access rights *on the laptop*:
```bash
# one-time setting of access rights to user directories
chmod o-rwx $HOME
mkdir ~/.ssh
chmod g-rwx,o-rwx ~/.ssh
touch ~/.ssh/config ~/.ssh/known_hosts
chmod 600 ~/.ssh/config ~/.ssh/known_hosts
```
> **Hint** The `.ssh` directory in the user's home folder is the standard storage location for both key pairs and SSH connection settings, so we prohibit access to it by the Others group (*outsiders*). Modern Linux distributions check access rights to files in the `.ssh` directory and may refuse authentication by key pairs.
### Generating an SSH key pair
Generating a pair of SSH keys in the `~/.ssh` directory on the laptop:
```bash
ssh-keygen -f ~/.ssh/id_clover -C "SSH key for Clover" -N ""
# Your identification has been saved in /home/galina/.ssh/id_clover
# Your public key has been saved in /home/galina/.ssh/id_clover.pub
chmod 400 ~/.ssh/id_clover*
```
### Copying SSH key to Raspberry Pi
After that [connect to Raspberry Pi via WiFi](wi fi.md) and continue to enter commands *on the laptop* to copy the key to the minicomputer:
```bash
ssh-copy-id -i ~/.ssh/id_clover.pub pi@192.168.11.1
# pi@192.168.11.1's password: *********
```
As a result, the so-called *public* part of the key will be copied from the laptop to the RPi microcomputer, and the *private* part will remain on the laptop. To verify the connection without entering a password, use the command indicating the path where the SSH key is located:
```bash
ssh -i ~/.ssh/id_clover pi@192.168.11.1
```
If the terminal does not require you to enter a password to connect to the RPi, then you did everything correctly and the SSH key pair works. Now you can type the exit command from the SSH terminal to continue configuring the laptop:
```bash
pi@clover-3270:~ $ exit
# logout
# Connection to 192.168.11.1 closed.
galina@Thinkpad-X1:~/.ssh$
```
## Configuring SSH connection to Clover
Now let's set up the SSH terminal in such a way that you don't have to enter the path to the private key every time. This is done by editing the `~/.ssh/config` file *on a laptop*. Open the file in a text editor and add the following lines to the file (if there is already some information there, then put them at the end of the file):
```txt
Host 192.168.11.1
User pi
IdentityFile ~/.ssh/id_clover
PreferredAuthentications publickey,password
PubkeyAuthentication yes
PasswordAuthentication yes
ConnectTimeout 1
TCPKeepAlive yes
ServerAliveInterval 2
ServerAliveCountMax 3
StrictHostKeyChecking no
```
This setting:
* affects the operation of the SSH terminal when connected to a computer with the IP address `192.168.11.1`;
* if the user name is not specified, the name `pi` will be used automatically;
* the private key `~/.ssh/id_clover` will be used automatically;
* if the key does not fit for some reason (it was replaced on one laptop, but forgot to replace it on another), then the SSH terminal will switch to password authentication (settings `PreferredAuthentications`, `PubkeyAuthentication`, `PasswordAuthentication`);
* if communication with RPi cannot be established (WiFi is not yet connected), then the SSH connection will not hang, but will be completed quickly (setting `ConnectTimeout`);
* if the connection with RPi is suddenly severed, the SSH connection will not hang, but will be completed quickly (settings `TCPKeepAlive`, `ServerAliveInterval`, `ServerAliveCountMax`);
* the unique SSH *fingerprints* of the RPi microcomputers mentioned above will no longer be checked (the settings `StrictHostKeyChecking`).
This will solve a lot of inconveniences associated with using SSH connections.
> **Hint** If you have several Raspberry Pi-based drones in your laboratory, and several laptops, then you can **generate SSH keys once**, copy them to all drones and spread them across all laptops, then you can quickly access any of the drones from any laptop.
Now, to connect to RPi from a Linux terminal, you just need to type `ssh 1[TAB][TAB][ENTER]` and the ip address `192.168.11.1` will be automatically updated on the command line, because the command shell uses addresses from the file `~/.ssh/config` and is able to "guess" your intentions to connect to the Clover. By pressing enter, you will instantly find yourself in the RPi terminal.
> **Hint** Graphical programs for Windows that support working with SSH keys, which you can use: [PuTTY](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html) and [MobaXterm](https://mobaxterm.mobatek.net/).
## Copying files using SSH
To copy a file `circle_flight.py` from the laptop to the RPi to the user's home folder `pi`, you can also use SSH. To do this, type the command in the command shell:
```bash
# first we specify 'what' we copy, and then 'where'
scp circle_flight.py 192.168.11.1
```
To copy `output.avi` file from the `examples` RPi' folder to the laptop, use a similar command:
```bash
# after the ':' character (colon), you can specify the path on the remote computer
# the path specified as './' means the current folder where the file will be copied
scp 192.168.11.1:examples/output.avi ./
```
## Remote command launch via SSH
To run a command at laptop on the RPi (that is, remotely), you can also use SSH.
Raspberry shutdown command:
```bash
ssh 192.168.11.1 'sudo shutdown now'
```
Example of a Python script' startup command:
```bash
ssh -t 192.168.11.1 'ROS_HOSTNAME=`hostname`.local && . /opt/ros/noetic/setup.bash && . /home/pi/catkin_ws/devel/setup.bash && python3 examples/get_telemetry.py'
```
In order to remotely start video recording, you can run the command:
```bash
ssh -t 192.168.11.1 'ROS_HOSTNAME=`hostname`.local && . /opt/ros/noetic/setup.bash && . /home/pi/catkin_ws/devel/setup.bash && rosrun image_view video_recorder image:=/main_camera/image_raw'
```

View File

@@ -0,0 +1,247 @@
<!-- markdownlint-disable MD041 -->
<a name="logo" href="https://swarm-in-blocks.gitbook.io/swarm-in-blocks/introduction/swarm-in-blocks"><img align="center" src="../assets/swarm_in_blocks_2/capa_swarm_23_banner.png" alt="Swarm in Blocks" style="width:100%;height:100%"/></a>
<h1 align="center" style="display: block; font-size: 2.5em; margin-block-start: 1em; margin-block-end: 1em;">
Swarm in Blocks
</h1>
[CopterHack-2023](copterhack2023.md), team **Atena**.
## Project Status[![](https://raw.githubusercontent.com/aregtech/areg-sdk/master/docs/img/pin.svg)](#project-status)
<table class="no-border">
<tr>
<td><img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grupo-SEMEAR-USP/swarm_in_blocks"></td>
<td><img alt="GitHub commit activity" src="https://img.shields.io/github/commit-activity/y/Grupo-SEMEAR-USP/swarm_in_blocks"></td>
<td><img alt="GitHub contributors" src="https://img.shields.io/github/contributors/Grupo-SEMEAR-USP/swarm_in_blocks"></td>
<td><img alt="GitHub language count" src="https://img.shields.io/github/languages/count/Grupo-SEMEAR-USP/swarm_in_blocks"></td>
</tr>
</table>
## Final Video ![](https://raw.githubusercontent.com/aregtech/areg-sdk/master/docs/img/pin.svg)
<p align="center">
<a href="https://www.youtube.com/watch?v=QFKgrqIAO1E&ab_channel=SwarminBlocks" title="Final Video 2023"><img img width="500" height="281" src="https://img.youtube.com/vi/QFKgrqIAO1E/maxresdefault.jpg" /></a>
</p>
---
## Table of contents[![](https://raw.githubusercontent.com/aregtech/areg-sdk/master/docs/img/pin.svg)](#table-of-contents)
- [Introduction](#Introduction)
- [Getting started](#getting-started)
- [Usage modes](#Usage-modes)
- [New Swarm Features](#New-Swarm-Features)
- [Conclusion](#Conclusion)
---
## Introduction[![](https://raw.githubusercontent.com/aregtech/areg-sdk/master/docs/img/pin.svg)](#Introduction)
Nowadays, **swarms of drones** are getting more and more applications and being used in several different areas, from agriculture to surveillance and rescues. But controlling a high amount of drones isn't a simple task, demanding a lot of studies and complex software.
Swarm in Blocks (from it's origin in 2022) was born looking to make a *high-level interface based on the blocks language*, to make simple handling swarms, without requiring advanced knowledge in all the necessary platforms, creating tools to allow a lot of applications based on the user needs and also using the Clover platform.
In 2023, Swarm in Blocks has taken an even bigger step, looking to fulfill our biggest vision **"It's never been easier to Swarm"**, we talk to transcend the local scope of the past project and explore the biggest problems for implementing a Swarm. For Copterhack 2023, we present Swarm in Blocks 2.0, an even more complete platform with the purpose of facing the biggest difficulties of a Swarm in a simple and polished way.
<p align="center">
<img width="600" src="https://raw.githubusercontent.com/Grupo-SEMEAR-USP/swarm_in_blocks/master/assets/intro/clovers_leds.gif" />
</p>
### Swarm in Blocks 2022
Swarm in Blocks is a CopterHack 2022 project. It's a high-level interface based on the blocks language, which consists of fitting code parts, like a puzzle. Each script represents a functionality, for example, conditional structures, loops, or functions that receive parameters and return an instruction to the swarm.
<p align="center">
<img width="500" src="https://raw.githubusercontent.com/Grupo-SEMEAR-USP/swarm_in_blocks/master/assets/intro/blocksIDE.gif" />
</p>
<p align="center">
<img width="500" src="https://raw.githubusercontent.com/Grupo-SEMEAR-USP/swarm_in_blocks/master/assets/intro/ring.gif" />
</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).
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**.
### What's new
As already mentioned, of the various problems that can increase the complexity of a real swarm, we decided to deal with the ones that most afflicted us and reintegrated our solutions into our central platform, building a single extremely complete and cohesive platform.
| Problem | Our Solution |
| -------- | -------- |
| Possible collision between drones (lack of safety especially for large Swarms) | Collision Avoidance System |
| Giant clutter to keep track of all Clovers in a swarm individually (several terminals, many simultaneous computers with several people to keep track of) | Swarm Station |
| Lack of basic features for handling a swarm pre-implemented in the Clover platform (such as access to battery data and raspberry computational power) | Full integration of low level data in our Swarm Station |
| Lack of security in indoor tests regarding the limitation of physical space (walls and objects) in the Swarm region | Safe Area Pop Up in Swarm Station |
| Decentralization of information and platforms for access | Web Homepage |
| Difficulty configuring physical drones for swarm | Our complete documentation with pre-designed settings for swarms in our repo image |
| Lack of a center for reports of successful tests with swarms of drones for the Clover platform describing the test conditions (odometry, etc.) | Show off section in our Gitbook |
And many other solutions are also featured on our platform, for more information please check the solutions described clearly and in detail throughout our **Gitbook**. We recommend reading in order to understand the fundamental precepts of our platform.
📖 **Access our [Gitbook](https://swarm-in-blocks.gitbook.io/swarm-in-blocks/background-theory/systems)!**
💻 **Access our [GitHub](https://github.com/Grupo-SEMEAR-USP/swarm_in_blocks.git)!**
<div align="right">[ <a href="#table-of-contents">↑ to top ↑</a> ]</div>
---
## Getting started[![](https://raw.githubusercontent.com/aregtech/areg-sdk/master/docs/img/pin.svg)](#getting-started)
Our platform was made to be extremely intuitive and easy to use. To start (after completing the installation we suggested in our gitbook), you can run the command:
```bash
roslaunch swarm_in_blocks simulation.launch num:=2
```
After that, you can open your browser and access our homepage by typing `localhost` in the search bar.
<div align="right">[ <a href="#table-of-contents">↑ to top ↑</a> ]</div>
---
## Usage modes[![](https://raw.githubusercontent.com/aregtech/areg-sdk/master/docs/img/pin.svg)](#Usage-modes)
The Swarm in Blocks can be programmed either with the blocks interface or directly in Python and we developed three main launch modes, each one focused on a different application of the project, they are:
- *Planning Mode:* Its main goal is to allow the user to check the drones' layout, save and load formations, before starting the simulator or using real clovers. In order to need less computational power and avoid possible errors during the simulation.
- *Simulation Mode:* In this mode happens the simulation indeed, starting the Gazebo, the necessary ROS nodes and some other tools. It allows applying the developed features, which will be explained ahead and see how they would behave in real life.
- *Navigation Mode:* The last mode will support executing everything developed in real clovers so that it's possible to control a swarm with block programming. The biggest obstacle yet is the practical testing of this mode, due to the financial difficulty of acquiring a Clover swarm.
<div align="right">[ <a href="#table-of-contents">↑ to top ↑</a> ]</div>
---
## New Swarm Features[![](https://raw.githubusercontent.com/aregtech/areg-sdk/master/docs/img/pin.svg)](#New-Swarm-Features)
With our vision of solving the problems that most plague the deployment of a real swarm, we have developed several features (and even integrated platforms), below we will list our main developments:
### Homepage
Like last year, we really wanted to make it easier for the user to go through our platform. That's why this year we decided to restructure our Homepage, gathering our main features and functionalities.
<p align="center">
<img width="700" src="https://raw.githubusercontent.com/Grupo-SEMEAR-USP/swarm_in_blocks/master/assets/homepage/homepage.gif"/>
</p>
### Swarm Station
The main feature from our platform is the *Swarm Station*, which is a **3d Web Visualizer** that shows in real time all the necessary information regarding the drones state, such as real time positioning and visualization, which clover is connected, the topics available and a lot more. Also, you can define a safe area to ensure each drones safety, forcing them to land in case they cross the forbidden area. The front end runs completely on the web browser, saving processing and installation resources. It also comes with a web terminal, allowing the user to open several instances of a terminal emulation in just one click.
<p align="center">
<img width="700" src="https://raw.githubusercontent.com/Grupo-SEMEAR-USP/swarm_in_blocks/master/assets/swarm_station/vid01.gif"/>
</p>
This package uses the ROS suite `rosbridge_server` to establish a communication between the ROS environment and the web server.
To run it, we recommend using **Firefox** browser to assure stability. But feel free to test it on other navigators.
If you launched our `simulation.launch` from the `swarm_in_blocks` package, then you just have to run
```bash
roslaunch swarm_station swarm_station.launch
```
Otherwise, you have to make sure that the `rosbridge_websocket` is running on port `9090`:
```bash
roslaunch rosbridge_server rosbridge_websocket.launch port:=9090
```
For more detailed instructions on how to use each single feature from the Swarm Station, check our [Gitbook page about the station](https://swarm-in-blocks.gitbook.io/swarm-in-blocks/).
### Swarm Collision Avoidance
When many drones move close to each other, collisions are very likely to occur. To avoid this problem, an algorithm was developed to avoid collisions between drones. When analyzing a collision, 3 types of scenario are possible, the case where one clover is stationary and the other in motion, the case where both are in motion and with parallel trajectories, and finally the case where both are in motion and with non-parallel trajectory.
To turn on the collision avoidance, it is necessary to run:
```bash
rosrun swarm_collision_avoidance swarm_collision_avoidance_node.py
```
<p align="center">
<img width="600" src="https://raw.githubusercontent.com/Grupo-SEMEAR-USP/swarm_in_blocks/master/assets/collision.gif" />
</p>
### Rasp Package
The Raspberry package was developed to instantiate a node that will be responsible for collecting essential processing, memory and temperature information from the raspberry and send it to the Swarm Station. It's the package that should be put on the `catkin_ws/src/` directory of each Raspberry Pi, because it also contains the `realClover.launch` needed to launch the swarm on real life.
### Swarm FPV
This package is a reformulation of one of the CopterHack 2022 implementations, the **Swarm First Person Viewer**. This year, we decided to restart its structure, making it run also completely on the web to integrate with the Swarm Station. It also depends on the `rosbridge_websocket` running on the port `9090` (default).
<p align="center">
<img width="600" src="https://raw.githubusercontent.com/Grupo-SEMEAR-USP/swarm_in_blocks/master/assets/fpv_2023.gif"/>
</p>
### Real Swarm
In order to fly a real swarm using clover, we decided to take an approach of putting every clover on the same ROS network / environment so that the master could talk to each one of them.
We did this by separating each drone topics / nodes / services with namespaces. The goal is to achieve the same effect as the simulation that we've done in [**CopterHack-2022**](copterhack2022.md), so each drone would have its own `/cloverID` namespace, and the ID is the identifier for each drone.
In other words, instead of just `simple_offboard` node for a single drone, we'd now have `/clover0/simple_offboard`, `/clover1/simple_offboard` and so on.
To launch it, you need to first stop clover's default daemon, and then connect all Raspberries to the same network. After that, you should connect all their `roscore` to the same IP address (the master's), and then launch the `realClover.launch` file passing the `ID` argument as a parameter. Again, for more detailed information on how this works, please check out our [gitbook](https://swarm-in-blocks.gitbook.io/swarm-in-blocks/):
```bash
sudo systemctl stop clover
roslaunch rasp_pkg realClover.launch ID:=0
```
<p align="center">
<img width="500" src="https://raw.githubusercontent.com/Grupo-SEMEAR-USP/swarm_in_blocks/master/assets/swarm_real/swarm.gif"/>
</p>
> **Note** We are aware that in the video the calibration of the drone control is not ideal, however, the objective of this test was really to validate the operation of the swarm in a real environment (which was actually done).
<div align="right">[ <a href="#table-of-contents">↑ to top ↑</a> ]</div>
---
## Conclusion[![](https://raw.githubusercontent.com/aregtech/areg-sdk/master/docs/img/pin.svg)](#Conclusion)
Engineering and robotics challenges have always been the main driver of Team Athena, from which we seek to impact society through innovation. Last year, during CopterHack 2022, there was no lack of challenges of this type, and in them we grew and exceeded our limits, all to deliver the best possible project: **Swarm in Blocks**. All the motivation to facilitate a task as complex as the manipulation of swarms of drones, even through block programming, delighted us a lot and we hope that it delights all our users.
With that came the Swarm in Blocks 2.0, which brought with it innovations that optimized the clover's flight control and that could allow for greater emotions in the handling of the drone, in addition to focusing on greater flight safety.
The Swarm in Blocks 2.0 presents new features for this year, such as the Web terminal, First Person View (FPV), Collision Avoidance, Clover UI and Swarm Station.
However, the work will not stop there. Our goal is to further improve our system and next steps include validating Collision Avoidance outside the simulated world and performing performance tests with network communication solutions to optimize Real Swarm.
Finally, we thank the entire COEX team that made CopterHack 2023 possible and all the support given during the competition. We are Team Atena, creator of the Swarm in Blocks platform and we appreciate all your attention!
<div align="right">[ <a href="#table-of-contents">↑ to top ↑</a> ]</div>
---
## The Atena Team
Atena Team 2023 (Swarm in Blocks 2.0):
- Agnes Bressan de Almeida : [GitHub](https://github.com/AgnesBressan), [LinkedIn](https://www.linkedin.com/in/agnes-bressan-148615262/)
- Felipe Tommaselli: [GitHub](https://github.com/Felipe-Tommaselli), [LinkedIn](https://www.linkedin.com/in/felipe-tommaselli-385a9b1a4/)
- Gabriel Ribeiro Rodrigues Dessotti : [GitHub](https://github.com/dessotti1), [LinkedIn](https://www.linkedin.com/in/gabriel-ribeiro-rodrigues-dessotti-8884a3216)
- José Carlos Andrade do Nascimento: [GitHub](https://github.com/joseCarlosAndrade), [LinkedIn](https://www.linkedin.com/in/jos%C3%A9-carlos-andrade-do-nascimento-71186421a)
- Lucas Sales Duarte : [GitHub](https://github.com/LucasDuarte026), [LinkedIn](https://www.linkedin.com/in/lucas-sales-duarte-a963071a1)
- Matheus Della Rocca Martins : [GitHub](https://github.com/MatheusDrm), [LinkedIn](https://www.linkedin.com/in/matheus-martins-9aba09212/)
- Nathan Fernandes Vilas Boas : [GitHub](https://github.com/uspnathan), [LinkedIn](https://www.linkedin.com/mwlite/in/nathan-fernandes-vilas-boas-047616262)
<p align="center">
<img width="500" src="https://raw.githubusercontent.com/Grupo-SEMEAR-USP/swarm_in_blocks/master/assets/atena_team.JPG"/>
</p>
In honor of Atena Team 2022:
- Guilherme Soares Silvestre : [GitHub](https://github.com/guisoares9), [LinkedIn](https://www.linkedin.com/in/guilherme-soares-silvestre-76570118b/)
- Eduardo Morelli Fares: [GitHub](https://github.com/faresedu), [LinkedIn](https://www.linkedin.com/in/eduardo-fares-a271561a0/)
- Felipe Tommaselli: [GitHub](https://github.com/Felipe-Tommaselli), [LinkedIn](https://www.linkedin.com/in/felipe-tommaselli-385a9b1a4/)
- João Aires C. F. Marsicano: [GitHub](https://github.com/Playergeek181), [LinkedIn](https://www.linkedin.com/in/joao-aires-correa-fernandes-marciano-53b426195/)
- José Carlos Andrade do Nascimento: [GitHub](https://github.com/joseCarlosAndrade), [LinkedIn](https://www.linkedin.com/in/jos%C3%A9-carlos-andrade-do-nascimento-71186421a)
- Rafael Saud C. Ferro: [GitHub](https://github.com/Rafael-Saud), [LinkedIn](https://www.linkedin.com/in/rafael-saud/)
<div align="right">[ <a href="#table-of-contents">↑ to top ↑</a> ]</div>

View File

@@ -58,6 +58,7 @@
* [COEX Pix](coex_pix.md)
* [COEX PDB](coex_pdb.md)
* [COEX GPS](coex_gps.md)
* [Использование SSH-ключей](ssh_keys.md)
* [Радио-телеметрия](radio_telemetry.md)
* [Камера Hawk Eye](hawk_eye.md)
* [Гид по автономному полету](auto_setup.md)
@@ -120,6 +121,7 @@
* [Конкурс видео](video_contest.md)
* [Образовательные конкурсы](educational_contests.md)
* [Проекты на базе Клевера](projects.md)
* [Система радионавигации](nav-beacon.md)
* [Advanced Clover Simulator](advanced_clover_simulator.md)
* [Copter For Space](c4s.md)
* [CopterCat CM4](copter_cat.md)

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

@@ -84,12 +84,6 @@ navigate(frame_id='aruco_5', x=0, y=0, z=1)
navigate(frame_id='aruco_7', x=-1, y=0, z=2)
```
Вращаться против часовой стрелки на высоте 1.5 метра над маркером 10:
```python
navigate(frame_id='aruco_10', x=0, y=0, z=1.5, yaw_rate=0.5)
```
Если необходимый маркер не появится в поле зрения в течение полусекунды, дрон продолжит выполнять предыдущую команду.
Подобные значения `frame_id` можно использовать и в других сервисах, например `get_telemetry`. Получение расположения дрона относительно маркера 3:

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