Compare commits

..

293 Commits

Author SHA1 Message Date
Oleg Kalachev
26c2387f5c Merge branch 'master' into recent-px4 2022-02-10 15:41:45 +03:00
Oleg Kalachev
826f631b97 Fix version in package.xml files 2022-02-10 13:49:14 +03:00
Oleg Kalachev
52b5d7b04e CI: disable Melodic build 2022-02-10 13:33:32 +03:00
Oleg Kalachev
455d52007e Update version in package.xml files 2022-02-10 13:31:12 +03:00
Oleg Kalachev
e9e6cabbb9 builder: use cv-camera@0.5.1 with init fix 2022-02-10 13:30:42 +03:00
Oleg Kalachev
8fcd6e9b9e builder: validate version of some ros packages 2022-02-10 13:30:14 +03:00
Oleg Kalachev
24d3a1df8d docs: minor fix of links rendering 2022-02-09 16:49:15 +03:00
Oleg Kalachev
9784e7bfa1 docs: change python to python3 in autolaunch article 2022-02-09 16:41:19 +03:00
Oleg Kalachev
fbad85d87f docs: add main_camera_optical to frames article 2022-02-07 09:44:53 +03:00
Oleg Kalachev
4fbc4f63ee docs: remove unused asset 2022-02-03 07:33:56 +03:00
Oleg Kalachev
c48a945258 Merge branch 'master' into recent-px4 2022-02-03 05:05:22 +03:00
Oleg Kalachev
c1ca40187e www: add date and offset param to topics viewer 2022-02-03 05:05:08 +03:00
Oleg Kalachev
39763c4a40 Merge branch 'master' into recent-px4 2022-02-03 04:37:31 +03:00
Oleg Kalachev
c1179869cd www: remove annoying hover title in topics viewer 2022-02-03 04:37:22 +03:00
Oleg Kalachev
6c43d5c230 docs: rework parameters article, make summary parameters table 2022-02-01 15:20:20 +03:00
Oleg Kalachev
265898912f clover.launch: add force_init argument
PX4 1.12.3 doesn’t init by flow without mag
force_init runs vpe_publisher to force init using vpe
2022-02-01 14:08:33 +03:00
Oleg Kalachev
d31bd75d7d docs: remove obsolete notes and simplify titles in autonomous flight article 2022-02-01 13:57:20 +03:00
Oleg Kalachev
e15ef587d7 docs: add note about possible unintended switching out of LAND mode 2022-02-01 13:47:30 +03:00
Oleg Kalachev
79903db95d Merge branch 'master' into recent-px4 2022-02-01 11:40:30 +03:00
Oleg Kalachev
2096be5080 docs: rename px4_parameters to parameters.md 2022-02-01 11:40:20 +03:00
Oleg Kalachev
14a9c0eb46 Merge branch 'master' into recent-px4 2022-02-01 11:38:17 +03:00
Oleg Kalachev
0c879f2aad docs: rename px4_parameters.md article to parameters.md 2022-02-01 11:37:41 +03:00
Oleg Kalachev
673dbb1feb docs: rename px4_parameters.md article to parameters.md 2022-02-01 11:36:52 +03:00
Oleg Kalachev
4446b22db4 Merge branch 'master' into recent-px4 2022-02-01 11:19:50 +03:00
Oleg Kalachev
f34e8b4774 docs: updates (en) 2022-02-01 11:19:40 +03:00
Oleg Kalachev
281f515ba7 Merge branch 'master' into recent-px4 2022-02-01 11:05:41 +03:00
Oleg Kalachev
be76ea82d7 docs: some updates to optical flow article 2022-02-01 11:04:10 +03:00
Oleg Kalachev
6a8806c476 docs: some updates in setup section 2022-02-01 11:03:27 +03:00
Oleg Kalachev
00a76a306e docs: update PX4 docs links 2022-02-01 11:02:26 +03:00
Oleg Kalachev
f66b53f9cb docs: update PX4 docs links 2022-02-01 11:01:56 +03:00
Oleg Kalachev
273e3191f1 docs: update PX4 docs links 2022-02-01 11:01:41 +03:00
Oleg Kalachev
28927246db docs: minor fix 2022-02-01 10:57:12 +03:00
Oleg Kalachev
ae08c62bf4 Merge branch 'master' into recent-px4 2022-02-01 10:54:55 +03:00
Oleg Kalachev
9f9b1d3115 docs: rephrase firmware flashing section to continue recommending COEX firmware 2022-02-01 10:54:35 +03:00
Oleg Kalachev
ca5817c3d2 builder: fix Butterfly installation
Fix the `can't find Rust compiler` error using the older PyOpenSSL
to not update `cryptography` because newer `cryptography` requires Rust to install.
2022-02-01 10:53:28 +03:00
Oleg Kalachev
f3fb3e4cee Merge branch 'master' into recent-px4 2022-02-01 08:31:09 +03:00
Oleg Kalachev
7717461631 genmap.py: use -o flag in example 2022-02-01 08:30:59 +03:00
Oleg Kalachev
3f352ebc06 docs: reduce size of some images 2022-02-01 08:29:29 +03:00
Oleg Kalachev
8c8fe5c40c docs: reduce qgc-params.png file size 2022-02-01 08:29:23 +03:00
Oleg Kalachev
d89e5eada7 selfcheck.py: add checking map=>body transform 2022-02-01 08:28:43 +03:00
Oleg Kalachev
80c853735d docs: reduce size of some images 2022-02-01 08:23:38 +03:00
Oleg Kalachev
9bd3c616da docs: reduce qgc-params.png file size 2022-02-01 08:19:15 +03:00
Oleg Kalachev
75209ea2f9 selfcheck.py: bring back info about non-Clover firmware 2022-02-01 07:56:47 +03:00
Oleg Kalachev
2ee90e62fc Minor typo in mavros_config 2022-02-01 07:04:43 +03:00
Oleg Kalachev
d0a0e5d50d selfcheck.py: add checking map=>body transform 2022-02-01 07:00:01 +03:00
Elena Seliverstova
848d9dcbe4 docs: contests article (#430)
Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2022-02-01 06:04:35 +03:00
Oleg Kalachev
6d68d06787 simple_offboard: default reference frames
To simplify running with rosrun
2022-01-30 00:37:24 +03:00
Oleg Kalachev
afe8abcd96 Merge branch 'master' into recent-px4 2022-01-28 08:08:51 +03:00
Oleg Kalachev
d18ca32688 www: add console page to show logs 2022-01-28 08:08:41 +03:00
Oleg Kalachev
bf9f7d035f docs: edit programming intro text 2022-01-28 06:21:53 +03:00
Oleg Kalachev
1aec5063d6 docs: simplify and fix some snippets 2022-01-28 06:20:57 +03:00
Oleg Kalachev
3b06a33cad genmap.py: use -p flag in example 2022-01-27 04:00:26 +03:00
Oleg Kalachev
47e39d5331 vpe_publisher: rename parameter publish_zero to force_init 2022-01-26 07:24:04 +03:00
Oleg Kalachev
e7eae1c02d ci: cancel previous docs builds to avoid publishing old site 2022-01-25 19:12:47 +03:00
Oleg Kalachev
e86b4da0ed ci: cancel previous docs builds to avoid publishing old site 2022-01-25 19:12:17 +03:00
Oleg Kalachev
6bcd670190 Merge branch 'master' into recent-px4 2022-01-21 23:22:58 +03:00
Oleg Kalachev
e3958d7fef selfcheck.py: increase long boot duration value to 20 2022-01-21 23:22:47 +03:00
Oleg Kalachev
fb47858010 selfcheck.py: add checking map->base_link tf transform 2022-01-21 23:22:33 +03:00
Oleg Kalachev
b628825420 Merge branch 'master' into recent-px4 2022-01-20 19:57:20 +03:00
Oleg Kalachev
a525714e3a mavros: disable startup_px4_usb_quirk 2022-01-20 19:56:44 +03:00
Oleg Kalachev
29fdbf23af docs: update copterhack-2022 teams list 2022-01-11 16:39:31 +03:00
Oleg Kalachev
6eacb8966a docs: fix broken links 2022-01-10 05:39:53 +03:00
Oleg Kalachev
d8afb711f0 docs: fix links copterhack-2022 articles 2022-01-10 04:56:06 +03:00
Oleg Kalachev
b3ac99fbef Merge branch 'master' into recent-px4 2021-12-17 07:40:18 +03:00
Oleg Kalachev
cba12e115e builder: remove unneeded catkin_blacklist_packages 2021-12-16 13:57:13 +03:00
Oleg Kalachev
ae9a5154ab Merge branch 'master' into recent-px4 2021-12-16 13:44:15 +03:00
Oleg Kalachev
bb6a6c81f3 selfcheck.py: don’t show 'different index' warnings 2021-12-16 13:41:14 +03:00
Oleg Kalachev
1878e467ac Merge branch 'master' into recent-px4 2021-12-16 13:35:23 +03:00
Elena Seliverstova
d27bbf31bd docs: video contest page (#427)
Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-12-16 00:21:48 +03:00
Oleg Kalachev
8668295cfe docs: fix 2021-12-14 19:24:59 +03:00
Oleg Kalachev
535b366bab docs: update copterhack article 2021-12-14 18:52:32 +03:00
Oleg Kalachev
9f6aa7dabd docs: add get-param and set-param snippets 2021-12-11 09:54:02 +03:00
Oleg Kalachev
f4d00a47af docs: fix 2021-12-10 16:19:07 +03:00
Oleg Kalachev
0f438235c2 docs: minor fix 2021-12-10 09:43:09 +03:00
Oleg Kalachev
e4ad687e28 docs: fix to native simulator setup article 2021-12-10 09:07:27 +03:00
Oleg Kalachev
5d58ffd1db docs: rework native simulator installation article 2021-12-10 07:53:55 +03:00
Oleg Kalachev
b2ed1fccc6 simple_offboard: remove warnings 2021-12-10 05:00:08 +03:00
Oleg Kalachev
aa136e7f15 docs: minor fix 2021-12-10 02:28:28 +03:00
Oleg Kalachev
9743bcbaaf Disable publish_sim_time in mavros as it breaks the simulation 2021-12-10 02:28:18 +03:00
Oleg Kalachev
75aed624db docs: remove unneeded 'coding' from program template 2021-11-30 16:40:35 +03:00
Oleg Kalachev
75b63ad77d Merge branch 'master' into recent-px4 2021-11-25 23:41:36 +03:00
Oleg Kalachev
36a4962bc0 www: add link to topics list page in topic viewer 2021-11-25 23:41:24 +03:00
Oleg Kalachev
140535b0b4 Merge branch 'master' into recent-px4 2021-11-25 23:36:30 +03:00
Oleg Kalachev
2cd3be1139 optical_flow: ability to change default flow gyro values 2021-11-25 23:36:20 +03:00
Oleg Kalachev
6909ba5819 www: change background when connection in closed in topics view 2021-11-25 23:27:09 +03:00
Oleg Kalachev
2a8c85144e Merge branch 'master' into recent-px4 2021-11-25 22:55:46 +03:00
Oleg Kalachev
f1783bdd0b selfcheck.py: ignore some records of error log in report 2021-11-25 22:54:45 +03:00
Oleg Kalachev
528be179e6 selfcheck.py: parse warnings from error log correctly 2021-11-25 22:49:31 +03:00
Oleg Kalachev
fe588e7af9 blocks: raise exception when cannot connect to pigpiod 2021-11-22 20:16:10 +03:00
Oleg Kalachev
15551db840 docs: add redirect from /gpio 2021-11-22 20:10:39 +03:00
Oleg Kalachev
65bc74b5ec docs: some updates to optical flow article 2021-11-19 10:16:10 +03:00
Oleg Kalachev
ac4f16f973 selfcheck.py: fix and simplify firmware version parsing, remove Clover firmware warning 2021-11-19 10:14:41 +03:00
Oleg Kalachev
9dc4407afc selfcheck.py: make not finding vcgencmd not a failure 2021-11-19 09:50:56 +03:00
Oleg Kalachev
365bd4146a selfcheck.py: add gzclient and gzserver to cpu eaters whitelist 2021-11-19 09:50:52 +03:00
Oleg Kalachev
fc99269404 selfcheck.py: remove timestamps from selfcheck reports 2021-11-19 09:50:43 +03:00
Oleg Kalachev
baf8b736d4 selfcheck.py: make not finding vcgencmd not a failure 2021-11-19 09:47:45 +03:00
Oleg Kalachev
bb318ce93f selfcheck.py: add gzclient and gzserver to cpu eaters whitelist 2021-11-19 09:47:07 +03:00
Oleg Kalachev
d7b6968fee selfcheck.py: remove timestamps from selfcheck reports 2021-11-19 09:46:46 +03:00
Oleg Kalachev
08f6aa7aee docs: update 2021-11-18 14:43:21 +03:00
Oleg Kalachev
d5e729c66c docs: update firmware flashing section 2021-11-16 09:09:50 +03:00
Oleg Kalachev
27c83d062c docs: use enumerated list for consistency 2021-11-16 07:40:27 +03:00
Oleg Kalachev
04bc9fb017 docs: some updates in setup section 2021-11-16 07:32:02 +03:00
Oleg Kalachev
b2928dd536 docs: info on no mags found error 2021-11-16 07:31:01 +03:00
Oleg Kalachev
2a4163cbeb docs: update PX4 docs links 2021-11-16 07:30:33 +03:00
Oleg Kalachev
d1edc95ab5 docs: minor fix 2021-11-16 07:28:31 +03:00
Oleg Kalachev
9231679353 copterhack-2022: update Moopt title 2021-11-09 16:31:43 +03:00
Oleg Kalachev
4defe2c7ef copterhack-2022: fix 2021-11-08 22:57:51 +03:00
Bartosz Ptak
9f3410847f copterhack-2022: fix (#423) 2021-11-08 22:56:46 +03:00
Oleg Kalachev
fa8da1cb33 copterhack-2022: add participants list 2021-11-08 17:38:43 +03:00
Oleg Kalachev
3bb285fd35 docs: fix 2021-11-03 18:59:48 +03:00
Oleg Kalachev
ec1829e60c docs: remove external image 2021-11-03 00:34:17 +03:00
Oleg Kalachev
c32a412f42 Builder: echo commands in image-ros.sh 2021-11-02 23:19:18 +03:00
Oleg Kalachev
810ddb4157 docs: update ros article 2021-11-02 20:58:27 +03:00
Oleg Kalachev
3656c1714a docs: update copterhack article 2021-11-01 20:11:30 +03:00
Oleg Kalachev
937b68aa43 docs: redirect /ros to English version 2021-11-01 19:12:46 +03:00
Oleg Kalachev
bdd1b06541 docs: fix building pdf 2021-10-30 21:57:49 +03:00
Oleg Kalachev
dd96c91b55 docs: minor fix 2021-10-30 21:36:51 +03:00
Oleg Kalachev
8f3d64e9aa docs: minor fix 2021-10-22 16:46:18 +03:00
Oleg Kalachev
cfd413ffc1 simulation: tune external camera model fov 2021-10-20 10:09:33 +03:00
Oleg Kalachev
ca054c88ba clover_simulation: add script for running gzweb 2021-10-12 05:55:16 +03:00
murata,katsutoshi
d55576bf4f udev: add CUAV X7 Pro (#392) 2021-10-12 01:46:52 +03:00
Oleg Kalachev
470e6ff0e9 Fix for editorconfig 2021-10-08 16:40:18 +03:00
Oleg Kalachev
441cf7fcf7 editoconfig-lint: don’t check .material files 2021-10-08 16:38:30 +03:00
Oleg Kalachev
fc5960586b simulation: add several separate aruco markers models 2021-10-08 16:35:12 +03:00
Oleg Kalachev
4aef1e616c docs: minor fix 2021-10-07 01:59:58 +03:00
Oleg Kalachev
463c08da96 docs: update simulation installation instructions 2021-10-07 01:32:16 +03:00
Oleg Kalachev
ebaaa14a7e docs: update header in sitl article (ru) 2021-10-07 01:17:33 +03:00
Oleg Kalachev
c0d33abff6 docs: add info on rostopic info and rostopic hz 2021-10-07 00:51:55 +03:00
Oleg Kalachev
3c4ef56b4e Fix can't find Rust compiler while installing cryptography
Using an older cryptography version that didn’t need Rust
See https://stackoverflow.com/a/68472128/6850197
2021-10-07 00:18:45 +03:00
Oleg Kalachev
17e806601d Tune parameters of external camera 2021-10-07 00:18:19 +03:00
Oleg Kalachev
3e3c5aa453 Add maintain_camera_rate argument to simulator.launch 2021-10-06 23:54:19 +03:00
Oleg Kalachev
7fd463d1cb docs: add note on bridge mode for using rviz etc 2021-10-06 22:12:47 +03:00
Oleg Kalachev
64b083b242 Add external camera model 2021-10-06 21:17:21 +03:00
Oleg Kalachev
b2ec48f0f3 blocks: minor fix 2021-10-06 17:53:25 +03:00
Oleg Kalachev
b249524828 Use markdownlint-cli@0.28.1 as of https://github.com/DavidAnson/markdownlint/issues/435 2021-10-05 16:33:38 +03:00
Oleg Kalachev
d0dcc0e72a docs: some fixes to rviz article 2021-10-05 15:34:59 +03:00
Oleg Kalachev
4c6e7029e8 docs: fix 2021-09-26 18:23:52 +03:00
Oleg Kalachev
613f70fd25 Add subscriber example 2021-09-24 17:34:54 +03:00
Oleg Kalachev
77832e65fa blocks: implement global navigation 2021-09-16 19:41:11 +03:00
Oleg Kalachev
01edd129ab blocks: show global_position block 2021-09-16 18:05:19 +03:00
Oleg Kalachev
d03acff31b simulator.launch: make gui argument work on jmavsim 2021-09-13 13:23:14 +03:00
oponfil
22e74febd6 docs: added the gsreamer's section in duocam_setup.md (#387)
* Added the gsreamer's section in duocam_setup.md

Added the section on how to modify video using GStreamer

* Edit

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-09-13 12:07:16 +03:00
Oleg Kalachev
989d9b66f1 simulation: disable optical flow for jmavsim simulation 2021-09-04 04:06:57 +03:00
oponfil
f8eb8e1e67 docs: fix in VEYE-MIPI-327E cam driver installation instruction (#386)
* Some fix in VEYE-MIPI-327E cam driver install

Don't update Linux Kernel before install VEYE-MIPI-327E driver

* Edit

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-09-02 21:30:58 +03:00
Oleg Kalachev
b92ebe7d60 www: determine rosdistro in topics view 2021-09-02 05:19:13 +03:00
Oleg Kalachev
af51e88179 Fix building docs
Use forked validate-links plugin
2021-09-02 05:18:22 +03:00
oponfil
59c8debcab docs: add duocam_setup.md (#385)
Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-08-25 00:29:31 +03:00
Oleg Kalachev
ec6f3089e3 docs: add snippet to wait for global position 2021-08-24 20:43:26 +03:00
Oleg Kalachev
2b88d21792 blocks: tooltips updates 2021-08-24 18:00:59 +03:00
Oleg Kalachev
274b81c50f blocks: fix global_position block 2021-08-24 17:49:21 +03:00
Oleg Kalachev
33a6dffb1f Make examples more verbose 2021-08-23 22:42:47 +03:00
Oleg Kalachev
5f9b3e82db clover: add GPS usage example 2021-08-23 22:39:29 +03:00
Oleg Kalachev
5f43367d82 simple_offboard: consider message timed out if time stamp is zero 2021-08-23 22:39:10 +03:00
Oleg Kalachev
7809e7ed2d docs: more notes on configuring the simulator 2021-08-23 22:34:54 +03:00
Oleg Kalachev
1688b97091 Enable GPS aiding in EKF2 by default in Clover airframe 2021-08-23 22:23:48 +03:00
Oleg Kalachev
1c6129fde8 clover_description: fix gps sensor 2021-08-23 22:23:24 +03:00
Oleg Kalachev
dae9599d64 web: confirm using Butterfly Terminal on a local machine 2021-08-18 21:15:31 +03:00
Oleg Kalachev
c0677f6aa3 docs: typo 2021-08-18 21:05:27 +03:00
Oleg Kalachev
e7bbf21700 docs: minor update to rangefinder article 2021-08-18 21:05:20 +03:00
Oleg Kalachev
58c10d7cb8 clover_blocks: make default yaw_tolerance 1 2021-08-18 20:35:27 +03:00
Oleg Kalachev
b6bd6bdde8 clover_description: simplify URDF and copy Gazebo plugins from current PX4’s Iris 2021-08-16 19:12:18 +03:00
Oleg Kalachev
3374c7756c docs: minor clarification to setup article 2021-08-16 18:40:04 +03:00
Oleg Kalachev
0dffeca55f clover_description: make xacro include relative 2021-08-14 21:39:57 +03:00
Oleg Kalachev
8cb911854d Minor changes to examples 2021-08-12 21:09:43 +03:00
Oleg Kalachev
a1b3efe67d simple_offboard: avoid TF_REPEATED_DATA warnings of setpoint frame 2021-08-12 13:00:23 +03:00
Oleg Kalachev
6700d8728f Add .vscode to .gitignore 2021-08-12 10:38:34 +03:00
Oleg Kalachev
be2e6ae198 clover_simulation: add Clover PX4 startup file 2021-08-11 19:17:36 +03:00
Oleg Kalachev
b9eed0f3ad optical_flow: publish flow when local position is not available
With integrated_*gyro = NAN
2021-08-10 07:06:15 +03:00
Oleg Kalachev
853a7fcf67 Minor code style fix 2021-08-10 06:56:47 +03:00
Oleg Kalachev
e342796f07 docs: add note on disabling optical flow if using ceiling markers placement 2021-08-04 08:00:36 +03:00
Oleg Kalachev
4fa70aa73a docs: fix link 2021-08-03 11:28:42 +03:00
Oleg Kalachev
226c91c3d8 docs: fix 2021-08-01 08:48:25 +03:00
SeliverstovaE
e33c9e78ea docs: add copterhack2021 video (ru) (#377)
Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-07-30 08:43:35 +03:00
SeliverstovaE
18c927469e docs: add copterhack2021 video (#378)
Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-07-30 08:43:10 +03:00
Oleg Kalachev
a465afd65c Don’t put .img file into images subdirectory in zip file 2021-07-30 08:20:11 +03:00
Oleg Kalachev
a2c65d2466 ci: print built image contents 2021-07-30 08:07:03 +03:00
Oleg Kalachev
ef7faa126a Fix aruco_gen utility for Python 3 2021-07-29 05:58:56 +03:00
Oleg Kalachev
d0666ca9d7 simulator.launch: add gui argument 2021-07-27 19:06:22 +03:00
Oleg Kalachev
b48f22cd35 simulator.launch: remove rc=false as it false by default 2021-07-23 14:32:22 +03:00
Oleg Kalachev
731f908053 clover_description: fix view_drone.launch to view clover4 urdf 2021-07-22 19:58:46 +03:00
timkondratiev
505a1efebd docs: add info how to determine Clover version (#376)
* Add info how to determine Clover version

* Optimize image

* Edit

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-07-22 16:47:18 +03:00
Oleg Kalachev
f1b5484e65 docs: minor fix 2021-07-20 13:39:18 +03:00
Oleg Kalachev
3343477a02 docs: remove trailing spaces 2021-07-20 13:23:18 +03:00
oponfil
60da608191 docs: add how to use Quectel EP06 4G modem (#375)
Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-07-20 13:19:01 +03:00
Oleg Kalachev
7e383d713d docs: typos 2021-07-17 20:34:25 +03:00
Oleg Kalachev
c2a60380b7 docs: edit copterhack-2022 template 2021-07-17 19:26:54 +03:00
oponfil
7f82f8683f docs: change some fasteners (#373)
* Changed installing Raspberry Pi with M2.5 bolts

Changed installing Raspberry Pi with M2.5 bolts

* Changed installing Raspberry Pi with M2.5 bolts

Changed installing Raspberry Pi with M2.5 bolts

* Changed some fasteners

Changed some bolts from M3x8 to M3x10

* Update assemble_4_2.md

* Update assemble_4_2_pro.md

* Update assemble_4_2.md

* Update assemble_4_2_ws.md

* Update assemble_4_2.md

* Update assemble_4_2_ws.md
2021-07-16 22:32:10 +03:00
Oleg Kalachev
e28cbea8d9 docs: add a note on creating a new branch into copterhack2022 2021-07-16 22:31:01 +03:00
Oleg Kalachev
27528c20dc docs: simplify 2021-07-16 21:55:18 +03:00
Oleg Kalachev
e3503fca35 docs: fix 2021-07-16 21:54:04 +03:00
Oleg Kalachev
40b8941cab docs: edit copterhack-2021 template 2021-07-16 21:27:19 +03:00
Oleg Kalachev
0a9b6fff95 docs: fix 2021-07-16 11:03:28 +03:00
Oleg Kalachev
4a4e539edd docs: fixes 2021-07-16 11:03:00 +03:00
Oleg Kalachev
8d24a737ac docs: typos 2021-07-16 10:33:46 +03:00
oponfil
20af13947d docs: changed installing Raspberry Pi with M2.5 bolts (#372)
* Changed installing Raspberry Pi with M2.5 bolts

Changed installing Raspberry Pi with M2.5 bolts

* Changed installing Raspberry Pi with M2.5 bolts

Changed installing Raspberry Pi with M2.5 bolts
2021-07-15 17:56:38 +03:00
Oleg Kalachev
e91609ff61 docs: typos 2021-07-14 21:48:14 +03:00
Oleg Kalachev
0024372c45 docs: remove unnecessary text 2021-07-14 21:23:23 +03:00
Oleg Kalachev
b62d202a29 docs: add not on ATT_W_MAG when using GPS 2021-07-14 20:34:44 +03:00
Oleg Kalachev
84d685469a aruco_pose: minor fix in readme 2021-07-14 20:33:49 +03:00
Oleg Kalachev
3f6bb0cd68 docs: comment out link to arucogenmap as it’s not up
Also link to author is added.
2021-07-14 12:00:50 +03:00
oponfil
c01a145a16 docs: specified how to install a COEX Pix (#371)
* Specify how to install COEX Pix

With ROLL_180_YAW_90 orientation

* Specify how to install COEX Pix

* Update assemble_4_2_pro.md

* Update assemble_4_2.md

* Update assemble_4_2_ws.md

* Update calibration.md

* Typos

* Edit

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-07-14 08:20:05 +03:00
oponfil
6d28bf4ef9 docs: added 4.2 to Clover Pro in summary (#370)
Fixed the title
2021-07-13 10:01:32 +03:00
oponfil
f6ea7209db docs: fix 'ZeroTire' to 'ZeroTier' (en) (#368)
Fixed spelling error
2021-07-12 19:27:12 +03:00
oponfil
21727ef76d docs: fix 'ZeroTire' to 'ZeroTier' (ru) (#369)
Fixed spelling error
2021-07-12 19:26:55 +03:00
oponfil
9847b7a71c docs: highlight GPIO21 (#359)
Highlighted GPIO21
2021-07-12 18:55:03 +03:00
oponfil
a5d44ff63a docs: update leds_old.md (#360)
Highlighted GPIO21
2021-07-12 18:54:39 +03:00
oponfil
391a2f9af9 docs: put the right images of how to connect a LED stripe (#361)
Put the right images of how to connect a LED stripe
2021-07-12 16:37:58 +03:00
oponfil
5918702fbd docs: update 4g.md (#355)
* Update 4g.md

Added how to stream from USB cam

* Edit

* Update 4g.md

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-07-12 10:45:01 +03:00
oponfil
69fe288a41 docs: specified the aluminum 15 mm stands (#366)
Specified the aluminum 15 mm stands
2021-07-12 10:31:02 +03:00
oponfil
5154720348 docs: specified the aluminum 15 mm stands (#367)
Specified the aluminum 15 mm stands
2021-07-12 10:30:47 +03:00
oponfil
cc1694661d docs: update copterhack2022.md (#365)
Delete PX4 v.1.12 case. Modified Pixhawk FMUv6U
2021-07-12 09:54:37 +03:00
oponfil
d5efa962d8 docs: update copterhack2022.md (#364)
Delete PX4 v.1.12 case. Modified Pixhawk FMUv6U
2021-07-12 09:54:26 +03:00
Oleg Kalachev
1195336cbc Exclude json-to-pretty-yaml.js from linting 2021-07-08 10:06:43 +03:00
Oleg Kalachev
5fc67b8e65 web: show messages in yaml format in topic viewer 2021-07-08 09:57:24 +03:00
Oleg Kalachev
c1409d4467 web: group 3d visualization and markers map visualization 2021-07-08 09:39:19 +03:00
Oleg Kalachev
7a1f09da98 image: log all clover service output to /var/log/clover.log 2021-07-08 09:25:29 +03:00
oponfil
6934cc7a1a docs: update 4g.md (#356)
* Update 4g.md

Add info to stream from usb camera video1

* Update 4g.md

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-07-07 06:50:31 +03:00
Oleg Kalachev
2550ffe532 Minor typo 2021-07-07 06:43:34 +03:00
Oleg Kalachev
9def866a30 web: add simple topics viewer 2021-07-07 06:34:52 +03:00
oponfil
802f8eeaa4 docs: update 4g.md (#354)
Shorted the title
2021-07-07 01:18:29 +03:00
Oleg Kalachev
504aa53b1a image: make udev rules symlinks
Rename package’s udev directory from config to more standard udev
2021-07-06 06:33:51 +03:00
Oleg Kalachev
015cf730c2 image: make clover.service and roscore.server symlinks 2021-07-06 06:25:45 +03:00
Oleg Kalachev
8e6ef727ce builder: show systemd version 2021-07-06 06:22:50 +03:00
1Den4ik1
973e1f1181 docs: update magnetic_grip_load.md (#352)
* Update magnetic_grip_load.md

* Update magnetic_grip_load.md

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-07-06 01:33:42 +03:00
Oleg Kalachev
275faa78a4 image: validate documented packages can be installed 2021-07-06 00:52:06 +03:00
Oleg Kalachev
fc7d010881 Exclude unused asset for readme from check 2021-06-30 16:32:22 +03:00
Oleg Kalachev
242e35f84a docs: make links to the latest release of vm 2021-06-30 16:10:22 +03:00
Oleg Kalachev
3f07d28e0f docs: simplify titles of simple offboard api articles 2021-06-30 16:06:33 +03:00
Oleg Kalachev
613d378e66 readme: add clover-4.2 image with margin 2021-06-30 16:03:11 +03:00
stinger000
769c421898 docs: add articles for Clover Pro (ru) (#350)
Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-06-29 23:03:02 +03:00
Oleg Kalachev
3830ceea04 aruco.launch: change default not-in-map marker size to 0.22 2021-06-29 21:50:05 +03:00
Oleg Kalachev
df3a11b035 docs: add link to @devclover chat 2021-06-29 01:21:33 +03:00
stinger000
ef5700845f docs: fix incorrect table (#351) 2021-06-28 20:00:51 +03:00
Oleg Kalachev
921084504e Make gitbook installation script
commit f83207848fafa302d6385f4814386c433aeb9686
Author: Oleg Kalachev <okalachev@gmail.com>
Date:   Wed Jun 23 17:35:01 2021 +0300

    Make gitbook installation script
2021-06-23 19:00:32 +03:00
Oleg Kalachev
6550780afb aruco.launch: remove unnecessary condition 2021-06-23 08:32:39 +03:00
1Den4ik1
2448915300 docs: add magnetic grip load model (ru) (#349)
* Add new article for Clover

* Update Gruz_dlya_magnitnogo_zahvata.md

* Gruz_dlya_magnitnogo_zahvata.md -> magnetic_grip_load.md

* Rename image files

* Optimize images

* Edit article

* Make images widths 300

* Files for 3D Print

* Update models.md

Add files for 3D print #338

* Update models.md

* Edit

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-06-22 18:19:53 +03:00
Oleg Kalachev
247a7917d9 docs: download ala-too logo to the repo 2021-06-19 05:16:52 +03:00
Oleg Kalachev
37f2c78b36 CI: shorten names 2021-06-18 00:56:16 +03:00
Oleg Kalachev
e76618bd3b cmake: install www directories 2021-06-17 23:42:33 +03:00
Oleg Kalachev
9fbfcfbd2e docs: remove unused assets 2021-06-16 15:21:30 +03:00
Oleg Kalachev
2003b4516a docs: fixes in models page 2021-06-16 15:02:57 +03:00
Oleg Kalachev
03985ae1b8 docs: add links to carbon parts 2021-06-15 20:40:55 +03:00
Oleg Kalachev
a47d5d1bfe docs: remove unused assets 2021-06-15 18:26:37 +03:00
Oleg Kalachev
20075dd40f docs: add links to hardware parts 2021-06-15 18:13:07 +03:00
Oleg Kalachev
c247c75d17 aruco_pose, clover, clover_blocks: fix install sections 2021-06-09 15:40:24 +03:00
Oleg Kalachev
c36279e536 image: move examples to clover package 2021-06-09 15:40:22 +03:00
SeliverstovaE
1471a53b3a docs: update copterhack2022.md (#348) 2021-06-09 15:37:26 +03:00
SeliverstovaE
931f50a458 docs: update copterhack 2022 (#347)
* Update copterhack2022.md

* Update copterhack2022.md

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-06-08 23:38:09 +03:00
Oleg Kalachev
118b4573fe docs: add link to packages repo 2021-06-08 20:28:38 +03:00
Oleg Kalachev
f77843f4a5 Move ROS Noetic (#327)
* builder: Use 64-bit Raspberry Pi OS

* travis: Use 64-bit builder

* builder: Don't try to install Melodic packages on Noetic

* clover: Use package version 3, update dependencies

* travis: Enable Noetic build

* standalone_install: Auto-select Python, ROS distro

* builder: Use variable substitution for ROS_DISTRO

* builder: Add Noetic package definitions

* builder: Use variable substitution for validation

* aruco_pose, clover: Allow compiling against OpenCV 3 and 4

* builder: Add proper Noetic repository

* builder: Don't force Tornado version

Assume rosbridge_suite depends on the right one.

* builder: Install packages for Python 3

* builder/test: Use Python3 interpreter for ROS tests

TODO (?): add tests for Python2?

* builder: Use Python 3 syntax for Python 3 tests

* builder: Install rpi_ws281x for Python3

* standalone_install: Use proper Python for pytest

* builder: Install espeak for python3

* builder: Use proper path for roscore

* builder: Install rosdep, etc. for python3

* builder: Run Clever/Clover test with Python3

* builder: Use Python3 for Clever compat layer

* builder: Enable OpenCV 4.2 repository

* builder: Force versions for ROS packages that use OpenCV

Also, hold their versions so that they don't get updated for no reason.

* aruco_pose/draw: Replace OpenCV projection code with a rewrite

* builder: Don't try to install compressed_transport twice

* clover: Fix importing urllib for Python3

* aruco_pose, clover: Expose Python scripts through CMake

* clover/selfcheck: Be more python3-compatible

This is basically commit a01d199890 from buster-python3, not sure if it aged well.

* roswww_static: Add python script installation

* clover_blocks: Use Python3 syntax for exec

* aruco_pose: Remove unused code

* Melodic => Noetic in some docs

* docs: add 0.22 migration article

* docs: remove unneeded comment

* docs: python 3 updates

* docs: python 3 update in auto_setup article

* docs: add ROS Noetic transition note

* aruco.launch: add placement, length and map arguments

* genmap.py: add -o argument for output file name

* docs: use -o argument of genmap.py

* simple_offboard: correctly check manual control timeout, separate it from kill switch check

* blocks: force led_leds index to int

* docs: update and fix 0.22 migration articles

* blocks: fix set_leds with color-typed argument

* aruco_gen: Open file in binary mode for Python3 compatibility

* clover: Use proper variable in aruco.launch

* led: change default number of leds to 72

* aruco_pose: Make sure there are no undefined symbols

Also, compile in apriltag_quad_thresh.cpp - it contains some of the functions referenced
in aruco.cpp, which would otherwise be undefined.

* aruco_pose: Make vendored library compatible with older OpenCVs

* aruco_pose, clover: Reduce the amount of OpenCV libs requested

* aruco_pose, clover: Move subscriptions to the end of init

* aruco_pose: Don't expose vendored library symbols

* aruco_pose: Simplify dynamic parameter callback setting

* builder: Build with debug symbols

* clover: Attempt to respawn dying nodelets

* Change Raspberry Pi OS to latest armhf, use packages.coex.tech as a source

* Add CRYPTOGRAPHY_DONT_BUILD_RUST=1

* Fix Node.js installation

* image: use older CMake (3.13.4-1)
Fixing https://travis-ci.org/github/CopterExpress/clover/jobs/764367665#L6984

* image: update Raspberry Pi OS to 2021-03-04

* image: bring back moving ld.so.preload out of the way while building

* Fix pthreads ld error

* Try to fix pthreads ld error

* Another attempt to fix pthreads ld error

* Yet another attempt to fix pthreads ld error

* Try to fix

* Be verbose

* Temporarily disable rc and camera_markers building

* Fix standalone-install

* Revert "Temporarily disable rc and camera_markers building"

This reverts commit e119220e91.

* Try to fix

* Try to fix

* Revert "image: use older CMake (3.13.4-1)"

This reverts commit df28da0060.

* Revert "Revert "image: use older CMake (3.13.4-1)""

This reverts commit a28c774e8f.

* Verbosity

* Debugging

* More debugging

* Display all CMake variables

* Try to fix

* Another try to fix

* Revert "Another try to fix"

This reverts commit 5a4c3a0da7.

* Another try to fix

* And another

* And yet another

* Continue...

* Cleanup

* Sources lists cleanup

* More cleanup

* Restore .git directory in clover repo

* Fix building documentation

* Fix documentation building in image

* Trigger build to update ws281x package

* Test

* Disable unneeded hack

* Disable hack

* image: add cmake-modules package

* www: add viewing clover.err file from web interface

* Remove hacks

* Show nodelet version

* docs: add packages article

* image: add image-view package for recording video from topics

* Minor fix

* CI: add Docker authentication on image build

* CI: fix Bash syntax

* CI: fix authentication in Docker

* CI: move Melodic build and editorconfig-lint to GitHub Actions (#331)

* Create main.yml

* Update main.yml

* Disable native Melodic build in Travis

* Run editorconfig-lint in Actions

* Let wget be less verbose

* Test

* Test ok

* Disable editorconfig-lint in Travis

* docs: add links to hardware sources

* CI: move image building to GitHub actions (#335)

* Start working on building image in GitHub actions

* Trigger GitHub on push to any branch

* Fix TRAVIS_TAG

* Add compress image step

* Disable image build in Travis

* Add upload image step

* Fix compress image

* Fix

* Fix

* Minor fix

* Trigger build on tag

* Show images sizes not in human format

* Upload only built image

* Make prerelease

* Upload assets on release not on tags

* readme: change build badge to GitHub Actions

* readme: add support chat badge

* CI: move documentation building to GitHub Actions (#337)

* CI: change docs target branch to actions

* CI: change docs target branch to master

* CI: use gh-pages target branch for docs

* CI: split up to several workflows

* CI: remove .travis.yml

* CI: change apt to apt-get

* CI: push documentation site to the main repo

* builder: less verbosity

* CI: add new key for apt
Fixing https://github.com/CopterExpress/clover/runs/2700356960#step:3:74

* Add Noetic building to CI

* Add test for QR recognition

* Fix

* Move QR recognition test to a separate file

* Fix QR recognition code for Python 3

* Import SetLEDs, LEDStateArray, LEDState in tests

* Add more imports to tests
(from documentation)

* Fix permissions

* Fix standalone-install for Python 2

* Fix QR recognition test

* Don’t use ROS for QR recognition test

* docs: remove non-working example

* Make v4l2 device file an argument in main_camera.launch

* Wait for v4l2 device before launching the camera driver

* Use exec in waitfile

* Transfer main camera nodelet manager to main_camera.launch

* Update cv_camera version to 0.5.1

* docs: minor fix

* Revert cv_camera to 0.5.0

* Update Raspberry Pi OS to 2021-05-07

* docs: add link to the last ROS Melodic version.

Co-authored-by: Alexey Rogachevskiy <sfalexrog@gmail.com>
2021-06-08 20:13:46 +03:00
Oleg Kalachev
5f62a8639a docs: use -o argument of genmap.py 2021-06-08 19:28:17 +03:00
Oleg Kalachev
fa1db1d90b genmap.py: add -o argument for output file name 2021-06-08 19:28:09 +03:00
Alexey Rogachevskiy
1a2e87bb6a aruco_pose, clover: Move subscriptions to the end of init 2021-06-08 19:23:39 +03:00
Oleg Kalachev
7dbd983ec5 Update Raspberry Pi OS to 2021-05-07 2021-06-08 19:10:30 +03:00
Oleg Kalachev
d2d395f1fc docs: add copterhack-2022 logo 2021-06-08 14:27:37 +03:00
oponfil
ff93f79c0a docs: some changes to copterhack2022 (#345)
Have made some changes in text
2021-06-07 19:39:18 +03:00
SeliverstovaE
5deb09eb45 docs: changed the dates for copterhack2022 (#344) 2021-06-07 19:38:39 +03:00
SeliverstovaE
70b8be5c5d docs: copterhack 2022 (en) (#343)
* Create copterhack2022.md

* Fixes

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-06-07 12:32:32 +03:00
Oleg Kalachev
2a08e20b47 docs: minor fix 2021-06-07 12:17:24 +03:00
SeliverstovaE
3328d8f4ac docs: update copterhack 2022 (#341) 2021-06-05 16:56:00 +03:00
oponfil
f7fb814894 docs: update copterhack 2022(#340)
Fixed some text phrases
2021-06-05 16:54:54 +03:00
SeliverstovaE
3a3b0bbd80 docs: Copterhack2022 (ru) (#336)
* Add new article for Clover

* Edit article

* Optimize images

* Remove unused asset

Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-06-05 12:06:42 +03:00
Oleg Kalachev
ca095f3f16 docs: update wi-fi screenshots 2021-06-04 09:14:56 +03:00
Oleg Kalachev
baf2467939 docs: minor fix 2021-06-03 17:53:55 +03:00
Oleg Kalachev
abba3bf876 docs: change some redirects to English version
Since GitHub pages considers /<page> as /<page>.html now
2021-06-03 11:38:19 +03:00
Oleg Kalachev
346373ed23 Use exec in waitfile 2021-06-03 09:58:41 +03:00
Oleg Kalachev
bb996056c9 docs: remove non-working example 2021-06-02 08:03:51 +03:00
Oleg Kalachev
0e0b1cdc31 docs: minor fix 2021-06-01 06:00:12 +03:00
1Den4ik1
eceaa0ec91 docs: add magnetic grip load article (ru) (#338)
Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2021-06-01 05:56:25 +03:00
Oleg Kalachev
f29686b9f4 CI: add new key for apt
Fixing https://github.com/CopterExpress/clover/runs/2700356960#step:3:74
2021-06-01 03:44:20 +03:00
Oleg Kalachev
b7f1f2b391 builder: less verbosity 2021-05-29 13:22:57 +03:00
Oleg Kalachev
6b0bb41564 CI: push documentation site to the main repo 2021-05-29 06:11:29 +03:00
Oleg Kalachev
563e5acad6 CI: change apt to apt-get 2021-05-29 05:31:29 +03:00
Oleg Kalachev
5932faa29c CI: remove .travis.yml 2021-05-29 05:29:32 +03:00
Oleg Kalachev
bcc2e86e6f CI: split up to several workflows 2021-05-29 05:27:20 +03:00
Oleg Kalachev
e80a1cc7d6 CI: use gh-pages target branch for docs 2021-05-28 22:43:58 +03:00
Oleg Kalachev
5fd3a92c7b CI: change docs target branch to master 2021-05-28 22:21:07 +03:00
Oleg Kalachev
84b87055df CI: change docs target branch to actions 2021-05-28 21:20:43 +03:00
Oleg Kalachev
7cc0f066c7 CI: move documentation building to GitHub Actions (#337) 2021-05-28 21:09:09 +03:00
Oleg Kalachev
868fc728dd readme: add support chat badge 2021-05-28 01:47:33 +03:00
Oleg Kalachev
faa90b89f6 readme: change build badge to GitHub Actions 2021-05-28 01:31:32 +03:00
Oleg Kalachev
f4d07e2c2c CI: move image building to GitHub actions (#335)
* Start working on building image in GitHub actions

* Trigger GitHub on push to any branch

* Fix TRAVIS_TAG

* Add compress image step

* Disable image build in Travis

* Add upload image step

* Fix compress image

* Fix

* Fix

* Minor fix

* Trigger build on tag

* Show images sizes not in human format

* Upload only built image

* Make prerelease

* Upload assets on release not on tags
2021-05-28 01:25:29 +03:00
Oleg Kalachev
fad7886012 docs: add links to hardware sources 2021-05-27 20:33:47 +03:00
Oleg Kalachev
7eb139fd22 CI: fix authentication in Docker 2021-05-26 23:56:41 +03:00
Oleg Kalachev
855d13e210 CI: fix Bash syntax 2021-05-26 23:46:09 +03:00
Oleg Kalachev
781b8962be CI: add Docker authentication on image build 2021-05-26 23:43:52 +03:00
Oleg Kalachev
047a965f9f CI: move Melodic build and editorconfig-lint to GitHub Actions (#331)
* Create main.yml

* Update main.yml

* Disable native Melodic build in Travis

* Run editorconfig-lint in Actions

* Let wget be less verbose

* Test

* Test ok

* Disable editorconfig-lint in Travis
2021-05-24 16:31:29 +03:00
Oleg Kalachev
47060db84b travis: disable native kinetic build 2021-05-20 20:59:50 +03:00
Oleg Kalachev
2693fd4ace docs: typos 2021-05-20 20:46:48 +03:00
Oleg Kalachev
faa702cab0 docs: typos 2021-05-20 20:27:46 +03:00
Oleg Kalachev
150ecbe29d Remove all unneeded static’s 2021-05-20 18:32:49 +03:00
Oleg Kalachev
df5e83e416 led: add error/ignore parameter to ignore some errors 2021-05-20 18:30:47 +03:00
Oleg Kalachev
1f2ba65669 Minor fix 2021-05-20 18:00:22 +03:00
311 changed files with 4600 additions and 132262 deletions

29
.github/workflows/build-image.yaml vendored Normal file
View File

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

23
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,23 @@
name: Build
on:
push:
branches: [ '*' ]
pull_request:
branches: [ master ]
jobs:
# melodic:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v2
# - name: Native Melodic build
# run: |
# docker run --rm -v $(pwd):/root/catkin_ws/src/clover ros:melodic-ros-base /root/catkin_ws/src/clover/builder/standalone-install.sh
noetic:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Native Noetic build
run: |
docker run --rm -v $(pwd):/root/catkin_ws/src/clover ros:noetic-ros-base /root/catkin_ws/src/clover/builder/standalone-install.sh

57
.github/workflows/docs.yml vendored Normal file
View File

@@ -0,0 +1,57 @@
name: Documentation
on:
push:
branches: [ '*' ]
pull_request:
branches: [ master ]
jobs:
docs:
runs-on: ubuntu-18.04
steps:
- name: Cancel previous runs
uses: styfle/cancel-workflow-action@0.9.1
with:
access_token: ${{ github.token }}
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v1
with: { node-version: '10' }
- name: Setup tools
run: |
sudo sh -c "echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | debconf-set-selections"
sudo apt-get update && sudo apt-get install -y calibre msttcorefonts
builder/assets/install_gitbook.sh
npm install markdownlint-cli@0.28.1 -g # FIXME: https://github.com/DavidAnson/markdownlint/issues/435
npm install svgexport -g
gitbook -V
markdownlint -V
- name: Run markdownlint
run: markdownlint docs
- name: Check Assets
run: |
./check_assets_size.py
./check_unused_assets.py
- name: Build GitBook
run: |
gitbook install
gitbook build
- name: Generate PDF
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
run: |
for i in 1 2 3 4; do gitbook pdf ./ _book/clover.pdf && break || sleep 1; done
sudo apt-get -q install ghostscript
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/default -dNOPAUSE -dQUIET -dBATCH -dDetectDuplicateImages -dCompressFonts=true -r150 -sOutputFile=_book/clover_ru_compressed.pdf _book/clover_ru.pdf
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/default -dNOPAUSE -dQUIET -dBATCH -dDetectDuplicateImages -dCompressFonts=true -r150 -sOutputFile=_book/clover_en_compressed.pdf _book/clover_en.pdf
rm _book/clover_ru.pdf && mv _book/clover_ru_compressed.pdf _book/clover_ru.pdf
rm _book/clover_en.pdf && mv _book/clover_en_compressed.pdf _book/clover_en.pdf
ls -lah _book/clover*.pdf
- name: Deploy
uses: JamesIves/github-pages-deploy-action@4.1.3
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
with:
branch: gh-pages
folder: _book
clean: true
single-commit: true # to avoid multiple copies of large pdf files

18
.github/workflows/editorconfig.yaml vendored Normal file
View File

@@ -0,0 +1,18 @@
name: Editorconfig
on:
push:
branches: [ '*' ]
pull_request:
branches: [ master ]
jobs:
editorconfig:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: .editorconfig Linter
run: |
wget --no-verbose https://github.com/okalachev/editorconfig-checker/releases/download/1.2.1-disable-spaces-amount/ec-linux-amd64
chmod +x ec-linux-amd64
./ec-linux-amd64 -spaces-after-tabs -e "roslib.js|ros3d.js|eventemitter2.js|json-to-pretty-yaml.js|draw.cpp|BinUtils.swift|\.idea|apps/android/app|blockly/|clover_blocks/programs/|highlight/|python.js|Assets.xcassets|test_parser_pass.txt|test_node_failure.txt|aruco_pose/vendor|\.stl|\.dxf|\.dae|\.material"

1
.gitignore vendored
View File

@@ -6,3 +6,4 @@ _book/
package-lock.json
clover_blocks/programs/*.*
!clover_blocks/programs/examples/*
/.vscode/

View File

@@ -110,7 +110,8 @@
"Li-ion",
"Nvidia",
"VirtualBox",
"VMware"
"VMware",
"DuoCam"
],
"code_blocks": false
},

View File

@@ -1,132 +0,0 @@
os: linux
dist: xenial
language: generic
services:
- docker
env:
global:
- DOCKER="sfalexrog/img-tool:qemu-update"
- TARGET_REPO="https://github.com/${TRAVIS_REPO_SLUG}.git"
- IMAGE_VERSION=${TRAVIS_TAG:-${TRAVIS_COMMIT:0:7}}
- IMAGE_NAME="$(basename -s '.git' ${TARGET_REPO})_${IMAGE_VERSION}.img"
git:
depth: 1
jobs:
fast_finish: true
include:
- stage: Build
name: "Raspberry Pi Image Build"
cache:
directories:
- imgcache
before_script:
- docker pull ${DOCKER}
# Check if there are any cached images, copy them to our "images" directory
- if [ -n "$(ls -A imgcache/*.zip)" ]; then mkdir -p images && cp imgcache/*.zip images; fi
script:
- if [[ -z ${TRAVIS_TAG} && "${TRAVIS_PULL_REQUEST}" != "false" ]]; then
echo "Commit range is ${TRAVIS_COMMIT_RANGE}" &&
if [ $(git diff --name-only ${TRAVIS_COMMIT_RANGE} | grep -v ^"docs/" | wc -l) -eq 0 ]; then
echo " === Docs-only change; skipping build ===" &&
export SKIP_BUILD=true;
fi;
fi
- if [ -z ${SKIP_BUILD} ]; then
docker run --privileged --rm -v /dev:/dev -v $(pwd):/builder/repo -e TRAVIS_TAG="${TRAVIS_TAG}" ${DOCKER};
fi
before_cache:
- cp images/*.zip imgcache
after_success:
- sudo chmod -R 777 *
- cd images && zip -9 ${IMAGE_NAME}.zip ${IMAGE_NAME} && stat --printf="Compressed image size:%s\n" ${IMAGE_NAME}.zip
before_deploy:
# Set up git user name and tag this commit
- git config --local user.name "goldarte"
- git config --local user.email "goldartt@gmail.com"
deploy:
provider: releases
token: ${GITHUB_OAUTH_TOKEN}
file: ${IMAGE_NAME}.zip
skip_cleanup: true
on:
tags: true
draft: true
name: ${TRAVIS_TAG}
- stage: Build
name: "Native Kinetic build"
env:
- NATIVE_DOCKER=ros:kinetic-ros-base
before_script:
- docker pull ${NATIVE_DOCKER}
script:
- docker run --rm -v $(pwd):/root/catkin_ws/src/clover ${NATIVE_DOCKER} /root/catkin_ws/src/clover/builder/standalone-install.sh
- stage: Build
name: "Native Melodic build"
env:
- NATIVE_DOCKER=ros:melodic-ros-base
before_script:
- docker pull ${NATIVE_DOCKER}
script:
- docker run --rm -v $(pwd):/root/catkin_ws/src/clover ${NATIVE_DOCKER} /root/catkin_ws/src/clover/builder/standalone-install.sh
- stage: Build
name: "Native Noetic build"
env:
- NATIVE_DOCKER=ros:noetic-ros-base
before_script:
- docker pull ${NATIVE_DOCKER}
script:
- docker run --rm -v $(pwd):/root/catkin_ws/src/clover ${NATIVE_DOCKER} /root/catkin_ws/src/clover/builder/standalone-install.sh
- stage: Build
name: "Documentation"
language: node_js
node_js:
- "10"
before_script:
- sudo sh -c "echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | debconf-set-selections"
- sudo apt update && sudo apt install -y calibre msttcorefonts
- npm install gitbook-cli -g
- gitbook fetch 3.2.3 && npm i npm@3.10.10 --prefix=~/.gitbook/versions/3.2.3/ # fixing https://travis-ci.org/github/CopterExpress/clover/jobs/766541125#L932
- npm install markdownlint-cli -g
- npm install svgexport -g
- gitbook -V
- markdownlint -V
script:
- markdownlint docs
- ./check_assets_size.py
- ./check_unused_assets.py
- gitbook install
- gitbook build
- for i in 1 2 3 4; do gitbook pdf ./ _book/clover.pdf && break || sleep 1; done
- sudo apt-get install ghostscript
- gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/default -dNOPAUSE -dQUIET -dBATCH -dDetectDuplicateImages -dCompressFonts=true -r150 -sOutputFile=_book/clover_ru_compressed.pdf _book/clover_ru.pdf
- gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/default -dNOPAUSE -dQUIET -dBATCH -dDetectDuplicateImages -dCompressFonts=true -r150 -sOutputFile=_book/clover_en_compressed.pdf _book/clover_en.pdf
- rm _book/clover_ru.pdf && mv _book/clover_ru_compressed.pdf _book/clover_ru.pdf
- rm _book/clover_en.pdf && mv _book/clover_en_compressed.pdf _book/clover_en.pdf
- ls -lah _book/clover*.pdf
deploy:
provider: pages
local_dir: _book
skip_cleanup: true
token: ${GITHUB_OAUTH_TOKEN}
keep_history: true
target_branch: master
repo: CopterExpress/clover.coex.tech
fqdn: clover.coex.tech
verbose: true
on:
branch: master
- stage: Build
name: Editorconfig-lint
language: generic
before_script:
- wget https://github.com/okalachev/editorconfig-checker/releases/download/1.2.1-disable-spaces-amount/ec-linux-amd64
- chmod +x ec-linux-amd64
script:
- ./ec-linux-amd64 -spaces-after-tabs -e "roslib.js|ros3d.js|eventemitter2.js|draw.cpp|BinUtils.swift|\.idea|apps/android/app|blockly/|clover_blocks/programs/|highlight/|python.js|Assets.xcassets|test_parser_pass.txt|test_node_failure.txt|aruco_pose/vendor|\.stl|\.dxf|\.dae"
stages:
- Build
# More info there
# https://github.com/travis-ci/travis-ci/issues/6893
# https://docs.travis-ci.com/user/customizing-the-build/
# https://docs.travis-ci.com/user/deployment/releases
# https://docs.travis-ci.com/user/environment-variables/

View File

@@ -1,6 +1,6 @@
# clover🍀: create autonomous drones easily
<img src="docs/assets/clover42-main.png" align="right" width="400px" alt="COEX Clover Drone">
<img src="docs/assets/clover42-main-margin.png" align="right" width="400px" alt="COEX Clover Drone">
Clover is an open source [ROS](https://www.ros.org)-based framework, providing user-friendly tools to control [PX4](https://px4.io)-powered drones. Clover is available as a ROS package, but is shipped mainly as a preconfigured image for Raspberry Pi. Once you've installed Raspberry Pi on your drone and flashed the image to its microSD card, taking the drone up in the air is a matter of minutes.
@@ -20,7 +20,7 @@ Clover drone is used on a wide range of educational events, including [Copter Ha
Preconfigured image for Raspberry Pi with installed and configured software, ready to fly, is available [in the Releases section](https://github.com/CopterExpress/clover/releases).
[![Build Status](https://travis-ci.org/CopterExpress/clover.svg?branch=master)](https://travis-ci.org/CopterExpress/clover)
![GitHub Workflow Status](https://img.shields.io/github/workflow/status/CopterExpress/clover/CI)
![GitHub all releases](https://img.shields.io/github/downloads/CopterExpress/clover/total)
Image features:
@@ -38,6 +38,10 @@ API description for autonomous flights is available [on GitBook](https://clover.
For manual package installation and running see [`clover` package documentation](clover/README.md).
## Support
[![Telegram Support Chat](https://img.shields.io/endpoint?label=Support%20Chat&url=https%3A%2F%2Ftelegram-badge-4mbpu8e0fit4.runkit.sh%2F%3Furl%3Dhttps%3A%2F%2Ft.me%2FCOEXHelpDesk)](https://t.me/COEXHelpdesk)
## License
While the Clover platform source code is available under the MIT License, note, that the [documentation](docs/) is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

View File

@@ -1,5 +1,4 @@
iOS-приложение для управления Клевером
--------------------------------------
# iOS-приложение для управления Клевером
Для установки зависимостей необходим [CocoaPods](https://cocoapods.org):

View File

@@ -202,11 +202,11 @@ set_property(TARGET aruco_pose
# )
## Mark executables and/or libraries for installation
# install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_node
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
install(TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
## Mark cpp header files for installation
# install(DIRECTORY include/${PROJECT_NAME}/
@@ -226,6 +226,10 @@ catkin_install_python(PROGRAMS src/genmap.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
install(DIRECTORY launch DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
install(DIRECTORY map DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
#############
## Testing ##
#############

View File

@@ -70,7 +70,7 @@ It's recommended to run it within the same nodelet manager with the camera nodel
* `~map` path to text file with markers list
* `~frame_id` published frame id (default: `aruco_map`)
* `~known_tilt` debug image width
* `~known_tilt` known tilt (pitch and roll) of markers map as a frame
* `~image_width` debug image width (default: 2000)
* `~image_height` debug image height (default: 2000)
* `~image_margin`  debug image margin (default: 200)

View File

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

View File

@@ -30,7 +30,7 @@ Options:
-o <filename> Output map file name in the 'map' subdirectory of aruco_pose package
Example:
rosrun aruco_pose genmap.py 0.33 2 4 1 1 0 > $(catkin_find aruco_pose map)/test_map.txt
rosrun aruco_pose genmap.py 0.33 2 4 1 1 0 -o test_map.txt
"""
from __future__ import print_function

View File

@@ -10,7 +10,7 @@
"yametrika",
"anchors",
"collapsible-menu",
"validate-links",
"validate-links@https://github.com/okalachev/gitbook-plugin-validate-links.git",
"bulk-redirect@https://github.com/okalachev/gitbook-plugin-bulk-redirect.git",
"sitemap@https://github.com/okalachev/plugin-sitemap.git",
"toolbar@https://github.com/hamishwillee/gitbook-plugin-toolbar.git",

View File

@@ -8,5 +8,9 @@ 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 \
2> >(tee /tmp/clover.err)"
ExecStartPre=+rm /var/log/clover.log
StandardOutput=file:/var/log/clover.log
StandardError=file:/var/log/clover.log
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,9 @@
#!/usr/bin/env bash
# GitBook CLI is deprecated, its installation is broken.
# This script fixes it until we stop using GitBook.
export NPM_CONFIG_UNSAFE_PERM=1
npm install gitbook-cli -g
gitbook fetch 3.2.3 && npm i npm@3.10.10 --prefix=~/.gitbook/versions/3.2.3/ # fixing https://travis-ci.org/github/CopterExpress/clover/jobs/766541125#L932

View File

@@ -16,7 +16,7 @@
set -e # Exit immidiately on non-zero result
# https://www.raspberrypi.org/software/operating-systems/#raspberry-pi-os-32-bit
SOURCE_IMAGE="https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2021-03-25/2021-03-04-raspios-buster-armhf-lite.zip"
SOURCE_IMAGE="https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2021-05-28/2021-05-07-raspios-buster-armhf-lite.zip"
export DEBIAN_FRONTEND=${DEBIAN_FRONTEND:='noninteractive'}
export LANG=${LANG:='C.UTF-8'}
@@ -105,8 +105,6 @@ ${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/butterf
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/monkey.service' '/lib/systemd/system/'
# software install
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-software.sh'
# examples
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/examples' '/home/pi/' # TODO: symlink?
# network setup
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-network.sh'
# avahi setup
@@ -115,15 +113,11 @@ ${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/avahi-s
# If RPi then use a one thread to build a ROS package on RPi, else use all
[[ $(arch) == 'armv7l' ]] && NUMBER_THREADS=1 || NUMBER_THREADS=$(nproc --all)
# Clover
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/clover.service' '/lib/systemd/system/'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/roscore.service' '/lib/systemd/system/'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/noetic-rosdep-clover.yaml' '/etc/ros/rosdep/'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/ros_python_paths' '/etc/sudoers.d/'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/pigpiod.service' '/lib/systemd/system/'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/launch.nanorc' '/usr/share/nano/'
# ${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/kinetic-ros-clover.rosinstall' '/home/pi/ros_catkin_ws/'
# Add PX4 udev rules
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${REPO_DIR}'/clover/config/99-px4fmu.rules' '/lib/udev/rules.d/'
# 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-validate.sh'

View File

@@ -13,7 +13,7 @@
# copies or substantial portions of the Software.
#
set -e # Exit immidiately on non-zero result
set -ex # exit on error, echo commands
REPO=$1
REF=$2
@@ -90,7 +90,7 @@ 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.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 \
@@ -112,7 +112,8 @@ 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 -DCATKIN_BLACKLIST_PACKAGES=clover_gazebo_plugins
catkin_make -j2 -DCMAKE_BUILD_TYPE=RelWithDebInfo
source devel/setup.bash
echo_stamp "Install clever package (for backwards compatibility)"
cd /home/pi/catkin_ws/src/clover/builder/assets/clever
@@ -121,9 +122,8 @@ rm -rf build # remove build artifacts
echo_stamp "Build Clover documentation"
cd /home/pi/catkin_ws/src/clover
NPM_CONFIG_UNSAFE_PERM=true npm install gitbook-cli -g
NPM_CONFIG_UNSAFE_PERM=true gitbook fetch 3.2.3 && npm i npm@3.10.10 --prefix=~/.gitbook/versions/3.2.3/ # fixing https://travis-ci.org/github/CopterExpress/clover/jobs/766541125#L932
NPM_CONFIG_UNSAFE_PERM=true gitbook install
builder/assets/install_gitbook.sh
gitbook install
gitbook build
touch node_modules/CATKIN_IGNORE docs/CATKIN_IGNORE _book/CATKIN_IGNORE clover/www/CATKIN_IGNORE apps/CATKIN_IGNORE # ignore documentation files by catkin
@@ -151,9 +151,20 @@ catkin_make run_tests #&& catkin_test_results
echo_stamp "Change permissions for catkin_ws"
chown -Rf pi:pi /home/pi/catkin_ws
echo_stamp "Change permissions for examples"
echo_stamp "Make \$HOME/examples symlink"
ln -s "$(catkin_find clover examples --first-only)" /home/pi
chown -Rf pi:pi /home/pi/examples
echo_stamp "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"
ln -s "$(catkin_find clover udev --first-only)"/* /lib/udev/rules.d/
echo_stamp "Setup ROS environment"
cat << EOF >> /home/pi/.bashrc
LANG='C.UTF-8'

View File

@@ -137,6 +137,8 @@ pip3 --version
echo_stamp "Install and enable Butterfly (web terminal)"
echo_stamp "Workaround for tornado >= 6.0 breaking butterfly"
export CRYPTOGRAPHY_DONT_BUILD_RUST=1
my_travis_retry pip3 install cryptography==3.4.6 # https://stackoverflow.com/a/68472128/6850197
my_travis_retry pip3 install pyOpenSSL==20.0.1
my_travis_retry pip3 install tornado==5.1.1
my_travis_retry pip3 install butterfly
my_travis_retry pip3 install butterfly[systemd]
@@ -153,7 +155,7 @@ systemctl enable monkey.service
echo_stamp "Install Node.js"
cd /home/pi
wget https://nodejs.org/dist/v10.15.0/node-v10.15.0-linux-armv6l.tar.gz
wget --no-verbose https://nodejs.org/dist/v10.15.0/node-v10.15.0-linux-armv6l.tar.gz
tar -xzf node-v10.15.0-linux-armv6l.tar.gz
cp -R node-v10.15.0-linux-armv6l/* /usr/local/
rm -rf node-v10.15.0-linux-armv6l/

View File

@@ -20,12 +20,20 @@ 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 "Move /etc/ld.so.preload back to its original position"
mv /etc/ld.so.preload.disabled-for-build /etc/ld.so.preload

View File

@@ -3,10 +3,17 @@
# Perform a "standalone install" in a Docker container
set -e
# Step 1: Install pip
apt update
apt install -y curl
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python3 ./get-pip.py
apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 # https://github.com/osrf/docker_images/issues/535
apt-get update
apt-get install -y curl
if [ "x${ROS_PYTHON_VERSION}" = "x3" ]; then
PYTHON=python3
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
else
PYTHON=python
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py
fi
${PYTHON} ./get-pip.py
# Step 1.5: Add deb.coex.tech to apt
curl http://deb.coex.tech/aptly_repo_signing.key 2> /dev/null | apt-key add -
@@ -34,7 +41,7 @@ ws281x:
ubuntu:
${CODENAME}: [ros-${ROS_DISTRO}-ws281x]
EOF
apt update
apt-get update
rosdep update
# Step 2: Run rosdep to install all dependencies
@@ -50,7 +57,7 @@ cd /root/catkin_ws
catkin_make
# Step 4: Run tests
python3 -m pip install --upgrade pytest # TODO: https://github.com/CopterExpress/clover/commit/5b970d51970cfa6f46e5c0b34acb7889d36b89c8
${PYTHON} -m pip install --upgrade pytest
cd /root/catkin_ws
source devel/setup.bash
catkin_make run_tests && catkin_test_results

BIN
builder/test/qr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

42
builder/test/test_qr.py Executable file
View File

@@ -0,0 +1,42 @@
#!/usr/bin/env python3
# Test QG recognition example
# Should be synced with the documentation: /docs/en/camera.md, /docs/ru/camera.md
# TODO: use real ROS topics
import rospy
from pyzbar import pyzbar
from cv_bridge import CvBridge
from sensor_msgs.msg import Image
bridge = CvBridge()
# rospy.init_node('barcode_test')
# Image subscriber callback function
def image_callback(data):
cv_image = bridge.imgmsg_to_cv2(data, 'bgr8') # OpenCV image
barcodes = pyzbar.decode(cv_image)
for barcode in barcodes:
b_data = barcode.data.decode("utf-8")
b_type = barcode.type
(x, y, w, h) = barcode.rect
xc = x + w/2
yc = y + h/2
print("Found {} with data {} with center at x={}, y={}".format(b_type, b_data, xc, yc))
# rospy.signal_shutdown('done')
# image_sub = rospy.Subscriber('main_camera/image_raw', Image, image_callback, queue_size=1)
# ==============================================================================
# Publish test image
# rospy.sleep(2)
import cv2
img = cv2.imread('qr.png')
image_callback(bridge.cv2_to_imgmsg(img, 'bgr8'))
# image_pub = rospy.Publisher('/main_camera/image_raw', Image, queue_size=1, latch=True)
# image_pub.publish(bridge.cv2_to_imgmsg(img, 'bgr8'))
# rospy.spin()

View File

@@ -4,18 +4,26 @@
import rospy
from geometry_msgs.msg import PoseStamped
from sensor_msgs.msg import Range, BatteryState
import cv2
import cv2.aruco
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
import numpy
import mavros
from mavros_msgs.msg import State, StatusText, ExtendedState
from mavros_msgs.msg import State, StatusText, ExtendedState, RCIn, Mavlink
from mavros_msgs.srv import CommandBool, CommandLong, SetMode
from std_srvs.srv import Trigger
from clover.srv import GetTelemetry, Navigate, NavigateGlobal, SetPosition, SetVelocity, \
SetAttitude, SetRates, SetLEDEffect
from led_msgs.srv import SetLEDs
from led_msgs.msg import LEDStateArray, LEDState
from aruco_pose.msg import Marker, MarkerArray, Point2D
import dynamic_reconfigure.client
import tf2_ros
import tf2_geometry_msgs

View File

@@ -34,6 +34,7 @@ i2cdetect -V
butterfly -h
# espeak --version
mjpg_streamer --version
systemctl --version
# ros stuff
@@ -57,5 +58,9 @@ rosversion rosshow
rosversion nodelet
rosversion image_view
# validate some versions
[[ $(rosversion cv_camera) == "0.5.1" ]] # patched version with init fix
[[ $(rosversion ws281x) == "0.0.12" ]]
# validate examples are present
[[ $(ls /home/pi/examples/*) ]]

View File

@@ -5,7 +5,7 @@ import sys
import subprocess
EXCLUDE = ('clever4-front-white.png', 'clever4-front-white-large.png', '.DS_Store',
'clever4-front-black-large.png','clover42-black.png')
'clever4-front-black-large.png','clover42-black.png', 'clover42-main-margin.png')
code = 0

View File

@@ -241,12 +241,12 @@ target_link_libraries(${PROJECT_NAME}
# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
## Mark executables and/or libraries for installation
# install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_node
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
# Mark executables and/or libraries for installation
install(TARGETS simple_offboard clover_rc camera_markers vpe_publisher clover_led shell clover
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
## Mark cpp header files for installation
# install(DIRECTORY include/${PROJECT_NAME}/
@@ -266,13 +266,21 @@ catkin_install_python(PROGRAMS src/selfcheck.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
install(DIRECTORY launch DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
install(DIRECTORY examples DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
install(DIRECTORY www DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
# TODO: install www
# Only install udev rules when building a Debian package
# FIXME: Other operating systems may have other prefixes
string(FIND ${CMAKE_INSTALL_PREFIX} "/opt/ros" _PREFIX_INDEX)
if (${_PREFIX_INDEX} EQUAL 0)
message(STATUS "Building as a Debian package - adding udev rules as installable files")
install(FILES
config/99-px4fmu.rules
udev/99-px4fmu.rules
DESTINATION /lib/udev/rules.d
)
else()

View File

@@ -36,7 +36,7 @@ curl https://raw.githubusercontent.com/mavlink/mavros/master/mavros/scripts/inst
You may optionally install udev rules to provide `/dev/px4fmu` symlink to your PX4-based flight controller connected over USB. Copy `99-px4fmu.rules` to your `/lib/udev/rules.d` folder:
```bash
cd ~/catkin_ws/src/clover/clover/config
cd ~/catkin_ws/src/clover/clover/udev
sudo cp 99-px4fmu.rules /lib/udev/rules.d
```

View File

@@ -15,17 +15,17 @@ set_attitude = rospy.ServiceProxy('set_attitude', srv.SetAttitude)
set_rates = rospy.ServiceProxy('set_rates', srv.SetRates)
land = rospy.ServiceProxy('land', Trigger)
# Take off and hover 1 m above the ground
print('Take off and hover 1 m above the ground')
navigate(x=0, y=0, z=1, frame_id='body', auto_arm=True)
# Wait for 3 seconds
rospy.sleep(3)
# Wait for 5 seconds
rospy.sleep(5)
# Fly forward 1 m
print('Fly forward 1 m')
navigate(x=1, y=0, z=0, frame_id='body')
# Wait for 3 seconds
rospy.sleep(3)
# Wait for 5 seconds
rospy.sleep(5)
# Perform landing
print('Perform landing')
land()

View File

@@ -15,23 +15,23 @@ set_attitude = rospy.ServiceProxy('set_attitude', srv.SetAttitude)
set_rates = rospy.ServiceProxy('set_rates', srv.SetRates)
land = rospy.ServiceProxy('land', Trigger)
# Take off and hover 1 m above the ground
print('Take off and hover 1 m above the ground')
navigate(x=0, y=0, z=1, frame_id='body', auto_arm=True)
# Wait for 3 seconds
rospy.sleep(3)
# Wait for 5 seconds
rospy.sleep(5)
# Fly 1 meter above ArUco marker 0
print('Fly 1 meter above ArUco marker 0')
navigate(x=0, y=0, z=1, frame_id='aruco_0')
# Wait for 3 seconds
rospy.sleep(3)
# Wait for 5 seconds
rospy.sleep(5)
# Fly to x=1 y=1 z=1 relative to ArUco markers map
print('Fly to x=1 y=1 z=1 relative to ArUco markers map')
navigate(x=1, y=1, z=1, frame_id='aruco_map')
# Wait for 3 seconds
rospy.sleep(3)
# Wait for 5 seconds
rospy.sleep(5)
# Perform landing
print('Perform landing')
land()

47
clover/examples/gps.py Normal file
View File

@@ -0,0 +1,47 @@
# Information: https://clover.coex.tech/en/simple_offboard.html#navigateglobal
import rospy
from clover import srv
from std_srvs.srv import Trigger
import math
rospy.init_node('flight')
get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry)
navigate = rospy.ServiceProxy('navigate', srv.Navigate)
navigate_global = rospy.ServiceProxy('navigate_global', srv.NavigateGlobal)
set_position = rospy.ServiceProxy('set_position', srv.SetPosition)
set_velocity = rospy.ServiceProxy('set_velocity', srv.SetVelocity)
set_attitude = rospy.ServiceProxy('set_attitude', srv.SetAttitude)
set_rates = rospy.ServiceProxy('set_rates', srv.SetRates)
land = rospy.ServiceProxy('land', Trigger)
# https://clover.coex.tech/en/snippets.html#wait_arrival
def wait_arrival(tolerance=0.2):
while not rospy.is_shutdown():
telem = get_telemetry(frame_id='navigate_target')
if math.sqrt(telem.x ** 2 + telem.y ** 2 + telem.z ** 2) < tolerance:
break
rospy.sleep(0.2)
start = get_telemetry()
if math.isnan(start.lat):
raise Exception('No global position, install and configure GPS sensor: https://clover.coex.tech/gps')
print('Start point global position: lat={}, lon={}'.format(start.lat, start.lon))
print('Take off 3 meters')
navigate(x=0, y=0, z=3, frame_id='body', auto_arm=True)
wait_arrival()
print('Fly 1 arcsecond to the North (approx. 30 meters)')
navigate_global(lat=start.lat+1.0/60/60, lon=start.lon, z=start.z+3, yaw=math.inf, speed=5)
wait_arrival()
print('Fly to home position')
navigate_global(lat=start.lat, lon=start.lon, z=start.z+3, yaw=math.inf, speed=5)
wait_arrival()
print('Land')
land()

View File

@@ -31,11 +31,11 @@ def navigate_wait(x=0, y=0, z=0, yaw=float('nan'), yaw_rate=0, speed=0.5, \
return res
rospy.sleep(0.2)
# Take off 1 meter
print('Take off 1 meter')
navigate_wait(z=1, frame_id='body', auto_arm=True)
# Fly forward 1 m
print('Fly forward 1 m')
navigate_wait(x=1, frame_id='body')
# Land
print('Land')
land()

View File

@@ -0,0 +1,15 @@
# Information: https://clover.coex.tech/en/laser.html
import rospy
from sensor_msgs.msg import Range
rospy.init_node('process_rangefinder')
def range_callback(msg):
# Process data from the rangefinder
print('Rangefinder distance:', msg.range)
# Subscribe to laser rangefinder data
rospy.Subscriber('rangefinder/range', Range, range_callback)
rospy.spin()

View File

@@ -3,16 +3,19 @@
<arg name="aruco_map" default="false"/>
<arg name="aruco_vpe" default="false"/>
<arg name="placement" default="floor"/> <!-- markers placement: floor, ceiling, unknown -->
<arg name="length" default="0.33"/> <!-- not-in-map markers length, m -->
<arg name="length" default="0.22"/> <!-- not-in-map markers length, m -->
<arg name="map" default="map.txt"/> <!-- markers map file name -->
<!-- For additional help go to https://clover.coex.tech/aruco -->
<arg name="force_init" default="false"/>
<arg name="disable" default="false"/> <!-- only force init -->
<!-- aruco_detect: detect aruco markers, estimate poses -->
<node name="aruco_detect" pkg="nodelet" if="$(arg aruco_detect)" type="nodelet" args="load aruco_pose/aruco_detect nodelet_manager" output="screen" clear_params="true" respawn="true">
<node name="aruco_detect" pkg="nodelet" if="$(eval aruco_detect and not disable)" type="nodelet" args="load aruco_pose/aruco_detect main_camera_nodelet_manager" output="screen" clear_params="true" respawn="true">
<remap from="image_raw" to="main_camera/image_raw"/>
<remap from="camera_info" to="main_camera/camera_info"/>
<remap from="map_markers" to="aruco_map/markers" if="$(arg aruco_map)"/>
<remap from="map_markers" to="aruco_map/markers"/>
<param name="estimate_poses" value="true"/>
<param name="send_tf" value="true"/>
<param name="known_tilt" value="map" if="$(eval placement == 'floor')"/>
@@ -26,7 +29,7 @@
</node>
<!-- aruco_map: estimate aruco map pose -->
<node name="aruco_map" pkg="nodelet" type="nodelet" if="$(arg aruco_map)" args="load aruco_pose/aruco_map nodelet_manager" output="screen" clear_params="true" respawn="true">
<node name="aruco_map" pkg="nodelet" type="nodelet" if="$(eval aruco_map and not disable)" args="load aruco_pose/aruco_map main_camera_nodelet_manager" output="screen" clear_params="true" respawn="true">
<remap from="image_raw" to="main_camera/image_raw"/>
<remap from="camera_info" to="main_camera/camera_info"/>
<remap from="markers" to="aruco_detect/markers"/>
@@ -41,11 +44,11 @@
</node>
<!-- vpe publisher from aruco markers -->
<node name="vpe_publisher" pkg="clover" type="vpe_publisher" if="$(arg aruco_vpe)" output="screen" clear_params="true">
<remap from="~pose_cov" to="aruco_map/pose"/>
<node name="vpe_publisher" pkg="clover" type="vpe_publisher" if="$(eval aruco_vpe or force_init)" output="screen" clear_params="true">
<remap from="~pose_cov" to="aruco_map/pose" if="$(arg aruco_vpe)"/>
<remap from="~vpe" to="mavros/vision_pose/pose"/>
<param name="frame_id" value="aruco_map_detected"/>
<param name="publish_zero" value="true"/>
<param name="frame_id" value="aruco_map_detected" if="$(arg aruco_vpe)"/>
<param name="force_init" value="$(arg force_init)"/>
<param name="offset_frame_id" value="aruco_map"/>
</node>
</launch>

View File

@@ -12,6 +12,7 @@
<arg name="led" default="true"/>
<arg name="blocks" default="false"/>
<arg name="rc" default="false"/>
<arg name="force_init" value="true"/> <!-- force estimator to init by publishing zero pose -->
<arg name="simulator" default="false"/> <!-- flag that we are operating on a simulated drone -->
@@ -33,28 +34,23 @@
</node>
<!-- aruco markers -->
<include file="$(find clover)/launch/aruco.launch" if="$(arg aruco)"/>
<include file="$(find clover)/launch/aruco.launch" if="$(eval aruco or force_init)">
<arg name="force_init" value="$(arg force_init)"/>
<arg name="disable" value="$(eval not aruco)"/>
</include>
<!-- optical flow -->
<node pkg="nodelet" type="nodelet" name="optical_flow" args="load clover/optical_flow nodelet_manager" if="$(arg optical_flow)" clear_params="true" output="screen" respawn="true">
<node pkg="nodelet" type="nodelet" name="optical_flow" args="load clover/optical_flow main_camera_nodelet_manager" if="$(arg optical_flow)" clear_params="true" output="screen" respawn="true">
<remap from="image_raw" to="main_camera/image_raw"/>
<remap from="camera_info" to="main_camera/camera_info"/>
<param name="calc_flow_gyro" value="true"/>
<param name="roi_rad" value="0.8"/>
</node>
<!-- main nodelet manager -->
<node pkg="nodelet" type="nodelet" name="nodelet_manager" args="manager" output="screen" clear_params="true" respawn="true">
<param name="num_worker_threads" value="2"/>
</node>
<node pkg="tf2_ros" type="static_transform_publisher" name="map_flipped_frame" args="0 0 0 3.1415926 3.1415926 0 map map_flipped"/>
<!-- simplified offboard control -->
<node name="simple_offboard" pkg="clover" type="simple_offboard" output="screen" clear_params="true">
<param name="reference_frames/body" value="map"/>
<param name="reference_frames/base_link" value="map"/>
<param name="reference_frames/navigate_target" value="map"/>
<param name="reference_frames/main_camera_optical" value="map"/>
</node>

View File

@@ -36,7 +36,7 @@
posctl: { r: 50, g: 100, b: 220 }
offboard: { r: 220, g: 20, b: 250 }
low_battery: { threshold: 3.6, effect: blink_fast, r: 255, g: 0, b: 0 }
error: { effect: flash, r: 255, g: 0, b: 0 }
error: { effect: flash, r: 255, g: 0, b: 0, ignore: [ "[lpe] vision position timeout" ]}
</rosparam>
</node>
</launch>

View File

@@ -3,6 +3,7 @@
<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="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"/>
@@ -17,9 +18,14 @@
<!-- static_transform_publisher arguments: x y z yaw pitch roll frame_id child_frame_id -->
<!-- <node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 -0.07 -1.5707963 0 3.1415926 base_link main_camera_optical"/> -->
<!-- camera nodelet manager -->
<node pkg="nodelet" type="nodelet" name="main_camera_nodelet_manager" args="manager" output="screen" clear_params="true" respawn="true">
<param name="num_worker_threads" value="2"/>
</node>
<!-- camera node -->
<node pkg="nodelet" type="nodelet" name="main_camera" args="load cv_camera/CvCameraNodelet nodelet_manager" clear_params="true" unless="$(arg simulator)" respawn="true">
<param name="device_path" value="/dev/video0"/> <!-- v4l2 device -->
<node pkg="nodelet" type="nodelet" name="main_camera" args="load cv_camera/CvCameraNodelet main_camera_nodelet_manager" launch-prefix="rosrun clover waitfile $(arg device)" clear_params="true" unless="$(arg simulator)" respawn="true">
<param name="device_path" value="$(arg device)"/>
<param name="frame_id" value="main_camera_optical"/>
<param name="camera_info_url" value="file://$(find clover)/camera_info/fisheye_cam.yaml"/>

View File

@@ -1,11 +1,11 @@
# Config file for mavros
# Based on https://raw.githubusercontent.com/mavlink/mavros/master/mavros/launch/px4_config.yaml
startup_px4_usb_quirk: true
startup_px4_usb_quirk: false
conn:
heartbeat_rate: 1.0 # send hertbeat rate in Hertz
timeout: 10.0 # hertbeat timeout in seconds
heartbeat_rate: 1.0 # send heartbeat rate in Hertz
timeout: 10.0 # heartbeat timeout in seconds
timesync_rate: 10.0 # TIMESYNC rate in Hertz (feature disabled if 0.0)
system_time_rate: 1.0 # send system time to FCU rate in Hertz (disabled if 0.0)
@@ -13,6 +13,7 @@ time:
time_ref_source: "fcu" # time_reference source
timesync_mode: MAVLINK
timesync_avg_alpha: 0.6 # timesync averaging factor
publish_sim_time: false # don't publish /clock
global_position:
frame_id: "map" # origin frame

View File

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

View File

@@ -12,6 +12,7 @@
#include <ros/ros.h>
#include <string>
#include <vector>
#include <boost/algorithm/string.hpp>
#include <clover/SetLEDEffect.h>
@@ -29,6 +30,7 @@ ros::Timer timer;
ros::Time start_time;
double blink_rate, blink_fast_rate, flash_delay, fade_period, wipe_period, rainbow_period;
double low_battery_threshold;
std::vector<std::string> error_ignore;
bool blink_state;
led_msgs::SetLEDs set_leds;
led_msgs::LEDStateArray state, start_state;
@@ -274,6 +276,10 @@ void handleMavrosState(const mavros_msgs::State& msg)
void handleLog(const rosgraph_msgs::Log& log)
{
if (log.level >= rosgraph_msgs::Log::ERROR) {
// check if ignored
for (auto const& str : error_ignore) {
if (log.msg.find(str) != std::string::npos) return;
}
notify("error");
}
}
@@ -302,6 +308,7 @@ int main(int argc, char **argv)
nh_priv.param("rainbow_period", rainbow_period, 5.0);
nh_priv.param("notify/low_battery/threshold", low_battery_threshold, 3.7);
nh_priv.param("notify/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);

View File

@@ -53,6 +53,7 @@ private:
std::unique_ptr<tf2_ros::Buffer> tf_buffer_;
std::unique_ptr<tf2_ros::TransformListener> tf_listener_;
bool calc_flow_gyro_;
float flow_gyro_default_;
void onInit()
{
@@ -69,15 +70,13 @@ private:
roi_px_ = nh_priv.param("roi", 128);
roi_rad_ = nh_priv.param("roi_rad", 0.0);
calc_flow_gyro_ = nh_priv.param("calc_flow_gyro", false);
flow_gyro_default_ = nh_priv.param("flow_gyro_default", NAN);
img_pub_ = it_priv.advertise("debug", 1);
flow_pub_ = nh.advertise<mavros_msgs::OpticalFlowRad>("mavros/px4flow/raw/send", 1);
velo_pub_ = nh_priv.advertise<geometry_msgs::TwistStamped>("angular_velocity", 1);
shift_pub_ = nh_priv.advertise<geometry_msgs::Vector3Stamped>("shift", 1);
flow_.integrated_xgyro = NAN; // no IMU available
flow_.integrated_ygyro = NAN;
flow_.integrated_zgyro = NAN;
flow_.time_delta_distance_us = 0;
flow_.distance = -1; // no distance sensor available
flow_.temperature = 0;
@@ -153,7 +152,7 @@ private:
cv::Point2d shift = cv::phaseCorrelate(prev_, curr_, hann_, &response);
// Publish raw shift in pixels
static geometry_msgs::Vector3Stamped shift_vec;
geometry_msgs::Vector3Stamped shift_vec;
shift_vec.header.stamp = msg->header.stamp;
shift_vec.header.frame_id = msg->header.frame_id;
shift_vec.vector.x = shift.x;
@@ -179,8 +178,8 @@ private:
double flow_x = atan2(points_undist[0].x, focal_length_x);
double flow_y = atan2(points_undist[0].y, focal_length_y);
// // Convert to FCU frame
static geometry_msgs::Vector3Stamped flow_camera, flow_fcu;
// Convert to FCU frame
geometry_msgs::Vector3Stamped flow_camera, flow_fcu;
flow_camera.header.frame_id = msg->header.frame_id;
flow_camera.header.stamp = msg->header.stamp;
flow_camera.vector.x = flow_y; // +y means counter-clockwise rotation around Y axis
@@ -196,18 +195,21 @@ private:
ros::Duration integration_time = msg->header.stamp - prev_stamp_;
uint32_t integration_time_us = integration_time.toSec() * 1.0e6;
// Calculate flow gyro
flow_.integrated_xgyro = flow_gyro_default_;
flow_.integrated_ygyro = flow_gyro_default_;
flow_.integrated_zgyro = flow_gyro_default_;
if (calc_flow_gyro_) {
try {
auto flow_gyro_camera = calcFlowGyro(msg->header.frame_id, prev_stamp_, msg->header.stamp);
static geometry_msgs::Vector3Stamped flow_gyro_fcu;
geometry_msgs::Vector3Stamped flow_gyro_fcu;
tf_buffer_->transform(flow_gyro_camera, flow_gyro_fcu, fcu_frame_id_);
flow_.integrated_xgyro = flow_gyro_fcu.vector.x;
flow_.integrated_ygyro = flow_gyro_fcu.vector.y;
flow_.integrated_zgyro = flow_gyro_fcu.vector.z;
} catch (const tf2::TransformException& e) {
// Invalidate previous frame
prev_.release();
goto publish_debug;
// Transform not available, keep NANs in flow gyro
}
}
@@ -236,7 +238,7 @@ publish_debug:
}
// Publish estimated angular velocity
static geometry_msgs::TwistStamped velo;
geometry_msgs::TwistStamped velo;
velo.header.stamp = msg->header.stamp;
velo.header.frame_id = fcu_frame_id_;
velo.twist.angular.x = flow_fcu.vector.x / integration_time.toSec();

View File

@@ -43,6 +43,8 @@ from mavros import mavlink
rospy.init_node('selfcheck')
os.environ['ROSCONSOLE_FORMAT']='[${severity}]: ${message}'
tf_buffer = tf2_ros.Buffer()
tf_listener = tf2_ros.TransformListener(tf_buffer)
@@ -193,24 +195,27 @@ def check_fcu():
failure('no connection to the FCU (check wiring)')
return
clover_tag = re.compile(r'-cl[oe]ver\.\d+$')
clover_fw = False
# Make sure the console is available to us
mavlink_exec('\n')
version_str = mavlink_exec('ver all')
if version_str == '':
info('no version data available from SITL')
r = re.compile(r'^FW (git tag|version): (v?\d\.\d\.\d.*)$')
is_clover_firmware = False
for ver_line in version_str.split('\n'):
match = r.search(ver_line)
if match is not None:
field, version = match.groups()
info('firmware %s: %s' % (field, version))
if 'clover' in version or 'clever' in version:
is_clover_firmware = True
for line in version_str.split('\n'):
if line.startswith('FW version: '):
info(line[len('FW version: '):])
elif line.startswith('FW git tag: '): # only Clover's firmware
tag = line[len('FW git tag: '):]
clover_fw = clover_tag.search(tag)
info(tag)
elif line.startswith('HW arch: '):
info(line[len('HW arch: '):])
if not is_clover_firmware:
failure('not running Clover PX4 firmware, https://clover.coex.tech/firmware')
if not clover_fw:
info('not Clover PX4 firmware, check https://clover.coex.tech/firmware')
est = get_param('SYS_MC_EST_GROUP')
if est == 1:
@@ -483,6 +488,12 @@ def check_local_position():
failure('roll is %.2f deg; place copter horizontally or redo level horizon calib',
math.degrees(roll))
if not tf_buffer.can_transform('base_link', pose.header.frame_id, rospy.get_rostime(), rospy.Duration(0.5)):
failure('can\'t transform from %s to base_link (timeout 0.5 s): is TF enabled?', pose.header.frame_id)
if not tf_buffer.can_transform('body', pose.header.frame_id, rospy.get_rostime(), rospy.Duration(0.5)):
failure('can\'t transform from %s to body (timeout 0.5 s)', pose.header.frame_id)
except rospy.ROSException:
failure('no local position')
@@ -612,13 +623,13 @@ def check_boot_duration():
output = subprocess.check_output('systemd-analyze').decode()
r = re.compile(r'([\d\.]+)s\s*$', flags=re.MULTILINE)
duration = float(r.search(output).groups()[0])
if duration > 15:
if duration > 20:
failure('long Raspbian boot duration: %ss (systemd-analyze for analyzing)', duration)
@check('CPU usage')
def check_cpu_usage():
WHITELIST = 'nodelet',
WHITELIST = 'nodelet', 'gzclient', 'gzserver'
CMD = "top -n 1 -b -i | tail -n +8 | awk '{ printf(\"%-8s\\t%-8s\\t%-8s\\n\", $1, $9, $12); }'"
output = subprocess.check_output(CMD, shell=True).decode()
processes = output.split('\n')
@@ -646,13 +657,22 @@ def check_clover_service():
elif 'failed' in output:
failure('service failed to run, check your launch-files')
r = re.compile(r'^(.*)\[(FATAL|ERROR)\] \[\d+.\d+\]: (.*?)(\x1b(.*))?$')
BLACKLIST = 'Unexpected command 520', 'Time jump detected', 'different index:'
r = re.compile(r'^(.*)\[(FATAL|ERROR| WARN)\] \[\d+.\d+\]: (.*?)(\x1b(.*))?$')
error_count = OrderedDict()
try:
for line in open('/tmp/clover.err', 'r'):
skip = False
for substr in BLACKLIST:
if substr in line:
skip = True
if skip:
continue
node_error = r.search(line)
if node_error:
msg = node_error.groups()[1] + ': ' + node_error.groups()[2]
msg = node_error.groups()[1].strip() + ': ' + node_error.groups()[2]
if msg in error_count:
error_count[msg] += 1
else:
@@ -753,7 +773,7 @@ def check_rpi_health():
# with some of the FLAGs OR'ed together
output = subprocess.check_output(['vcgencmd', 'get_throttled']).decode()
except OSError:
failure('could not call vcgencmd binary; not a Raspberry Pi?')
info('could not call vcgencmd binary; not a Raspberry Pi?')
return
throttle_mask = int(output.split('=')[1], base=16)

View File

@@ -181,9 +181,10 @@ inline bool waitTransform(const string& target, const string& source,
ros::spinOnce();
r.sleep();
}
return false;
}
#define TIMEOUT(msg, timeout) (ros::Time::now() - msg.header.stamp > timeout)
#define TIMEOUT(msg, timeout) (msg.header.stamp.isZero() || (ros::Time::now() - msg.header.stamp > timeout))
bool getTelemetry(GetTelemetry::Request& req, GetTelemetry::Response& res)
{
@@ -441,6 +442,10 @@ void publish(const ros::Time stamp)
// publish setpoint frame
if (!setpoint.child_frame_id.empty()) {
if (setpoint.header.stamp == position_msg.header.stamp) {
return; // avoid TF_REPEATED_DATA warnings
}
setpoint.transform.translation.x = position_msg.pose.position.x;
setpoint.transform.translation.y = position_msg.pose.position.y;
setpoint.transform.translation.z = position_msg.pose.position.z;
@@ -712,7 +717,7 @@ bool serve(enum setpoint_type_t sp_type, float x, float y, float z, float vx, fl
}
if (sp_type == VELOCITY) {
static Vector3Stamped vel;
Vector3Stamped vel;
vel.header.frame_id = frame_id;
vel.header.stamp = stamp;
vel.vector.x = vx;
@@ -843,6 +848,7 @@ bool land(std_srvs::Trigger::Request& req, std_srvs::Trigger::Response& res)
busy = false;
return true;
}
return false;
}
int main(int argc, char **argv)
@@ -867,6 +873,13 @@ int main(int argc, char **argv)
nh_priv.param<string>("body_frame", body.child_frame_id, "body");
nh_priv.getParam("reference_frames", reference_frames);
// Default reference frames
std::map<string, string> default_reference_frames;
default_reference_frames[body.child_frame_id] = local_frame;
default_reference_frames[fcu_frame] = local_frame;
if (!target.child_frame_id.empty()) default_reference_frames[target.child_frame_id] = local_frame;
reference_frames.insert(default_reference_frames.begin(), default_reference_frames.end()); // merge defaults
state_timeout = ros::Duration(nh_priv.param("state_timeout", 3.0));
local_position_timeout = ros::Duration(nh_priv.param("local_position_timeout", 2.0));
velocity_timeout = ros::Duration(nh_priv.param("velocity_timeout", 2.0));

View File

@@ -53,7 +53,7 @@ void publishZero(const ros::TimerEvent& e)
}
ROS_INFO_THROTTLE(10, "publish zero");
static geometry_msgs::PoseStamped zero;
geometry_msgs::PoseStamped zero;
zero.header.frame_id = local_frame_id;
zero.header.stamp = e.current_real;
zero.pose.orientation.w = 1;
@@ -141,11 +141,11 @@ int main(int argc, char **argv) {
vpe_pub = nh_priv.advertise<PoseStamped>("vpe", 1);
//vpe_cov_pub = nh_priv_.advertise<PoseStamped>("pose_cov_pub", 1);
if (nh_priv.param("publish_zero", false)) {
if (nh_priv.param("force_init", false) || nh_priv.param("publish_zero", false)) { // publish_zero is old name
// publish zero to initialize the local position
zero_timer = nh.createTimer(ros::Duration(0.1), &publishZero);
publish_zero_timout = ros::Duration(nh_priv.param("publish_zero_timout", 5.0));
publish_zero_duration = ros::Duration(nh_priv.param("publish_zero_duration", 5.0));
publish_zero_timout = ros::Duration(nh_priv.param("force_init_timeout", 5.0));
publish_zero_duration = ros::Duration(nh_priv.param("force_init_duration", 5.0));
local_position_sub = nh.subscribe("mavros/local_position/pose", 1, &localPositionCallback);
}

View File

@@ -6,4 +6,4 @@
echo "wait for file $1"
while [ ! -e "$1" ]; do sleep 1; done;
echo "file $1 appeared"
"${@:2}"
exec "${@:2}"

View File

@@ -12,4 +12,6 @@ SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0016", ATTRS{produ
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"

View File

@@ -1 +0,0 @@
/tmp/clover.err

1
clover/www/clover.log Symbolic link
View File

@@ -0,0 +1 @@
/var/log/clover.log

23
clover/www/console.html Normal file
View File

@@ -0,0 +1,23 @@
<h1>
/var/log/clover.log
<a style="font-size: 0.5em; vertical-align: super; font-weight: normal" href="clover.log" download>download</a>
</h1>
<pre></pre>
<script type="module">
var pre = document.querySelector('pre');
fetch('clover.log?' + Math.random()).then(function(response) { // random to forbid caching
if (response.status == 404) {
pre.innerHTML = '/var/log/clover.log does not exist';
return;
} else if (response.status !== 200) {
pre.innerHTML('Error ' + response.status);
return;
}
response.text().then(function(content) {
pre.innerHTML = content;
});
});
</script>

View File

@@ -4,12 +4,12 @@
<ul>
<li><a href="docs">View documentation</a> (snapshot of <a href="https://clover.coex.tech">clover.coex.tech</a>)</li>
<li><a href="topics.html">View topics</a></li>
<li><a href="" id="wvs">View image topics</a> (<code>web_video_server</code>)</li>
<li><a href="" id="butterfly">Open web terminal</a> (<code>Butterfly</code>)</li>
<li><a href="viz.html">View 3D visualization</a> (<code>ros3djs</code>)</li>
<li><a href="aruco_map.html">3D visualization for markers map</a> (<code>ros3djs</code>)</li>
<li>View <a href="viz.html">View 3D visualization</a>, <a href="aruco_map.html">3D visualization for markers map</a> (<code>ros3djs</code>)</li>
<li><a href="../clover_blocks/">Blocks programming</a> (<code>Blockly</code>)</li>
<li><a href="clover.err">Clover console</a> (<code>tmp/clover.err</code>)</li>
<li><a href="console.html">Clover console</a> (<code>/var/log/clover.log</code>)</li>
</ul>
<div class="version"></div>
@@ -18,6 +18,14 @@
document.querySelector("#wvs").href = location.protocol + '//' + location.hostname + ':8080';
document.querySelector("#butterfly").href = location.protocol + '//' + location.hostname + ':57575';
document.querySelector("#butterfly").addEventListener('click', function(e) {
if (location.hostname == 'localhost' || location.hostname == '127.0.0.1') {
if (!confirm('Please use regular Terminal app on a local machine.\nClick OK to proceed to Butterfly anyway.')) {
e.preventDefault();
}
}
});
// Determine image version
fetch('clover_version').then(function(response) {
if (response.status !== 200) return;

View File

@@ -0,0 +1,236 @@
// Browserified https://www.npmjs.com/package/json-to-pretty-yaml module
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
(function() {
"use strict";
var typeOf = require('remedial').typeOf;
var trimWhitespace = require('remove-trailing-spaces');
function stringify(data) {
var handlers, indentLevel = '';
handlers = {
"undefined": function() {
// objects will not have `undefined` converted to `null`
// as this may have unintended consequences
// For arrays, however, this behavior seems appropriate
return 'null';
},
"null": function() {
return 'null';
},
"number": function(x) {
return x;
},
"boolean": function(x) {
return x ? 'true' : 'false';
},
"string": function(x) {
// to avoid the string "true" being confused with the
// the literal `true`, we always wrap strings in quotes
return JSON.stringify(x);
},
"array": function(x) {
var output = '';
if (0 === x.length) {
output += '[]';
return output;
}
indentLevel = indentLevel.replace(/$/, ' ');
x.forEach(function(y, i) {
// TODO how should `undefined` be handled?
var handler = handlers[typeOf(y)];
if (!handler) {
throw new Error('what the crap: ' + typeOf(y));
}
output += '\n' + indentLevel + '- ' + handler(y, true);
});
indentLevel = indentLevel.replace(/ /, '');
return output;
},
"object": function(x, inArray, rootNode) {
var output = '';
if (0 === Object.keys(x).length) {
output += '{}';
return output;
}
if (!rootNode) {
indentLevel = indentLevel.replace(/$/, ' ');
}
Object.keys(x).forEach(function(k, i) {
var val = x[k],
handler = handlers[typeOf(val)];
if ('undefined' === typeof val) {
// the user should do
// delete obj.key
// and not
// obj.key = undefined
// but we'll error on the side of caution
return;
}
if (!handler) {
throw new Error('what the crap: ' + typeOf(val));
}
if (!(inArray && i === 0)) {
output += '\n' + indentLevel;
}
output += k + ': ' + handler(val);
});
indentLevel = indentLevel.replace(/ /, '');
return output;
},
"function": function() {
// TODO this should throw or otherwise be ignored
return '[object Function]';
}
};
return trimWhitespace(handlers[typeOf(data)](data, true, true) + '\n');
}
window.yamlStringify = stringify;
module.exports.stringify = stringify;
}());
},{"remedial":2,"remove-trailing-spaces":3}],2:[function(require,module,exports){
/*jslint onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true */
(function () {
"use strict";
var global = Function('return this')()
, classes = "Boolean Number String Function Array Date RegExp Object".split(" ")
, i
, name
, class2type = {}
;
for (i in classes) {
if (classes.hasOwnProperty(i)) {
name = classes[i];
class2type["[object " + name + "]"] = name.toLowerCase();
}
}
function typeOf(obj) {
return (null === obj || undefined === obj) ? String(obj) : class2type[Object.prototype.toString.call(obj)] || "object";
}
function isEmpty(o) {
var i, v;
if (typeOf(o) === 'object') {
for (i in o) { // fails jslint
v = o[i];
if (v !== undefined && typeOf(v) !== 'function') {
return false;
}
}
}
return true;
}
if (!String.prototype.entityify) {
String.prototype.entityify = function () {
return this.replace(/&/g, "&amp;").replace(/</g,
"&lt;").replace(/>/g, "&gt;");
};
}
if (!String.prototype.quote) {
String.prototype.quote = function () {
var c, i, l = this.length, o = '"';
for (i = 0; i < l; i += 1) {
c = this.charAt(i);
if (c >= ' ') {
if (c === '\\' || c === '"') {
o += '\\';
}
o += c;
} else {
switch (c) {
case '\b':
o += '\\b';
break;
case '\f':
o += '\\f';
break;
case '\n':
o += '\\n';
break;
case '\r':
o += '\\r';
break;
case '\t':
o += '\\t';
break;
default:
c = c.charCodeAt();
o += '\\u00' + Math.floor(c / 16).toString(16) +
(c % 16).toString(16);
}
}
}
return o + '"';
};
}
if (!String.prototype.supplant) {
String.prototype.supplant = function (o) {
return this.replace(/{([^{}]*)}/g,
function (a, b) {
var r = o[b];
return typeof r === 'string' || typeof r === 'number' ? r : a;
}
);
};
}
if (!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^\s*(\S*(?:\s+\S+)*)\s*$/, "$1");
};
}
// CommonJS / npm / Ender.JS
module.exports = {
typeOf: typeOf,
isEmpty: isEmpty
};
global.typeOf = global.typeOf || typeOf;
global.isEmpty = global.isEmpty || isEmpty;
}());
},{}],3:[function(require,module,exports){
"use strict";
/**
* removeTrailingSpaces
* Remove the trailing spaces from a string.
*
* @name removeTrailingSpaces
* @function
* @param {String} input The input string.
* @returns {String} The output string.
*/
module.exports = function removeTrailingSpaces(input) {
// TODO If possible, use a regex
return input.split("\n").map(function (x) {
return x.trimRight();
}).join("\n");
};
},{}]},{},[1]);

83
clover/www/js/topics.js Normal file
View File

@@ -0,0 +1,83 @@
const url = 'ws://' + location.hostname + ':9090';
const ros = new ROSLIB.Ros({ url: url });
const params = Object.fromEntries(new URLSearchParams(window.location.search).entries());
ros.on('connection', function () {
document.body.classList.add('connected');
document.body.classList.remove('closed');
init();
});
ros.on('close', function () {
document.body.classList.remove('connected');
document.body.classList.add('closed');
setTimeout(function() {
// reconnect
ros.connect(url);
}, 2000);
});
const title = document.querySelector('h1');
const topicsList = document.querySelector('#topics');
const topicMessage = document.querySelector('#topic-message');
function viewTopicsList() {
title.innerHTML = 'Topics:';
ros.getTopics(function(topics) {
topicsList.innerHTML = topics.topics.map(function(topic, i) {
const type = topics.types[i];
if (type == 'sensor_msgs/Image') {
let url = `${location.protocol}//${location.hostname}:8080/stream_viewer?topic=${topic}`;
return `<li><a href="${url}" class=topic title=${type}>${topic}</a> &#x1F5BC;</li>`;
} else {
return `<li><a href="?topic=${topic}" class=topic title=${type}>${topic}</a></li>`;
}
}).join('');
});
}
let rosdistro;
function viewTopic(topic) {
let index = '<a href=topics.html>Topics</a>';
title.innerHTML = `${index}: ${topic}`;
topicMessage.style.display = 'block';
ros.getTopicType(topic, function(typeStr) {
const [pack, type] = typeStr.split('/');
let href = `https://docs.ros.org/en/${rosdistro}/api/${pack}/html/msg/${type}.html`;
title.innerHTML = `${index}: ${topic} <a id="topic-type" href=${href} target="_blank">${typeStr}</a>`;
});
new ROSLIB.Topic({ ros: ros, name: topic }).subscribe(function(msg) {
document.title = topic;
if (mouseDown) return;
if (msg.header.stamp) {
if (params.date || params.offset) {
let date = new Date(msg.header.stamp.secs * 1e3 + msg.header.stamp.nsecs * 1e-6);
if (params.date) msg.header.date = date.toISOString();
if (params.offset) msg.header.offset = (new Date() - date) * 1e-3;
}
}
topicMessage.innerHTML = yamlStringify(msg); // JSON.stringify(msg, null, 4);
});
}
let mouseDown;
topicMessage.addEventListener('mousedown', function() { mouseDown = true; });
topicMessage.addEventListener('mouseup', function() { mouseDown = false; });
function init() {
if (!params.topic) {
viewTopicsList();
} else {
new ROSLIB.Param({ ros: ros, name: '/rosdistro'}).get(function(value) {
rosdistro = value.trim();
viewTopic(params.topic);
});
}
}

28
clover/www/topics.html Normal file
View File

@@ -0,0 +1,28 @@
<html lang="en">
<head>
<title>ROS topics</title>
<script src="js/roslib.js"></script>
<link rel="icon" href="data:,"> <!-- make chrome don't request icon -->
<script type="module" src="js/topics.js"></script>
<script src="js/json-to-pretty-yaml.js"></script>
<style>
#topics { line-height: 1.2em; }
#topic-view {
display: none;
}
#topic-message {
display: none;
white-space: pre;
font-family: monospace;
}
#topic-type { font-family: monospace; font-size: 0.5em; vertical-align: super; font-weight: normal; }
.topic { font-family: monospace; }
body.closed { background-color: rgb(207, 207, 207); }
</style>
</head>
<body>
<h1>&nbsp;</h1>
<ul id="topics"></ul>
<code id="topic-message">No messages received</code>
</body>
</html>

View File

@@ -73,6 +73,13 @@ catkin_install_python(PROGRAMS src/clover_blocks
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
# TODO: store programs in home directory?
install(DIRECTORY programs
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)
install(DIRECTORY www DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
#############
## Testing ##
#############

View File

@@ -10,7 +10,7 @@ Internal package documentation is given below.
## Frontend
The frontend files are located in [`www`](./www/) subdirectory. The frontend application uses [`roblib.js`](http://wiki.ros.org/roslibjs) library for communicating with backend node and other ROS resources.
The frontend files are located in [`www`](./www/) subdirectory. The frontend application uses [`roslib.js`](http://wiki.ros.org/roslibjs) library for communicating with backend node and other ROS resources.
## `clover_blocks` node
@@ -30,7 +30,8 @@ The frontend files are located in [`www`](./www/) subdirectory. The frontend app
Parameters read by frontend:
* `~navigate_tolerance` (*float*) distance tolerance in meters, used for navigate-like blocks (default: 0.2).
* `~yaw_tolerance` (*float*) yaw angle tolerance in degrees, used in set_yaw block (default: 20).
* `~navigate_global_tolerance` (*float*) distance tolerance for global coordinates navigation (default: 1).
* `~yaw_tolerance` (*float*) yaw angle tolerance in degrees, used in set_yaw block (default: 1).
* `~sleep_time` (*float*) duration of sleep in loop cycles, used for navigate-like blocks (default: 0.2).
* `~confirm_run` (*bool*) enable confirmation to run the program (default: true).

View File

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

View File

@@ -146,6 +146,7 @@ def stop(req):
return {'success': True}
# TODO: find dir in installed package
programs_path = rospy.get_param('~programs_dir', os.path.dirname(os.path.abspath(__file__)) + '/../programs')

View File

@@ -31,6 +31,14 @@ function considerFrameId(e) {
this.getInput('Y').fieldRow[0].setValue('y');
this.getInput('Z').fieldRow[0].setValue('z');
}
if (this.getInput('LAT')) { // block has global coordinates
let global = frameId.startsWith('GLOBAL');
this.getInput('LAT').setVisible(global);
this.getInput('LON').setVisible(global);
this.getInput('X').setVisible(!global);
this.getInput('Y').setVisible(!global);
this.getInput('Z').fieldRow[0].setValue(frameId == 'GLOBAL' ? 'altitude' : 'z');
}
}
if (this.getInput('ID')) { // block has marker id field
this.getInput('ID').setVisible(frameId == 'ARUCO'); // toggle id field
@@ -65,6 +73,9 @@ function updateSetpointBlock(e) {
Blockly.Blocks['navigate'] = {
init: function () {
let navFrameId = frameIds.slice();
navFrameId.push(['global', 'GLOBAL_LOCAL'])
navFrameId.push(['global, WGS 84 alt.', 'GLOBAL'])
this.appendDummyInput()
.appendField("navigate to point");
this.appendValueInput("X")
@@ -73,12 +84,20 @@ Blockly.Blocks['navigate'] = {
this.appendValueInput("Y")
.setCheck("Number")
.appendField("left");
this.appendValueInput("LAT")
.setCheck("Number")
.appendField("latitude")
.setVisible(false);
this.appendValueInput("LON")
.setCheck("Number")
.appendField("longitude")
.setVisible(false)
this.appendValueInput("Z")
.setCheck("Number")
.appendField("up");
this.appendDummyInput()
.appendField("relative to")
.appendField(new Blockly.FieldDropdown(frameIds), "FRAME_ID");
.appendField(new Blockly.FieldDropdown(navFrameId), "FRAME_ID");
this.appendValueInput("ID")
.setCheck("Number")
.appendField("with ID")
@@ -268,7 +287,7 @@ Blockly.Blocks['mode'] = {
.appendField("current flight mode");
this.setOutput(true, "String");
this.setColour(COLOR_STATE);
this.setTooltip("");
this.setTooltip("Returns current flight mode (POSCTL, OFFBOARD, etc).");
this.setHelpUrl(DOCS_URL + '#' + this.type);
}
};
@@ -375,7 +394,7 @@ Blockly.Blocks['take_off'] = {
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(COLOR_FLIGHT);
this.setTooltip("Take off on desired altitude in meters");
this.setTooltip("Take off on desired altitude in meters.");
this.setHelpUrl(DOCS_URL + '#' + this.type);
}
};
@@ -391,7 +410,7 @@ Blockly.Blocks['land'] = {
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(COLOR_FLIGHT);
this.setTooltip("");
this.setTooltip("Land the drone.");
this.setHelpUrl(DOCS_URL + '#' + this.type);
}
};
@@ -400,10 +419,10 @@ Blockly.Blocks['global_position'] = {
init: function () {
this.appendDummyInput()
.appendField("current")
.appendField(new Blockly.FieldDropdown([["latitude", "LATITUDE"], ["longitude", "LONGITUDE"], ["altitude", "ALTITUDE"]]), "NAME");
.appendField(new Blockly.FieldDropdown([["latitude", "LAT"], ["longitude", "LON"], ["altitude", "ALT"]]), "FIELD");
this.setOutput(true, "Number");
this.setColour(230);
this.setTooltip("");
this.setColour(COLOR_STATE);
this.setTooltip("Returns current global position (latitude, longitude, altitude above the WGS 84 ellipsoid).");
this.setHelpUrl(DOCS_URL + '#' + this.type);
}
};

View File

@@ -52,6 +52,8 @@
<value name="X"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
<value name="Y"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
<value name="Z"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
<value name="LAT"><shadow type="math_number"><field name="NUM">47.397503</field></shadow></value>
<value name="LON"><shadow type="math_number"><field name="NUM">8.544945</field></shadow></value>
<value name="SPEED"><shadow type="math_number"><field name="NUM">0.5</field></shadow></value>
<value name="ID"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
</block>
@@ -85,6 +87,7 @@
<value name="ID"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
</block>
<block type="get_attitude"></block>
<block type="global_position"></block>
<block type="distance">
<value name="X"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
<value name="Y"><shadow type="math_number"><field name="NUM">0</field></shadow></value>

View File

@@ -39,7 +39,8 @@ var workspace = Blockly.inject('blockly', {
function readParams() {
return Promise.all([
ros.readParam('navigate_tolerance', true, 0.2),
ros.readParam('yaw_tolerance', true, 20),
ros.readParam('navigate_global_tolerance', true, 1),
ros.readParam('yaw_tolerance', true, 1),
ros.readParam('sleep_time', true, 0.2),
ros.readParam('confirm_run', true, true),
]);
@@ -210,7 +211,7 @@ function loadPrograms() {
updateChanged();
}, function(err) {
document.querySelector('.backend-fail').style.display = 'inline';
alert(`Error loading programs list.\n\nHave you enabled clover_blocks in clover.launch?`);
alert(`Error loading programs list.\n\nHave you enabled 'blocks' in clover.launch?`);
runButton.disabled = true;
})
}

View File

@@ -33,6 +33,18 @@ const NAVIGATE_WAIT = () => `\ndef navigate_wait(x=0, y=0, z=0, speed=0.5, frame
return
rospy.sleep(${params.sleep_time})\n`;
const NAVIGATE_GLOBAL_WAIT = () => `\ndef navigate_global_wait(lat, lon, z, speed=0.5):
res = navigate_global(lat=lat, lon=lon, z=z, yaw=float('inf'), speed=speed)
if not res.success:
raise Exception(res.message)
while not rospy.is_shutdown():
telem = get_telemetry(frame_id='navigate_target')
if math.sqrt(telem.x ** 2 + telem.y ** 2 + telem.z ** 2) < ${params.navigate_global_tolerance}:
return
rospy.sleep(${params.sleep_time})\n`;
const LAND_WAIT = () => `\ndef land_wait():
land()
while get_telemetry().armed:
@@ -68,6 +80,9 @@ function generateROSDefinitions() {
if (rosDefinitions.offboard) {
code += `get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry)\n`;
code += `navigate = rospy.ServiceProxy('navigate', srv.Navigate)\n`;
if (rosDefinitions.navigateGlobal) {
code += `navigate_global = rospy.ServiceProxy('navigate_global', srv.NavigateGlobal)\n`;
}
if (rosDefinitions.setVelocity) {
code += `set_velocity = rospy.ServiceProxy('set_velocity', srv.SetVelocity)\n`;
}
@@ -94,6 +109,10 @@ function generateROSDefinitions() {
Blockly.Python.definitions_['import_math'] = 'import math';
code += NAVIGATE_WAIT();
}
if (rosDefinitions.navigateGlobalWait) {
Blockly.Python.definitions_['import_math'] = 'import math';
code += NAVIGATE_GLOBAL_WAIT();
}
if (rosDefinitions.landWait) {
code += LAND_WAIT();
}
@@ -161,24 +180,48 @@ Blockly.Python.navigate = function(block) {
let x = Blockly.Python.valueToCode(block, 'X', Blockly.Python.ORDER_NONE);
let y = Blockly.Python.valueToCode(block, 'Y', Blockly.Python.ORDER_NONE);
let z = Blockly.Python.valueToCode(block, 'Z', Blockly.Python.ORDER_NONE);
let frameId = buildFrameId(block);
let lat = Blockly.Python.valueToCode(block, 'LAT', Blockly.Python.ORDER_NONE);
let lon = Blockly.Python.valueToCode(block, 'LON', Blockly.Python.ORDER_NONE);
let wait = block.getFieldValue('WAIT') == 'TRUE';
let frameId = block.getFieldValue('FRAME_ID');
let speed = Blockly.Python.valueToCode(block, 'SPEED', Blockly.Python.ORDER_NONE);
let params = [`x=${x}`, `y=${y}`, `z=${z}`, `frame_id=${frameId}`, `speed=${speed}`];
simpleOffboard();
if (block.getFieldValue('WAIT') == 'TRUE') {
rosDefinitions.navigateWait = true;
// global coordinates
if (frameId.startsWith('GLOBAL')) {
rosDefinitions.navigateGlobal = true;
simpleOffboard();
return `navigate_wait(${params.join(', ')})\n`;
if (frameId == 'GLOBAL') {
z = `${z} + get_telemetry().alt - get_telemetry().z`;
}
if (wait) {
rosDefinitions.navigateGlobalWait = true;
simpleOffboard();
return `navigate_global_wait(lat=${lat}, lon=${lon}, z=${z}, speed=${speed})\n`;
} else {
return `navigate_global(lat=${lat}, lon=${lon}, z=${z}, yaw=float('inf'), speed=${speed})\n`;
}
} else {
if (frameId != 'body') {
params.push(`yaw=float('nan')`);
frameId = buildFrameId(block);
let params = [`x=${x}`, `y=${y}`, `z=${z}`, `frame_id=${frameId}`, `speed=${speed}`];
if (wait) {
rosDefinitions.navigateWait = true;
simpleOffboard();
return `navigate_wait(${params.join(', ')})\n`;
} else {
if (frameId != 'body') {
params.push(`yaw=float('nan')`);
}
return `navigate(${params.join(', ')})\n`;
}
return `navigate(${params.join(', ')})\n`;
}
}
@@ -315,6 +358,12 @@ Blockly.Python.get_attitude = function(block) {
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
}
Blockly.Python.global_position = function(block) {
simpleOffboard();
var code = `get_telemetry().${block.getFieldValue('FIELD').toLowerCase()}`;
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
}
Blockly.Python.distance = function(block) {
rosDefinitions.distance = true;
simpleOffboard();
@@ -415,7 +464,7 @@ Blockly.Python.led_count = function(block) {
function pigpio() {
Blockly.Python.definitions_['import_pigpio'] = 'import pigpio';
Blockly.Python.definitions_['init_pigpio'] = 'pi = pigpio.pi()';
Blockly.Python.definitions_['init_pigpio'] = 'pi = pigpio.pi()\nif not pi.connected: raise Exception(\'Cannot connect to pigpiod\')';
}
const GPIO_READ = `\ndef gpio_read(pin):

View File

@@ -14,7 +14,7 @@ You may provide additional parameters for `spawn_drone.launch` as well:
* `rangefinder` (*boolean*, default: *true*) - controls whether the drone will have a downward-facing laser rangefinder attached;
* `led` (*boolean*, default: *true*) - controls whether the drone will have a programmable LED strip (requires plugins from `clover_simulation`);
* `gps` (*boolean*, default: *true*) - controls whether the drone will have a simulated GPS attached (requires plugins from `sitl_gazebo`);
* `maintain_camera_rate` (*boolean*, default: *false*) - slow down the simultion to maintain camera publishing rate (internally changes the camera plugin from `libgazebo_ros_camera.so` to `libthrottling_camera.so` from [`clover_simulation`](../clover_simulation/README.md#throttling-camera-plugin-throttling_camera)).
* `maintain_camera_rate` (*boolean*, default: *false*) - slow down the simulation to maintain camera publishing rate (internally changes the camera plugin from `libgazebo_ros_camera.so` to `libthrottling_camera.so` from [`clover_simulation`](../clover_simulation/README.md#throttling-camera-plugin-throttling_camera)).
For example, in order to spawn a drone without a GPS module, you may use the following command:

View File

@@ -1,7 +1,7 @@
<launch>
<arg name="model" default="$(find clover_description)/urdf/drones/clover4.xacro"/>
<arg name="model" default="$(find clover_description)/urdf/clover/clover4.xacro"/>
<param name="robot_description" command="$(find xacro)/xacro.py $(arg model)"/>
<param name="robot_description" command="xacro $(arg model)"/>
<node name="rviz" pkg="rviz" type="rviz" required="true"/>
</launch>

View File

@@ -1,6 +1,6 @@
<package format="2">
<name>clover_description</name>
<version>0.21.1</version>
<version>0.23.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,5 +1,5 @@
<?xml version="1.0"?>
<robot name="clover_camera" xmlns:xacro="http://ros.org/wiki/xacro">
<robot name="clover" xmlns:xacro="http://ros.org/wiki/xacro">
<xacro:arg name="main_camera" default="true"/>
<xacro:arg name="rangefinder" default="true"/>
@@ -8,10 +8,10 @@
<xacro:arg name="maintain_camera_rate" default="false"/>
<xacro:arg name="use_clover_physics" default="false"/>
<xacro:include filename="$(find clover_description)/urdf/clover/clover4_base.xacro" />
<xacro:include filename="$(find clover_description)/urdf/sensors/rpi_cam.urdf.xacro"/>
<xacro:include filename="$(find clover_description)/urdf/sensors/distance_sensor.urdf.xacro"/>
<xacro:include filename="$(find clover_description)/urdf/leds/led_strip.xacro"/>
<xacro:include filename="clover4_base.xacro" />
<xacro:include filename="../sensors/rpi_cam.urdf.xacro"/>
<xacro:include filename="../sensors/distance_sensor.urdf.xacro"/>
<xacro:include filename="../leds/led_strip.xacro"/>
<!-- Create camera plugin -->
<xacro:if value="$(arg main_camera)">
@@ -36,11 +36,17 @@
</xacro:if>
<xacro:if value="$(arg gps)">
<!-- Instantiate gps plugin. -->
<xacro:gps_plugin_macro
namespace="${namespace}"
gps_noise="true"
/>
<gazebo>
<include>
<uri>model://gps</uri>
<pose>0.1 0 0 0 0 0</pose>
<name>gps0</name>
</include>
<joint name='gps0_joint' type='fixed'>
<child>gps0::link</child>
<parent>base_link</parent>
</joint>
</gazebo>
</xacro:if>
</robot>

View File

@@ -1,40 +1,15 @@
<?xml version="1.0"?>
<robot name="clover" xmlns:xacro="http://ros.org/wiki/xacro">
<!-- Properties that can be assigned at build time as arguments.
Is there a reason not to make all properties arguments?
-->
<xacro:arg name='name' default='iris' />
<xacro:arg name='mavlink_addr' default='INADDR_ANY' />
<xacro:arg name='mavlink_udp_port' default='14560' />
<xacro:arg name='mavlink_tcp_port' default='4560' />
<xacro:arg name='serial_enabled' default='false' />
<xacro:arg name='serial_device' default='/dev/ttyACM0' />
<xacro:arg name='baudrate' default='921600' />
<xacro:arg name='qgc_addr' default='INADDR_ANY' />
<xacro:arg name='qgc_udp_port' default='14550' />
<xacro:arg name='sdk_addr' default='INADDR_ANY' />
<xacro:arg name='sdk_udp_port' default='14540' />
<xacro:arg name='hil_mode' default='false' />
<xacro:arg name='hil_state_level' default='false' />
<xacro:arg name='send_vision_estimation' default='false' />
<xacro:arg name='send_odometry' default='false' />
<xacro:arg name='enable_lockstep' default='true' />
<xacro:arg name='use_tcp' default='true' />
<xacro:arg name='vehicle_is_tailsitter' default='false' />
<xacro:arg name='visual_material' default='DarkGrey' />
<xacro:arg name='enable_mavlink_interface' default='true' />
<xacro:arg name='enable_wind' default='false' />
<!-- The following causes segfault with multiple vehicles if defaults to true!!! -->
<xacro:arg name='enable_ground_truth' default='false' />
<xacro:arg name='enable_logging' default='false' />
<xacro:arg name='log_file' default='iris' />
<xacro:arg name='log_file' default='clover' />
<!-- macros for gazebo plugins, sensors -->
<xacro:include filename="$(find clover_description)/urdf/component_snippets.urdf.xacro" />
<xacro:include filename="../component_snippets.urdf.xacro" />
<!-- Instantiate iris "mechanics" -->
<xacro:include filename="$(find clover_description)/urdf/clover/clover4_physics.xacro" />
<xacro:include filename="clover4_physics.xacro" />
<xacro:if value="$(arg enable_wind)">
<xacro:wind_plugin_macro
@@ -49,126 +24,8 @@
/>
</xacro:if>
<!-- Instantiate magnetometer plugin. -->
<xacro:magnetometer_plugin_macro
namespace="${namespace}"
pub_rate="20"
noise_density="0.0004"
random_walk="0.0000064"
bias_correlation_time="600"
mag_topic="/mag"
>
</xacro:magnetometer_plugin_macro>
<!-- Instantiate barometer plugin. -->
<xacro:barometer_plugin_macro
namespace="${namespace}"
pub_rate="10"
baro_topic="/baro"
>
</xacro:barometer_plugin_macro>
<xacro:if value="$(arg enable_mavlink_interface)">
<!-- Instantiate mavlink telemetry interface. -->
<xacro:mavlink_interface_macro
namespace="${namespace}"
imu_sub_topic="/imu"
gps_sub_topic="/gps"
mag_sub_topic="/mag"
baro_sub_topic="/baro"
mavlink_addr="$(arg mavlink_addr)"
mavlink_udp_port="$(arg mavlink_udp_port)"
mavlink_tcp_port="$(arg mavlink_tcp_port)"
serial_enabled="$(arg serial_enabled)"
serial_device="$(arg serial_device)"
baudrate="$(arg baudrate)"
qgc_addr="$(arg qgc_addr)"
qgc_udp_port="$(arg qgc_udp_port)"
sdk_addr="$(arg sdk_addr)"
sdk_udp_port="$(arg sdk_udp_port)"
hil_mode="$(arg hil_mode)"
hil_state_level="$(arg hil_state_level)"
vehicle_is_tailsitter="$(arg vehicle_is_tailsitter)"
send_vision_estimation="$(arg send_vision_estimation)"
send_odometry="$(arg send_odometry)"
enable_lockstep="$(arg enable_lockstep)"
use_tcp="$(arg use_tcp)"
>
</xacro:mavlink_interface_macro>
</xacro:if>
<!-- Mount an ADIS16448 IMU. -->
<xacro:imu_plugin_macro
namespace="${namespace}"
imu_suffix=""
parent_link="base_link"
imu_topic="/imu"
mass_imu_sensor="0.015"
gyroscope_noise_density="0.0003394"
gyroscopoe_random_walk="0.000038785"
gyroscope_bias_correlation_time="1000.0"
gyroscope_turn_on_bias_sigma="0.0087"
accelerometer_noise_density="0.004"
accelerometer_random_walk="0.006"
accelerometer_bias_correlation_time="300.0"
accelerometer_turn_on_bias_sigma="0.1960"
>
<inertia ixx="0.00001" ixy="0.0" ixz="0.0" iyy="0.00001" iyz="0.0" izz="0.00001" />
<origin xyz="0 0 0" rpy="0 0 0" />
</xacro:imu_plugin_macro>
<xacro:if value="$(arg enable_ground_truth)">
<!-- Mount an IMU providing ground truth. -->
<xacro:imu_plugin_macro
namespace="${namespace}"
imu_suffix="gt"
parent_link="base_link"
imu_topic="ground_truth/imu"
mass_imu_sensor="0.00001"
gyroscope_noise_density="0.0"
gyroscopoe_random_walk="0.0"
gyroscope_bias_correlation_time="1000.0"
gyroscope_turn_on_bias_sigma="0.0"
accelerometer_noise_density="0.0"
accelerometer_random_walk="0.0"
accelerometer_bias_correlation_time="300.0"
accelerometer_turn_on_bias_sigma="0.0"
>
<inertia ixx="0.00001" ixy="0.0" ixz="0.0" iyy="0.00001" iyz="0.0" izz="0.00001" />
<origin xyz="0 0 0" rpy="0 0 0" />
</xacro:imu_plugin_macro>
<!-- Mount a generic odometry sensor providing ground truth. -->
<xacro:odometry_plugin_macro
namespace="${namespace}/ground_truth"
odometry_sensor_suffix="gt"
parent_link="base_link"
pose_topic="pose"
pose_with_covariance_topic="pose_with_covariance"
position_topic="position"
transform_topic="transform"
odometry_topic="odometry"
parent_frame_id="world"
mass_odometry_sensor="0.00001"
measurement_divisor="1"
measurement_delay="0"
unknown_delay="0.0"
noise_normal_position="0 0 0"
noise_normal_quaternion="0 0 0"
noise_normal_linear_velocity="0 0 0"
noise_normal_angular_velocity="0 0 0"
noise_uniform_position="0 0 0"
noise_uniform_quaternion="0 0 0"
noise_uniform_linear_velocity="0 0 0"
noise_uniform_angular_velocity="0 0 0"
enable_odometry_map="false"
odometry_map=""
image_scale=""
>
<inertia ixx="0.00001" ixy="0.0" ixz="0.0" iyy="0.00001" iyz="0.0" izz="0.00001" /> <!-- [kg.m^2] [kg.m^2] [kg.m^2] [kg.m^2] [kg.m^2] [kg.m^2] -->
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
</xacro:odometry_plugin_macro>
</xacro:if>
<!-- Gazebo plugins -->
<xacro:include filename="$(find clover_description)/urdf/clover/clover4_gazebo.xacro" />
<xacro:if value="$(arg enable_logging)">
<!-- Instantiate a logger -->

View File

@@ -0,0 +1,183 @@
<?xml version="1.0"?>
<!-- Reference: https://github.com/PX4/PX4-SITL_gazebo/blob/7505aee97d2d3112fb2bd95198946345c6fa0b07/models/iris/iris.sdf.jinja#L430 -->
<robot xmlns:xacro="http://ros.org/wiki/xacro">
<!-- IMU link -->
<link name="/imu_link">
<inertial>
<inertia ixx="0.00001" ixy="0.0" ixz="0.0" iyy="0.00001" iyz="0.0" izz="0.00001"/>
<mass value="0.015"/>
<!-- [kg] -->
<origin rpy="0 0 0" xyz="0 0 0"/>
</inertial>
</link>
<!-- IMU joint -->
<joint name="/imu_joint" type="fixed">
<origin rpy="0 0 0" xyz="0 0 0"/>
<parent link="base_link"/>
<child link="/imu_link"/>
<!-- <limit upper="0" lower="0" effort="0" velocity="0" /> -->
</joint>
<gazebo reference="/imu_joint">
<disableFixedJointLumping>true</disableFixedJointLumping>
<preserveFixedJoint>true</preserveFixedJoint>
</gazebo>
<gazebo>
<plugin name='groundtruth_plugin' filename='libgazebo_groundtruth_plugin.so'>
<robotNamespace/>
</plugin>
<plugin name='magnetometer_plugin' filename='libgazebo_magnetometer_plugin.so'>
<robotNamespace/>
<pubRate>100</pubRate>
<noiseDensity>0.0004</noiseDensity>
<randomWalk>6.4e-06</randomWalk>
<biasCorrelationTime>600</biasCorrelationTime>
<magTopic>/mag</magTopic>
</plugin>
<plugin name='barometer_plugin' filename='libgazebo_barometer_plugin.so'>
<robotNamespace/>
<pubRate>50</pubRate>
<baroTopic>/baro</baroTopic>
<baroDriftPaPerSec>0</baroDriftPaPerSec>
</plugin>
<plugin name='mavlink_interface' filename='libgazebo_mavlink_interface.so'>
<robotNamespace/>
<imuSubTopic>/imu</imuSubTopic>
<magSubTopic>/mag</magSubTopic>
<baroSubTopic>/baro</baroSubTopic>
<mavlink_addr>INADDR_ANY</mavlink_addr>
<mavlink_tcp_port>4560</mavlink_tcp_port>
<mavlink_udp_port>14560</mavlink_udp_port>
<serialEnabled>false</serialEnabled>
<serialDevice>/dev/ttyACM0</serialDevice>
<baudRate>921600</baudRate>
<qgc_addr>INADDR_ANY</qgc_addr>
<qgc_udp_port>14550</qgc_udp_port>
<sdk_addr>INADDR_ANY</sdk_addr>
<sdk_udp_port>14540</sdk_udp_port>
<hil_mode>false</hil_mode>
<hil_state_level>0</hil_state_level>
<send_vision_estimation>0</send_vision_estimation>
<send_odometry>1</send_odometry>
<enable_lockstep>1</enable_lockstep>
<use_tcp>1</use_tcp>
<motorSpeedCommandPubTopic>/gazebo/command/motor_speed</motorSpeedCommandPubTopic>
<control_channels>
<channel name='rotor1'>
<input_index>0</input_index>
<input_offset>0</input_offset>
<input_scaling>1000</input_scaling>
<zero_position_disarmed>0</zero_position_disarmed>
<zero_position_armed>100</zero_position_armed>
<joint_control_type>velocity</joint_control_type>
</channel>
<channel name='rotor2'>
<input_index>1</input_index>
<input_offset>0</input_offset>
<input_scaling>1000</input_scaling>
<zero_position_disarmed>0</zero_position_disarmed>
<zero_position_armed>100</zero_position_armed>
<joint_control_type>velocity</joint_control_type>
</channel>
<channel name='rotor3'>
<input_index>2</input_index>
<input_offset>0</input_offset>
<input_scaling>1000</input_scaling>
<zero_position_disarmed>0</zero_position_disarmed>
<zero_position_armed>100</zero_position_armed>
<joint_control_type>velocity</joint_control_type>
</channel>
<channel name='rotor4'>
<input_index>3</input_index>
<input_offset>0</input_offset>
<input_scaling>1000</input_scaling>
<zero_position_disarmed>0</zero_position_disarmed>
<zero_position_armed>100</zero_position_armed>
<joint_control_type>velocity</joint_control_type>
</channel>
<channel name='rotor5'>
<input_index>4</input_index>
<input_offset>1</input_offset>
<input_scaling>324.6</input_scaling>
<zero_position_disarmed>0</zero_position_disarmed>
<zero_position_armed>0</zero_position_armed>
<joint_control_type>velocity</joint_control_type>
<joint_control_pid>
<p>0.1</p>
<i>0</i>
<d>0</d>
<iMax>0.0</iMax>
<iMin>0.0</iMin>
<cmdMax>2</cmdMax>
<cmdMin>-2</cmdMin>
</joint_control_pid>
<joint_name>zephyr_delta_wing::propeller_joint</joint_name>
</channel>
<channel name='rotor6'>
<input_index>5</input_index>
<input_offset>0</input_offset>
<input_scaling>0.524</input_scaling>
<zero_position_disarmed>0</zero_position_disarmed>
<zero_position_armed>0</zero_position_armed>
<joint_control_type>position</joint_control_type>
<joint_name>zephyr_delta_wing::flap_left_joint</joint_name>
<joint_control_pid>
<p>10.0</p>
<i>0</i>
<d>0</d>
<iMax>0</iMax>
<iMin>0</iMin>
<cmdMax>20</cmdMax>
<cmdMin>-20</cmdMin>
</joint_control_pid>
</channel>
<channel name='rotor7'>
<input_index>6</input_index>
<input_offset>0</input_offset>
<input_scaling>0.524</input_scaling>
<zero_position_disarmed>0</zero_position_disarmed>
<zero_position_armed>0</zero_position_armed>
<joint_control_type>position</joint_control_type>
<joint_name>zephyr_delta_wing::flap_right_joint</joint_name>
<joint_control_pid>
<p>10.0</p>
<i>0</i>
<d>0</d>
<iMax>0</iMax>
<iMin>0</iMin>
<cmdMax>20</cmdMax>
<cmdMin>-20</cmdMin>
</joint_control_pid>
</channel>
<channel name='rotor8'>
<input_index>7</input_index>
<input_offset>0</input_offset>
<input_scaling>0.524</input_scaling>
<zero_position_disarmed>0</zero_position_disarmed>
<zero_position_armed>0</zero_position_armed>
<joint_control_type>position</joint_control_type>
</channel>
</control_channels>
</plugin>
<static>0</static>
<plugin name='rotors_gazebo_imu_plugin' filename='libgazebo_imu_plugin.so'>
<robotNamespace/>
<linkName>/imu_link</linkName>
<imuTopic>/imu</imuTopic>
<gyroscopeNoiseDensity>0.00018665</gyroscopeNoiseDensity>
<gyroscopeRandomWalk>3.8785e-05</gyroscopeRandomWalk>
<gyroscopeBiasCorrelationTime>1000.0</gyroscopeBiasCorrelationTime>
<gyroscopeTurnOnBiasSigma>0.0087</gyroscopeTurnOnBiasSigma>
<accelerometerNoiseDensity>0.00186</accelerometerNoiseDensity>
<accelerometerRandomWalk>0.006</accelerometerRandomWalk>
<accelerometerBiasCorrelationTime>300.0</accelerometerBiasCorrelationTime>
<accelerometerTurnOnBiasSigma>0.196</accelerometerTurnOnBiasSigma>
</plugin>
</gazebo>
</robot>

View File

@@ -6,7 +6,7 @@
-->
<robot name="iris" xmlns:xacro="http://ros.org/wiki/xacro">
<robot name="clover" xmlns:xacro="http://ros.org/wiki/xacro">
<!-- Properties -->
<xacro:property name="namespace" value="" />
<xacro:property name="rotor_velocity_slowdown_sim" value="10" />
@@ -84,7 +84,7 @@
</xacro:unless>
<!-- Included URDF Files -->
<xacro:include filename="$(find clover_description)/urdf/clover/clover4_macros.xacro" />
<xacro:include filename="clover4_macros.xacro" />
<!-- Instantiate multirotor_base_macro once -->
<xacro:clover4_base_macro

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<robot name="rpi_camera" xmlns:xacro="http://ros.org/wiki/xacro">
<xacro:include filename="$(find clover_description)/urdf/camera_sensor.urdf.xacro"/>
<xacro:include filename="../camera_sensor.urdf.xacro"/>
<xacro:macro name="distance_sensor" params="name:=lidar_vl53l1x parent x:=0 y:=0 z:=0 roll:=0 pitch:=0 yaw:=0 range_min:=0.01 range_max:=4.0 resolution:=0.01 rate:=10">
<joint name="${name}_joint" type="fixed">

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<robot name="pinhole_camera" xmlns:xacro="http://ros.org/wiki/xacro">
<xacro:include filename="$(find clover_description)/urdf/camera_sensor.urdf.xacro"/>
<xacro:include filename="../camera_sensor.urdf.xacro"/>
<xacro:camera_sensor name="main_camera" width="640" height="480" rate="30" horizontal_fov="${120.0*pi/180.0}"/>
</robot>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<robot name="rpi_camera" xmlns:xacro="http://ros.org/wiki/xacro">
<xacro:include filename="$(find clover_description)/urdf/camera_sensor.urdf.xacro"/>
<xacro:include filename="../camera_sensor.urdf.xacro"/>
<xacro:macro name="rpi_cam" params="name:=rpi_cam parent x:=0 y:=0 z:=0 roll:=0 pitch:=0 yaw:=0 width:=320 height:=240 rate:=40 do_throttling:=false">
<joint name="${name}_joint" type="fixed">

View File

@@ -55,7 +55,7 @@ A visual Gazebo plugin is used for the LED strip. An example of the plugin usage
The plugin accepts the following parameters during instantiation:
* `robotNamespace` (*string*, default: "") - a ROS namespace for the plugin;
* `ledCount` (*integer*, required) - total numer of LEDs in a strip.
* `ledCount` (*integer*, required) - total number of LEDs in a strip.
The plugin will provide the following service:

View File

@@ -0,0 +1,36 @@
#!/bin/sh
#
# @name COEX Clover Simulator
#
# @type Quadrotor X
#
. ${R}etc/init.d-posix/airframes/10016_iris # base on iris
param set ATT_W_EXT_HDG 0.5
param set ATT_EXT_HDG_M 1
param set COM_DISARM_LAND 1.0
param set LPE_FLW_SCALE 1.0
param set LPE_FLW_R 0.2
param set LPE_FLW_RR 0.0
param set LPE_FLW_QMIN 10
param set LPE_VIS_DELAY 0.0
param set LPE_VIS_Z 0.1
param set LPE_FUSION 86
param set SENS_FLOW_ROT 0
param set SENS_FLOW_MINHGT 0.01
param set SENS_FLOW_MAXHGT 4.0
param set SENS_FLOW_MAXR 10.0
param set EKF2_AID_MASK 27 # gps + flow + vis pos + vis yaw
param set EKF2_OF_DELAY 0
param set EKF2_OF_QMIN 10
param set EKF2_OF_N_MIN 0.05
param set EKF2_OF_N_MAX 0.2
param set EKF2_HGT_MODE 2
param set EKF2_EVA_NOISE 0.1
param set EKF2_EVP_NOISE 0.1
param set EKF2_EV_DELAY 0

View File

@@ -4,16 +4,18 @@
<arg name="est" default="ekf2"/> <!-- PX4 estimator: lpe, ekf2 -->
<arg name="vehicle" default="clover"/> <!-- PX4 vehicle configuration: clover, clover_vpe -->
<arg name="main_camera" default="true"/> <!-- Simulated vision position estimation camera (optical flow, ArUco) -->
<arg name="maintain_camera_rate" default="false"/> <!-- Slow simulation down to maintain camera rate -->
<arg name="rangefinder" default="true"/> <!-- Simulated downward-facing rangefinder, vl53l1x-like -->
<arg name="led" default="true"/> <!-- Simulated LED strip, ws281x-like -->
<arg name="gps" default="false"/> <!--Simulated GPS module -->
<arg name="use_clover_physics" default="false"/> <!-- Use inertial parameters from CAD models -->
<arg name="gui" default="true"/> <!-- Run Gazebo with GUI -->
<!-- Gazebo instance -->
<include file="$(find gazebo_ros)/launch/empty_world.launch" if="$(eval type == 'gazebo')">
<!-- Workaround for crashes in VMware -->
<env name="SVGA_VGPU10" value="0"/>
<arg name="gui" value="true"/>
<arg name="gui" value="$(arg gui)"/>
<arg name="world_name" value="$(find clover_simulation)/resources/worlds/clover_aruco.world"/>
<arg name="verbose" value="true"/>
</include>
@@ -27,13 +29,16 @@
<!-- Clover model -->
<include file="$(find clover_description)/launch/spawn_drone.launch" if="$(eval type == 'gazebo')">
<arg name="main_camera" value="$(arg main_camera)"/>
<arg name="maintain_camera_rate" value="$(arg maintain_camera_rate)"/>
<arg name="rangefinder" value="$(arg rangefinder)"/>
<arg name="led" value="$(arg led)"/>
<arg name="gps" value="$(arg gps)"/>
<arg name="use_clover_physics" value="$(arg use_clover_physics)"/>
</include>
<node name="jmavsim" pkg="px4" type="jmavsim_run.sh" output="screen" if="$(eval type == 'jmavsim')"/>
<node name="jmavsim" pkg="px4" type="jmavsim_run.sh" output="screen" if="$(eval type == 'jmavsim')">
<env name="HEADLESS" value="1" if="$(eval not gui)"/>
</node>
<param name="use_sim_time" value="false" if="$(eval type == 'jmavsim')"/>
@@ -43,10 +48,10 @@
<arg name="fcu_conn" value="sitl"/>
<arg name="fcu_ip" value="127.0.0.1"/>
<arg name="gcs_bridge" value=""/>
<arg name="rc" default="false"/>
<arg name="web_video_server" default="false" if="$(eval type == 'jmavsim')"/>
<arg name="main_camera" default="false" if="$(eval type == 'jmavsim')"/>
<arg name="aruco" default="false" if="$(eval type == 'jmavsim')"/>
<arg name="optical_flow" default="false" if="$(eval type == 'jmavsim')"/>
<arg name="led" default="false" if="$(eval type == 'jmavsim')"/>
</include>
</launch>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0"?>
<sdf version="1.5">
<model name="aruco_100">
<static>true</static>
<link name="marker_100_link">
<pose>0 0 1e-3 0 0 1.5707963267948966</pose>
<visual name="visual_marker_100">
<cast_shadows>false</cast_shadows>
<geometry>
<box>
<size>0.22 0.22 1e-3</size>
</box>
</geometry>
<material>
<script>
<uri>model://aruco_100/materials/scripts</uri>
<uri>model://aruco_100/materials/textures</uri>
<name>aruco/marker_100</name>
</script>
</material>
</visual>
</link>
</model>
</sdf>

View File

@@ -0,0 +1,15 @@
material aruco/marker_100
{
technique
{
pass
{
texture_unit
{
texture aruco_marker_100.png
filtering none
scale 1.0 1.0
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 B

View File

@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<model>
<name>ArUco Marker 100</name>
<version>1.0</version>
<sdf version="1.5">marker_100.sdf</sdf>
<author>
<name>Marker Generator script</name>
<email>marker@generator.sh</email>
</author>
<description>
ArUco marker #100
</description>
</model>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0"?>
<sdf version="1.5">
<model name="aruco_101">
<static>true</static>
<link name="marker_101_link">
<pose>0 0 1e-3 0 0 1.5707963267948966</pose>
<visual name="visual_marker_101">
<cast_shadows>false</cast_shadows>
<geometry>
<box>
<size>0.44 0.44 1e-3</size>
</box>
</geometry>
<material>
<script>
<uri>model://aruco_101/materials/scripts</uri>
<uri>model://aruco_101/materials/textures</uri>
<name>aruco/marker_101</name>
</script>
</material>
</visual>
</link>
</model>
</sdf>

View File

@@ -0,0 +1,15 @@
material aruco/marker_101
{
technique
{
pass
{
texture_unit
{
texture aruco_marker_101.png
filtering none
scale 1.0 1.0
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 B

View File

@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<model>
<name>ArUco Marker 101</name>
<version>1.0</version>
<sdf version="1.5">marker_101.sdf</sdf>
<author>
<name>Marker Generator script</name>
<email>marker@generator.sh</email>
</author>
<description>
ArUco marker #101
</description>
</model>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0"?>
<sdf version="1.5">
<model name="aruco_102">
<static>true</static>
<link name="marker_102_link">
<pose>0 0 1e-3 0 0 1.5707963267948966</pose>
<visual name="visual_marker_102">
<cast_shadows>false</cast_shadows>
<geometry>
<box>
<size>0.44 0.44 1e-3</size>
</box>
</geometry>
<material>
<script>
<uri>model://aruco_102/materials/scripts</uri>
<uri>model://aruco_102/materials/textures</uri>
<name>aruco/marker_102</name>
</script>
</material>
</visual>
</link>
</model>
</sdf>

View File

@@ -0,0 +1,15 @@
material aruco/marker_102
{
technique
{
pass
{
texture_unit
{
texture aruco_marker_102.png
filtering none
scale 1.0 1.0
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 B

View File

@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<model>
<name>ArUco Marker 102</name>
<version>1.0</version>
<sdf version="1.5">marker_102.sdf</sdf>
<author>
<name>Marker Generator script</name>
<email>marker@generator.sh</email>
</author>
<description>
ArUco marker #102
</description>
</model>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0"?>
<sdf version="1.5">
<model name="camera">
<static>true</static>
<link name='camera_link'>
<pose>0 0 0 0 0 0</pose>
<sensor name='camera' type='camera'>
<camera>
<horizontal_fov>1.8</horizontal_fov>
<image>
<format>B8G8R8</format>
<width>640</width>
<height>480</height>
</image>
<clip>
<near>0.02</near>
<far>300</far>
</clip>
</camera>
<always_on>1</always_on>
<update_rate>30</update_rate>
<visualize>1</visualize>
<plugin name='camera_plugin' filename='libgazebo_ros_camera.so'>
<alwaysOn>1</alwaysOn>
<imageTopicName>image_raw</imageTopicName>
<cameraTopicName>camera_info</cameraTopicName>
<cameraName>camera</cameraName>
<frameName>/camera</frameName>
</plugin>
</sensor>
</link>
</model>
</sdf>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<model>
<name>Camera</name>
<version>1.0</version>
<sdf version="1.5">camera.sdf</sdf>
<author>
<name>Oleg Kalachev</name>
<email>okalachev@gmail.com</email>
</author>
<description>
External camera
</description>
</model>

View File

@@ -1,6 +1,6 @@
<package format="2">
<name>clover_simulation</name>
<version>0.21.1</version>
<version>0.23.0</version>
<description>The clover_simulation package provides worlds and launch files for Gazebo.</description>
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>

View File

@@ -0,0 +1,8 @@
#!/usr/bin/env bash
# script for running gzweb
# usage: ./gzweb [<port>]
export NVM_DIR=$HOME/.nvm
source $NVM_DIR/nvm.sh
npm start --prefix $HOME/gzweb -p ${1-8080}

View File

@@ -41,4 +41,4 @@ def save_world(world, file):
'''
Save the world to file-like object
'''
return world.write(file)
return world.write(file, encoding='unicode')

Binary file not shown.

Before

Width:  |  Height:  |  Size: 695 KiB

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Слой_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 566.93 226.77" style="enable-background:new 0 0 566.93 226.77;" xml:space="preserve">
<style type="text/css">
.st0{fill:#3679BC;}
.st1{fill:#27B4AA;}
</style>
<g>
<polygon class="st0" points="356.5,37.35 287.97,37.35 287.97,56.03 312.9,56.03 312.9,105.92 331.58,105.92 331.58,56.03
356.5,56.03 "/>
<polygon class="st0" points="434.54,56.03 434.54,37.35 366,37.35 366,37.39 365.97,37.39 365.97,105.92 366,105.92 384.65,105.92
434.54,105.92 434.54,87.24 384.65,87.24 384.65,80.99 415.89,80.99 415.89,62.31 384.65,62.31 384.65,56.03 "/>
<polygon class="st0" points="356.55,134.06 356.52,120.82 343.35,120.86 318.39,145.81 306.6,145.81 306.6,120.86 287.92,120.86
287.92,189.39 306.6,189.39 306.6,164.49 318.45,164.49 343.35,189.39 356.52,189.42 356.55,176.18 335.5,155.12 "/>
<path class="st0" d="M88.62,56.3h34.3V37.35h-34.3c-18.94,0-34.3,15.36-34.3,34.3s15.36,34.3,34.3,34.3h34.3V87h-34.3
c-8.48,0-15.35-6.87-15.35-15.35C73.28,63.17,80.15,56.3,88.62,56.3z"/>
<path class="st0" d="M181.76,155.12v34.3h18.95v-34.3c0-18.94-15.36-34.3-34.3-34.3s-34.3,15.36-34.3,34.3v34.3h18.95v-34.3
c0-8.48,6.87-15.35,15.35-15.35C174.89,139.78,181.76,146.65,181.76,155.12z"/>
<path class="st0" d="M244.21,139.78h34.3v-18.95h-34.3c-18.94,0-34.3,15.36-34.3,34.3s15.36,34.3,34.3,34.3h34.3v-18.95h-34.3
c-8.48,0-15.35-6.87-15.35-15.35C228.86,146.65,235.73,139.78,244.21,139.78z"/>
<polygon class="st0" points="104.15,120.82 104.15,145.55 73.46,145.55 73.46,120.82 54.32,120.82 54.32,189.42 73.46,189.42
73.46,164.69 104.15,164.69 104.15,189.42 122.92,189.42 122.92,120.82 "/>
<path class="st1" d="M453.24,145.34c-0.23-13.68-11.67-24.52-25.35-24.52h-24.53v18.68h24.77c3.37,0,6.27,2.59,6.43,5.96
c0.17,3.6-2.7,6.56-6.25,6.56h-6.26c-10.32,0-18.68,8.36-18.68,18.68v0v18.65h49.88v-18.65H428.3
C442.22,170.71,453.47,159.31,453.24,145.34z"/>
<path class="st1" d="M512.59,145.34c-0.23-13.68-11.67-24.52-25.35-24.52h-24.53v18.68h24.77c3.37,0,6.27,2.59,6.43,5.96
c0.17,3.6-2.7,6.56-6.25,6.56h-6.26c-10.32,0-18.68,8.36-18.68,18.68v0v18.65h49.88v-18.65h-24.94
C501.57,170.71,512.82,159.31,512.59,145.34z"/>
<path class="st0" d="M200.29,66.27c-2.97-18.71-20.55-31.47-39.25-28.49c-18.71,2.97-31.47,20.55-28.49,39.25
c2.97,18.71,20.55,31.47,39.25,28.49C190.5,102.56,203.26,84.98,200.29,66.27z M166.42,87c-8.48,0-15.35-6.87-15.35-15.35
c0-8.48,6.87-15.35,15.35-15.35c8.48,0,15.35,6.87,15.35,15.35C181.76,80.13,174.89,87,166.42,87z"/>
<rect x="375.22" y="120.82" transform="matrix(-1 -1.224647e-16 1.224647e-16 -1 769.1138 266.6382)" class="st1" width="18.68" height="24.99"/>
<path class="st0" d="M253.7,37.39v-0.04h-33.19v0.04h-10.61v68.53h18.68V87h25.11c13.7,0,24.81-11.11,24.81-24.81
C278.51,48.49,267.4,37.39,253.7,37.39z M250.69,71.46h-22.1V53.17h22.1v0.01c5.05,0,9.14,4.09,9.14,9.14
C259.83,67.37,255.74,71.46,250.69,71.46z"/>
<path class="st0" d="M512.61,62.19c0-13.7-11.11-24.81-24.81-24.81v-0.04h-33.19v0.01h-10.61v68.6h18.68V87h17.79l18.92,18.92
l13.17,0.03l0.04-13.24l-10.36-10.36C508.52,77.85,512.61,70.5,512.61,62.19z M484.79,71.46
C484.79,71.46,484.79,71.46,484.79,71.46h-22.1V53.17h22.1v0.01c0,0,0,0,0,0c5.05,0,9.14,4.09,9.14,9.14
C493.92,67.37,489.83,71.46,484.79,71.46z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
docs/assets/dhcp.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

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