Compare commits

...

1098 Commits

Author SHA1 Message Date
Oleg Kalachev
bb772d9ce0 vpe_publisher: allow taking pose data from topic 2019-10-01 11:30:36 +02:00
Oleg Kalachev
a6bdedbfc1 selfcheck.py: fix velocity check 2019-09-27 00:39:24 +03:00
Oleg Kalachev
68fc2fee1a vpe_publisher: quick fix 2019-09-26 00:44:03 +03:00
Oleg Kalachev
a4fa53ba1b vpe_publisher: implement ~reset service 2019-09-25 23:59:48 +03:00
Oleg Kalachev
3ba4ebf3a2 gitbook: make main page language select 2019-09-17 03:15:10 +03:00
Oleg Kalachev
5c2441e2e8 image: add importing SetLedEffect in tests 2019-09-16 20:24:13 +03:00
Oleg Kalachev
45356b19a9 docs: add note about flying relative to a marker in the map 2019-09-15 17:53:15 +03:00
Alexey Rogachevskiy
e1a11bd70a aruco_pose: Allow rgb8 map images 2019-09-11 23:10:36 +03:00
Alexey Rogachevskiy
035384cd6f builder: Make tests run again 2019-09-11 21:56:10 +03:00
Oleg Kalachev
16a2ecef2e gitbook: fix 2019-09-11 20:59:20 +03:00
Tenessinum
727fde82a8 docs: change size of iframes in Big Challenges article (#177) 2019-09-10 17:28:11 +03:00
Oleg Kalachev
fc1df980ff docs: fix link to the latest firmware 2019-09-10 16:25:39 +03:00
Alexey Rogachevskiy
2e7bcde38e docs: Revise simple_offboard translation (en) 2019-09-10 14:23:06 +03:00
Alexey Rogachevskiy
5a8ce0cf0c docs/en: Remove non-English words 2019-09-09 22:41:18 +03:00
Oleg Kalachev
e78c57a734 Change Clever documentation domain name 2019-09-09 16:22:48 +03:00
Oleg Kalachev
9581cc6496 Create CNAME 2019-09-09 16:13:19 +03:00
Oleg Kalachev
eddec45259 gitbook: make redirect pages blank 2019-09-08 00:45:30 +03:00
Alamoris
2e903b45a3 aruco_pose: improve processing of axis visualization in aruco_map/image (#167)
* aruco_pose: improved processing of axis visualization in the topic /aruco_map/image

* aruco_pose: reworked method for drawing axis arrow

* aruco_pose: fix indentation error

* Fix style
2019-09-06 18:25:49 +03:00
Alexey Rogachevskiy
50739a3ea8 clever.launch: change log formatting (#175)
* clever.launch: Add node name to output format

* selfcheck: Use new log format

* aruco_pose, clever: Remove node names from messages

* aruco_pose, clever: Use nodelet-aware rosconsole macros

* clever.launch: Use logger name instead of node name

* clever.launch: change rosconsole format a little
2019-09-06 17:47:31 +03:00
Oleg Kalachev
fb5f8e5078 Merge pull request #174 from sfalexrog/line-buffering
clever.service: Add line buffering
2019-09-05 22:19:15 +03:00
Oleg Kalachev
ba9d968b44 simple_offboard: make map a reference frame navigate_target 2019-09-05 22:10:21 +03:00
Oleg Kalachev
0a4b398c90 simple_offboard: make navigate_target static transform 2019-09-05 22:10:03 +03:00
Oleg Kalachev
86938a1afe simple_offboard: lower nav_from_sp_flag only on success service calls 2019-09-05 21:55:43 +03:00
sfalexrog
1af20c0869 clever.service: Add line buffering 2019-09-05 21:03:52 +03:00
Oleg Kalachev
fda030e539 clever.service: pipe all errors to /tmp/clever.err (#176)
* clever.service: pipe all errors to /tmp/clever.err

* clever.service: run with Bash

* selfcheck: parse node errors and group them
2019-09-05 20:45:00 +03:00
Oleg Kalachev
91e1d3c8f3 selfcheck: add a note 2019-09-05 18:25:58 +03:00
Oleg Kalachev
5071139d09 selfcheck.py: check clever.service failed to run 2019-09-05 18:03:59 +03:00
Oleg Kalachev
d2c201dba4 led: set the default brightness to 100 2019-09-05 17:54:00 +03:00
Oleg Kalachev
f9620b241d Merge branch 'nav_from_sp' 2019-09-04 19:35:48 +03:00
Oleg Kalachev
291b4a17e4 led: restore filling if leds colors changed 2019-09-04 19:34:22 +03:00
Oleg Kalachev
8696ad14a5 aruco_pose: don’t publish transforms of markers in the map 2019-09-04 19:15:00 +03:00
Oleg Kalachev
4b0605fcbb aruco_map: add markers topic 2019-09-04 12:22:34 +03:00
Oleg Kalachev
6b56e45ef9 gitbook: change localized-footer plugin version 2019-09-03 01:14:11 +03:00
Oleg Kalachev
506568ebd8 gitbook: fix markdownlint in footers 2019-09-03 01:08:11 +03:00
Oleg Kalachev
2b671d9c18 gitbook: fix localized-footer 2019-09-03 00:58:49 +03:00
Oleg Kalachev
a1ada2d55c docs: change license to CC BY-NC-SA 2019-09-03 00:48:55 +03:00
MariaS2000
c711446e49 docs: control of the drone by the power of thought (#158) 2019-09-03 00:43:57 +03:00
Oleg Kalachev
588ccaf314 Merge pull request #172 from CopterExpress/selfcheck_roslaunch
Show roslaunch errors in selfcheck
2019-09-02 20:12:49 +03:00
sfalexrog
d8128bfebc builder: repo.coex.space -> deb.coex.tech 2019-09-02 14:07:48 +03:00
sfalexrog
1be06b8cee init_rpi: Use lower case hostname 2019-09-01 20:14:42 +03:00
xsestech
1533092d67 docs: fixed mistake in auto_setup article (en) (#171) 2019-09-01 14:31:20 +03:00
xsestech
100f697691 docs: fixed mistake in auto_setup article (ru) (#171) 2019-09-01 14:30:51 +03:00
Oleg Kalachev
2d4e835089 gitbook: redirect from power.html 2019-08-31 22:29:51 +03:00
Oleg Kalachev
cd63afe268 clever.service: remove service auto-restart 2019-08-31 22:20:05 +03:00
Oleg Kalachev
0f27928631 selfcheck.py: show roslaunch errors 2019-08-31 22:19:14 +03:00
Hany Hamed
4acf45e97d docs: add a placeholder for human pose estimation project with the demo videos (ru) (#170)
* Add a placeholder for human pose estimation project with the demo videos in docs/ru

* Solve the errors of travis because of markdownlint
2019-08-30 20:30:55 +03:00
Oleg Kalachev
67392a8f1e selfcheck.py: add battery voltage checks 2019-08-29 23:59:26 +03:00
Oleg Kalachev
059f932951 simple_offboard: add nav_from_sp parameter 2019-08-29 23:34:17 +03:00
Oleg Kalachev
f9b1a82b5e Add LED strip support layer (#168)
Co-authored-by: sfalexrog <sfalexrog@gmail.com>
2019-08-29 22:17:49 +03:00
Oleg Kalachev
1773a1ccae Use rangefinder/range for rangefinder data (remapped in mavros side) 2019-08-29 17:05:34 +03:00
Oleg Kalachev
e254472f3d gitbook: fix generating link to the latest firmware 2019-08-29 14:46:22 +03:00
Oleg Kalachev
fc89f80388 docs: remove unnecessary executable permission 2019-08-28 06:38:20 +03:00
Alamoris
e710c7fdb1 Merge pull request #166 from Alamoris/divider_constant
Divider constant
2019-08-26 14:52:27 +03:00
Alamoris
663a302ebd docs: fix md mistake 2019-08-26 14:28:16 +03:00
Alamoris
01d382331a docs: add voltage divider constant in en article 2019-08-26 14:17:24 +03:00
Alamoris
5c973f044b Add voltage divider constant 2019-08-26 13:06:46 +03:00
timkondratiev
a2f1ad2bcb docs: add English version of auto_setup article (#165)
* docs: add english version of auto_setup article

* docs: add auto setup article to summary

* docs: fix auto setup article

* docs: fix error in auto_setup.md

* docs: add trailing newline to auto config

* docs: finish translating auto setup

* docs: fix errors auto setup

* docs: fixed errors in auto setup article
2019-08-24 01:42:34 +03:00
sfalexrog
892dc8dba2 builder: Update kernel version 2019-08-23 10:40:32 +03:00
timkondratiev
b5f4ebde66 docs: add step-by-step guide on how to fly autonomously (ru) (#164)
Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2019-08-23 04:54:03 +03:00
Oleg Kalachev
86d84e5c0a selfcheck.py: make selfcheck work if there is no systemd module 2019-08-19 19:22:47 +03:00
Oleg Kalachev
cd34cc077b Bring back docs checks 2019-08-19 19:18:47 +03:00
sfalexrog
61e9239241 docs: Update safety article (en), minor fixes (ru) 2019-08-19 16:22:53 +03:00
sfalexrog
5d1f38888c docs/assemble_4: Address found issues (en/ru) 2019-08-19 14:05:00 +03:00
Oleg Kalachev
b8a27fcc98 gitbook: minor style fix 2019-08-19 04:27:08 +03:00
Oleg Kalachev
c6182bc9ac docs: add flight controller example in glossary 2019-08-19 04:07:57 +03:00
Oleg Kalachev
8253fc3b1a docs: fix in english glossary 2019-08-19 04:07:43 +03:00
Oleg Kalachev
8f5017532f docs: typos 2019-08-19 04:05:43 +03:00
Oleg Kalachev
d6722fb84a docs: fix modes article 2019-08-19 03:43:08 +03:00
sfalexrog
7f642da02f docs: Minor fixes, update glossary (en) 2019-08-18 21:27:34 +03:00
Oleg Kalachev
6cf36d5a0a docs: add imu glossary definition 2019-08-17 20:19:46 +03:00
Oleg Kalachev
56e42a1cef docs: add some glossary definitions 2019-08-17 20:17:17 +03:00
Oleg Kalachev
35bf315227 selfcheck.py: check CBRK_USB_CHK parameter 2019-08-17 20:17:17 +03:00
Oleg Kalachev
2859f7c68d docs: remove unused assets 2019-08-17 10:19:09 +03:00
Oleg Kalachev
783937c5e8 docs: translate image article, various fixes 2019-08-17 10:16:56 +03:00
Oleg Kalachev
d73e1dd72a readme: fix 2019-08-17 10:04:23 +03:00
Oleg Kalachev
dd7946a9bb docs: re-arrange the order of assembly articles 2019-08-17 10:01:42 +03:00
Alamoris
81d0282d11 Reworked article about pid tuning (#143)
Co-authored-by: Oleg Kalachev <okalachev@gmail.com>
2019-08-17 10:00:52 +03:00
Oleg Kalachev
8c5309c753 travis: remove unneeded deploy 2019-08-17 09:30:04 +03:00
Oleg Kalachev
2b50b9bd8c Rework gitbook, add Clever 4 instruction (#163)
Co-authored-by: sfalexrog <sfalexrog@gmail.com>

* Rework the structure.
* Add Clever 4 assembling instruction.
* Rework setup articles.
* Many additional changes.
2019-08-17 09:23:46 +03:00
sfalexrog
a4ba3a6030 builder: add nanorc for launch files (#162)
* builder: Add nanorc for launch files

* nanorc: Change top comment
2019-08-13 20:28:21 +03:00
sfalexrog
5808647971 Use GitHub to generate changelogs (#160)
* gen_changelog: Allow GitHub to generate changelog for us

* Change format for auto changelog
2019-08-13 19:10:34 +03:00
sfalexrog
e72db1775f Docs: LED english article update (and minor related fixes) (#159)
* docs: LED article translation

* docs: Translate parameters, set default pin to 21

* docs: Update library link

* docs: Update note about pigpiod
2019-08-13 19:06:07 +03:00
Arthur Golubtsov
04ca1f2631 docs: Remove unused image form assets 2019-08-13 18:07:06 +03:00
Oleg Kalachev
a926c0b93d gitbook: add automated checking for unused assets, remove unused assets 2019-08-11 18:19:19 +03:00
Oleg Kalachev
fb3d8c9747 gitbook: add language-picker 2019-08-11 06:30:49 +03:00
mmkuznecov
f64b9f5225 docs: changes in face recognition and object counting articles (#157)
* Update object_counting.md

* Add files via upload

* Update face_recognition.md
2019-08-08 22:41:08 +03:00
Oleg Kalachev
9614216bb3 gitbook: fix lists css 2019-08-08 21:40:56 +03:00
sfalexrog
8c6a9d010b builder: Update kernel version 2019-08-07 23:56:42 +03:00
Oleg Kalachev
4c4b0ba6fa gitbook: add css file, adjust lists style 2019-08-07 23:17:16 +03:00
Oleg Kalachev
fc1a12f13e Repalce readme’s photo 2019-08-07 19:34:18 +03:00
Oleg Kalachev
8c50ca3a9e readme: fix roscore.service path 2019-08-06 22:26:40 +03:00
mmkuznecov
76ab7f46a6 docs: update object_counting.md (#155) 2019-08-06 21:39:15 +03:00
Oleg Kalachev
e3d0837403 docs: change recommended LPE_FLW_R to 0.2 2019-08-06 20:10:29 +03:00
Arthur Golubtsov
84c81b8ad8 docs: Small fix in contributing article 2019-08-06 12:36:10 +03:00
sfalexrog
17dbc5b4fb docs: Add note about pigpiod and LED strip 2019-08-06 10:40:11 +03:00
Oleg Kalachev
95784b11be docs: small fix 2019-08-04 22:18:25 +03:00
VeneraDal
4d59748dea docs: update trainer mode article 2019-08-04 22:16:40 +03:00
mmkuznecov
7238eed4ef docs: update object counting article (#153)
* Add files via upload

* Update object_counting.md
2019-08-04 20:58:59 +03:00
Oleg Kalachev
0acbf61c8f docs: fix ROS_HOSTNAME value 2019-08-04 18:36:19 +03:00
Oleg Kalachev
c5bcb165cc builder: fix ROS_HOSTNAME value in .bashrc 2019-08-04 18:34:05 +03:00
Oleg Kalachev
1538ec33f7 Rework assigning hostname and service files (#150)
* Rework assigning hostname and service files

* docs: small fix in hostname article

* Correct path to setup.bash in clever.service

* docs: correct ip in hostname article

* init_rpi: put normal and .local hostname on one line in hosts

* docs: add English version of hostname article

* clever.service: use sh instead of bash

* docs: Spellcheck english version, add note about hostname vs SSID

* clever.service: return roscore requirement back
2019-08-04 00:40:27 +03:00
Oleg Kalachev
05af14a792 Add editorconfig-checker (#149)
* Add editorconfig-checker

* Editorconfig-check fix

* Remove temporal cat
2019-08-01 23:27:04 +03:00
Arthur Golubtsov
9873c24cae docs: add information about writing new article (#148)
* docs: Add information about writing new article

* docs: Add illustrations for pull request

* docs: Trying to make markdown linter happy

* docs: Trying to make markdown linter happy 2

* docs: Trying to make markdown linter happy 3

* docs: Finall corrections of article about writing new article

* docs: Finall corrections of article about writing new article 2
2019-08-01 19:00:05 +03:00
Tenessinum
8956b3459e docs: add article about "Big Challenges 2019" (#147)
* Added article about "Big Challenges 2019"

* Fixed md errors

* Changed article name

* Update bigchallenges.md

* Update bigchallenges.md

* Added markdownlint-disable

* Added videos to Aerotaxi article
2019-08-01 17:39:02 +03:00
sfalexrog
a236574642 docs: Add links to eLinux 2019-08-01 15:43:02 +03:00
sfalexrog
45f637e9a8 docs: GPIO proofreading 2019-08-01 15:43:02 +03:00
Oleg Kalachev
f05e0cc33e docs: add English version of GPIO article 2019-08-01 15:43:02 +03:00
Oleg Kalachev
9b1d58143e aruco.launch: define image_axis parameter 2019-08-01 04:07:31 +03:00
Oleg Kalachev
60fd4f9c0f aruco_map: add image_axis parameter for drawing axis on ~image topic 2019-08-01 04:06:18 +03:00
Oleg Kalachev
47bc3b90da simple_offboard: use velocity_body topic (for supporting mavros > 0.29) 2019-07-31 20:20:12 +03:00
Oleg Kalachev
991d7c9798 docs: add note about setting aruco to true in clever.launch 2019-07-31 19:03:31 +03:00
sfalexrog
d9aa62e2dd clever: Move udev rule file, add note to readme 2019-07-31 17:19:41 +03:00
timkondratiev
c590302130 docs: edit "setup" article (#145)
* Added a new parameter setup

Empty Voltage (per cell) - 3.50V.

* Added a new parameter setup

Empty Voltage (per cell) - 3.50V.

* Deleted outdated screenshot

* Added updated screenshot

* deleted wrong screenshot

* Added updated screenshot
2019-07-31 17:04:41 +03:00
sfalexrog
32cdce47c4 simple_offboard: Use string literal as format string 2019-07-31 13:30:00 +03:00
Oleg Kalachev
99e6518c90 docs: check images size is not larger than 600K 2019-07-31 03:11:43 +03:00
Alamoris
f953b1bbd9 Changed the condition of the roll flip 2019-07-30 19:38:13 +03:00
Oleg Kalachev
f5da6bc11c docs: add more proper names to markdownlint 2019-07-30 18:03:42 +03:00
Hany Hamed
b25a58c047 docs: fix EOL sequence 2019-07-30 16:15:45 +03:00
Oleg Kalachev
977c69908e docs: small fix 2019-07-30 04:11:00 +03:00
Oleg Kalachev
22940e266f docs: little fix 2019-07-30 04:05:46 +03:00
Oleg Kalachev
df134841c3 docs: fix article name 2019-07-30 03:57:06 +03:00
Oleg Kalachev
d94d3cc88d Merge pull request #142 from CopterExpress/robocross-2019-article
[WIP] docs: add article about robocross-2019
2019-07-30 03:52:51 +03:00
Oleg Kalachev
3db1f653bc docs: add article about robocross-2019 2019-07-30 03:50:44 +03:00
Oleg Kalachev
4cf825e004 simple_offboard: obtain vehicle pose using lookupTransform 2019-07-30 00:26:43 +03:00
Oleg Kalachev
6ea693eb85 docs: while True -> while not rospy.is_shutdown() in snippets 2019-07-29 22:48:49 +03:00
Hany Hamed
76a358e3bb docs: adding the documentation of human pose estimation drone control project in the English docs of Git book (#141)
* Add Human pose estimation drone control project to the documentation in Gitbook

* Update human_pose_estimation_drone_control.md

* Update human_pose_estimation_drone_control.md

* Change the videos links

* Update human_pose_estimation_drone_control.md

Fix markdownlint warnings

* Reduce the size of poses image
2019-07-26 18:50:04 +03:00
timkondratiev
6a6f26aff7 docs: fix the 3d-scanning drone article (#140)
* Fixed broken video link

* Fixed broken embedded video and image width

* Fixed image width on mobile
2019-07-26 16:32:37 +03:00
timkondratiev
e83c284313 docs: add article about 3D-scanning drone (#139)
* Added a photo of 3d-scanning drone

* Added a new article about 3d-scanning drone.

* Updated the article

* Included the new article about 3d-scanning drone.

* Added a new article.

* Included a new article

3D-scanning drone

* Fixed bugs

* Fixed md syntax
2019-07-25 19:07:20 +03:00
Oleg Kalachev
2e4b1e2637 simple_offboard: ensure all the arguments are finite 2019-07-23 22:07:28 +03:00
Oleg Kalachev
b3e2158250 simple_offboard: quick fix for /navigate_global sometimes not working 2019-07-22 15:09:46 +03:00
Oleg Kalachev
06a79f8d66 simple_offboard: descrease timeout for local position in /navigate_global 2019-07-22 15:09:46 +03:00
sfalexrog
18fff51181 docs: Fix MAVLink links, revert global setpoint note 2019-07-21 23:26:36 +03:00
Oleg Kalachev
eae36ab22d simple_offboard: fix transform timeout in /navigate_global 2019-07-21 21:46:52 +03:00
Oleg Kalachev
82f2a2df50 simple_offboard: increase the rate of checking in waitTransform 2019-07-21 21:25:51 +03:00
Oleg Kalachev
ea072ad01a selfcheck.py: check results must not be capitalized 2019-07-20 20:52:51 +03:00
Oleg Kalachev
0801ea2b67 selfcheck.py: catch some more exceptions 2019-07-20 20:02:14 +03:00
Oleg Kalachev
f7d3122f58 www: use location.hostname for hostname 2019-07-20 19:50:43 +03:00
Oleg Kalachev
bc0e45740f Use aruco_map_ prefix for markers in the map 2019-07-20 17:30:06 +03:00
Oleg Kalachev
57c22fccf7 docs: add takeoff_wait function to snippets 2019-07-20 15:33:06 +03:00
Oleg Kalachev
09d06a517f Update Flask version 2019-07-19 23:51:42 +03:00
sfalexrog
865b999431 builder: Update kernel version 2019-07-15 19:40:56 +03:00
Oleg Kalachev
0522622cea docs: add land_wait function to snippets 2019-07-14 12:35:17 +03:00
Oleg Kalachev
7b6103b941 docs: unneeded note about Cyrillic in English version 2019-07-14 12:28:51 +03:00
sfalexrog
95a509cd60 docs: Fix repository link 2019-07-12 17:19:54 +03:00
Oleg Kalachev
4cca8b2d84 selfcheck.py: print board rotation 2019-07-11 15:57:06 +03:00
sfalexrog
33ff7ea694 docs: Sync network docs across languages 2019-07-09 16:03:38 +03:00
Hany Hamed
d958d565a7 Fix network documentation in the English gitbook (#136)
Fix network documentation in the English gitbook
2019-07-09 15:06:14 +03:00
Oleg Kalachev
96cc0c7ad9 Forgotten lines 2019-07-03 05:38:10 +03:00
Oleg Kalachev
997484cd1f aruco_map: fix includes order 2019-07-03 05:23:44 +03:00
Oleg Kalachev
48b24a5fef aruco_map: possibility to publish static transforms for map's markers 2019-07-03 05:18:44 +03:00
Oleg Kalachev
2ae5ffe09f aruco_pose: add testing markers' tf frames 2019-07-02 05:18:33 +03:00
Oleg Kalachev
da29beda47 builder: run tests after GeographicLib datasets is installed 2019-07-02 02:54:20 +03:00
Oleg Kalachev
0303e645b7 Fix typo 2019-07-02 01:26:07 +03:00
Oleg Kalachev
979c863033 Add some test for clever package 2019-07-02 01:21:49 +03:00
Oleg Kalachev
46b8390c03 Little fix 2019-07-02 01:01:07 +03:00
Oleg Kalachev
e5df1cd1a0 aruco_pose: require all the nodelets not to crash in tests 2019-07-02 00:39:47 +03:00
Oleg Kalachev
32c04ef58d Bring back lxml to package.xml 2019-07-01 23:54:26 +03:00
Oleg Kalachev
596fa9aecf Add tf2_web_republisher to package dependencies 2019-07-01 22:47:47 +03:00
Oleg Kalachev
f883825def clever.launch: support copter_visualization renamed to visualization 2019-07-01 22:24:04 +03:00
Oleg Kalachev
d65df5d1ba Improve manual installation instruction and make some related fixes 2019-07-01 22:20:15 +03:00
tinderad
a183be2708 docs: add new version of camera calibration article (#134) 2019-06-29 15:34:57 +03:00
Oleg Kalachev
9c9ac3150d Use pytest for tests (#133)
* aruco_pose: use pytest

* Use ros_pytest

* Add ros_pytest to rosdep

* aruco_pose: compare floats more roughly in pytest

* aruco_pose: rewrite all the rest tests in pytest
2019-06-28 17:40:40 +03:00
Oleg Kalachev
82649cbe20 aruco_pose: remove unused lines from tests 2019-06-26 23:02:32 +03:00
Oleg Kalachev
b542851b24 aruco_pose: fix crashing the nodelet if markers on the map are to small 2019-06-26 23:00:49 +03:00
Oleg Kalachev
65d359b5c2 aruco_pose: fix command for running tests in readme 2019-06-26 22:42:08 +03:00
Oleg Kalachev
1b6f38f8cf docs: small fix 2019-06-26 21:15:58 +03:00
Oleg Kalachev
81f0dfd530 docs: other fixes to trainer mode article 2019-06-26 19:52:05 +03:00
Oleg Kalachev
52ed11ef8c docs: fixes to trainer mode article 2019-06-26 19:50:05 +03:00
Oleg Kalachev
4b384d9f61 selfcheck.py: show the number of markers in the map 2019-06-26 19:29:43 +03:00
VeneraDal
d37bd8ee87 docs: add trainer mode article
* Add files via upload

* Add files via upload

* Добавила статью по настройке  режима тренера.

В разделе "Настройки", после статьи Полётные режимы.

* Update Trainer_mode.md

* Update Trainer_mode.md

* Update Trainer_mode.md
2019-06-26 17:36:14 +03:00
Oleg Kalachev
8d606c2ed1 image: unlock vim version 2019-06-24 00:05:20 +03:00
Tenessinum
d2a405cb79 Aruco Map Generator markdown (#130)
* Add Aruco Map Generator markdown

* Add Aruco Map Generator link

* Fixed errors in arucogenmap.md
2019-06-23 18:34:59 +03:00
Andrei Korigodski
1b97bfa5a0 docs: fix en/README 2019-06-21 13:44:38 +03:00
garinegor
c2254c52d4 Fixed ap mode commands error (#131)
* fixed ap mode commands error

* removed unexpected spaces
2019-06-21 11:23:08 +02:00
Oleg Kalachev
8f304b628f Merge branch 'proof_reading' 2019-06-21 02:53:32 +02:00
sfalexrog
90c8fb5bac docs: firmware article 2019-06-20 01:25:00 +03:00
sfalexrog
bcd48bbd90 docs: linter 2019-06-20 01:03:42 +03:00
thomashamain
e0ed27875f doc: snippets.md 2019-06-19 22:34:32 +03:00
thomashamain
6f49b6dfda doc: ros-install.md ros.md
line 109: "working on serval PCs?" means that ROS is working on several PCs? I think a specification is needed.
2019-06-19 21:49:14 +03:00
sfalexrog
6a17217fbd docs: laser.md article 2019-06-19 21:47:22 +03:00
sfalexrog
2090f0a1ae docs: selfcheck.md proofreading 2019-06-19 21:29:41 +03:00
sfalexrog
fdae8ee2aa docs: mavros article 2019-06-19 21:16:18 +03:00
sfalexrog
7f802d3efd docs: make linter happy 2019-06-19 19:03:53 +03:00
thomashamain
5237ccf590 doc : optical_flow.md
i'm affraid i did not translate correctly the part at line 92:
the speed will be controlled such as Optical Flow "values"? do not exceed 50% of the "given parameter"?
2019-06-17 23:45:53 +03:00
Oleg Kalachev
25f69596fc Move body frame publishing to simple_offboard.cpp 2019-06-16 15:43:53 +03:00
Oleg Kalachev
7610f02b38 main_camera.launch: enable automatic rescaling camera calibration 2019-06-15 17:58:00 +03:00
sfalexrog
9218460d52 docs: Finish aruco_map translation 2019-06-14 19:36:56 +03:00
sfalexrog
db692f1484 docs: Start updating ArUco articles 2019-06-14 19:36:37 +03:00
sfalexrog
6d4663e4f4 docs: Rename some of the english articles 2019-06-14 19:36:26 +03:00
thomashamain
cfcb7ce652 lint fixes 2019-06-14 19:34:03 +03:00
Oleg Kalachev
7e10d0d17c docs: update snippets 2019-06-13 20:25:45 +03:00
sfalexrog
3a1e95a551 docs: Fix aruco_map ambiguity 2019-06-12 00:53:13 +03:00
thomashamain
cd34277c64 This commit is a correction of previous version
copter = helicopter, use drone.
blanch is not the correct term, use to tin which is widely used.
Flat cable is used but I beleive ribbon cable is more common (not sure)
Unclear sections (did not understand in russian neither, coming from an unadviced reader it might be usefull to clarify those points)
- l.61 "the red and black wires are to be tinned on both ends using tweezers" (did you mean soldering iron?)
- l.82 "disconnect the power and move yellow jumper to the other tweezer" (did you mean pins)
- l.145 "thus, it will be clear which motor is controlled" (unsure if by going through the procedure we activate the motors individually or by setting the throttle to 10% we simply see the direction of spin as it's slow)

not linked to the proof reading:
do you power the rgb strip directly from the raspberry pi with pin 40 (gpio 21) ?because it can be dangerous as the led strip is drawing x mA  or even x A, and the RPI is not designed to withstand such currents (I beleive not more than 500mA), be carefull :o
2019-06-12 00:28:35 +03:00
sfalexrog
88f4b4c10e docs: Specify actual topic and callback names 2019-06-11 23:03:20 +03:00
thomashamain
314e313947 Proofing for English documentation
copter = helicopter
2019-06-11 19:57:09 +03:00
thomashamain
596c111199 This commit is a correction of the previous version. A slight modification is suggested.
- Copter in English is a synonyme of helicopter, use drone or quadrocopter.
- I would modify ther term "additionnal frame" as it might be understood as spare frame. I would describe them as "top frame" "bottom frame" "main frame" etc.
2019-06-11 18:48:16 +03:00
sfalexrog
0b35c9902d buider: Update key (again) 2019-06-11 16:39:53 +03:00
sfalexrog
fd8425c6a7 builder: Update ROS key 2019-06-11 16:02:58 +03:00
sfalexrog
793f3630ef builder: Fix pull request check 2019-06-11 15:41:51 +03:00
sfalexrog
3915dd09bb docs: Fix axis ambiguity 2019-06-11 15:39:44 +03:00
Oleg Kalachev
789e09b7b9 docs: fixes to flip snippet 2019-06-07 18:35:11 +03:00
sfalexrog
0fb88bafb4 docs: web_video_server type parameter 2019-06-06 21:05:53 +03:00
sfalexrog
4786b51466 clever: Add publish_rate for web_video_server 2019-06-04 17:59:38 +03:00
Oleg Kalachev
d3fffb7b54 docs: small fix in gpio article 2019-06-04 15:51:07 +03:00
sfalexrog
e1444978bb builder: fast docs rebuild (for pull requests) (#126)
* builder: Skip builds for docs-only pull requests

* force rebuild

* travis: Fix bad syntax

* travis: Be more strict about checking for changes

* travis: Make build skipping more noticeable
2019-06-03 21:16:04 +03:00
Oleg Kalachev
9932062631 Update sources hats 2019-06-03 17:18:27 +03:00
Oleg Kalachev
8a5e1318c7 docs: "fix" English version link 2019-05-31 19:11:23 +03:00
Oleg Kalachev
7d6acc52e9 docs: clarify snippets a little 2019-05-31 18:37:09 +03:00
Oleg Kalachev
b850844fa2 Remove bad 17 marker from cmit aruco map 2019-05-30 22:47:18 +03:00
Alamoris
4c01e710fc aruco_pose: Add cmit aruco map 2019-05-30 19:46:35 +03:00
Oleg Kalachev
161506d89a docs: translate images to English 2019-05-30 00:54:26 +03:00
sfalexrog
bb2c2cfac9 builder: Use PWM peripheral for pigpiod 2019-05-28 21:00:28 +03:00
sfalexrog
8019712d8c Revert "aruco_map: Use two-pass solvePnP"
This reverts commit 91f6f6dd32. Additional testing revealed this "fix" to provide incorrect results.
2019-05-28 20:54:49 +03:00
Oleg Kalachev
41e9f407fd docs: fix IR connection illustration 2019-05-27 16:09:28 +03:00
sfalexrog
c8008efeac builder: Update base image and packages 2019-05-27 13:52:50 +03:00
Oleg Kalachev
c5dbf44bba docs: correct flip snippet 2019-05-25 14:34:41 +03:00
Oleg Kalachev
c0217d8aff docs: add autogenerated link to clever firmware + small fixes 2019-05-25 14:34:29 +03:00
Oleg Kalachev
ee1a493636 selfcheck.py: don't show OK if there were info messages 2019-05-24 00:29:56 +03:00
Oleg Kalachev
2a755005a6 selfcheck.py: print image version 2019-05-24 00:24:00 +03:00
Oleg Kalachev
4807db85a7 selfcheck.py: improve aruco check 2019-05-24 00:24:00 +03:00
Oleg Kalachev
82a2a5e5f7 clever.launch: remove launching arduino bridge 2019-05-24 00:24:00 +03:00
sfalexrog
73e17aeb48 builder: Add realsense packages 2019-05-23 16:50:24 +03:00
Oleg Kalachev
0af7d406bd Merge pull request #125 from sfalexrog/WIP/aruco_fix
aruco_map: Use two-pass solvePnP
2019-05-22 15:19:42 +03:00
sfalexrog
78f43ad078 builder: Update kernel version 2019-05-21 08:53:52 +03:00
Oleg Kalachev
8faa838bb9 selfcheck.py: function for printing checks info 2019-05-20 20:29:42 +03:00
Oleg Kalachev
f499608cc2 selfcheck.py: describe camera orientation 2019-05-20 18:46:48 +03:00
Oleg Kalachev
486c62f625 docs: simplify wi-fi config instructions 2019-05-20 16:54:45 +03:00
Oleg Kalachev
29b9f47eea selfcheck.py: follow PEP-8 in imports 2019-05-20 16:10:33 +03:00
Oleg Kalachev
bba9f3db76 selfcheck.py: simplify camera check 2019-05-20 16:02:47 +03:00
sfalexrog
91f6f6dd32 aruco_map: Use two-pass solvePnP
There are cases when iterative solvePnP method converges on a "wrong" camera position due to projectPoints not treating negative Z values properly.
Other methods don't seem to be affected by that, but their results differ from the iterative method slightly. By combining these two methods we
"nudge" the iterative method towards the correct camera position and get satisfactory results most of the time.

Sometimes, though, even with the "nudge" the iterative method diverges catastrophically, and this is not caught by the solver. We work around that
by assuming our camera position cannot be too far from the markers.
2019-05-20 12:29:42 +03:00
sfalexrog
ec57f7d0a3 builder: Fix git configuration 2019-05-17 11:48:16 +03:00
sfalexrog
683e06dc20 builder: Remove pymavlink definition
Rosdep repository has pymavlink definition as of 831b1b2ad5
2019-05-15 23:19:46 +03:00
sfalexrog
6dfba25d45 selfcheck.py: perform version and preflight checks (#123)
* selfcheck: Perform version and preflight checks

* selfcheck: Fail commander check if no data received

* selfcheck: Print firmware version

* selfcheck: Create publishers and subscribers globally

* selfcheck.py: add note about firmware in gitbook

* selfcheck: Move firmware version checks to FCU checks

* selfcheck: Show commander warnings

* selfcheck: Remove prompt line from received mavlink message

* clever: Add pymavlink as a ROS dependency
2019-05-15 16:51:12 +03:00
sfalexrog
ffa2f89c8e builder: Set default keyboard layout to US 2019-05-14 19:38:18 +03:00
sfalexrog
a99c381f11 builder: Install libjpeg8 manually 2019-05-14 19:26:26 +03:00
Oleg Kalachev
36d088d648 docs: that’s unneeded 2019-05-14 05:04:55 +03:00
sfalexrog
f0ab0a8e11 docs: Add MOSFET+magnet schematic 2019-05-13 19:16:42 +03:00
sfalexrog
53c2cf6998 aruco_map: map parser improvements (#118)
* aruco_map: Improve parser

* aruco_map: Use marker id for map visualization

* aruco_pose: Add parser pass test

* aruco_map: Code style

* aruco_pose: Add more test cases

* aruco_map: Better message handling

* aruco_map: Be more informative about bad lines

* aruco_map: Add failure mode tests

* aruco_map: Be less strict about map contents

* aruco_pose: Restructure tests

* aruco_map: Don't use marker id in visualization

* aruco_map: Check for marker uniqueness

* aruco_pose: Use board data to reject duplicate markers

* aruco_pose/test: Spelling fixes
2019-05-13 17:43:20 +03:00
Oleg Kalachev
ae3d3a955b docs: recommend disabling baro in LPE_FUSION for aruco VPE 2019-05-13 14:47:44 +03:00
Oleg Kalachev
2e11db0756 docs: recommend LPE for aruco VPE 2019-05-13 14:45:16 +03:00
Oleg Kalachev
66e21443a9 docs: update en 2019-05-13 07:07:36 +03:00
Oleg Kalachev
81c3d6d42b docs: small addition to contributing 2019-05-13 06:32:08 +03:00
Oleg Kalachev
9f4df86cae docs: make markdownlint happy 2019-05-13 06:27:56 +03:00
Oleg Kalachev
beca5f25e9 gitbook: set gitbook version to ^3.2.2 2019-05-13 03:01:08 +03:00
Ilya Petrov
10785183e1 docs: update in ceiling markers config 2019-05-11 14:29:40 +03:00
Oleg Kalachev
7c5af5f494 selfcheck.py: code syle 2019-05-11 14:19:42 +03:00
Oleg Kalachev
cabe76a607 selfcheck.py: "fusing" -> "fusion" in warnings 2019-05-11 14:04:03 +03:00
Oleg Kalachev
d2912aebd8 selfcheck.py: increase angular velocity limit 2019-05-11 10:16:27 +03:00
Oleg Kalachev
efb9bf2f7a selfcheck.py: don't fall when mavros/param/get is unavailable 2019-05-11 10:16:27 +03:00
Oleg Kalachev
7f8b78ad7d selfcheck.py: code style 2019-05-11 10:16:27 +03:00
Oleg Kalachev
34095bfaa7 selfcheck.py: check PX4 VPE parameters when vpe_publisher is running 2019-05-11 10:16:27 +03:00
Arthur
747f26742d Edit instruction about the connection of pixracer and RC 2019-05-08 17:33:00 +03:00
Oleg Kalachev
31f586070d image: fix espeak installation 2019-05-08 08:54:06 +03:00
sfalexrog
021aa69110 clever: Selfcheck improvements 2019-05-08 07:54:40 +03:00
sfalexrog
b5a01e6a7e selfcheck: Check logs for errors 2019-05-08 07:54:40 +03:00
Oleg Kalachev
5b02f59583 image: add espeak 2019-05-08 05:15:13 +03:00
Alamoris
1c33102b8f docs: revision of the article about sitl (#114)
* Add rus article about install ROS

* Add lines

* Add article about launching gazebo

* Some fix

* Add fix

* Fix

* Text fix

* Fix MD exceptions

* docs: edit sitl articles

* article fix
2019-05-08 04:18:09 +03:00
Oleg Kalachev
bca7445ebe docs: some fixes 2019-05-08 02:23:09 +03:00
Oleg Kalachev
d47a95e134 docs: add some rules to markdownlint + some editing 2019-05-08 02:19:42 +03:00
Oleg Kalachev
064e402a2d selfcheck.py: show error when exception occurred in check 2019-05-07 23:46:34 +03:00
Arthur Golubtsov
5b617d91a9 docs: add article about clever image building (#121)
* Add article about clever image building

* Image building article: fix text style and add link to SUMMARY.md
2019-05-07 17:28:30 +03:00
sfalexrog
2a4dce3e09 builder: Show actual retry count 2019-05-06 21:27:04 +03:00
sfalexrog
cf9b7abcfa builder: Try even harder to update rosdep 2019-05-06 20:02:18 +03:00
Oleg Kalachev
751caa906c Revert "Verify Google Webmaster (again)"
This reverts commit ff244345a7.
2019-05-06 06:55:17 +03:00
Oleg Kalachev
ff244345a7 Verify Google Webmaster (again) 2019-05-06 06:48:53 +03:00
sfalexrog
c73c7857c6 builder: Try harder to update rosdep 2019-05-05 11:04:08 +03:00
Oleg Kalachev
b9b4d762ea docs: make markdownlint happy 2019-05-05 00:25:17 +03:00
mmkuznecov
8929fd534f docs: article about object counting (#120)
* Add files via upload

* Add files via upload

* Update SUMMARY.md

* Update SUMMARY.md

* Update object_counting.md

* Update object_counting.md

* Update object_counting.md

* Update object_counting.md

* Add files via upload

* Update object_counting.md

* Delete giff.gif

* Delete people_static.gif

* Update object_counting.md
2019-05-04 22:57:29 +03:00
sfalexrog
dff4487d9b travis: Deploy docs to master 2019-05-04 19:14:24 +03:00
sfalexrog
00c12ed305 travis: Deploy to github pages 2019-05-04 19:08:25 +03:00
Oleg Kalachev
91cae1e4c6 Revert "Verify Google Webmaster"
This reverts commit 73f600b41b.
2019-05-01 18:23:06 +03:00
Oleg Kalachev
328572f7b1 Gitbook update 2019-05-01 18:02:53 +03:00
Oleg Kalachev
73f600b41b Verify Google Webmaster 2019-05-01 17:53:41 +03:00
Arthur
2a5d511b2b gen_changelog: Fix script failure when there is no tag in repo 2019-04-30 13:40:14 +03:00
sfalexrog
bc0039ccb7 ESP8266 module documentation (#117)
* docs: Start working on ESP8266 article

* docs: More work on esp8266 article

* docs: esp8266 article fixes
2019-04-29 17:59:51 +03:00
Ilya Petrov
378efd9fab dictionary parameter of aruco_map nodelet
aruco_map nodelet has it's own dictionary parameter
2019-04-29 00:00:34 +03:00
Oleg Kalachev
c2b974f407 docs: clarify summary a little 2019-04-25 23:29:40 +03:00
Oleg Kalachev
1778f1d9eb docs: remove Cyrillic comments from simple_offboard program stub 2019-04-25 23:12:57 +03:00
Oleg Kalachev
25ca8f8b97 Remove rangefinder offset 2019-04-25 19:00:31 +03:00
Oleg Kalachev
94c191f65f selfcheck.py: fix checking LPE_FLW_SCALE parameter 2019-04-23 01:59:54 +03:00
Andrei Korigodski
6f95037e56 docs: update article on GPIO 2019-04-18 18:41:38 +03:00
Oleg Kalachev
17916f931c docs: add article on GPIO 2019-04-18 18:21:59 +03:00
sfalexrog
d09dfba905 docs: Add note about web_video_server and Python 2019-04-16 15:44:57 +03:00
sfalexrog
e631459181 ros: Add rosshow package 2019-04-16 14:52:16 +03:00
Oleg Kalachev
86da07bca8 simple_offboard: param for performing land only in offboard mode 2019-04-13 16:10:04 +03:00
Oleg Kalachev
bb9f56f6a6 docs: nti: add info on utf coding in Python scripts 2019-04-11 14:03:02 +03:00
Oleg Kalachev
a37f58ada9 image: update Linux kernel version 2019-04-11 11:33:53 +03:00
Oleg Kalachev
a3bc692679 docs: pep-8 2019-04-10 14:30:41 +03:00
Oleg Kalachev
bd8b17a51d docs: restore info on led ros node in nti2019 2019-04-10 14:29:43 +03:00
Oleg Kalachev
9ac980f278 selfcheck.py: increase rangefinder timeout to 4 2019-04-10 13:46:17 +03:00
Oleg Kalachev
742041448d docs: edit nti article a little 2019-04-10 11:41:37 +03:00
Oleg Kalachev
fe83930e42 docs: remote info on ros node from nti 2019 2019-04-10 10:24:17 +03:00
Oleg Kalachev
a93ae126bc docs: very little fix 2019-04-10 10:07:00 +03:00
sfalexrog
199247c745 docs: Style fix 2019-04-10 09:50:34 +03:00
sfalexrog
4746f3181d docs: Add ros_ws281x example 2019-04-10 02:03:20 +03:00
Oleg Kalachev
74f84a22d9 docs: edit nti2019.md 2019-04-09 20:40:49 +03:00
Oleg Kalachev
d37ac64f64 docs: small fix for markdownlint 2019-04-09 18:03:01 +03:00
sfalexrog
3f94335554 docs: Add MQTT publishing example 2019-04-09 16:23:42 +03:00
sfalexrog
1d591965a3 init_rpi: Fix typo in sed command 2019-04-09 10:31:12 +03:00
sfalexrog
7519958698 init: Automatically set Clever hostname 2019-04-08 20:16:48 +03:00
Oleg Kalachev
be7624b309 docs: edit nti article 2019-04-08 16:11:09 +03:00
sfalexrog
e9e8c84ddf aruco_pose: Try to draw as much of axes as possible 2019-04-07 22:46:38 +03:00
Oleg Kalachev
6535943cc8 docs: fix 2019-04-07 19:15:05 +03:00
Oleg Kalachev
375b19146c docs: changes 2019-04-07 19:14:34 +03:00
Oleg Kalachev
77602021ae Merge branch 'master' of github.com:CopterExpress/clever 2019-04-07 19:12:40 +03:00
sfalexrog
0df66a8df7 Add annotated MQTT sample 2019-04-07 17:28:42 +03:00
Oleg Kalachev
ae9302bfc2 Remove +x flag from main_camera.launch 2019-04-07 16:35:29 +03:00
Oleg Kalachev
993cc50276 docs: edit nti.md 2019-04-07 16:12:02 +03:00
Oleg Kalachev
06bf2d5b56 docs: add some info on using clever for NTI 2019 2019-04-06 19:54:26 +03:00
Oleg Kalachev
db03222a19 docs: add some info on nti 2019 2019-04-04 22:14:24 +03:00
sfalexrog
fea6992964 builder: Fix kernel version 2019-04-04 20:54:42 +03:00
Oleg Kalachev
67ddfa6c5e docs: NTI olympics 2019 page stub created 2019-04-04 19:50:04 +03:00
sfalexrog
9e77a11cf5 builder: Update kernel version 2019-04-03 14:14:20 +03:00
Oleg Kalachev
928d2e38d4 gitbook: remove yandex webmaster validation 2019-04-03 00:01:46 +03:00
Oleg Kalachev
eb9b621662 gitbook: fix for yandex webmaster 2019-04-02 23:33:40 +03:00
Oleg Kalachev
dfd6736fb0 gitbook: remove redirect for a while 2019-04-02 23:29:37 +03:00
Oleg Kalachev
08ea466232 Yandex.Webmaster verification 2019-04-02 23:26:11 +03:00
sfalexrog
07b6dcde51 builder: Update base image 2019-04-02 20:47:33 +03:00
sfalexrog
66aa4729ad docs: Minor px4flow article fix 2019-04-02 18:07:39 +03:00
Oleg Kalachev
bb825c3c30 docs: edit px4flow article a little 2019-03-29 18:24:17 +03:00
sfalexrog
32635def32 PX4FLOW article (#113)
* px4flow: Start writing documentation

* px4flow: Add more information

* docs/px4flow: Pixracer connection and configuration

* docs/px4flow: Lint fixes
2019-03-29 18:21:25 +03:00
Alamoris
0342e7da39 Small fix 2019-03-29 17:23:22 +03:00
Oleg Kalachev
995a1395de Add articles on new aruco navigation to gitbook 2019-03-28 00:30:54 +03:00
Oleg Kalachev
99f207d0f6 selfcheck.py: small fix 2019-03-27 20:49:58 +03:00
Oleg Kalachev
29c401e5fa selfcheck.py: show failures when exception occurred 2019-03-27 20:49:58 +03:00
Arthur
b3c0e2d290 image: add ros and python paths for working with sudo 2019-03-27 13:29:40 +03:00
Arthur
d053571053 builder: remove get-pip.py after installation 2019-03-27 12:45:13 +03:00
Arthur
e59a0221ca image: change restart option for clever.service and roscore.service from on-abort to on-failure 2019-03-27 12:40:44 +03:00
Oleg Kalachev
b53bf19c8d simple_offboard: comment out incorrect yaw calculation if yaw=nan 2019-03-27 08:11:54 +03:00
Oleg Kalachev
b6c493513c vpe_publisher: reduce offset_timeout to make vpe faults less likely 2019-03-27 02:24:59 +03:00
Oleg Kalachev
24bf9f8907 ios app: add privacy policy in English 2019-03-27 00:17:07 +03:00
Oleg Kalachev
3338d42a77 iOS app: add confidentiality policy 2019-03-26 23:32:32 +03:00
sfalexrog
27e890825d docs/flow: Add note about SENS_FLOW_MAXR 2019-03-26 23:30:03 +03:00
Oleg Kalachev
68f810cd1a builder: remove python-rosinstall-generator version fix 2019-03-26 22:10:13 +03:00
Oleg Kalachev
0c872a101f gitbook: add link to the English version 2019-03-26 21:54:00 +03:00
sfalexrog
04c33d5b03 aruco_pose/draw: Be more strict about drawing axis 2019-03-21 21:52:20 +03:00
Oleg Kalachev
b4e8d9b18a aruco_pose: little style fix 2019-03-21 20:58:44 +03:00
Oleg Kalachev
e601080a95 aruco_pose: add param auto_flip 2019-03-21 20:55:35 +03:00
Oleg Kalachev
84c16a7296 aruco_pose: fix snapping alrogithm 2019-03-21 20:55:35 +03:00
Oleg Kalachev
c227910431 aruco_pose: fix office ceiling map 2019-03-21 20:55:35 +03:00
sfalexrog
acec09192b aruco_map: Try to fix frame drawing bug
`cv::aruco::drawAxis` would attempt to draw detected frame origin even when it's behind the camera. This resulted in an invalid, flipped frame displayed in `/aruco_map/debug`.

This commit prevents drawing frame axis if the frame origin (projected to the screen space) is behind the screen plane.
2019-03-20 16:14:29 +03:00
sfalexrog
03584e410b docs: Update docker SITL docs 2019-03-19 14:49:33 +03:00
Oleg Kalachev
c22f8b2a7c docs: small fix 2019-03-19 01:20:30 +03:00
Oleg Kalachev
445b6022c6 gitbook: add some redirects 2019-03-19 00:58:10 +03:00
Oleg Kalachev
c2994e520a gitbook: redirect from aruco/ 2019-03-19 00:43:26 +03:00
Oleg Kalachev
d2b13aff92 optical_flow: use try when transform from camera to base_link frame 2019-03-18 23:50:57 +03:00
garinegor
63d3449cc5 Added clever blocks programming (#111)
* added clever blocks markdown

* added the 2nd way of downloading  project

* spelling

* deleted 2 extra cd's
2019-03-17 20:06:44 +03:00
Oleg Kalachev
7c29d9d75a selfcheck.py: improve range sensor checking 2019-03-17 00:43:44 +03:00
Oleg Kalachev
fbaece0f88 selfcheck.py: check VPE settings for EKF2 2019-03-17 00:36:12 +03:00
Oleg Kalachev
4721f39c24 selfcheck.py: check optical flow parameters for EKF2 2019-03-17 00:31:17 +03:00
Oleg Kalachev
407e40136f docs: add more info on selfcheck 2019-03-16 04:21:38 +03:00
Oleg Kalachev
89bd502216 selfcheck.py: check some PX4 parameters 2019-03-16 04:09:39 +03:00
Oleg Kalachev
6e6aace884 Typo 2019-03-16 03:08:49 +03:00
Oleg Kalachev
ad0f952f74 Add page for 3D visualization of markers map 2019-03-15 21:46:51 +03:00
Oleg Kalachev
05791bb0bf genmap.py: remove unused arguments 2019-03-15 19:56:34 +03:00
Alamoris
9cbfc5b687 Fix top left setting 2019-03-15 19:51:10 +03:00
sfalexrog
df0f1c9df0 SITL: Address requested changes 2019-03-15 19:05:59 +03:00
sfalexrog
46ce55f7dd SITL: Docker-based SITL documentation 2019-03-15 19:05:59 +03:00
Oleg Kalachev
60ebdab19f selfcheck.py: fix rangefinder checking 2019-03-15 17:39:24 +03:00
Alamoris
bfcba26df2 Delete extra photos 2019-03-15 02:20:05 +03:00
Oleg Kalachev
cac05d5231 docs: more info on optical flow 2019-03-15 00:03:42 +03:00
Oleg Kalachev
fd2f0a5394 docs: remove experimental warning from flow article 2019-03-15 00:00:16 +03:00
Oleg Kalachev
3906c4242b docs: typo 2019-03-14 23:45:49 +03:00
Oleg Kalachev
6fae8df7f6 docs: tune optical flow settings 2019-03-14 23:20:09 +03:00
Oleg Kalachev
7f70e0e2e4 docs: tune vision variances 2019-03-14 23:00:13 +03:00
Oleg Kalachev
3aedddd97f docs: autogenerate link to latest clever firmware 2019-03-14 22:59:57 +03:00
Oleg Kalachev
cdda65fe92 docs: clever 3 assemble: add info on 4 ESCs 2019-03-14 19:50:15 +03:00
sfalexrog
6e31667ca1 travis: Generate changelog for tags 2019-03-14 17:03:55 +03:00
Oleg Kalachev
47ed0481b1 Remove marker 17 as of too common faults + remove CRLF 2019-03-13 23:13:45 +03:00
Oleg Kalachev
a8f3ff694a builder: don’t continue on rosdep install errors 2019-03-13 17:09:58 +03:00
Oleg Kalachev
f30beea983 Typo 2019-03-13 05:05:41 +03:00
Oleg Kalachev
d62e0cac27 Add genmap.py tool 2019-03-13 04:31:45 +03:00
Oleg Kalachev
f74df65622 ios app: new release 2019-03-11 22:07:54 +03:00
Oleg Kalachev
055ce814d7 docs: add little note on tf2 2019-03-11 20:43:27 +03:00
Oleg Kalachev
c68f82feab builder: fix tests 2019-03-10 15:07:23 +03:00
Oleg Kalachev
b2aa5241cd selfcheck.py: updates to aruco check 2019-03-10 03:04:38 +03:00
Oleg Kalachev
f2b37d8ea2 aruco_map: fix drawing maps with pitch/roll rotated markers 2019-03-10 02:28:14 +03:00
Oleg Kalachev
c9768cce4d builder: more tests 2019-03-10 01:44:48 +03:00
Oleg Kalachev
e6266e52f8 aruco_pose: remove irrelevant comment 2019-03-09 21:44:08 +03:00
Oleg Kalachev
21ff16e206 Fix typo 2019-03-09 18:12:37 +03:00
Oleg Kalachev
75eb6fc3ee This comment was breaking everything 2019-03-07 03:17:28 +03:00
Oleg Kalachev
ec6c5e71bc aruco_pose: loose assertion even more 2019-03-07 01:35:28 +03:00
Oleg Kalachev
134fbf5713 aruco.launch: add link to docs 2019-03-06 23:59:13 +03:00
Oleg Kalachev
d065958456 main_camera.launch: add some comments 2019-03-06 23:57:45 +03:00
Oleg Kalachev
5cd7e5c94b docs: clarify a little 2019-03-06 23:38:24 +03:00
Oleg Kalachev
67d25c0d6b aruco_pose: loose floats assertion for make tests pass 2019-03-06 23:32:37 +03:00
Oleg Kalachev
ffa207899d docs: some info on MPC_THR_HOVER 2019-03-06 23:28:34 +03:00
Oleg Kalachev
b5324335be docs: add info on optical flow on LPE 2019-03-06 23:28:34 +03:00
Alamoris
58c2318d84 Add office ceiling aruco map 2019-03-06 17:40:03 +03:00
sfalexrog
a3079c5b12 rosdep: Add image_publisher package 2019-03-06 17:19:07 +03:00
Oleg Kalachev
5b5f072e2f aruco_pose: don’t use pytest 2019-03-05 23:11:55 +03:00
Oleg Kalachev
2bf6400e43 aruco_pose: add test dependency image_publisher 2019-03-05 23:11:55 +03:00
sfalexrog
c779e771ee travis: Use max clone depth (should help with "reference is not a tree" errors) 2019-03-05 20:39:26 +03:00
Oleg Kalachev
048927e7d7 builder: try to fix running packages tests 2019-03-05 20:33:24 +03:00
Oleg Kalachev
1271ded5e0 builder: fail build in tests failure 2019-03-05 20:31:09 +03:00
Oleg Kalachev
f828a9692d mavros.launch: switch to plugin whitelist 2019-03-05 19:25:54 +03:00
Oleg Kalachev
429c7a8c8b builder: run catkin_ws packages tests 2019-03-05 17:31:45 +03:00
Oleg Kalachev
84d6a341e0 builder: remove node.js install artifact 2019-03-05 16:58:14 +03:00
sfalexrog
9588d1d2d9 travis: Name release after tag 2019-03-05 16:26:53 +03:00
sfalexrog
575e46b425 butterfly: Install tornado 5.1.1 to work around Butterfly using missing APIs 2019-03-05 16:24:53 +03:00
Oleg Kalachev
c00882def6 aruco_pose: moar tests 2019-03-03 00:14:13 +03:00
Oleg Kalachev
394af64553 aruco_pose: improve tests 2019-03-02 23:59:26 +03:00
Oleg Kalachev
7a56a7b231 aruco_pose: add length to Marker message 2019-03-02 23:59:26 +03:00
Oleg Kalachev
23516b0fc1 spaces -> tabs 2019-03-02 23:59:26 +03:00
Oleg Kalachev
2b82516a97 aruco_map: fix drawing map image 2019-03-02 23:59:26 +03:00
sfalexrog
a9e1015bad Merge branch 'master' of https://github.com/copterexpress/clever 2019-03-01 23:30:04 +03:00
sfalexrog
8257724fcc px4fmu.rules: Only apply to non-bootloader devices 2019-03-01 23:29:14 +03:00
Oleg Kalachev
222ea3ecbf simple_offboard: simplify code 2019-03-01 23:27:47 +03:00
Oleg Kalachev
591650fcd7 docs: add link to v1.8.2-clever.1 firmware 2019-03-01 22:33:02 +03:00
Oleg Kalachev
42e437a32f aruco_pose: fixes to readme 2019-03-01 21:54:59 +03:00
Oleg Kalachev
aaa6f33a60 Typo 2019-03-01 21:52:45 +03:00
Oleg Kalachev
0b3bcda599 docs: add link to English documentation of aruco_pose 2019-03-01 21:50:51 +03:00
sfalexrog
603a4079f5 builder: Don't copy image cache to the image 2019-03-01 21:31:43 +03:00
sfalexrog
868036c33f Rename udev rules file 2019-03-01 21:27:19 +03:00
sfalexrog
4c85b4247b Merge branch 'master' of https://github.com/copterexpress/clever 2019-03-01 21:04:32 +03:00
sfalexrog
094681ae68 web_video_server: Use ros_compressed stream type by default 2019-03-01 21:03:44 +03:00
sfalexrog
24e516b898 ROS/px4: Access px4-based devices by /dev/px4fmu
We assume there won't be more than one FMU connected to the Raspberry Pi at any given time.
2019-03-01 20:59:33 +03:00
Oleg Kalachev
03d6431779 docs: fix 2019-03-01 20:58:59 +03:00
Oleg Kalachev
5a13b6743e docs: add documentation on new aruco_pose 2019-03-01 20:58:12 +03:00
Oleg Kalachev
09c9f65165 aruco_pose: add readme 2019-03-01 17:43:15 +03:00
Oleg Kalachev
d3885135e9 aruco_map: remove unused parameter 2019-03-01 17:39:32 +03:00
Oleg Kalachev
5a31a8e44a aruco.launch: fix 2019-03-01 17:39:32 +03:00
Oleg Kalachev
b8f5dc3cc3 aruco_pose: add sample launch file 2019-03-01 17:39:32 +03:00
Oleg Kalachev
35f6780469 Little fix 2019-03-01 17:39:32 +03:00
sfalexrog
23204bb561 optical_flow: Use correct signs for gyro calculations 2019-03-01 15:22:13 +03:00
Oleg Kalachev
f1c614d91a aruco_pose: use Pose instead of PoseWithCovariance in Marker message (for now) 2019-03-01 13:04:07 +03:00
Oleg Kalachev
af4321c530 docs: typo 2019-03-01 12:47:53 +03:00
Oleg Kalachev
52039d09e9 simple_offboard: rename frame target to navigate_target 2019-03-01 12:47:34 +03:00
Oleg Kalachev
349afa9a62 aruco_pose: fix tests 2019-03-01 12:38:50 +03:00
Oleg Kalachev
9a8202422e aruco_pose: draw detected markers in aruco_map/debug topic 2019-03-01 12:38:07 +03:00
Oleg Kalachev
db9d3cb398 aruco_map: align marker map by z axis 2019-02-28 23:33:05 +03:00
Oleg Kalachev
b2a53e5872 Add aruco_map/debug topic 2019-02-28 23:05:00 +03:00
Oleg Kalachev
8b5b3fb806 Disable mavros if fcu_conn = none 2019-02-28 19:55:18 +03:00
Oleg Kalachev
d8964b1b99 aruco_pose: style fix 2019-02-28 19:55:18 +03:00
Oleg Kalachev
3a6191b76b aruco_pose: remove using namespace from .h-file 2019-02-28 19:55:18 +03:00
sfalexrog
8d73b3aee0 builder: Remove redundant TODOs 2019-02-28 15:03:25 +03:00
sfalexrog
6c6a762174 ROS: Use ROS_HOSTNAME instead of ROS_IP (#101) 2019-02-28 13:58:22 +03:00
Oleg Kalachev
ff3ce062dd docs: fetch link to latest RPi image automatically 2019-02-28 12:52:34 +03:00
Oleg Kalachev
a12175ed70 New launch file for aruco_pose and vpe_publisher 2019-02-27 23:12:47 +03:00
Oleg Kalachev
25c485043d aruco_pose: add sample office map 2019-02-27 23:12:16 +03:00
Oleg Kalachev
913b70dc28 vpe_publisher: simplify 2019-02-27 23:11:42 +03:00
Oleg Kalachev
407a7bb4b3 vpe_publisher: fixes 2019-02-27 22:30:56 +03:00
Oleg Kalachev
4aaa0dd645 Add aruco markers to web rviz 2019-02-26 19:36:24 +03:00
Oleg Kalachev
1bfc190654 aruco_pose: fix generating gridboard 2019-02-26 19:36:01 +03:00
Oleg Kalachev
8237800058 clever.launch: simplify 2019-02-26 12:51:14 +03:00
Oleg Kalachev
fc1ca3f397 Rename frame map_upside_down to map_flipped 2019-02-26 10:16:38 +03:00
Oleg Kalachev
615194fc2a aruco_pose: rename known_orientation to known_tilt 2019-02-26 09:10:36 +03:00
Oleg Kalachev
fb676afa07 docs: add optical flow article 2019-02-26 09:06:49 +03:00
Oleg Kalachev
4fd9900cf1 docs: small fixes 2019-02-26 09:06:36 +03:00
Oleg Kalachev
0fae74e08a docs: spelling and linting 2019-02-25 20:35:59 +03:00
Oleg Kalachev
f677b60467 docs: lint 2019-02-25 20:26:27 +03:00
Oleg Kalachev
289f01428a docs: add info on configuring rangefinder in PX4 2019-02-25 19:19:30 +03:00
Konstantin Eliseev
bfaa28a7ac New EN articles, Summary structure update (#109)
* 10 new EN Articles

New EN articles upload

* Edit articles

* Edit articles

* New EN articles, Summary structure update

* Lessons links update
2019-02-25 17:41:06 +03:00
Oleg Kalachev
736f47e8af docs: little fix 2019-02-25 17:38:35 +03:00
sfalexrog
bb2ae1bad6 builder: Be more thorough about not copying the image into itself 2019-02-24 20:57:01 +03:00
sfalexrog
d9cd7c161b builder: Copy checked out repo instead of re-cloning it 2019-02-24 19:39:36 +03:00
sfalexrog
4d77c4a400 ROS: Install opencv3 with Neon support
Since we don't want to replace version 3.3.1 from our repository, we simply set our opencv package version to 3.3.19. That's a terrible hack, but at least that makes ROS happy.
2019-02-24 19:31:53 +03:00
sfalexrog
e24523cd46 builder: Actually use the correct builder
The whole point of the previous commit was to switch to a builder with a newer QEMU, and somehow I forgot to add that to .travis.yml. Whoops.
2019-02-24 01:12:04 +03:00
sfalexrog
2ca70c03eb builder: Re-enable loading cv2 in tests 2019-02-23 23:16:22 +03:00
Oleg Kalachev
4775919808 docs: spelling 2019-02-23 10:14:12 +03:00
Oleg Kalachev
8b034dc813 aruco_pose: more tests 2019-02-22 20:04:46 +03:00
Alamoris
a6484223a3 Add some info about ir sensors and rework leds.md (#107)
* Create new artile ir_sensors.md

Create new article about ir sensors and their compatibility wit python.

* docs: edit ir_sensors.md

* Fix markdown mistake

* Add new article about IR sensors

* Add some fix and information about IR transmitter

* Add some fix

* Add info about py-irsend

* Change connections images

* Edit summary.md

* Edit

* Add some info about led and ir sensors

* Add some fix about ir and rework article about leds

* Fix in led

* Reset sitl

* fix

* Edit

* Small fixes

* Edit
2019-02-22 17:57:39 +03:00
Oleg Kalachev
022eaed76c aruco_pose: rename snap_orientation to known_orientation 2019-02-22 16:44:01 +03:00
Oleg Kalachev
6382c25417 builder: add some tests for validating built image 2019-02-22 16:39:32 +03:00
Oleg Kalachev
c8844b424e aruco_pose: add basic tests 2019-02-22 14:57:36 +03:00
Oleg Kalachev
306185aafe aruco_detect: add length_override parameter for overriding individual marker’s length 2019-02-22 11:11:19 +03:00
Oleg Kalachev
70e1d6e5fd docs: /release service was removed 2019-02-22 09:30:01 +03:00
Oleg Kalachev
7be687b867 Add mavros_config.yaml 2019-02-21 19:19:54 +03:00
Oleg Kalachev
683bda7401 mavros.launch: don’t user px4_config.yaml, simplify distance_sensor config 2019-02-21 17:40:01 +03:00
Oleg Kalachev
21b753ad16 Add simple experimental web gcs 2019-02-21 15:58:41 +03:00
Oleg Kalachev
af244973c3 vpe_publisher: rename some params and topics 2019-02-21 10:32:07 +03:00
Oleg Kalachev
7d9d05120a Fix 2019-02-21 10:31:14 +03:00
Oleg Kalachev
1731798921 clever.launch: set otpical_flow/calc_flow_gyro to true by default 2019-02-21 10:30:59 +03:00
Oleg Kalachev
3a6d02a4b1 optical_flow: read from ~image_raw 2019-02-21 10:30:39 +03:00
Oleg Kalachev
9f91eb7beb clever.service: force all the ROS-nodes to output to the screen 2019-02-21 10:28:00 +03:00
Oleg Kalachev
d57d87a0e1 Set mavros respawn_delay to 1 second 2019-02-21 10:27:38 +03:00
Oleg Kalachev
c31e819db9 builder: install latest version of python-rosdep 2019-02-20 12:45:43 +03:00
Oleg Kalachev
97cffa4b19 vpe_publisher: continue publishing zero for publish_zero_duration when local position appears 2019-02-20 11:11:28 +03:00
Oleg Kalachev
60fd891477 Unused code 2019-02-20 10:10:00 +03:00
Oleg Kalachev
88e6a52868 Add vpe_publisher node 2019-02-19 19:52:53 +03:00
sfalexrog
7a89f1be8f builder: Try to not build Python wheels 2019-02-19 19:48:34 +03:00
Oleg Kalachev
d448928bc7 Fix 2019-02-19 16:11:11 +03:00
Alamoris
781d0132f2 Create new article about ir sensors (#104)
* Create new artile ir_sensors.md

Create new article about ir sensors and their compatibility wit python.

* docs: edit ir_sensors.md

* Fix markdown mistake

* Add new article about IR sensors

* Add some fix and information about IR transmitter

* Add some fix

* Add info about py-irsend

* Change connections images

* Edit summary.md

* Edit
2019-02-19 15:43:10 +03:00
Oleg Kalachev
ea5923be24 docs: camera troubleshooting 2019-02-19 10:06:06 +03:00
Oleg Kalachev
51f076fae4 optical_flow: add note 2019-02-18 10:24:27 +03:00
Oleg Kalachev
2e6707fddb docs: edits 2019-02-18 08:32:32 +03:00
Konstantin Eliseev
e33326171a 10 new EN Articles (#105) 2019-02-18 08:21:02 +03:00
Oleg Kalachev
bedd660078 gitbook: add sitemap plugin 2019-02-18 07:47:16 +03:00
Oleg Kalachev
e72b520f30 aruco_map: parametrize output image width, height and margin 2019-02-16 22:47:21 +03:00
Oleg Kalachev
2e1104fc0e builder: hardcode 2 threads number for clever package build 2019-02-16 05:17:21 +03:00
Oleg Kalachev
6c1a138e97 .editoconfig: add CMakeLists style 2019-02-15 19:54:40 +03:00
Oleg Kalachev
9af45cf757 docs: add info on logs.px4.io 2019-02-15 19:54:40 +03:00
Oleg Kalachev
67e2185d70 docs: more proper-names checks! 2019-02-15 02:56:28 +03:00
Oleg Kalachev
82f9b9d6c1 aruco_map: enable rotating (yaw, pitch, roll) each marker in the map 2019-02-14 05:46:00 +03:00
Oleg Kalachev
c2dafd73bb Improve .editorconfig a little 2019-02-14 04:52:25 +03:00
Oleg Kalachev
db218e248a simple_offboard: report the last STATUSTEXT message on arming and offboard timeout 2019-02-13 23:55:38 +03:00
Oleg Kalachev
6f92f7ca71 Fix docs 2019-02-13 22:04:28 +03:00
Oleg Kalachev
730273c9fe docs: add article on vl53l1x rangefinder 2019-02-13 21:48:20 +03:00
sfalexrog
23fd44cb1f builder: Install pip from pypa 2019-02-13 18:08:44 +03:00
sfalexrog
4d28073110 optical_flow: Lower precision from double to single 2019-02-13 17:25:47 +03:00
Oleg Kalachev
6f05a13ecf docs: fixes 2019-02-13 13:20:47 +03:00
Oleg Kalachev
24e8db8889 docs: small improvements 2019-02-13 13:20:47 +03:00
sfalexrog
e6ba681298 docs: Add note about flow sensor rotation 2019-02-12 19:52:12 +03:00
Oleg Kalachev
cb4468e719 Fix 2019-02-12 09:36:51 +03:00
Oleg Kalachev
c4448315aa aruco_map: publish visualization markers 2019-02-12 03:16:44 +03:00
Oleg Kalachev
6898837c22 Set recommended tab width for .txt files 2019-02-12 01:14:15 +03:00
Oleg Kalachev
9cf6524ad6 aruco_detect: fix single markers frame (with snapping) 2019-02-12 00:15:59 +03:00
Oleg Kalachev
e61ea4adc8 Move interactive.py node to clever_tools 2019-02-10 03:33:05 +03:00
Oleg Kalachev
ed855907f1 docs: fix markdown, remove markdownlint ignore 2019-02-10 03:17:21 +03:00
Oleg Kalachev
6f86b9e623 Use tabs in all .cpp files 2019-02-10 02:56:25 +03:00
Oleg Kalachev
b3d6432d4a Remove unused file 2019-02-10 02:54:12 +03:00
Oleg Kalachev
9c9078d23d Remove aruco_vpe nodelet 2019-02-10 02:51:48 +03:00
Oleg Kalachev
6247a623b9 aruco_pose: cleanup package.xml and change format to 2 2019-02-10 00:39:09 +03:00
Oleg Kalachev
adc485c75a Refactor aruco_pose, split up to aruco_detect and aruco_map notelets 2019-02-10 00:33:31 +03:00
Oleg Kalachev
38f89fd68f Merge branch 'kishere-master' 2019-02-09 06:27:25 +03:00
Oleg Kalachev
5847992d26 docs: make linter happy 2019-02-09 06:07:59 +03:00
sfalexrog
0a0e1585f2 travis: Only attempt to copy cached images if there are any 2019-02-09 05:53:10 +03:00
sfalexrog
e443da60c4 Try to cache initial Raspbian image 2019-02-09 05:53:10 +03:00
sfalexrog
ab026a5ea5 Try to be more verbose with wget 2019-02-09 05:53:10 +03:00
sfalexrog
5f0e035d03 builder: Use official Raspbian mirror for initial image download
Downloads from our mirror often time out, resulting in failed builds for no good reason. We may want to try relying on official mirrors instead, they should have higher bandwidth.
2019-02-09 05:53:10 +03:00
sfalexrog
ac173919e9 Merge branch 'master' into master 2019-02-08 14:30:00 +03:00
Oleg Kalachev
6738018a4a image: add ntpdate 2019-02-08 02:34:06 +03:00
Oleg Kalachev
fdb1e18aa8 snippets: add example on changing flight mode 2019-02-08 02:34:06 +03:00
sfalexrog
032f49eaa0 optical_flow: Invalidate previous frame on error 2019-02-07 00:24:59 +03:00
sfalexrog
8f332d8d53 Automatically build and lint documentation (#100)
* Build and publish docs with the RPi image

* travis: Don't use docker for gitbook building

* docs: markdownlint fixes

* travis: Don't lint lessons

* travis: Don't lint lessons (for real this time)

* docs: Style fixes

* travis: Fix typo to actually deploy build artifacts

* travis: Disable automatic docs deployment, revisit this later
2019-02-06 19:28:02 +03:00
sfalexrog
94a8b7a040 builder: Run rosdep for the 'pi' user 2019-02-06 18:20:25 +03:00
Oleg Kalachev
6a54749a05 Remove unused file 2019-02-06 03:13:53 +03:00
Oleg Kalachev
e45a78844f Improve clever/package.xml a little 2019-02-05 23:13:04 +03:00
Konstantin Eliseev
232401e730 EN articles update
8 new English articles
2019-02-05 14:20:11 +03:00
Oleg Kalachev
a89dda8576 Run clever.service and roscore.service from user pi 2019-01-31 22:56:10 +03:00
Oleg Kalachev
2cbc9481fa Add ros3d.js web visualization page 2019-01-28 19:31:13 +03:00
Oleg Kalachev
930bf03550 Fix building documentation 2019-01-28 02:54:08 +03:00
Oleg Kalachev
fff52fc357 Fix building documentation 2019-01-28 02:07:23 +03:00
Oleg Kalachev
9f9bc3d143 Serve web interface and documentation from clever directory 2019-01-28 01:04:29 +03:00
Oleg Kalachev
d33a4b8d6f image: install Node.js 2019-01-28 00:57:25 +03:00
Oleg Kalachev
81e7331037 image: update python-rosdep to 0.15.0-1 2019-01-27 02:13:07 +03:00
Oleg Kalachev
ba9718b65b clever.launch: little simplification 2019-01-27 00:23:30 +03:00
Konstantin Eliseev
e25b1d3e07 New EN Articles
9 new EN articles
2019-01-26 23:12:09 +03:00
Oleg Kalachev
b02ebf8336 Move arduino.launch contents to clever.launch 2019-01-26 17:37:17 +03:00
sfalexrog
79d9c7dfea Update ROS package definitions 2019-01-26 16:15:07 +03:00
Oleg Kalachev
5c59e71f90 Change Monkey log paths 2019-01-25 22:25:09 +03:00
Oleg Kalachev
827f268484 Style fixes 2019-01-25 22:24:53 +03:00
Oleg Kalachev
30f982b096 Fix 2019-01-25 22:24:29 +03:00
Oleg Kalachev
21a34f3cbe image: add package tf2-web-republisher 2019-01-25 22:17:20 +03:00
Oleg Kalachev
fc411afdfc Rename monkey conf file + change monkey log path 2019-01-25 22:17:20 +03:00
Konstantin Eliseev
dffd818a42 New EN Articles
9 new EN articles
2019-01-25 18:32:04 +03:00
Tennessium
36b9aaba30 Some edits (#97) 2019-01-25 17:41:32 +03:00
tinderad
4de34fb219 Article about camera calibration (#96)
* Add files via upload

* added images

* updated links

* Update calibration.md

* added article
2019-01-25 15:32:10 +03:00
Oleg Kalachev
d4f6290c73 docs: add info on main web interface 2019-01-24 22:52:53 +03:00
Oleg Kalachev
b707531fd1 docs: add some info on rqt_image_view 2019-01-24 22:52:53 +03:00
sfalexrog
cccfffe06e Install opencv3 with Neon and VFPv3 by default
Also, mark all new releases as drafts.
2019-01-24 22:47:47 +03:00
Oleg Kalachev
bb67263e58 optical_flow: add calc_flow_gyro param 2019-01-23 21:44:13 +03:00
Oleg Kalachev
1282a28c2f docs: update docs for new simple_offboard and frames settings 2019-01-23 21:41:52 +03:00
sfalexrog
20b506f515 builder: Add missing ROS packages 2019-01-23 20:26:47 +03:00
sfalexrog
d24cf9de29 aruco_pose: Use find_package instead of hardcoded opencv paths 2019-01-23 15:29:46 +03:00
Oleg Kalachev
48e670d7aa simple_offboard: make yaw in set_velocity work 2019-01-22 17:47:53 +03:00
Oleg Kalachev
a43ff641ba Decrease mavros respawn delay 2019-01-22 17:47:53 +03:00
Oleg Kalachev
68b02e9963 Fix reading tf frame name in optical flow node 2019-01-22 17:47:53 +03:00
sfalexrog
e5220012de builder: Change docker image used for building
Also, be more thorough about killing dirmngr.
2019-01-21 21:01:51 +03:00
sfalexrog
8c92c5446e docs: Spelling fixes 2019-01-21 13:15:22 +03:00
Oleg Kalachev
b88dd6cdf2 Remove unused global_local.py 2019-01-20 20:48:31 +03:00
Oleg Kalachev
84a333231d Fix 2019-01-20 20:40:27 +03:00
Oleg Kalachev
c1a2e984ba Add roslib.js to linguist-vendored 2019-01-20 20:38:50 +03:00
Tennessium
53cc575c23 Added Android app source code (#94)
* Added android app

* Added Google Play picture

* Update rc.md

* Update rc.md

* Update rc.md

* Update rc.md

* Update rc.md

* Update rc.md

* Create android.md

* Update SUMMARY.md

* Update android.md

* Update android.md
2019-01-20 20:33:20 +03:00
Oleg Kalachev
7e2cea7425 Merge pull request #95 from mmkuznecov/master
Update face recognition article
2019-01-20 19:26:17 +03:00
mmkuznecov
f5d049f026 Update face_recognition.md 2019-01-20 19:17:54 +03:00
mmkuznecov
4a01640228 Update face_recognition.md 2019-01-20 19:11:09 +03:00
mmkuznecov
54eb6a62ec Add files via upload 2019-01-20 19:08:13 +03:00
mmkuznecov
42f7ec4f93 Update face_recognition.md 2019-01-20 19:03:01 +03:00
Oleg Kalachev
c153febb2e Merge pull request #92 from sfalexrog/WIP/update-package-xml
package: Update package.xml to version specification 2.0
2019-01-18 16:21:04 +03:00
sfalexrog
c18f130bc7 package: Update package.xml to version specification 2.0 2019-01-18 14:25:58 +03:00
Oleg Kalachev
829710dc34 Merge pull request #91 from sfalexrog/WIP/add-compressed-transport
ros: Add compressed_image_transport installation
2019-01-17 23:05:17 +03:00
sfalexrog
4a1c7c7a58 ros: Add compressed_image_transport installation 2019-01-17 22:26:36 +03:00
Oleg Kalachev
90f0305f9c Code style 2019-01-16 23:46:45 +03:00
Oleg Kalachev
c726310f3e Head for simple_offboard.cpp 2019-01-16 23:40:04 +03:00
Oleg Kalachev
2632522c13 Rename frames: local_origin -> map, fcu -> base_link, fcu_horiz -> body
To make it more compliant with REP-105
2019-01-16 22:42:26 +03:00
Oleg Kalachev
d4d91d37ee Remove libfcu_horiz 2019-01-16 22:31:48 +03:00
Oleg Kalachev
18f4498a58 Fix simple_offboard frames 2019-01-16 22:28:37 +03:00
Oleg Kalachev
5045cd6333 Fix simple_offboard building 2019-01-16 22:00:09 +03:00
Oleg Kalachev
2d3f14f534 Remove fcu_horiz library 2019-01-16 21:30:45 +03:00
Oleg Kalachev
af4d043e4e Remove SetPositionGlobal.srv from CMakeLists 2019-01-16 21:29:19 +03:00
Oleg Kalachev
fa820a998d Rewrite simple_offboard node in C++
* update_frame parameter removed
* lat, lon type changed to float64
* add reference_frames parameters
* misc parameters changes
2019-01-16 20:46:45 +03:00
Oleg Kalachev
31c7cdda01 Remove typo in package.xml 2019-01-16 20:44:32 +03:00
Oleg Kalachev
ddfe67fc45 Remove unused fcu_horiz nodelet 2019-01-16 20:44:07 +03:00
Oleg Kalachev
1b9c6d0dd6 Merge pull request #90 from sfalexrog/WIP/update-rosdep
build: Update python-rosdep to 0.14.0
2019-01-16 17:00:43 +03:00
sfalexrog
7bddeffd4e build: Update python-rosdep to 0.14.0
python-rosdep 0.13.0 was removed from Raspbian repositories, breaking our build.
2019-01-16 13:13:48 +03:00
Oleg Kalachev
b9c13053f1 Merge pull request #88 from kishere/master
EN Articles
2019-01-15 23:15:50 +03:00
Oleg Kalachev
0e4273d242 Merge pull request #89 from sfalexrog/WIP/builder_fixes
build: Kill dirmngr before unmounting chroot
2019-01-14 19:20:21 +03:00
sfalexrog
eb8cddb534 build: Kill dirmngr before unmounting chroot 2019-01-14 15:48:13 +03:00
Konstantin Eliseev
63506698e9 EN Articles
8 new English articles, SUMMARY.md updated
2019-01-14 11:49:49 +03:00
Oleg Kalachev
68db337316 docs: make camera frame images smaller 2019-01-11 21:59:24 +03:00
sfalexrog
b7d6c77218 sitl.launch: style fix 2019-01-11 18:48:34 +03:00
sfalexrog
b0805abc84 sitl: Re-add rangefinder argument 2019-01-11 18:48:22 +03:00
sfalexrog
89561771a0 sitl: Remove unused parameters from sitl.launch 2019-01-11 18:48:09 +03:00
Oleg Kalachev
bd371b4b11 docs: add info about rqt_multiplot installation 2019-01-11 17:30:54 +03:00
Oleg Kalachev
91dd98abb0 clever.launch: style fix 2019-01-03 13:54:37 +03:00
Oleg Kalachev
c622ccfc85 clever.launch: style fix 2019-01-03 13:39:32 +03:00
Oleg Kalachev
d07eba683d Replace Python vl53l1x node to C++ vl53l1x_ros (from package) 2019-01-03 13:36:33 +03:00
Oleg Kalachev
77e172e623 Fix typo 2019-01-03 09:32:18 +03:00
Oleg Kalachev
e0da6e2ddf image: add vl53l1x ros package 2019-01-03 09:31:24 +03:00
Oleg Kalachev
834d53c069 docs: editing face recog article 2019-01-03 05:24:37 +03:00
Oleg Kalachev
07bcaf21a1 docs: editing face recog article 2019-01-03 05:21:37 +03:00
Oleg Kalachev
5ef2be56c4 Merge pull request #86 from mmkuznecov/patch-1
A new article about face recognition
2019-01-03 05:12:48 +03:00
mmkuznecov
f06c358718 A new article about face recognition
This is a part of my COEX internship project where I implemented a face recognition feature that works with CLEVER.
2018-12-30 19:53:12 +03:00
Oleg Kalachev
ac590abda9 gitbook: editing en 2018-12-30 07:29:22 +03:00
Oleg Kalachev
e0b8b44fb3 Merge pull request #85 from kishere/master
EN Articles
2018-12-30 07:23:19 +03:00
Konstantin Eliseev
a114608a0d EN Articles
7 new English articles
2018-12-29 22:40:56 +03:00
Oleg Kalachev
63e3ba32db docs: update sonar article 2018-12-28 11:10:48 +03:00
Oleg Kalachev
5c2c14ca23 image: add i2c-tools 2018-12-28 04:42:05 +03:00
Oleg Kalachev
14f1b30a3b en gitbook: editing 2018-12-24 01:54:35 +03:00
Oleg Kalachev
10d872f85e Merge pull request #84 from kishere/master
New EN articles
2018-12-24 01:45:02 +03:00
Konstantin Eliseev
55c06dfd85 New EN articles
5 new translated articles
2018-12-23 12:32:44 +03:00
Oleg Kalachev
7a94494638 gitbook: little fix 2018-12-20 20:55:46 +03:00
Oleg Kalachev
f618b32321 gitbook: rebuild 2018-12-20 20:53:31 +03:00
Oleg Kalachev
44d94e6a39 docs: fix lessons links 2018-12-20 19:11:02 +03:00
Oleg Kalachev
e82c11521d docs: rviz doc improvment 2018-12-19 02:08:06 +03:00
Oleg Kalachev
b9c2ee109b docs: fixes 2018-12-15 09:31:30 +03:00
Oleg Kalachev
4bb213c9e4 docs: fix error 2018-12-15 09:30:01 +03:00
Oleg Kalachev
cb20739494 readme: add translation of the word clever 2018-12-15 09:28:21 +03:00
Oleg Kalachev
214be6d9a5 docs: little fix 2018-12-15 02:24:43 +03:00
Oleg Kalachev
f58978a442 docs: add frame_id default 2018-12-14 17:25:54 +03:00
Oleg Kalachev
7359763b0c docs: editing en 2018-12-14 16:54:05 +03:00
Oleg Kalachev
ec32d4a859 Merge pull request #83 from kishere/master
Translated Articles
2018-12-14 16:47:47 +03:00
Konstantin Eliseev
609fa2874f Add files via upload
3 new translated articles (RU to EN)
2018-12-14 13:06:35 +03:00
Oleg Kalachev
43bfcb4f59 docs: fixes 2018-12-13 10:01:37 +03:00
Oleg Kalachev
d3509ac5f9 docs: use original hc-sr04 connection schematic 2018-12-13 04:07:33 +03:00
Oleg Kalachev
612f58e5a6 readme: little addition 2018-12-13 01:38:12 +03:00
Oleg Kalachev
aa8ed7662f docs: add article about using sonar 2018-12-13 01:16:10 +03:00
Oleg Kalachev
06df8848bd image: add rpi_ws281x library for LED 2018-12-13 00:19:45 +03:00
Andrei Korigodski
02b365eb96 docs: fix typo in copterhack2017.md 2018-12-12 21:21:54 +03:00
Oleg Kalachev
db71d0e234 docs: tune arduino article 2018-12-12 06:07:30 +03:00
Oleg Kalachev
21121b294d docs: tune titles 2018-12-12 05:04:25 +03:00
Oleg Kalachev
4bca49113a Use normal link to documentation 2018-12-12 04:40:44 +03:00
Oleg Kalachev
54e6701c51 License file is not markdown 2018-12-12 04:29:14 +03:00
Oleg Kalachev
8f73c6af0b image: add pigpiod library 2018-12-12 04:14:37 +03:00
Oleg Kalachev
962ac189ea ios rc: merge repeated notifications 2018-12-12 02:14:13 +03:00
Oleg Kalachev
1e1d11b216 docs: add video from Copter Hack 2018 2018-12-12 00:30:58 +03:00
Oleg Kalachev
c3dd18d661 docs: tuning 2018-12-10 08:07:45 +03:00
Oleg Kalachev
e5c66ec77d docs: reduce images size 2018-12-10 07:57:32 +03:00
Oleg Kalachev
52ab8de1cc docs: editing and linting 2018-12-10 07:30:53 +03:00
Oleg Kalachev
31351100aa docs: making linter happy + remove unused 2018-12-10 07:11:00 +03:00
Oleg Kalachev
6f59e4c9d6 docs: yaw example 2018-12-09 22:58:21 +03:00
Oleg Kalachev
79a78ceb7b docs: small fix 2018-12-09 00:36:59 +03:00
Oleg Kalachev
ef3776e235 docs: add estimation info to glossary 2018-12-09 00:32:27 +03:00
Oleg Kalachev
422ce4b3f7 docs: aruco docs improvements 2018-12-08 23:45:56 +03:00
Oleg Kalachev
00a3ec01f2 docs: ‘vision yaw’ was removed from LPE_FUSION 2018-12-08 23:26:58 +03:00
Oleg Kalachev
da37f29d9d docs: improvements 2018-12-07 18:33:02 +03:00
Oleg Kalachev
a69146a36e docs: little addition 2018-12-07 18:33:02 +03:00
Oleg Kalachev
e7b12be958 docs: foo => flight 2018-12-07 06:20:23 +03:00
Arthur Golubtsov
c8994aebb4 Add camera visualization for Clever 3 2018-12-05 00:55:09 +03:00
Oleg Kalachev
47fc673d73 docs: add info on how to change wi-fi ssid and password 2018-12-05 00:14:30 +03:00
Oleg Kalachev
8a4cdb3287 docs: fix 2018-12-04 17:04:56 +03:00
Oleg Kalachev
253d3563d5 docs: fix links 2018-12-04 16:53:40 +03:00
Oleg Kalachev
96e6c5bc71 selfcheck.py: don’t capitalize failure messages 2018-12-03 06:31:10 +03:00
Oleg Kalachev
8c5a0716e7 selfcheck.py: check VPE and local position inconsistency 2018-12-03 06:26:01 +03:00
Oleg Kalachev
ff7ffa0c22 docs: editing 2018-12-01 21:29:26 +03:00
Oleg Kalachev
ced31329ef docs: small fix 2018-12-01 20:34:39 +03:00
Oleg Kalachev
3b2433127d gitbook: move Russian version to subdirectory, set up redirects, fix rich quotes, fixes 2018-12-01 06:59:02 +03:00
Oleg Kalachev
29c2ebc086 book.json cleanup 2018-11-30 21:10:36 +03:00
Oleg Kalachev
fb14d158ad gitbook: add anchors plugin 2018-11-30 20:55:29 +03:00
Oleg Kalachev
0e4b2a6e50 gitbook: fix link and add validate-links plugin 2018-11-30 20:38:56 +03:00
Oleg Kalachev
3c6482e204 .gitignore: add gitbook artifacts 2018-11-28 23:05:23 +03:00
Oleg Kalachev
72945cb094 docs: add Markdown tooling info 2018-11-28 23:03:52 +03:00
Oleg Kalachev
b8271dd49c docs: add English version 2018-11-28 02:18:50 +03:00
Oleg Kalachev
4cf8e19923 docs: unused file 2018-11-23 22:15:11 +03:00
Oleg Kalachev
436ec5e638 docs: unused files 2018-11-23 22:14:39 +03:00
Oleg Kalachev
d311c0584d docs: unused document 2018-11-23 22:12:38 +03:00
Oleg Kalachev
f98c31aba2 docs: style 2018-11-23 22:01:05 +03:00
Oleg Kalachev
3ca36f6edf docs: add link 2018-11-23 21:55:11 +03:00
Oleg Kalachev
7cdb627b1b docs: improve web_video_server article 2018-11-23 21:52:23 +03:00
Oleg Kalachev
8d8421ae35 docs: more info on image download page 2018-11-23 21:45:11 +03:00
Oleg Kalachev
08c38106ab docs: style 2018-11-23 21:39:37 +03:00
Oleg Kalachev
2a19a91714 docs: qgc_bridge: style 2018-11-23 21:35:54 +03:00
Oleg Kalachev
d9b29c89d9 docs: typo 2018-11-23 21:34:13 +03:00
Oleg Kalachev
c04eb6fd31 docs: wifi.md: add illustration 2018-11-23 21:33:10 +03:00
Oleg Kalachev
d1f58c2835 docs: style 2018-11-23 21:27:32 +03:00
Oleg Kalachev
29c360a501 markdownlint: allow question marks in headings 2018-11-23 21:23:41 +03:00
Oleg Kalachev
700e2b5e0f docs: safety.md style 2018-11-23 21:21:39 +03:00
Oleg Kalachev
ce1790d5e8 docs: fix network.md style 2018-11-23 21:18:18 +03:00
Oleg Kalachev
1f9ae88946 docs: fix style for assembling of clever 3 2018-11-23 00:05:37 +03:00
Oleg Kalachev
5abbdbab6c docs: improvements 2018-11-22 23:39:56 +03:00
Oleg Kalachev
80208e4c5e docs: style 2018-11-22 23:34:50 +03:00
Oleg Kalachev
c65f9eaace docs: unused file 2018-11-22 23:33:32 +03:00
Oleg Kalachev
9ebd744d2c docs: small addition 2018-11-22 22:45:39 +03:00
Oleg Kalachev
74fe0cce59 docs: small fix 2018-11-22 22:43:20 +03:00
Oleg Kalachev
8aec577706 gitbook: remove versions plugin 2018-11-22 22:40:50 +03:00
Oleg Kalachev
4c7cd17051 docs: make structure for summary 2018-11-22 22:39:24 +03:00
Oleg Kalachev
af2ce1bdc9 docs: edit raspberry pi article a little 2018-11-22 22:29:06 +03:00
Andrei Korigodski
de85a30065 docs: comment out TODOs in contributing.md 2018-11-22 19:59:51 +03:00
Andrei Korigodski
ae5ead3c75 docs: fix typo in contributing.md 2018-11-22 19:59:16 +03:00
Andrei Korigodski
e20d2f4076 docs: rename contribution.md to contributing.md 2018-11-22 19:48:27 +03:00
Oleg Kalachev
30a6ee9528 docs: fixes 2018-11-21 22:10:28 +03:00
Oleg Kalachev
6332e96b4e docs: fixes 2018-11-21 22:09:57 +03:00
Oleg Kalachev
4cf63fbd33 docs: fix 2018-11-21 22:08:47 +03:00
Oleg Kalachev
d32ec1004f docs: fixes 2018-11-21 22:08:27 +03:00
Oleg Kalachev
74940a3e31 docs: fixes 2018-11-21 22:05:58 +03:00
Oleg Kalachev
3de413cf71 docs: contribution 2018-11-21 22:01:17 +03:00
Oleg Kalachev
37443c9fdc docs: remove unused 2018-11-21 22:01:17 +03:00
Arthur Golubtsov
65666d619d Change docker image to add ability of copying directories 2018-11-19 18:50:20 +03:00
Arthur Golubtsov
3d85acaf68 Generate documentation pages via Gitbook toolchain and serve them with monkey-server 2018-11-19 18:48:48 +03:00
goldarte
b4287801a2 Updates docs/leds.md
Auto commit by GitBook Editor
2018-11-19 12:48:34 +00:00
Arthur Golubtsov
a51553fa1f Delete 2nd keyserver for ros, which was added for tests 2018-11-18 19:19:07 +03:00
Oleg Kalachev
e76f1a003d Merge pull request #81 from vilesovds/patch-3
docs: link in URL encoding format
2018-11-17 04:55:16 +03:00
Arthur Golubtsov
b31d88507e Fix versions of dirmngr (to 2.1.18-8~deb9u3) and python-rosdep (to 0.13.0-1) 2018-11-16 21:47:38 +03:00
Oleg Kalachev
d8ae4a3ad4 selfcheck.py: check pitch and roll angles (level horizon) 2018-11-15 22:59:05 +03:00
Oleg Kalachev
cb0f79cd2f docs: edit style 2018-11-14 19:23:37 +03:00
Oleg Kalachev
1b64cfbad6 docs: setup.md: edit style 2018-11-14 19:22:11 +03:00
Oleg Kalachev
0d7d299b7d docs: typos 2018-11-13 19:03:39 +03:00
Oleg Kalachev
9051b5d836 docs: add Butterfly terminal access info 2018-11-13 18:41:49 +03:00
Oleg Kalachev
3d95d83d9a docs: add selfchecking info 2018-11-13 18:41:49 +03:00
Arthur Golubtsov
f7e8497879 Delete pictures from root 2018-11-13 14:41:22 +03:00
DMITRY VILESOV
d61dea4b92 docs: link in URL encoding format
Самый простой способ запихнуть скобки в ссылку для gitbook - использовать %28 ... %29 вместо них. Русские символы были также закодированы на всякий случай...
2018-11-10 15:23:40 +03:00
Arthur Golubtsov
9cf4a7a9fa Edit summary structure, add missing links (zap.md and cl3_connectESC4in1.md) 2018-11-09 20:09:24 +03:00
Arthur Golubtsov
488be6185e Merge pull request #67 from Svetk0/CL3_assemble_new
Cl3 assemble new
2018-11-09 19:30:31 +03:00
Arthur Golubtsov
0649c0c58f Merge branch 'master' into CL3_assemble_new 2018-11-09 19:28:20 +03:00
Oleg Kalachev
24f30ca5e5 Merge pull request #80 from vilesovds/patch-2
docs: added escape chars to brackets in the link
2018-11-09 16:15:02 +03:00
Oleg Kalachev
eeb639d2b7 docs: edited fpv article a little 2018-11-09 01:50:32 +03:00
ArtemOsokin
abb8294bb0 Update SUMMARY.md 2018-11-09 01:43:25 +03:00
ArtemOsokin
237e562a4f docs: add fpv instruction (#1)
* Create fpv.md

* Update fpv.md

* Update fpv.md

* Add files via upload

* Add files via upload

* Add files via upload

* Update fpv.md

* Add files via upload

* Update fpv.md

* Update fpv.md

* Add files via upload

* Add files via upload

* Delete fpv_1.png

* Add files via upload

* Delete fpv_1.png

* Add files via upload
2018-11-09 01:42:47 +03:00
DMITRY VILESOV
e89185c654 docs: added escape chars to brackets in the link
А вот зачем дублировать эту ссылку под №12, но на английском - непонятно
2018-11-09 00:50:47 +03:00
Oleg Kalachev
a34272256a docs: remove image captions 2018-11-08 05:18:34 +03:00
Oleg Kalachev
e853df7781 docs: small fix 2018-11-08 05:11:53 +03:00
Oleg Kalachev
3517cfb869 Tune image captions 2018-11-08 05:08:57 +03:00
Oleg Kalachev
4886c3ef4c docs: small changes 2018-11-08 05:06:53 +03:00
Oleg Kalachev
51f8ea0ca4 gitbook: add image-caption plugin 2018-11-08 05:06:02 +03:00
Oleg Kalachev
7daa941ffe docs: add more info about Copter Hack 2018 2018-11-08 05:04:08 +03:00
Oleg Kalachev
5ed097ee0b snippets: add anchor link to each snippet 2018-11-08 04:33:23 +03:00
Oleg Kalachev
4e069c1e75 docs: tabs->spaces in python code 2018-11-08 04:27:08 +03:00
Oleg Kalachev
17ba10e2f2 snippets: add tf2 transform example 2018-11-05 21:04:04 +03:00
Arthur Golubtsov
dacf6a38ab changed default settings of main_camera.launch 2018-11-02 22:54:47 +03:00
Arthur Golubtsov
a4aa8bcc6d Add information and illustrations about camera orientations, update default settings in main_camera.launch 2018-11-02 22:28:50 +03:00
Arthur Golubtsov
5c8700257b Merge branch 'master' of https://github.com/CopterExpress/clever 2018-11-02 20:11:08 +03:00
Arthur Golubtsov
862b45a512 Add information for camera_markers visualization 2018-11-02 20:10:03 +03:00
Oleg Kalachev
db20dd0ec7 Merge pull request #79 from sfalexrog/WIP/build-script-fixes
Build script fixes
2018-11-02 18:56:43 +03:00
sfalexrog
8932314853 build-scripts: Disable system-wide upgrade for pip
Upgrading pip system-wide should be a task for the system package manager,
and doing it through pip itself seems to be frowned upon (not to mention leaving
the end user with a broken package installer and broken packages). It also seems
to have some fun/nasty side effects (like setting pip up to install packages for python3
instead of python2, for which pip2 is used).

Debian-packaged pip, while being older, doesn't seem to break stuff for now. End user should
be able to upgrade to a newer pip locally (which seems like the right thing to do), but
a possibility of having a more recent pip should be looked into nonetheless.
2018-11-02 11:08:19 +03:00
sfalexrog
8e0e5bba19 build-scripts: Fix upgrading pip for python3 2018-11-02 09:56:42 +03:00
Oleg Kalachev
3da2c1c79a Fix Etcher screensot 2018-11-01 19:25:44 +03:00
Oleg Kalachev
39e8874b87 Merge pull request #74 from timkondratiev/patch-1
Fixed missing sudoers changes
2018-10-29 16:52:40 +03:00
timkondratiev
d320702470 Fixed missing sudoers changes 2018-10-25 17:42:20 +03:00
Oleg Kalachev
110bba7c32 Update snippets.md 2018-10-23 04:45:20 +03:00
Oleg Kalachev
c653207daf Update copterhack2018.md 2018-10-21 02:46:04 +03:00
Oleg Kalachev
f1b4d779cb Update copterhack2018.md 2018-10-21 02:45:09 +03:00
Oleg Kalachev
0ead8d41e1 Update aruco.md 2018-10-21 02:41:26 +03:00
Oleg Kalachev
088e42a88a Update copterhack2018.md 2018-10-21 02:40:55 +03:00
Oleg Kalachev
12d2f42e41 docs: little update 2018-10-21 02:38:08 +03:00
goldarte
9c65f61db4 Creates docs/copterhack2018.md
Auto commit by GitBook Editor
2018-10-20 13:16:12 +00:00
Oleg Kalachev
225062cefe docs: some info on optical flow troubleshooting 2018-10-19 14:18:19 +03:00
Oleg Kalachev
a6196c182d Fix Travis build status link 2018-10-19 04:13:43 +03:00
Oleg Kalachev
1342182d7c Fix Travis build status icon 2018-10-19 04:13:01 +03:00
Oleg Kalachev
163af20d29 Tune up sitl.launch a little 2018-10-19 03:36:34 +03:00
Oleg Kalachev
d376bc0553 selfcheck: add vpe or mocap data checking 2018-10-19 03:32:42 +03:00
Oleg Kalachev
802d04e1eb selfcheck: add checking optical flow data 2018-10-19 03:23:46 +03:00
Oleg Kalachev
99b03ae5be selfcheck: add rangefinder data checking 2018-10-19 03:22:49 +03:00
Oleg Kalachev
9a3c13da77 simple_offboard: better handle non-existent frame_ids in get_telemetry 2018-10-19 00:14:19 +03:00
Oleg Kalachev
d012c4fe7a simple_offboard: fix bug when navigate target is at 0 distance 2018-10-18 23:48:26 +03:00
Oleg Kalachev
75d20b1234 docs: update opt-flow firmware link 2018-10-18 01:42:38 +03:00
Oleg Kalachev
96fb8a21e6 docs: small fix 2018-10-18 01:42:38 +03:00
Oleg Kalachev
39787af90b simple_offboard: make behaviour more reasonable when frame_id doesn’t exist 2018-10-18 01:42:38 +03:00
Oleg Kalachev
07a8ed0dc2 clever.launch: little fix 2018-10-18 01:42:38 +03:00
Oleg Kalachev
ee3941f16c Merge pull request #72 from vilesovds/patch-1
Fixed broken links
2018-10-18 00:40:54 +03:00
vilesovds
ffe89f8265 Fixed broken links 2018-10-18 00:27:07 +03:00
Artem Smirnov
2a0562188a image: Add params for monkey 2018-10-17 16:04:58 +03:00
Artem Smirnov
7978c9e6fa Merge pull request #71 from urpylka/master
Последние правки
2018-10-17 15:07:24 +03:00
Arthur Golubtsov
4237192802 Merge branch 'master' of https://github.com/CopterExpress/clever 2018-10-16 18:36:27 +03:00
Arthur Golubtsov
3caa6796b6 set the body/frame_id value to fcu_horiz 2018-10-16 14:20:59 +03:00
Oleg Kalachev
fcf9b6b909 docs: px4 parameters article stub 2018-10-16 02:48:56 +03:00
Artem Smirnov
572d8dc55f image: Delete enable web server param 2018-10-14 08:33:23 +03:00
Artem Smirnov
6f473816a1 image: Fix path to roscore.env 2018-10-14 08:33:09 +03:00
Artem Smirnov
6701c17332 image: Add debug output 2018-10-14 06:59:49 +03:00
Artem Smirnov
89cee43d38 image: Move my repeat func to my_travis_retry 2018-10-14 05:17:48 +03:00
Artem Smirnov
c17dde8f8f image: Remove symlink 2018-10-12 20:38:49 +03:00
Artem Smirnov
6e1aa44f2d image: Fix version cv_camera 2018-10-12 20:38:30 +03:00
Artem Smirnov
660d26bbce image: Fix bug 2018-10-12 19:25:23 +03:00
Artem Smirnov
7e7cb1c085 image: Remove sudo 2018-10-12 19:23:20 +03:00
Artem Smirnov
2aef7fbfba image: Don't use symlink 2018-10-12 19:13:34 +03:00
Artem Smirnov
76347bf4cc image: Change monkey startup 2018-10-12 19:12:24 +03:00
Artem Smirnov
280a0003ed image: Replace : to = for versions 2018-10-12 18:54:30 +03:00
Artem Smirnov
74a1e1cbee image: Fix rosdep key 2018-10-12 18:37:59 +03:00
Artem Smirnov
2099c75fa8 image: Add dependencies for compressed-image-transport 2018-10-12 18:37:43 +03:00
Artem Smirnov
cbb19271bf image: Debug install packages w versions 2018-10-12 18:37:07 +03:00
Oleg Kalachev
6fc2f952ce docs: add info on using rqt 2018-10-12 16:55:16 +03:00
Artem Smirnov
62c22d3539 image: Add ros_comm & rosbash
Doesn't work roscd & rosrun
2018-10-12 16:51:06 +03:00
Artem Smirnov
83ea7b8f54 image: Update cv_camera 2018-10-11 16:36:41 +03:00
Artem Smirnov
52fbe86e0f image: Add my_travis_retry for pip install 2018-10-10 15:28:29 +03:00
Artem Smirnov
d000f81356 image: Remove /dev/null on apt update 2018-10-10 15:28:11 +03:00
Artem Smirnov
e815c14070 image: Replace True to true, False to false 2018-10-10 13:23:58 +03:00
Artem Smirnov
8b4b7221b5 image: Unfix git 2018-10-10 12:09:41 +03:00
Artem Smirnov
6c025d84ad Merge pull request #68 from urpylka/master
New structure of the CLEVER
2018-10-10 11:51:19 +03:00
Artem Smirnov
ed08f41065 image: Enable debug output on install packages 2018-10-10 11:50:14 +03:00
Artem Smirnov
71e8d74160 image: Remove spaces 2018-10-10 11:47:32 +03:00
Artem Smirnov
6261ff9da5 Merge remote-tracking branch 'upstream/master' 2018-10-09 20:03:34 +03:00
Oleg Kalachev
f507923cb1 docs for experimental optical flow feature 2018-10-09 15:54:08 +03:00
Oleg Kalachev
8017904261 z_shift param in vl53 driver 2018-10-09 14:53:11 +03:00
Artem Smirnov
9a4d467d9f image: Add mavros_extras as depend of clever 2018-10-03 23:41:59 +03:00
Artem Smirnov
640781f381 image: Add web_video_server as depend of clever 2018-10-03 22:31:47 +03:00
Artem Smirnov
b255de4627 image: Change debug output in init_rpi.sh 2018-10-03 22:15:45 +03:00
Artem Smirnov
bb9ece650f image: Add cv_camera as depend for clever 2018-10-03 18:58:05 +03:00
Svetk0
ea860e20a6 Add files via upload 2018-10-03 13:23:47 +03:00
Svetk0
87686c1d36 Delete cl3_connectionESC4in1.jpg 2018-10-03 13:23:22 +03:00
Svetk0
e7ee8d2317 Add files via upload 2018-10-03 13:17:54 +03:00
Svetk0
b21c6bce9f Delete cl3_connectionESC4in1.jpg 2018-10-03 13:15:49 +03:00
Artem Smirnov
415689d725 image: Fix IMAGE_VERSION 2018-10-02 18:18:12 +03:00
Artem Smirnov
1b66508df7 image: Change source image path 2018-10-02 18:15:20 +03:00
Artem Smirnov
12c431f87c image: Remove MIT license 2018-10-02 17:43:56 +03:00
Artem Smirnov
00a506cfdf image: Add update pip 2018-10-02 17:42:30 +03:00
Artem Smirnov
e13ca40a75 image: Fix monkey 2018-10-02 15:59:42 +03:00
Svetk0
679e0bbd00 Add files via upload 2018-10-01 23:46:16 +03:00
Svetk0
58a73b3b53 Create cl3_connectESC4in1.md 2018-10-01 23:41:17 +03:00
Artem Smirnov
3a2ea23822 image: Remove slash 2018-10-01 22:00:25 +03:00
Artem Smirnov
fd4afdfc84 image: Fix butterfly.socket path 2018-10-01 20:18:50 +03:00
Artem Smirnov
ec757e3418 image: Replace echo to echo_stamp 2018-10-01 20:16:01 +03:00
Artem Smirnov
efd9d82131 Merge branch 'before-merge'
# Conflicts:
#	builder/assets/clever.service
#	builder/assets/hardware_setup.sh
#	builder/assets/kinetic-ros-clever.rosinstall
#	builder/assets/roscore.env
#	builder/assets/roscore.service
2018-10-01 20:06:01 +03:00
Artem Smirnov
affd349ee9 image: Install Monkey (web server) 2018-10-01 20:01:13 +03:00
Artem Smirnov
2ae1c1dfaa image: Install Butterfly (web terminal) 2018-10-01 20:01:13 +03:00
Artem Smirnov
bc6f066804 image: remove dubllicated code 2018-10-01 20:01:13 +03:00
Artem Smirnov
1f5f814f42 image: Update web_video_server version 2018-10-01 20:01:13 +03:00
Artem Smirnov
fc9b33b698 image: Add compressed_image_transport plugin 2018-10-01 20:01:13 +03:00
Artem Smirnov
1ed4221d9f image: Add ROS packages for interactive markers 2018-10-01 20:01:13 +03:00
Artem Smirnov
fe7f29b76f image: Set up syntax highlighting in vim for .launch files 2018-10-01 20:01:13 +03:00
Artem Smirnov
a165a4817c image: Deny byobu to check available updates 2018-10-01 20:01:13 +03:00
Artem Smirnov
e35a7fe108 image_builder: add ltrace utility 2018-10-01 20:01:13 +03:00
Artem Smirnov
f91b7742c3 image_builder: new configure UART on RPi 2018-10-01 20:01:13 +03:00
Artem Smirnov
5065ca8c3b image_builder: change os version to 2018-06-27 2018-10-01 20:01:13 +03:00
Artem Smirnov
3a2b8bd1f4 image_builder: Set max space for syslogs 2018-10-01 20:01:13 +03:00
Artem Smirnov
837c7af7ee image_builder: change builder to img-tool 2018-10-01 20:01:13 +03:00
Artem Smirnov
6c9103835f image_builder: remove docker_builder from repo
see: https://github.com/urpylka/img-tool
2018-10-01 20:01:13 +03:00
Artem Smirnov
d16a27c891 image_builder: try to fix image path 2018-10-01 20:01:13 +03:00
Artem Smirnov
834e21aaf0 image_builder: fix visibility TRAVIS_TAG in image-build 2018-10-01 20:01:13 +03:00
Artem Smirnov
7260433a91 image_builder: fix problem w setup TRAVIS_TAG 2018-10-01 20:01:13 +03:00
Artem Smirnov
c4bfff69f4 image_builder: remove unused string 2018-10-01 20:01:13 +03:00
Artem Smirnov
e71515ee3e image_builder: fix sh to bash 2018-10-01 20:01:13 +03:00
Artem Smirnov
2372824122 image_builder: fix image name in travis 2018-10-01 20:01:13 +03:00
Artem Smirnov
521baaa652 image_builder: move mjpeg-streamer to ros-clever 2018-10-01 20:01:13 +03:00
Artem Smirnov
8df037d1ad image_builder: install lxml w apt
pymavlink required lxml
can't install w pip https://stackoverflow.com/questions/33064433/lxml-will-never-finish-building-on-ubuntu
2018-10-01 20:01:13 +03:00
Artem Smirnov
afdbe7ba7a image_builder: fix headers & move apt init block 2018-10-01 20:01:13 +03:00
Artem Smirnov
852308c78d image_builder: add header 2018-10-01 20:01:13 +03:00
Artem Smirnov
020f3b6259 image_builder: fix lxml
https://github.com/ArduPilot/pymavlink
2018-10-01 20:01:13 +03:00
Artem Smirnov
4fdcb32044 image_builder: fix comments 2018-10-01 20:01:13 +03:00
Artem Smirnov
d55e7ed404 image_builder: delete comments 2018-10-01 20:01:13 +03:00
Artem Smirnov
4e38266101 image_builder: update .travis.yml 2018-10-01 20:01:13 +03:00
Artem Smirnov
330e3f92b4 image_builder: fix libxml2 requirements 2018-10-01 20:01:13 +03:00
Artem Smirnov
72ea0daeec image_builder: fix visibility of the function 2018-10-01 20:01:13 +03:00
Artem Smirnov
b938b28076 image_builder: fix path to mjpeg-streamer 2018-10-01 20:01:13 +03:00
Artem Smirnov
5bb818332a docs: add script for generate ros_lib to arduino article 2018-10-01 20:01:13 +03:00
Artem Smirnov
85a7db1b56 image_builder: fix geographic lib datasets 2018-10-01 20:01:13 +03:00
Artem Smirnov
972abc6277 image_builder: some fixes after transition to the new architecture 2018-10-01 20:01:13 +03:00
Artem Smirnov
5fdf22afc3 image_builder: fix pip package 2018-10-01 20:01:13 +03:00
Artem Smirnov
80669d7e2f image_builder: little fixes 2018-10-01 20:01:13 +03:00
Artem Smirnov
74157b4901 image_builder: fix path to builder API 2018-10-01 20:01:13 +03:00
Artem Smirnov
a42f631bf4 image_builder: little fixes 2018-10-01 20:01:13 +03:00
Artem Smirnov
47648cd57f image_builder: remove git debug string 2018-10-01 20:01:13 +03:00
Artem Smirnov
eec5b9c9b2 image_builder: change date output 2018-10-01 20:01:13 +03:00
Artem Smirnov
61544c2099 image_builder: new architecture for builder 2018-10-01 20:01:13 +03:00
Artem Smirnov
afa3523cb2 image_builder: fix syntax 2018-10-01 20:01:13 +03:00
Artem Smirnov
8c6af93fd1 image_builder: add qemu-arm-static to image-chroot.sh 2018-10-01 20:01:13 +03:00
Artem Smirnov
3dd5747b3c image_builder: fix bug w ${3:='def'} & standardization vars 2018-10-01 20:01:13 +03:00
Artem Smirnov
2901234d9c image_builder: new name for temp scripts 2018-10-01 20:01:13 +03:00
Artem Smirnov
595e67a928 image_builder: fix bug w scope of variable 2018-10-01 20:01:13 +03:00
Artem Smirnov
fa817d9f80 image_builder: fix bugs 2018-10-01 20:01:13 +03:00
Artem Smirnov
72b20f8c94 image_builder: fix image path 2018-10-01 20:01:13 +03:00
Artem Smirnov
6dc0bd5cc5 image_builder: disable stdout in wget 2018-10-01 20:01:13 +03:00
Artem Smirnov
da9eb7d0ba image_builder: disable debug comments 2018-10-01 20:01:13 +03:00
Artem Smirnov
18f973ce00 image_builder: debug 2018-10-01 20:01:13 +03:00
Artem Smirnov
469542416d image_builder: delete echo_stamp 2018-10-01 20:01:13 +03:00
Artem Smirnov
fb6b96fa5b image_builder: try to interrupt script-stage 2018-10-01 20:01:13 +03:00
Artem Smirnov
98f0b57eb6 image_builder: fix path to script after redesign builder 2018-10-01 20:01:13 +03:00
Artem Smirnov
4f8956829f image_builder: fix syntax with quotes & = 2018-10-01 20:01:13 +03:00
Artem Smirnov
9c6991e9d7 image_builder: fix syntax 2018-10-01 20:01:13 +03:00
Artem Smirnov
59b2c3895c image_builder: remove yadisk uploader 2018-10-01 20:01:13 +03:00
Artem Smirnov
ccef57f311 image_builder: new structure of builder 2018-10-01 20:01:13 +03:00
Artem Smirnov
c25a752b20 image_builder: add only tag or branch format 2018-10-01 20:01:13 +03:00
Artem Smirnov
9ecf10ea43 image_builder: update readme 2018-10-01 20:01:13 +03:00
Artem Smirnov
1238107b13 image_builder: try to build by my tag 2018-10-01 20:01:13 +03:00
Artem Smirnov
55fc7493c9 image_builder: remove on: tags: true 2018-10-01 20:01:13 +03:00
Artem Smirnov
5959f7cbcc image_builder: add no-verbose flag to wget 2018-10-01 20:01:13 +03:00
Artem Smirnov
25ab5933a2 image_builder: remove Jenkins files 2018-10-01 20:01:13 +03:00
Artem Smirnov
2e019c136f image_builder: try to fix travis 2018-10-01 20:01:13 +03:00
Artem Smirnov
1d91f2800d image_builder: fix trouble w permissions 2018-10-01 20:01:13 +03:00
Artem Smirnov
66b879ebb7 image_builder: add sudo for zip command 2018-10-01 20:01:13 +03:00
Artem Smirnov
e47824b1ff image_builder: use BUILD_DIR in Travis 2018-10-01 20:01:13 +03:00
Artem Smirnov
0e791c7bf7 image_builder: replace Jenkins to Travis icon 2018-10-01 20:01:13 +03:00
Artem Smirnov
4a02d27e35 image_builder: remove --no-verbose flag 2018-10-01 20:01:13 +03:00
Artem Smirnov
224d09be9f image_builder: show percents 2018-10-01 20:01:13 +03:00
Artem Smirnov
f236db3392 image_builder: fix got TARGET_COMMIT 2018-10-01 20:01:13 +03:00
Artem Smirnov
ee88d7d6bf image_builder: fix quotes 2018-10-01 20:01:13 +03:00
Artem Smirnov
273310f915 image_builder: add IMAGE_NAME 2018-10-01 20:01:13 +03:00
Artem Smirnov
405b956b06 image_builder: fix path in travis 2018-10-01 20:01:13 +03:00
Artem Smirnov
ef88fcbfd3 image_builder: fix path to images & add debug output 2018-10-01 20:01:13 +03:00
Artem Smirnov
c98913000c image_builder: fix docker image 2018-10-01 20:01:13 +03:00
Artem Smirnov
85d765e5e7 image_builder: delete space 2018-10-01 20:01:13 +03:00
Artem Smirnov
1406229b11 image_builder: move deploy folder to assets 2018-10-01 20:01:13 +03:00
Artem Smirnov
9c3a8627b5 image_builder: remove space in .travis 2018-10-01 20:01:13 +03:00
Artem Smirnov
a548fcafa8 image_builder: remove unused in gitignore 2018-10-01 20:01:13 +03:00
Artem Smirnov
b029054946 image_builder: remove clever_arduino.tar.gz
use generate_ros_lib script
2018-10-01 20:01:13 +03:00
Artem Smirnov
bcab7a9b15 remove _config.yml 2018-10-01 20:01:13 +03:00
Artem Smirnov
5cf7e86d33 image_builder: split builder_docker & builder_scripts skip travis 2018-10-01 20:01:13 +03:00
Artem Smirnov
c0cd53c733 image_builder: fix syntax: delete slash 2018-10-01 20:01:13 +03:00
Artem Smirnov
45743ca6ac image_builder: change get_new_image to get_image 2018-10-01 20:01:13 +03:00
Artem Smirnov
54048922fa image_builder: fix permissions & fix get_new_image 2018-10-01 20:01:13 +03:00
Artem Smirnov
2b1fd00ca0 image_builder: comment all stages for test gh release 2018-10-01 20:01:13 +03:00
Artem Smirnov
ccc5a12320 image_builder: zip image 2018-10-01 20:01:13 +03:00
Artem Smirnov
c828effd23 image_builder: split image_config.sh & standardization headers 2018-10-01 20:01:13 +03:00
Artem Smirnov
d7e6629567 image_builder: add normal deploy & delete unused code [skip travis] 2018-10-01 20:01:13 +03:00
Artem Smirnov
b6a06c62d1 image_builder: fix clever requirements 2018-10-01 20:01:13 +03:00
Artem Smirnov
cea91bd082 image_builder: comment unused import 2018-10-01 20:01:13 +03:00
Artem Smirnov
a9e5270acd image_builder: fix syntax in README 2018-10-01 20:01:13 +03:00
Artem Smirnov
3f5b856310 image_builder: try to fix bug w can't find setup.bash 2018-10-01 20:01:13 +03:00
Artem Smirnov
7595971f96 image_builder: add threads flag to wstool 2018-10-01 20:01:13 +03:00
Artem Smirnov
1ecc2774d7 image_builder: use deb package for mjpg-streamer 2018-10-01 20:01:13 +03:00
Artem Smirnov
7e47914abe image_builder: comment not working code 2018-10-01 20:01:13 +03:00
Artem Smirnov
ef204e0a54 image_builder: add error handler 2018-10-01 20:01:13 +03:00
Artem Smirnov
8e1015f64e image_builder: unused tee 2018-10-01 20:01:13 +03:00
Artem Smirnov
ec9d7ab22f image_builder: comment github deploy 2018-10-01 20:01:13 +03:00
Artem Smirnov
8cc9a916c4 image_builder: fix syntax 2018-10-01 20:01:13 +03:00
Artem Smirnov
0d1c1bfec2 image_builder: remove cache 2018-10-01 20:01:13 +03:00
Artem Smirnov
90debd91ba image_builder: install ros-kinetic-ros as depend for clever 2018-10-01 20:01:13 +03:00
Artem Smirnov
bccecbbc88 image_builder: try to use github release 2018-10-01 20:01:13 +03:00
Artem Smirnov
850afc6688 image_builder: Add link to .travis.yml 2018-10-01 20:01:13 +03:00
Artem Smirnov
3bffcba4de image_builder: fix .travis.yml 2018-10-01 20:01:13 +03:00
Artem Smirnov
0fc319c2af image_builder: debug 2018-10-01 20:01:13 +03:00
Artem Smirnov
3434f6963e image_builder: add yaml file to repo 2018-10-01 20:01:13 +03:00
Artem Smirnov
482d47a48c image_builder: debug 2018-10-01 20:01:13 +03:00
Artem Smirnov
0ce4714f8e image_builder: debug 2018-10-01 20:01:13 +03:00
Artem Smirnov
1d27febf6a image_builder: debug rosdep 2018-10-01 20:01:13 +03:00
Artem Smirnov
290301115b image_builder: debug 2018-10-01 20:01:13 +03:00
Artem Smirnov
81ef67787a image_builder: syntax fix 2018-10-01 20:01:13 +03:00
Artem Smirnov
815bebf6f2 image_builder: fix clever.rosinstall 2018-10-01 20:01:13 +03:00
Artem Smirnov
1f29d4c0ec image_builder: remove numbers 2018-10-01 20:01:13 +03:00
Artem Smirnov
4eaf8c87c5 image_builder: fix install dirmngr 2018-10-01 20:01:13 +03:00
Artem Smirnov
234b377ceb image_builder: TEMP: Add support installation wo sources 2018-10-01 20:01:13 +03:00
Artem Smirnov
23ba569e48 image_builder: change rosdep installation loop 2018-10-01 20:01:13 +03:00
Artem Smirnov
6e364009e3 image_builder: restyle for init ros_catkin_ws 2018-10-01 20:01:13 +03:00
Artem Smirnov
b1f79c1903 image_builder: add comments whats need todo 2018-10-01 20:01:13 +03:00
Artem Smirnov
0cb23e600c image_builder: trans /dev/null to comment 2018-10-01 20:01:13 +03:00
Artem Smirnov
04b22af49d image_builder: comeback /dev/null 2018-10-01 20:01:13 +03:00
Artem Smirnov
1e0589b3ed image_builder: debug opencv installation 2018-10-01 20:01:13 +03:00
Artem Smirnov
214224101c image_builder: stderr to /dev/null 2018-10-01 20:01:13 +03:00
Artem Smirnov
d574adbc3f image_builder: debug opencv installation 2018-10-01 20:01:13 +03:00
Artem Smirnov
1c77d030d9 image_builder: debug opencv installation 2018-10-01 20:01:13 +03:00
Artem Smirnov
0410246918 image_builder: debug opencv installation 2018-10-01 20:01:13 +03:00
Artem Smirnov
a86e662c1e image_builder: disable OK of apt-key 2018-10-01 20:01:13 +03:00
Artem Smirnov
c68fb8883c image_builder: debug opencv installation 2018-10-01 20:01:13 +03:00
Artem Smirnov
7dd0779f69 image_builder: remove own 'q' 2018-10-01 20:01:13 +03:00
Artem Smirnov
98ad1cdba8 image_builder: debug opencv installation 2018-10-01 20:01:13 +03:00
Artem Smirnov
386c88a8f4 image_builder: debug installation opencv 2018-10-01 20:01:13 +03:00
Artem Smirnov
5accc55e93 image_builder: debug opencv installation 2018-10-01 20:01:13 +03:00
Artem Smirnov
756e50d3ac image_builder: debug 2018-10-01 20:01:13 +03:00
Artem Smirnov
d8c4b452c5 image_builder: debug opencv installation 2018-10-01 20:01:13 +03:00
Artem Smirnov
1430968566 image_builder: fix syntax 2018-10-01 20:01:13 +03:00
Artem Smirnov
13fcc3c20a image_builder: debug opencv3 installation 2018-10-01 20:01:13 +03:00
Artem Smirnov
8b7c20b40c image_builder: replace terrible echo 2018-10-01 20:01:13 +03:00
Artem Smirnov
f7b58c9e6d image_builder: debug 2018-10-01 20:01:13 +03:00
Artem Smirnov
2adb329ece image_builder: delete duplicate string 2018-10-01 20:01:13 +03:00
Artem Smirnov
a5cdb9dc00 image_builder: debug opencv installation 2018-10-01 20:01:13 +03:00
Artem Smirnov
c971b1b00c image_builder: add opencv version & messages for SUCCESS/ERROR 2018-10-01 20:01:13 +03:00
Artem Smirnov
85bbd15bd0 image_builder: remove old comment 2018-10-01 20:01:13 +03:00
Artem Smirnov
dc597c9299 image_builder: try to fix continue if error between stages 2018-10-01 20:01:13 +03:00
Artem Smirnov
b85b8a978a image_builder: disable /dev/null for debub
E: Unable to correct problems, you have held broken packages.
2018-10-01 20:01:13 +03:00
Artem Smirnov
b27ad9d395 image_builder: rm stderr in coex-mirror.gpg download 2018-10-01 20:01:13 +03:00
Artem Smirnov
671de1a799 image_builder: fix stderr transmission 2018-10-01 20:01:13 +03:00
Artem Smirnov
2565997fb6 image_builder: change key-storage 2018-10-01 20:01:13 +03:00
Artem Smirnov
8baba02f98 image_builder: stderr to /dev/null 2018-10-01 20:01:13 +03:00
Artem Smirnov
fbbfdd54e8 image_builder: fix syntax & move install opencv to software stage 2018-10-01 20:01:13 +03:00
Artem Smirnov
a09bc7156a image_builder: install opencv3 as deb package 2018-10-01 20:01:13 +03:00
Artem Smirnov
5922619605 image_builder: redirect stderr to file 2018-10-01 20:01:13 +03:00
Artem Smirnov
2bd9e119f8 image_builder: little fix 2018-10-01 20:01:13 +03:00
Artem Smirnov
a52faadbef image_builder: update readme 2018-10-01 20:01:13 +03:00
Artem Smirnov
5751184c46 image_builder: idea 2018-10-01 20:01:13 +03:00
Artem Smirnov
d7418e80c2 image_builder: success if success 2018-10-01 20:01:13 +03:00
Artem Smirnov
d9578d3c32 image_builder: add travis 2018-10-01 20:01:13 +03:00
Artem Smirnov
66b09ee99a image_builder: try ros build on travis 2018-10-01 20:01:13 +03:00
Artem Smirnov
8b213d6103 image_builder: disable STDERR in mjpeg-streamer 2018-10-01 20:01:13 +03:00
Artem Smirnov
2f584fd2d7 image_builder: disable STDOUT in wget image 2018-10-01 20:01:13 +03:00
Artem Smirnov
9cf8357c4f image_builder: change master by default 2018-10-01 20:01:13 +03:00
Artem Smirnov
3f53de0832 image_builder: fix autosizer awk
echo "2:48234496B:7516192767B:7467958272B:ext4::;" | awk -F: '{ print substr($2,0,length($2)-1) }'
Default awk in docker: 4823449
GNU Awk 4.1.3, API: 1.1 (GNU MPFR 3.1.4, GNU MP 6.1.0): 48234496
2018-10-01 20:01:13 +03:00
Artem Smirnov
59e6f33e9f image_builder: not listing /image_builder/image/ 2018-10-01 20:01:13 +03:00
Artem Smirnov
24edace814 image_builder: rename to build.sh 2018-10-01 20:01:13 +03:00
Artem Smirnov
5da1125ecd image_builder: use dynamic counting vars 2018-10-01 20:01:13 +03:00
Artem Smirnov
8566c2ccbd image_builder: temp comment ROS for debug 2018-10-01 20:01:13 +03:00
Artem Smirnov
d3acb298e8 image_builder: move REGISTER to var 2018-10-01 20:01:13 +03:00
Artem Smirnov
3827bb4210 image_builder: add --rm flag 2018-10-01 20:01:13 +03:00
Artem Smirnov
e71519d358 image_builder: add exit code true 2018-10-01 20:01:13 +03:00
Artem Smirnov
4c2a881407 image_builder: delete condition of existing dir 2018-10-01 20:01:13 +03:00
Artem Smirnov
a67179105c image_builder: fix path 2018-10-01 20:01:13 +03:00
Artem Smirnov
e092cec215 image_builder: remove $ from params message 2018-10-01 20:01:13 +03:00
Artem Smirnov
4f8e9019af image_builder: add bc to Docker image 2018-10-01 20:01:13 +03:00
Artem Smirnov
4d68f77368 image_builder: fix var 2018-10-01 20:01:13 +03:00
Artem Smirnov
a05ae6cafe image_builder: add params message 2018-10-01 20:01:13 +03:00
Artem Smirnov
1283219c51 image_builder: force write 2018-10-01 20:01:13 +03:00
Artem Smirnov
de30d0d09f image_builder: doc: update docker link 2018-10-01 20:01:13 +03:00
Artem Smirnov
ab5df9f725 image_builder: fix path 2018-10-01 20:01:13 +03:00
Artem Smirnov
613fe1639c image_builder: change sample 2018-10-01 20:01:13 +03:00
Artem Smirnov
4de6468393 image_builder: remove VOLUME from docker file 2018-10-01 20:01:13 +03:00
Artem Smirnov
c4f4c9a81a image_builder: try to fix bag 2018-10-01 20:01:13 +03:00
Artem Smirnov
5a22dce8d4 image_builder: fix path 2018-10-01 20:01:13 +03:00
Artem Smirnov
bea4f3044c image_builder: add test Dockerfile 2018-10-01 20:01:13 +03:00
Artem Smirnov
f8018aab68 image_builder: add TODO to autosizer 2018-10-01 20:01:13 +03:00
Artem Smirnov
a9d9adc25f image_builder: add readme for docker 2018-10-01 20:01:13 +03:00
Artem Smirnov
e04cb7cb6a image_builder: use params for threads numbers 2018-10-01 20:01:13 +03:00
Artem Smirnov
8539ff8430 image_builder: move partition change to init script 2018-10-01 20:01:13 +03:00
Artem Smirnov
8b60d2c61d image_builder: delete unused script 2018-10-01 20:01:13 +03:00
Artem Smirnov
5590e64e0a image_builder: little syntax fix 2018-10-01 20:01:13 +03:00
Artem Smirnov
8379f8ac6a image_builder: add suffix for mktemp 2018-10-01 20:01:13 +03:00
Artem Smirnov
fcd6d41586 image_builder: change manual to autobuild 2018-10-01 20:01:13 +03:00
Artem Smirnov
c72b04a413 image_builder: add main script for build 2018-10-01 20:01:13 +03:00
Artem Smirnov
342bf0caed image_builder: add config file for build 2018-10-01 20:01:13 +03:00
Artem Smirnov
850b18ab35 image_builder: remove unused comment 2018-10-01 20:01:13 +03:00
Artem Smirnov
f2437b4722 image_builder: remove STATIC FUNCTION comments 2018-10-01 20:01:13 +03:00
Artem Smirnov
595d84fb7c image_builder: changes vars to SCRIPTS_DIR & IMAGE_PATH 2018-10-01 20:01:13 +03:00
Artem Smirnov
26246e3ef7 image_builder: git clone w checks 2018-10-01 20:01:13 +03:00
Artem Smirnov
70196d69ad image_builder: use another vars init 2018-10-01 20:01:13 +03:00
Artem Smirnov
5f6ba57b33 image_builder: mv rosinstall to scripts 2018-10-01 20:01:13 +03:00
Artem Smirnov
749d465556 image_builder: little syntax fix 2018-10-01 20:01:13 +03:00
Artem Smirnov
f143a94426 image_builder: rename all to IMAGE_PATH 2018-10-01 20:01:13 +03:00
Artem Smirnov
916ad43f4e image_builder: use IMAGE_PATH in get_image 2018-10-01 20:01:13 +03:00
Artem Smirnov
4850d03825 image_builder: use IMAGE_PATH in publish image 2018-10-01 20:01:13 +03:00
Artem Smirnov
8c72eb65ff image_builder: fix syntax ros_install 2018-10-01 20:01:13 +03:00
Artem Smirnov
be2ffe7580 image_builder: delete comments & spaces 2018-10-01 20:01:13 +03:00
Artem Smirnov
a0a54716b8 image_builder: not used double space after slash 2018-10-01 20:01:13 +03:00
Artem Smirnov
386c85c01b image_builder: delete STATIC FUNCTION comments 2018-10-01 20:01:13 +03:00
Artem Smirnov
908a7bfcc0 image_builder: little syntax fix 2018-10-01 20:01:13 +03:00
Artem Smirnov
a2e0e483b5 image_builder: set var by default 2018-10-01 20:01:13 +03:00
Artem Smirnov
f84e6d4598 image_builder: enhancement apt`s call 2018-10-01 20:01:13 +03:00
Artem Smirnov
5e5247aee1 image_builder: migrate from build.Jenkinsfile to manual.sh 2018-10-01 20:01:13 +03:00
Artem Smirnov
2e27485e3b image_builder: fix numbers 2018-10-01 20:01:13 +03:00
Artem Smirnov
67cb2f1c8f image_builder: self-remove if return non-zero code 2018-10-01 20:01:13 +03:00
Artem Smirnov
f2ff6eaa4a image_builder: add echo_bold to autosizer 2018-10-01 20:01:13 +03:00
Artem Smirnov
2367709b2e image_builder: add autoremove to init scripts 2018-10-01 20:01:13 +03:00
Artem Smirnov
3fc266a061 image_builder: add echo_stamp to other files 2018-10-01 20:01:13 +03:00
Artem Smirnov
a008f6b57c image_builder: fix sed expression 2018-10-01 20:01:13 +03:00
Artem Smirnov
27ef8da039 image_builder: add todo 2018-10-01 20:01:13 +03:00
Artem Smirnov
e45665502f image_builder: fix colors 2018-10-01 20:01:13 +03:00
Artem Smirnov
c6297469d7 image_builder: try to fix syntax 2018-10-01 20:01:13 +03:00
Artem Smirnov
b419b400ba image_builder: temp solution for fix mount if already mounted 2018-10-01 20:01:13 +03:00
Artem Smirnov
e7a7a87e48 image_builder: change code order in manual.sh 2018-10-01 20:01:13 +03:00
Artem Smirnov
61cb198893 image_builder: add quotes to manual 2018-10-01 20:01:13 +03:00
Artem Smirnov
dc02747f87 image_builder: add autosizer to manual 2018-10-01 20:01:13 +03:00
Artem Smirnov
676c3d6b79 image_builder: remove partition numbers 2018-10-01 20:01:13 +03:00
Artem Smirnov
e32ed43c29 image_builder: add lines 2018-10-01 20:01:13 +03:00
Artem Smirnov
b4fabf70c2 image_builder: try to normal template 2018-10-01 20:01:13 +03:00
Artem Smirnov
e0af232f76 image_builder: authors to top 2018-10-01 20:01:13 +03:00
Artem Smirnov
bdd9997bb5 image_builder: add echo_stamp 2018-10-01 20:01:13 +03:00
Artem Smirnov
950503d231 image_builder: edit to HW setup at init script 2018-10-01 20:01:13 +03:00
Artem Smirnov
20a6275ae8 image_builder: test build 2018-10-01 20:01:13 +03:00
Artem Smirnov
ef187ed37e image_builder: disable apt output 2018-10-01 20:01:13 +03:00
Artem Smirnov
11f6818663 image_builder: -j4 2018-10-01 20:01:13 +03:00
Artem Smirnov
41ef3b1d22 image_builder: /dev/null 2018-10-01 20:01:13 +03:00
Artem Smirnov
1ddec5f97b image_builder: test_install 2018-10-01 20:01:13 +03:00
Artem Smirnov
9ddd4a63bb image_builder: add cp address support 2018-10-01 20:01:13 +03:00
Artem Smirnov
3f1d9e3be0 image_builder: refactor manual script 2018-10-01 20:01:13 +03:00
Artem Smirnov
fa7c5ee40d image_builder: remove macos's shit 2018-10-01 20:01:13 +03:00
Artem Smirnov
10ee12bfcd image_builder: add all.sh 2018-10-01 20:01:13 +03:00
Artem Smirnov
a43e5861d7 image_builder: remove mount_system function 2018-10-01 20:01:13 +03:00
Artem Smirnov
1724dcc8ff image_builder: add qemu 2018-10-01 20:01:13 +03:00
Artem Smirnov
aca11bdb40 Remove conflict files 2018-09-30 19:21:36 +03:00
Oleg Kalachev
862ee9a2d0 simple_offboard: get local frame name from mavros params 2018-09-28 03:49:45 +03:00
Oleg Kalachev
a1f29738ab Add one auxiliary frames node, rename ‘fcu_horiz’ to ‘body’ by default 2018-09-28 03:41:22 +03:00
Yuliya1404
b03919ed86 Update lessons.md 2018-09-27 18:28:35 +03:00
Oleg Kalachev
d5c6c67f11 Update Flask version 2018-09-27 06:17:09 +03:00
Oleg Kalachev
07d33798a0 Add Python version of vl53l1x driver 2018-09-27 06:11:52 +03:00
Oleg Kalachev
27a748c6a6 selfcheck: add angular velocity check 2018-09-27 03:49:17 +03:00
goldarte
9c839854fa Updates docs/testovoe-opisanie-klevera-po-shablonu-robotsrosorggapter.md
Auto commit by GitBook Editor
2018-09-26 17:21:43 +00:00
goldarte
fb2ea36c4b Creates docs/testovoe-opisanie-klevera-po-shablonu-robotsrosorggapter.md
Auto commit by GitBook Editor
2018-09-26 17:20:45 +00:00
Oleg Kalachev
6ae4d63c30 Set camera capture delay 2018-09-26 01:39:19 +03:00
Oleg Kalachev
ae3ef67825 mavros: blacklisted home_position plugin 2018-09-26 01:18:51 +03:00
Oleg Kalachev
751412e639 selfcheck.py: check camera info dimensions 2018-09-22 01:46:31 +03:00
Oleg Kalachev
c73921af4f docs: add warning to rc 2018-09-22 01:38:28 +03:00
Oleg Kalachev
ab9106f902 Minor improvements to selfcheck 2018-09-22 01:28:11 +03:00
Artem Smirnov
aad6940ca7 Merge branch 'CL3_assemble_new' 2018-09-21 06:16:03 +05:00
Artem Smirnov
470e4264b2 docs: Fix syntax & other in articles of assemble 2018-09-21 06:11:27 +05:00
Artem Smirnov
72e76638ff docs: Move images from root 2018-09-21 06:11:27 +05:00
Svetk0
af1388a067 docs: Add assemble's doc of Clever 3 2018-09-21 05:36:13 +05:00
Svetk0
769c999c98 Update assemble_clever3_4in1.md 2018-09-20 11:51:10 +03:00
Svetk0
e0e53aa517 Add files via upload 2018-09-20 11:50:57 +03:00
Svetk0
3a59e60373 Add files via upload 2018-09-20 11:46:09 +03:00
Svetk0
78b4b9c938 Delete cl3_testMotorsFlysky.JPG 2018-09-20 11:45:26 +03:00
Svetk0
ea166af67b Delete cl3_mountPixracer.JPG 2018-09-20 11:45:00 +03:00
Svetk0
5baddc9946 Delete cl3_mountRaspberryPi.JPG 2018-09-20 11:44:32 +03:00
Svetk0
7357694211 Update assemble_clever3_4in1.md 2018-09-20 11:43:02 +03:00
Oleg Kalachev
8205a7c33f docs: add link to Termius 2018-09-20 09:48:30 +03:00
Oleg Kalachev
f532372535 Attempt 4 to fix build, temporarily move Butterfly install to ros_install 2018-09-19 21:32:43 +03:00
Svetk0
1dd2d0c1e4 Update assemble_clever3_4in1.md 2018-09-19 17:33:16 +03:00
Svetk0
5e5d46ee4e Update assemble_clever3_4in1.md 2018-09-19 17:29:28 +03:00
Svetk0
91782898fc Update assemble_clever3_4in1.md 2018-09-19 17:28:06 +03:00
Svetk0
58d41eda8b Update assemble_clever3_4in1.md 2018-09-19 17:23:43 +03:00
Svetk0
c017102cc9 Update assemble_clever3_4in1.md 2018-09-19 17:22:50 +03:00
Svetk0
2f757f9bfd Update assemble_clever3_4in1.md 2018-09-19 15:50:10 +03:00
Svetk0
e9c759df15 Add files via upload 2018-09-19 15:48:16 +03:00
Svetk0
111eab727e Update assemble_clever3_4in1.md 2018-09-19 15:47:20 +03:00
Svetk0
1f39d5e938 Create assemble_clever3_4in1.md 2018-09-19 12:42:24 +03:00
Svetk0
9bf908bdfb Update SUMMARY.md 2018-09-19 12:41:07 +03:00
Svetk0
cba5100d17 Update SUMMARY.md 2018-09-19 12:40:44 +03:00
Svetk0
d9b3a029c3 Update assemble.md 2018-09-19 12:26:05 +03:00
Oleg Kalachev
a2a34a4e2f Fix build, attempt 3 2018-09-19 08:16:33 +03:00
Oleg Kalachev
6f96c9e3ff Fix build, attempt #2 2018-09-19 07:04:34 +03:00
Svetk0
58ede7e85e Add files via upload 2018-08-21 13:24:52 +03:00
Svetk0
432e60f9cc Add files via upload 2018-08-17 11:47:31 +03:00
Artem Smirnov
b2bc692cc2 image_builder: add manual.sh 2018-08-16 23:40:12 +03:00
716 changed files with 88581 additions and 7108 deletions

View File

@@ -9,5 +9,12 @@ charset = utf-8
indent_style = space
indent_size = 4
[*.{js,html}]
[*.{cpp,h,js,html,txt}]
indent_style = tab
[*.txt]
tab_width = 8
[CMakeLists.txt]
indent_style = space
indent_size = 2

5
.gitattributes vendored
View File

@@ -1,2 +1,5 @@
apps/ios/cleverrc/roslib.js linguist-vendored
apps/ios/cleverrc/BinUtils.swift linguist-vendored
roslib.js linguist-vendored
eventemitter2.js linguist-vendored
ros3d.js linguist-vendored
three.min.js linguist-vendored

6
.gitignore vendored
View File

@@ -1,2 +1,6 @@
/deploy/ros_lib/
*.pyc
*.DS_Store
/images
node_modules/
_book/
package-lock.json

View File

@@ -1,22 +1,112 @@
{
"MD003": false,
"MD010": {
"code_blocks": false
},
"MD013": false,
"MD024": false,
"MD026" :{
"punctuation": ".,;:!"
},
"MD033": false,
"MD034": false,
"MD040": false,
"MD044": {
"names": [
"COEX",
"Copter Express",
"Коптер Экспресс",
"Клевер",
"MAVLink",
"ROS",
"ROS Kinetic",
"OpenCV",
"Gazebo",
"GitHub",
"FPV",
"PPM",
"PWM",
"Python",
"C++",
"JavaScript",
"Node.js",
"Django",
"Flask",
"HTTP",
"HTTPS",
"WebSocket",
"RPC",
"PX4",
"ArduPilot",
"jMAVSim",
"px4.io",
"logs.px4.io",
"QGroundControl",
"QGC",
"WireShark",
"FlightPlot",
"OFFBOARD",
"ACRO",
"RPY",
"LPE",
"EKF2",
"IMU",
"VPE",
"SITL",
"PID",
"Wi-Fi",
"Raspberry Pi",
"RPi",
"Linux",
"GNU",
"GNU/Linux",
"Windows",
"Docker",
"RFC",
"Travis",
"travis-ci.org",
"travis-ci.com",
"macOS",
"iOS",
"Android",
"Bluetooth",
"Raspbian",
"Raspbian Jesse",
"Raspbian Stretch",
"Raspbian Buster",
"Pixhawk",
"Pixracer",
"ArUco"
"Arduino",
"GPS",
"ArUco",
"LIRC",
"GPIO",
"HC-SR04",
"RCW-0001",
"RealSense",
"NUC",
"NVIDIA",
"Jetson",
"Jetson Nano",
"STM",
"LED",
"USB",
"FAT32",
"uORB",
"SSH",
"PuTTY",
"API",
"UART",
"GND",
"VCC",
"SCL",
"SDA",
"TCP",
"UDP",
"QR",
"Li-ion"
],
"code_blocks": false
}
},
"MD045": false
}

104
.travis.yml Normal file
View File

@@ -0,0 +1,104 @@
sudo: required
language: generic
services:
- docker
env:
global:
- DOCKER="sfalexrog/img-tool:qemu-update"
- TARGET_REPO="https://github.com/${TRAVIS_REPO_SLUG}.git"
- if [[ -z ${TRAVIS_TAG} ]]; then IMAGE_VERSION="${TRAVIS_COMMIT}}"; else IMAGE_VERSION="${TRAVIS_TAG}"; fi
- IMAGE_NAME="$(basename -s '.git' ${TARGET_REPO})_${IMAGE_VERSION}.img"
git:
depth: 50
jobs:
fast_finish: true
include:
- stage: Build
name: "Raspberry Pi Image Build"
cache:
directories:
- imgcache
before_script:
- docker pull ${DOCKER}
# Check if there are any cached images, copy them to our "images" directory
- if [ -n "$(ls -A imgcache/*.zip)" ]; then mkdir -p images && cp imgcache/*.zip images; fi
script:
- if [[ -z ${TRAVIS_TAG} && "${TRAVIS_PULL_REQUEST}" != "false" ]]; then
echo "Commit range is ${TRAVIS_COMMIT_RANGE}" &&
if [ $(git diff --name-only ${TRAVIS_COMMIT_RANGE} | grep -v ^"docs/" | wc -l) -eq 0 ]; then
echo " === Docs-only change; skipping build ===" &&
export SKIP_BUILD=true;
fi;
fi
- if [ -z ${SKIP_BUILD} ]; then
docker run --privileged --rm -v /dev:/dev -v $(pwd):/builder/repo -e TRAVIS_TAG="${TRAVIS_TAG}" ${DOCKER};
fi
before_cache:
- cp images/*.zip imgcache
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"
- sudo chmod -R 777 *
- cd images && zip ${IMAGE_NAME}.zip ${IMAGE_NAME}
deploy:
provider: releases
api_key: ${GITHUB_OAUTH_TOKEN}
file: ${IMAGE_NAME}.zip
skip_cleanup: true
on:
tags: true
draft: true
name: ${TRAVIS_TAG}
- stage: Build
name: "Documentation"
language: node_js
node_js:
- "10"
before_script:
- npm install gitbook-cli -g
- npm install markdownlint-cli -g
- gitbook -V
- markdownlint -V
script:
- markdownlint docs
- ./check_assets_size.py
- ./check_unused_assets.py
- gitbook install
- gitbook build
deploy:
provider: pages
local-dir: _book
skip-cleanup: true
github-token: ${GITHUB_OAUTH_TOKEN}
keep-history: true
target-branch: master
repo: CopterExpress/clever.coex.tech
fqdn: clever.coex.tech
verbose: true
on:
branch: master
- stage: Annotate
name: Auto-generate changelog
language: python
python: 3.6
install:
- pip install GitPython PyGithub
script:
- PYTHONUNBUFFERED=1 python ./gen_changelog.py
- 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|Assets.xcassets|test_parser_pass.txt|test_node_failure.txt"
stages:
- Build
- Annotate
# 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

View File

@@ -1,20 +1,20 @@
# CLEVER
<img src="docs/assets/clever3.png" align="right" width="300px" alt="CLEVER drone">
<img src="docs/assets/clever4-front-white.png" align="right" width="400px" alt="CLEVER drone">
CLEVER is an educational programmable drone kit consisting of an unassembled quadcopter, open source software and documentation. The kit includes Pixhawk/Pixracer autopilot running PX4 firmware, Raspberry Pi 3 as companion computer, a camera for computer vision navigation as well as additional sensors and peripheral devices.
CLEVER (Russian: *"Клевер"*, meaning *"Clover"*) is an educational programmable drone kit consisting of an unassembled quadcopter, open source software and documentation. The kit includes Pixhawk/Pixracer autopilot running PX4 firmware, Raspberry Pi 3 as companion computer, a camera for computer vision navigation as well as additional sensors and peripheral devices.
Copter Express has implemented a large number of different autonomous drone projects using exactly the same platform: [automated pizza delivery](https://www.youtube.com/watch?v=hmkAoZOtF58) in Samara and Kazan, coffee delivery in Skolkovo Innovation Center, [autonomous quadcopter with charging station](https://www.youtube.com/watch?v=RjX6nUqw1mI) for site monitoring and security, winning drones on [Robocross-2016](https://www.youtube.com/watch?v=dGbDaz_VmYU) and [Robocross-2017](https://youtu.be/AQnd2CRczbQ) competitions and many others.
**The main documentation in Russian is available [on our Gitbook](https://clever.copterexpress.com/).**
**The main documentation is available [on Gitbook](https://clever.coex.tech/).**
Use it to learn how to assemble, configure, pilot and program autonomous CLEVER drone.
## Preconfigured RPi 3 image
## Raspberry Pi image
**Preconfigured image for Raspberry Pi 3 with installed and configured software, ready to fly, is available [in the Releases section](https://github.com/CopterExpress/clever/releases).**
[![Build Status](http://builder.coex.space/job/CopterExpress---clever/badge/icon)](http://builder.coex.space/job/CopterExpress---clever/)
[![Build Status](https://travis-ci.org/CopterExpress/clever.svg?branch=master)](https://travis-ci.org/CopterExpress/clever)
Image includes:
@@ -23,55 +23,81 @@ Image includes:
* Configured networking
* OpenCV
* mavros
* Periphery drivers (`pigpiod`, `rpi_ws281x`, etc)
* CLEVER software bundle for autonomous drone control
API description (in Russian) for autonomous flights is available [on GitBook](https://copterexpress.gitbooks.io/clever/simple_offboard.html).
API description (in Russian) for autonomous flights is available [on GitBook](https://clever.coex.tech/simple_offboard.html).
## Manual installation
Install ROS Kinetic according to the [documentation](http://wiki.ros.org/kinetic/Installation).
Install ROS Kinetic according to the [documentation](http://wiki.ros.org/kinetic/Installation), then [create a Catkin workspace](http://wiki.ros.org/catkin/Tutorials/create_a_workspace).
Clone repo to directory `/home/pi/catkin_ws/src/clever`:
Clone this repo to directory `~/catkin_ws/src/clever`:
```bash
cd ~/catkin_ws/src
git clone https://github.com/CopterExpress/clever.git clever
```
Build ROS packages:
All the required ROS packages (including `mavros` and `opencv`) can be installed using `rosdep`:
```bash
cd ~/catkin_ws/
rosdep install -y --from-paths src --ignore-src
```
Build ROS packages (on memory constrained platforms you might be going to need to use `-j1` key):
```bash
cd ~/catkin_ws
catkin_make -j1
```
Enable systemd service `roscore` (if not enabled):
To complete `mavros` install you'll need to install `geographiclib` datasets:
```bash
sudo systemctl enable /home/pi/catkin_ws/src/clever/deploy/roscore.service
curl https://raw.githubusercontent.com/mavlink/mavros/master/mavros/scripts/install_geographiclib_datasets.sh | sudo bash
```
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/clever/clever/config
sudo cp 99-px4fmu.rules /lib/udev/rules.d
```
Alternatively you may change the `fcu_url` property in `mavros.launch` file to point to your flight controller device.
## Running
Enable systemd service `roscore` (if not running):
```bash
sudo systemctl enable /home/<username>/catkin_ws/src/clever/builder/assets/roscore.service
sudo systemctl start roscore
```
Enable systemd service `clever`:
To start connection to SITL, use:
```bash
sudo systemctl enable /home/pi/catkin_ws/src/clever/deploy/clever.service
roslaunch clever sitl.launch
```
To start connection to the flight controller, use:
```bash
roslaunch clever clever.launch
```
> Note that the package is configured to connect to `/dev/px4fmu` by default (see [previous section](#manual-installation)). Install udev rules or specify path to your FCU device in `mavros.launch`.
Also, you can enable and start the systemd service:
```bash
sudo systemctl enable /home/<username>/catkin_ws/src/clever/deploy/clever.service
sudo systemctl start clever
```
### Dependencies
## License
[ROS Kinetic](http://wiki.ros.org/kinetic).
Necessary ROS packages:
* `opencv3`
* `mavros`
* `rosbridge_suite`
* `web_video_server`
* `cv_camera`
* `nodelet`
* `dynamic_reconfigure`
* `bondcpp`, branch `master`
* `roslint`
* `rosserial`
While the Clever 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,2 +0,0 @@
theme: jekyll-theme-cayman
tagline: Конструктор программируемого квадрокоптера

11
apps/android/.gitignore vendored Normal file
View File

@@ -0,0 +1,11 @@
*.iml
.gradle
/local.properties
/.idea/caches/build_file_checksums.ser
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
.DS_Store
/build
/captures
.externalNativeBuild

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WizardSettings">
<option name="children">
<map>
<entry key="imageWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="imageAssetPanel">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="launcher">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="foregroundImage">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="scalingPercent" value="54" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="backgroundAssetType" value="COLOR" />
<entry key="backgroundColor" value="ffffff" />
<entry key="foregroundImage" value="C:\Users\Motoy\Desktop\COEX\logo.png" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</component>
</project>

View File

@@ -0,0 +1,35 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>

View File

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

18
apps/android/.idea/gradle.xml generated Normal file
View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

38
apps/android/.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="7">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="6">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

12
apps/android/.idea/runConfigurations.xml generated Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

6
apps/android/.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

1
apps/android/app/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

View File

@@ -0,0 +1,33 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
defaultConfig {
applicationId "express.copter.cleverrc"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

21
apps/android/app/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

Binary file not shown.

View File

@@ -0,0 +1,24 @@
package express.copter.cleverrc
import android.support.test.InstrumentationRegistry
import android.support.test.runner.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getTargetContext()
assertEquals("express.copter.cleverrc", appContext.packageName)
}
}

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="express.copter.cleverrc">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"
android:screenOrientation="landscape"
android:theme="@style/NoUiAppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 69.988266 69.987198"
height="69.987198"
width="69.988266"
xml:space="preserve"
id="svg2"
version="1.1"><metadata
id="metadata8"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs6"><clipPath
id="clipPath18"
clipPathUnits="userSpaceOnUse"><path
id="path16"
d="M 0,52.49 H 52.491 V 0 H 0 Z" /></clipPath></defs><g
transform="matrix(1.3333333,0,0,-1.3333333,0,69.9872)"
id="g10"><g
id="g12"><g
clip-path="url(#clipPath18)"
id="g14"><g
transform="translate(35.6531,35.3361)"
id="g20"><path
id="path22"
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
d="M 0,0 C 0.279,0.322 0.5,0.686 0.657,1.081 0.827,1.513 0.914,1.968 0.917,2.434 0.92,2.924 0.829,3.403 0.647,3.857 0.458,4.329 0.165,4.77 -0.2,5.13 -0.587,5.512 -1.061,5.812 -1.571,5.995 -2.138,6.198 -2.756,6.262 -3.358,6.18 -3.821,6.115 -4.263,5.967 -4.671,5.739 -4.886,5.618 -5.094,5.472 -5.291,5.305 L -5.467,5.151 C -5.527,5.099 -5.587,5.049 -5.649,5.003 -5.775,4.909 -5.906,4.827 -6.04,4.759 -6.173,4.691 -6.314,4.633 -6.458,4.586 -6.575,4.549 -6.696,4.519 -6.819,4.496 -6.917,4.478 -7.017,4.465 -7.115,4.457 c -0.623,-0.052 -1.281,0.082 -1.9,0.385 -0.224,0.111 -0.439,0.241 -0.64,0.387 -0.042,0.03 -0.084,0.063 -0.127,0.095 -0.039,0.031 -0.069,0.054 -0.102,0.09 -0.023,0.025 -0.043,0.05 -0.061,0.077 -0.056,0.082 -0.093,0.176 -0.107,0.271 -0.004,0.022 -0.005,0.044 -0.006,0.066 l -0.002,6.486 c -0.534,0.589 -1.115,1.136 -1.728,1.626 -0.913,0.73 -1.913,1.352 -2.971,1.845 -0.867,0.405 -1.779,0.725 -2.711,0.952 -0.851,0.208 -1.731,0.34 -2.617,0.391 -0.912,0.053 -1.834,0.023 -2.741,-0.092 -0.741,-0.094 -1.479,-0.246 -2.194,-0.453 -1.274,-0.365 -2.494,-0.905 -3.628,-1.604 -0.824,-0.507 -1.603,-1.101 -2.316,-1.764 -0.687,-0.64 -1.317,-1.35 -1.871,-2.109 -0.505,-0.692 -0.951,-1.432 -1.327,-2.2 -0.375,-0.764 -0.684,-1.566 -0.919,-2.383 -0.201,-0.7 -0.351,-1.423 -0.446,-2.147 -0.12,-0.919 -0.153,-1.858 -0.099,-2.79 0.05,-0.838 0.171,-1.673 0.359,-2.482 0.201,-0.856 0.481,-1.7 0.833,-2.507 0.546,-1.253 1.265,-2.423 2.136,-3.479 0.317,-0.384 0.654,-0.753 1.002,-1.098 0.158,-0.157 0.32,-0.31 0.485,-0.459 h 6.121 c 0.051,0.08 0.099,0.161 0.143,0.245 0.037,0.071 0.072,0.144 0.104,0.218 0.026,0.062 0.05,0.128 0.073,0.193 0.132,0.394 0.159,0.784 0.077,1.127 -0.013,0.052 -0.028,0.105 -0.046,0.157 -0.024,0.068 -0.053,0.136 -0.087,0.201 -0.048,0.09 -0.105,0.174 -0.169,0.249 -0.035,0.041 -0.07,0.079 -0.107,0.116 l -0.024,0.026 c -0.025,0.029 -0.046,0.053 -0.066,0.079 -0.014,0.02 -0.02,0.029 -0.027,0.038 l -0.079,0.096 c -0.109,0.134 -0.212,0.277 -0.304,0.42 -0.207,0.318 -0.378,0.659 -0.506,1.013 -0.118,0.32 -0.202,0.651 -0.252,0.985 -0.085,0.571 -0.073,1.146 0.035,1.71 0.098,0.509 0.273,0.999 0.521,1.454 0.258,0.475 0.588,0.903 0.98,1.272 0.419,0.394 0.895,0.711 1.415,0.942 0.557,0.249 1.15,0.393 1.762,0.428 0.659,0.035 1.298,-0.05 1.914,-0.258 0.653,-0.221 1.268,-0.585 1.78,-1.05 0.541,-0.492 0.977,-1.106 1.261,-1.776 0.151,-0.357 0.26,-0.729 0.324,-1.106 0.072,-0.415 0.092,-0.843 0.058,-1.272 -0.031,-0.388 -0.108,-0.773 -0.227,-1.144 -0.11,-0.341 -0.257,-0.673 -0.441,-0.988 -0.103,-0.177 -0.216,-0.347 -0.335,-0.503 -0.037,-0.051 -0.077,-0.1 -0.117,-0.151 l -0.033,-0.04 -0.005,0.002 -0.049,-0.07 c -0.022,-0.028 -0.043,-0.054 -0.066,-0.08 l -0.076,-0.08 c -0.028,-0.03 -0.055,-0.062 -0.081,-0.094 -0.05,-0.063 -0.095,-0.131 -0.134,-0.202 -0.035,-0.064 -0.066,-0.131 -0.09,-0.199 -0.019,-0.053 -0.035,-0.105 -0.049,-0.158 -0.085,-0.34 -0.062,-0.729 0.066,-1.123 0.021,-0.066 0.045,-0.13 0.071,-0.193 0.03,-0.073 0.063,-0.145 0.1,-0.215 0.045,-0.088 0.096,-0.176 0.156,-0.269 h 7.162 l 0.002,7.527 c 10e-4,0.022 0.002,0.043 0.006,0.065 0.008,0.061 0.027,0.124 0.057,0.187 0.03,0.06 0.067,0.114 0.111,0.161 0.034,0.037 0.065,0.062 0.102,0.09 l 0.062,0.048 c 0.087,0.065 0.173,0.126 0.262,0.183 0.487,0.316 1.027,0.526 1.563,0.608 0.154,0.024 0.312,0.037 0.482,0.04 0.037,0.001 0.076,0 0.113,-0.001 0.062,-0.002 0.124,-0.005 0.186,-0.01 0.123,-0.011 0.247,-0.029 0.367,-0.053 0.338,-0.071 0.654,-0.2 0.939,-0.383 0.11,-0.07 0.214,-0.149 0.31,-0.231 0.031,-0.026 0.061,-0.053 0.09,-0.081 l 0.029,-0.028 -0.07,-0.106 c 0.003,-0.003 0.007,-0.007 0.01,-0.01 l 0.071,0.101 0.215,-0.169 c 0.13,-0.101 0.243,-0.179 0.358,-0.25 0.24,-0.146 0.497,-0.266 0.763,-0.355 0.656,-0.219 1.363,-0.253 2.04,-0.097 0.374,0.086 0.731,0.229 1.059,0.424 C -0.581,-0.571 -0.268,-0.309 0,0" /></g><g
transform="translate(41.5882,22.8337)"
id="g24"><path
id="path26"
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
d="M 0,0 V 0 L 0.053,0.044 0.013,0.018 Z" /></g><g
transform="translate(28.5515,3.2736)"
id="g28"><path
id="path30"
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0.934,-0.757 1.959,-1.398 3.045,-1.906 0.84,-0.39 1.72,-0.702 2.615,-0.927 0.883,-0.222 1.796,-0.362 2.714,-0.416 0.944,-0.054 1.897,-0.019 2.832,0.106 0.707,0.094 1.414,0.242 2.102,0.439 1.276,0.368 2.496,0.908 3.628,1.605 0.798,0.492 1.556,1.065 2.251,1.704 0.724,0.666 1.384,1.408 1.962,2.205 0.468,0.646 0.886,1.334 1.242,2.044 0.409,0.815 0.742,1.672 0.99,2.547 0.179,0.628 0.316,1.274 0.409,1.921 0.14,0.979 0.182,1.98 0.123,2.973 -0.048,0.819 -0.165,1.638 -0.348,2.433 -0.2,0.872 -0.484,1.732 -0.843,2.556 -0.538,1.234 -1.247,2.392 -2.106,3.442 -0.313,0.381 -0.648,0.752 -0.998,1.1 l -0.52,0.493 H 12.982 L 12.831,22.068 C 12.797,22.003 12.763,21.931 12.732,21.857 12.705,21.794 12.681,21.73 12.659,21.665 12.527,21.268 12.5,20.878 12.582,20.536 c 0.012,-0.053 0.027,-0.105 0.045,-0.156 0.024,-0.069 0.054,-0.137 0.088,-0.202 0.046,-0.086 0.103,-0.171 0.169,-0.251 0.027,-0.032 0.056,-0.062 0.086,-0.093 l 0.045,-0.048 c 0.023,-0.025 0.044,-0.051 0.065,-0.078 l -0.046,-0.082 0.061,0.057 0.003,-0.002 0.022,-0.028 -10e-4,-10e-4 0.01,-0.015 0.004,0.003 0.05,-0.062 c 0.171,-0.212 0.322,-0.433 0.451,-0.659 0.275,-0.478 0.469,-0.996 0.575,-1.538 0.141,-0.718 0.124,-1.472 -0.05,-2.181 -0.152,-0.623 -0.431,-1.228 -0.807,-1.751 -0.303,-0.42 -0.667,-0.79 -1.082,-1.1 C 11.868,12.048 11.425,11.81 10.954,11.64 10.456,11.461 9.935,11.362 9.406,11.345 8.955,11.331 8.505,11.376 8.07,11.48 c -0.494,0.118 -0.965,0.308 -1.399,0.565 -0.509,0.301 -0.958,0.685 -1.333,1.14 -0.393,0.477 -0.692,1.014 -0.89,1.596 -0.218,0.645 -0.305,1.348 -0.25,2.031 0.029,0.355 0.095,0.704 0.194,1.037 0.114,0.383 0.273,0.751 0.474,1.095 0.095,0.164 0.207,0.334 0.334,0.503 0.038,0.051 0.078,0.102 0.118,0.151 L 5.45,19.56 v 0 l -0.101,0.074 0.055,0.073 c 0.023,0.028 0.045,0.054 0.066,0.078 l 0.076,0.08 c 0.03,0.031 0.057,0.062 0.082,0.095 0.05,0.063 0.095,0.131 0.135,0.203 0.034,0.063 0.065,0.13 0.09,0.199 0.019,0.052 0.034,0.103 0.047,0.156 0.086,0.341 0.063,0.73 -0.065,1.124 -0.021,0.065 -0.044,0.129 -0.071,0.193 -0.033,0.082 -0.071,0.162 -0.113,0.24 -0.044,0.084 -0.092,0.165 -0.143,0.244 h -7.162 l -0.002,-7.532 c -0.001,-0.02 -0.003,-0.041 -0.006,-0.06 -0.015,-0.099 -0.052,-0.192 -0.107,-0.272 -0.018,-0.027 -0.039,-0.052 -0.061,-0.076 -0.035,-0.037 -0.064,-0.061 -0.102,-0.09 -0.02,-0.016 -0.042,-0.033 -0.065,-0.05 -0.122,-0.091 -0.254,-0.181 -0.393,-0.264 -0.619,-0.37 -1.29,-0.565 -1.942,-0.565 -0.093,-0.003 -0.179,0.003 -0.268,0.011 -0.11,0.01 -0.221,0.025 -0.33,0.046 -0.36,0.071 -0.709,0.213 -1.008,0.411 -0.109,0.072 -0.213,0.152 -0.309,0.237 -0.029,0.026 -0.058,0.052 -0.085,0.079 h -0.026 l -0.022,0.042 -0.036,0.027 c -0.035,0.03 -0.061,0.051 -0.087,0.072 l -0.073,0.059 c -0.212,0.162 -0.427,0.296 -0.648,0.404 -0.416,0.204 -0.861,0.328 -1.324,0.367 -0.345,0.028 -0.695,0.012 -1.037,-0.053 -0.259,-0.05 -0.511,-0.126 -0.75,-0.228 -0.498,-0.211 -0.954,-0.534 -1.32,-0.936 -0.345,-0.381 -0.614,-0.838 -0.779,-1.322 -0.154,-0.455 -0.218,-0.933 -0.191,-1.421 0.026,-0.462 0.136,-0.909 0.326,-1.327 0.175,-0.386 0.412,-0.738 0.706,-1.047 0.283,-0.296 0.609,-0.543 0.97,-0.734 0.319,-0.168 0.661,-0.289 1.015,-0.36 0.449,-0.089 0.906,-0.095 1.357,-0.021 0.246,0.041 0.49,0.108 0.725,0.198 0.254,0.098 0.499,0.225 0.727,0.377 0.113,0.075 0.229,0.161 0.343,0.257 l 0.068,0.054 0.016,0.046 0.041,0.002 c 0.012,0.013 0.02,0.02 0.029,0.028 l 0.055,0.052 c 0.051,0.043 0.1,0.084 0.151,0.124 0.104,0.08 0.212,0.151 0.322,0.213 0.28,0.159 0.589,0.268 0.917,0.324 0.152,0.026 0.31,0.04 0.48,0.043 h 0.109 C -4.1,9.429 -3.938,9.414 -3.782,9.389 -3.261,9.303 -2.734,9.095 -2.256,8.787 -2.167,8.73 -2.08,8.668 -1.996,8.604 l 0.053,-0.04 c 0.048,-0.037 0.077,-0.061 0.111,-0.097 0.047,-0.05 0.084,-0.104 0.113,-0.162 0.029,-0.062 0.048,-0.125 0.057,-0.187 0.003,-0.02 0.005,-0.04 0.006,-0.06 L -1.654,8.021 V 1.566 C -1.142,1.001 -0.585,0.474 0,0" /></g><g
transform="translate(22.2707,17.571)"
id="g32"><path
id="path34"
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
d="m 0,0 v -0.008 l 0.011,0.019 v 0 z" /></g><g
transform="translate(40.657,22.3049)"
id="g36"><path
id="path38"
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
d="M 0,0 Z" /></g><g
transform="translate(49.1867,28.5134)"
id="g40"><path
id="path42"
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0.721,0.884 1.337,1.848 1.832,2.865 0.359,0.739 0.659,1.516 0.89,2.311 0.244,0.839 0.413,1.706 0.503,2.579 0.173,1.678 0.063,3.352 -0.329,4.976 -0.323,1.339 -0.834,2.625 -1.518,3.823 -0.416,0.728 -0.898,1.425 -1.432,2.072 -0.597,0.724 -1.268,1.394 -1.993,1.994 -0.636,0.525 -1.32,0.999 -2.034,1.409 -0.75,0.431 -1.539,0.796 -2.345,1.086 -1,0.359 -2.041,0.609 -3.095,0.743 -0.401,0.051 -0.808,0.086 -1.209,0.104 -0.205,0.009 -0.41,0.014 -0.615,0.015 h -0.098 c -0.479,-0.003 -0.943,-0.026 -1.379,-0.069 -0.825,-0.08 -1.65,-0.231 -2.451,-0.45 -0.861,-0.235 -1.705,-0.551 -2.509,-0.941 -0.765,-0.371 -1.502,-0.811 -2.191,-1.308 -0.571,-0.411 -1.115,-0.866 -1.618,-1.352 -0.236,-0.227 -0.471,-0.469 -0.698,-0.72 v -6.121 c 0.079,-0.052 0.161,-0.1 0.245,-0.144 0.07,-0.037 0.143,-0.071 0.216,-0.102 0.064,-0.027 0.13,-0.051 0.195,-0.074 0.394,-0.132 0.784,-0.158 1.127,-0.077 0.053,0.012 0.105,0.027 0.156,0.045 0.069,0.024 0.136,0.054 0.201,0.088 0.088,0.047 0.173,0.104 0.251,0.169 0.04,0.034 0.078,0.071 0.116,0.107 l 0.029,0.028 c 0.035,0.029 0.055,0.046 0.077,0.063 l 0.107,0.085 c 0.164,0.132 0.314,0.24 0.466,0.338 0.319,0.205 0.662,0.373 1.018,0.502 0.317,0.115 0.649,0.198 0.987,0.245 0.56,0.082 1.126,0.068 1.681,-0.038 0.51,-0.098 1,-0.273 1.455,-0.521 0.473,-0.257 0.901,-0.587 1.272,-0.981 0.394,-0.418 0.711,-0.894 0.942,-1.414 0.248,-0.558 0.392,-1.151 0.427,-1.762 0.037,-0.645 -0.052,-1.307 -0.258,-1.914 -0.22,-0.652 -0.583,-1.267 -1.049,-1.781 -0.491,-0.54 -1.105,-0.976 -1.776,-1.26 -0.352,-0.149 -0.724,-0.259 -1.106,-0.325 -0.421,-0.072 -0.849,-0.091 -1.272,-0.057 -0.371,0.03 -0.739,0.1 -1.09,0.21 -0.365,0.113 -0.716,0.267 -1.042,0.458 -0.167,0.096 -0.336,0.209 -0.503,0.334 -0.051,0.039 -0.102,0.078 -0.151,0.118 l -0.108,0.086 c -0.028,0.022 -0.053,0.043 -0.079,0.065 -0.03,0.028 -0.056,0.054 -0.082,0.079 -0.029,0.026 -0.061,0.054 -0.094,0.081 -0.064,0.05 -0.132,0.095 -0.201,0.133 -0.064,0.035 -0.132,0.065 -0.201,0.091 -0.051,0.018 -0.101,0.034 -0.154,0.046 C -20.829,6.024 -21.219,6 -21.613,5.873 -21.677,5.852 -21.742,5.828 -21.806,5.802 -21.887,5.768 -21.967,5.73 -22.045,5.689 -22.129,5.645 -22.21,5.598 -22.289,5.546 v -7.162 l 7.532,-0.003 c 0.02,-0.001 0.04,-0.002 0.06,-0.005 0.098,-0.015 0.192,-0.052 0.272,-0.107 0.026,-0.018 0.053,-0.039 0.076,-0.062 0.035,-0.033 0.058,-0.061 0.085,-0.096 l 0.053,-0.068 c 0.094,-0.125 0.184,-0.257 0.267,-0.395 0.362,-0.608 0.557,-1.269 0.563,-1.912 0.002,-0.099 -0.002,-0.198 -0.01,-0.298 -0.009,-0.11 -0.025,-0.221 -0.046,-0.33 -0.072,-0.362 -0.213,-0.711 -0.41,-1.008 -0.074,-0.11 -0.153,-0.214 -0.238,-0.309 -0.026,-0.029 -0.053,-0.057 -0.08,-0.086 l -0.025,-0.026 v 10e-4 l -0.18,-0.227 c -0.083,-0.106 -0.161,-0.219 -0.23,-0.334 -0.143,-0.233 -0.26,-0.483 -0.349,-0.744 -0.223,-0.654 -0.261,-1.359 -0.109,-2.037 0.084,-0.378 0.229,-0.742 0.429,-1.083 0.208,-0.351 0.47,-0.665 0.779,-0.932 0.323,-0.28 0.687,-0.5 1.081,-0.656 0.429,-0.17 0.884,-0.257 1.352,-0.26 h 0.026 c 0.482,0 0.951,0.09 1.397,0.269 0.473,0.19 0.913,0.483 1.274,0.848 0.383,0.388 0.682,0.862 0.865,1.371 0.203,0.566 0.267,1.184 0.184,1.786 -0.066,0.477 -0.221,0.931 -0.461,1.349 -0.117,0.204 -0.256,0.4 -0.413,0.584 l -0.073,0.089 0.005,0.01 -0.002,0.006 0.007,0.002 0.017,0.033 0.035,0.065 -0.091,-0.085 -0.053,0.057 c -0.051,0.06 -0.101,0.12 -0.148,0.182 -0.091,0.121 -0.173,0.253 -0.243,0.391 -0.067,0.13 -0.125,0.27 -0.172,0.417 -0.038,0.116 -0.068,0.239 -0.091,0.363 -0.018,0.097 -0.031,0.196 -0.039,0.294 -0.052,0.624 0.082,1.281 0.385,1.901 0.109,0.221 0.239,0.436 0.386,0.639 0.031,0.043 0.064,0.085 0.096,0.127 0.032,0.041 0.055,0.069 0.09,0.102 0.025,0.023 0.051,0.045 0.078,0.063 0.079,0.054 0.172,0.091 0.27,0.106 0.02,0.003 0.04,0.004 0.06,0.005 l 0.038,0.003 h 6.454 C -0.981,-1.113 -0.465,-0.57 0,0" /></g>
</g></g></g></svg>

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,24 @@
<html>
<head>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui">
<link rel="stylesheet" href="main.css">
<script src="roslib.js"></script>
</head>
<body>
<div class="telemetry"><span class="mode">DISCONNECTED</span></div>
<div class="battery"></div>
<div class="logo"></div>
<div class="container">
<div class="stick stick-left">
<div class="stick-pointer"></div>
</div>
<div class="stick stick-right">
<div class="stick-pointer"></div>
</div>
</div>
<div class="notifications"></div>
<script src="main.js" type="text/javascript"></script>
<script src="telemetry.js" type="text/javascript"></script>
</body>
</html>

View File

@@ -0,0 +1,125 @@
html, body {
margin: 0;
padding: 0;
user-select: none;
font-family: sans-serif;
background: #212121;
color: rgba(255, 255, 255, 0.9);
}
* {
user-select: none;
}
.stick {
border-radius: 50%;
width: 5cm;
height: 5cm;
position: relative;
transform: translateZ(0);
border: 4px solid rgba(255,255,255,.4);
box-shadow: 0 0 0 1px rgba(0,0,0,.2), inset 0 0 0 1px rgba(0,0,0,.2);
}
.stick-pointer {
position: absolute;
border-radius: 50%;
background-color: rgba(255,255,255,.25);
box-shadow: 0 0 10px rgba(0,0,0,.3);
width: 3cm;
height: 3cm;
margin-left: -1.5cm;
margin-top: -1.5cm;
top: 2.5cm;
left: 2.5cm;
pointer-events: none;
transform: translateZ(0);
}
.container {
display: flex;
justify-content: space-around;
align-items: center;
width: 100%;
height: 100%;
}
.telemetry {
position: absolute;
text-align: center;
width: 100%;
top: 30px;
font-size: 20px;
user-select: none;
pointer-events: none;
}
body.armed .telemetry .mode {
font-weight: bold;
}
@keyframes scale {
0% { transform: scale(1.0); }
50% { transform: scale(1.2); }
100% { transform: scale(1.0); }
}
.battery {
position: absolute;
text-align: center;
width: 100%;
bottom: 30px;
font-size: 20px;
user-select: none;
pointer-events: none;
}
body.low-battery .battery {
color: #ff554b;
animation: scale 0.3s 1 ease-in-out
}
.logo {
position: absolute;
background: url(clever.svg);
-webkit-background-size: 50px;
background-size: 50px;
width: 50px;
height: 50px;
top: 50%;
left: 50%;
margin-top: -25px;
margin-left: -25px;
font-size: 20px;
user-select: none;
pointer-events: none;
}
.notifications {
pointer-events: none;
position: absolute;
top: 0;
left: 0;
right: 0;
color: white;
}
.notifications.hidden {
transform: translateY(-100%);
}
.notifications.anim {
transition: transform 0.2s ease;
}
.notifications .item {
font-size: 4mm;
-webkit-text-size-adjust: none;
background: #fca83a;
padding: 3mm;
padding-bottom: 1.5mm;
}
.notifications .item:last-child {
padding-bottom: 3mm;
}

View File

@@ -0,0 +1,138 @@
function throttle(func, ms) {
var isThrottled = false,
savedArgs,
savedThis;
function wrapper() {
if (isThrottled) {
savedArgs = arguments;
savedThis = this;
return;
}
func.apply(this, arguments);
isThrottled = true;
setTimeout(function() {
isThrottled = false;
if (savedArgs) {
wrapper.apply(savedThis, savedArgs);
savedArgs = savedThis = null;
}
}, ms);
}
return wrapper;
}
function postAppMessage(msg) {
if (window.webkit != undefined) {
if (window.webkit.messageHandlers.appInterface != undefined) {
window.webkit.messageHandlers.appInterface.postMessage(JSON.stringify(msg));
}
} else if (window.appInterface != undefined) {
window.appInterface.postMessage(JSON.stringify(msg));
}
}
function callNativeApp(name, msg) {
try {
postAppMessage(msg);
return true;
} catch(err) {
console.warn('The native context does not exist yet');
return false;
}
}
var rcLastPublish = null;
function rcPublish() {
callNativeApp('control', controlMessage);
rcLastPublish = new Date();
}
rcPublishThrottled = throttle(rcPublish, 30);
setInterval(function() {
if (rcLastPublish !== null && new Date() - rcLastPublish > 800) {
rcPublishThrottled();
}
}, 50);
var body = document.querySelector('body');
var stickLeft = document.querySelector('.stick-left');
var stickRight = document.querySelector('.stick-right');
var controlMessage = { x: 0, y: 0, z: 0, r: 0 };
function onStickTouchMove(touch) {
var target = touch.target;
var targetRect = target.getBoundingClientRect();
var stickPointer = target.querySelector('.stick-pointer');
var offsetX = touch.clientX - targetRect.left;
var offsetY = touch.clientY - targetRect.top;
var x = 2 * offsetX / targetRect.width;
var y = 2 * offsetY / targetRect.height;
x = Math.max(0, x);
x = Math.min(2, x);
y = Math.max(0, y);
y = Math.min(2, y);
stickPointer.style.left = (x * 50) + '%';
stickPointer.style.top = (y * 50) + '%';
x -= 1;
y = 1 - y;
if (target.matches('.stick-left')) {
controlMessage.z = Math.round((y + 1) * 500);
controlMessage.r = Math.round(x * 1000);
} else if (target.matches('.stick-right')) {
controlMessage.x = Math.round(y * 1000);
controlMessage.y = Math.round(x * 1000);
}
}
body.addEventListener('touchmove', function (e) {
e.preventDefault();
});
function stickTouchStart(e) {
setControlMode();
callNativeApp('controlStart');
onStickTouchMove(e.changedTouches[0]);
rcPublishThrottled();
e.stopPropagation();
e.preventDefault();
}
function stickTouchMove(e) {
for (touch of e.changedTouches) {
onStickTouchMove(touch);
}
//onStickTouchMove(e.changedTouches[0]);
rcPublishThrottled();
e.stopPropagation();
e.preventDefault();
}
function stickTouchEnd(e) {
var pointer = e.target.querySelector('.stick-pointer');
if (e.target.matches('.stick-left')) {
controlMessage.r = 0;
pointer.style.left = '50%';
} else if (e.target.matches('.stick-right')) {
controlMessage.x = 0;
controlMessage.y = 0;
pointer.style.left = '50%';
pointer.style.top = '50%';
}
rcPublishThrottled();
}
stickLeft.addEventListener('touchmove', stickTouchMove);
stickRight.addEventListener('touchmove', stickTouchMove);
stickLeft.addEventListener('touchstart', stickTouchStart);
stickRight.addEventListener('touchstart', stickTouchStart);
stickLeft.addEventListener('touchend', stickTouchEnd);
stickRight.addEventListener('touchend', stickTouchEnd);

View File

@@ -0,0 +1,142 @@
function throttle(func, ms) {
var isThrottled = false,
savedArgs,
savedThis;
function wrapper() {
if (isThrottled) {
savedArgs = arguments;
savedThis = this;
return;
}
func.apply(this, arguments);
isThrottled = true;
setTimeout(function() {
isThrottled = false;
if (savedArgs) {
wrapper.apply(savedThis, savedArgs);
savedArgs = savedThis = null;
}
}, ms);
}
return wrapper;
}
function postAppMessage(msg) {
if (window.webkit != undefined) {
if (window.webkit.messageHandlers.appInterface != undefined) {
window.webkit.messageHandlers.appInterface.postMessage(JSON.stringify(msg));
}
}
else if (window.appInterface != undefined) {
window.appInterface.postMessage(JSON.stringify(msg));
}
}
function callNativeApp(name, msg) {
try {
postAppMessage(msg);
return true;
} catch(err) {
console.warn('The native context does not exist yet');
return false;
}
}
var rcLastPublish = null;
function rcPublish() {
callNativeApp('control', controlMessage);
rcLastPublish = new Date();
}
rcPublishThrottled = throttle(rcPublish, 30);
setInterval(function() {
if (rcLastPublish !== null && new Date() - rcLastPublish > 800) {
rcPublishThrottled();
}
}, 50);
var body = document.querySelector('body');
var stickLeft = document.querySelector('.stick-left');
var stickRight = document.querySelector('.stick-right');
var controlMessage = { x: 0, y: 0, z: 0, r: 0 };
function onStickTouchMove(touch) {
var target = touch.target;
var targetRect = target.getBoundingClientRect();
var stickPointer = target.querySelector('.stick-pointer');
var offsetX = touch.clientX - targetRect.left;
var offsetY = touch.clientY - targetRect.top;
var x = 2 * offsetX / targetRect.width;
var y = 2 * offsetY / targetRect.height;
x = Math.max(0, x);
x = Math.min(2, x);
y = Math.max(0, y);
y = Math.min(2, y);
stickPointer.style.left = (x * 50) + '%';
stickPointer.style.top = (y * 50) + '%';
x -= 1;
y = 1 - y;
if (target.matches('.stick-left')) {
controlMessage.z = Math.round((y + 1) * 500);
controlMessage.r = Math.round(x * 1000);
} else if (target.matches('.stick-right')) {
controlMessage.x = Math.round(y * 1000);
controlMessage.y = Math.round(x * 1000);
}
}
body.addEventListener('touchmove', function (e) {
e.preventDefault();
});
function stickTouchStart(e) {
setControlMode();
callNativeApp('controlStart');
onStickTouchMove(e.changedTouches[0]);
rcPublishThrottled();
e.stopPropagation();
e.preventDefault();
}
function stickTouchMove(e) {
for (touch of e.changedTouches) {
onStickTouchMove(touch);
}
//onStickTouchMove(e.changedTouches[0]);
rcPublishThrottled();
e.stopPropagation();
e.preventDefault();
}
function stickTouchEnd(e) {
var pointer = e.target.querySelector('.stick-pointer');
if (e.target.matches('.stick-left')) {
controlMessage.r = 0;
pointer.style.left = '50%';
} else if (e.target.matches('.stick-right')) {
controlMessage.x = 0;
controlMessage.y = 0;
pointer.style.left = '50%';
pointer.style.top = '50%';
}
rcPublishThrottled();
}
stickLeft.addEventListener('touchmove', stickTouchMove);
stickRight.addEventListener('touchmove', stickTouchMove);
stickLeft.addEventListener('touchstart', stickTouchStart);
stickRight.addEventListener('touchstart', stickTouchStart);
stickLeft.addEventListener('touchend', stickTouchEnd);
stickRight.addEventListener('touchend', stickTouchEnd);

3693
apps/android/app/src/main/assets/roslib.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,115 @@
var url = 'ws://192.168.11.1:9090';
var modeEl = document.querySelector('.telemetry .mode');
var batteryEl = document.querySelector('.battery');
var notificationsEl = document.querySelector('.notifications');
var ros = new ROSLIB.Ros({ url: url });
ros.on('connection', function () {
body.classList.add('connected');
});
ros.on('close', function () {
body.classList.remove('connected');
modeEl.classList.remove('armed');
modeEl.innerHTML = 'DISCONNECTED';
batteryEl.innerHTML = '';
setTimeout(function() {
modeEl.innerHTML = 'RECONNECTING';
ros.connect(url);
}, 2000);
});
var fcuState;
new ROSLIB.Topic({
ros: ros,
name: '/state_latched',
messageType: 'mavros_msgs/State'
}).subscribe(function(message) {
body.classList.toggle('fcu-disconnected', !message.connected);
body.classList.toggle('armed', message.armed);
fcuState = message;
modeEl.classList.toggle('armed', fcuState.armed);
modeEl.innerHTML = message.connected ? fcuState.mode : 'DISCONNECTED FROM FCU';
console.log('state', message);
});
function notifyLowBattery() {
console.log('low battery');
callNativeApp('lowBattery');
body.classList.remove('low-battery');
void body.offsetWidth; // trick for repeating animation
body.classList.add('low-battery');
}
notifyLowBatteryThrottled = throttle(notifyLowBattery, 15000);
new ROSLIB.Topic({
ros: ros,
name: '/mavros/battery',
messageType: 'sensor_msgs/BatteryState',
throttle_rate: 5000
}).subscribe(function(message) {
var LOW_BATTERY = 3.8;
batteryEl.innerHTML = (message.cell_voltage[0].toFixed(2) + ' V') || '';
if (message.cell_voltage[0] < LOW_BATTERY) {
notifyLowBatteryThrottled();
} else {
body.classList.remove('low-battery');
}
});
var notificationHideTimer;
function notify(text, severity) {
var item = document.createElement('div');
item.innerHTML = text;
item.classList.add('item');
notificationsEl.prepend(item);
var itemHeight = item.offsetHeight;
notificationsEl.classList.remove('anim');
notificationsEl.style.transform = 'translateY(' + -itemHeight + 'px)';
setTimeout(function() {
notificationsEl.classList.add('anim');
notificationsEl.style.transform = 'translateY(0)';
}, 0);
clearTimeout(notificationHideTimer);
notificationHideTimer = setTimeout(function() {
notificationsEl.style.transform = '';
notificationsEl.classList.add('hidden');
setTimeout(function() {
notificationsEl.innerHTML = '';
}, 210);
}, 4000);
}
new ROSLIB.Topic({
ros: ros,
name: '/mavros/statustext/recv',
messageType: 'mavros_msgs/StatusText'
}).subscribe(function(message) {
var BLACKLIST = ['CMD: ', 'PR: ', 'DROPPED', 'Clock skew detected', 'MANUAL CONTROL LOST'];
if (message.severity <= 4) {
if (BLACKLIST.some(function(e) {
return message.text.indexOf(e) != -1;
})) {
console.log('Filtered out message ' + message.text);
return;
}
notify(message.text, message.severity);
callNativeApp('notification', message);
}
});
var setMode = new ROSLIB.Service({
ros: ros,
name : '/mavros/set_mode',
serviceType : 'mavros_msgs/SetMode'
});
function setControlMode() {
var CONTROL_MODE = 'STABILIZED';
setMode.callService(new ROSLIB.ServiceRequest({ custom_mode: CONTROL_MODE }));
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -0,0 +1,86 @@
package express.copter.cleverrc
import android.content.Context
import android.os.Build
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.view.WindowManager
import android.webkit.JavascriptInterface
import kotlinx.android.synthetic.main.activity_main.*
import org.json.JSONObject
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetAddress
import java.nio.ByteBuffer
fun pack(x: Short, y: Short, z: Short, r: Short): ByteArray {
val pump_on_buf: ByteBuffer = ByteBuffer.allocate(8)
pump_on_buf.putShort(r)
pump_on_buf.putShort(z)
pump_on_buf.putShort(y)
pump_on_buf.putShort(x)
return pump_on_buf.array().reversedArray()
}
fun send(host: String, port: Int, data: ByteArray, senderPort: Int = 0): Boolean {
var ret = false
var socket: DatagramSocket? = null
try {
socket = DatagramSocket(senderPort)
val address = InetAddress.getByName(host)
val packet = DatagramPacket(data, data.size, address, port)
socket.send(packet)
ret = true
} catch (e: Exception) {
e.printStackTrace()
} finally {
socket?.close()
}
return ret
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fullScreenCall()
main_web.loadUrl("file:///android_asset/index.html")
main_web.settings.apply {
domStorageEnabled = true
javaScriptEnabled = true
loadWithOverviewMode = true
useWideViewPort = true
setSupportZoom(false)
}
main_web.addJavascriptInterface(WebAppInterface(this), "appInterface")
}
private fun fullScreenCall() {
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
if (Build.VERSION.SDK_INT < 19) {
val v = this.window.decorView
v.systemUiVisibility = View.GONE
} else {
//for higher api versions.
val decorView = window.decorView
val uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
decorView.systemUiVisibility = uiOptions
}
}
}
class WebAppInterface(c: Context) {
@JavascriptInterface
public fun postMessage(message: String) {
val data = JSONObject(message)
send("255.255.255.255", 35602, pack(data.getInt("x").toShort(), data.getInt("y").toShort(), data.getInt("z").toShort(), data.getInt("r").toShort()))
}
}

View File

@@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0"/>
<item
android:color="#00000000"
android:offset="1.0"/>
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1"/>
</vector>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:height="108dp"
android:width="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path android:fillColor="#008577"
android:pathData="M0,0h108v108h-108z"/>
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
</vector>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/main_web"/>
</FrameLayout>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#fafafa</color>
<color name="colorPrimaryDark">#d1d1d1</color>
<color name="colorAccent">#757575</color>
</resources>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#FFFFFF</color>
</resources>

View File

@@ -0,0 +1,3 @@
<resources>
<string name="app_name">CLEVER RC</string>
</resources>

View File

@@ -0,0 +1,18 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="NoUiAppTheme"
parent="Theme.AppCompat.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>

View File

@@ -0,0 +1,17 @@
package express.copter.cleverrc
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

27
apps/android/build.gradle Normal file
View File

@@ -0,0 +1,27 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.2.71'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View File

@@ -0,0 +1,15 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official

Binary file not shown.

View File

@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

172
apps/android/gradlew vendored Normal file
View File

@@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
apps/android/gradlew.bat vendored Normal file
View File

@@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -0,0 +1 @@
include ':app'

View File

@@ -1,5 +1,4 @@
iOS-приложение для управления Клевером
--------------------------------------
# iOS-приложение для управления Клевером
Для установки зависимостей необходим [CocoaPods](https://cocoapods.org):
@@ -8,3 +7,11 @@ pod install
```
Для разработки и сборки откройте в XCode файл `cleverrc.xcworkspace`.
## Политика конфиденциальности
App Store приложение CLEVER RC не собирает и не хранит каких-либо личных данных пользователя.
## Privacy policy
The App Store app CLEVER RC does not collect and store any personal user data.

View File

@@ -145,8 +145,15 @@
"size" : "44x44",
"idiom" : "watch",
"scale" : "2x",
"role" : "longLook",
"subtype" : "42mm"
"role" : "appLauncher",
"subtype" : "40mm"
},
{
"size" : "50x50",
"idiom" : "watch",
"scale" : "2x",
"role" : "appLauncher",
"subtype" : "44mm"
},
{
"size" : "86x86",
@@ -162,10 +169,24 @@
"role" : "quickLook",
"subtype" : "42mm"
},
{
"size" : "108x108",
"idiom" : "watch",
"scale" : "2x",
"role" : "quickLook",
"subtype" : "44mm"
},
{
"idiom" : "watch-marketing",
"size" : "1024x1024",
"scale" : "1x"
},
{
"size" : "44x44",
"idiom" : "watch",
"scale" : "2x",
"role" : "longLook",
"subtype" : "42mm"
}
],
"info" : {

View File

@@ -17,9 +17,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.1</string>
<string>1.2</string>
<key>CFBundleVersion</key>
<string>6</string>
<string>7</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>

View File

@@ -64,9 +64,19 @@ new ROSLIB.Topic({
var notificationHideTimer;
function notify(text, severity) {
var repeated = notificationsEl.querySelector('.item:first-of-type[data-text=' + text + ']');
if (repeated) {
// don't repeat notifications
var count = repeated.getAttribute('data-count') || 1;
repeated.setAttribute('data-count', ++count);
repeated.innerHTML = text + ' (' + count + ')';
return;
}
var item = document.createElement('div');
item.innerHTML = text;
item.classList.add('item');
item.setAttribute('data-text', text);
notificationsEl.prepend(item);
var itemHeight = item.offsetHeight;
notificationsEl.classList.remove('anim');

View File

@@ -16,11 +16,15 @@ find_package(catkin REQUIRED COMPONENTS
image_transport
cv_bridge
tf
#tf2
#tf2_ros
#aruco_msgs
tf2
tf2_ros
tf2_geometry_msgs
sensor_msgs
message_generation
)
find_package(OpenCV 3 REQUIRED)
## System dependencies are found with CMake's conventions
# find_package(Boost REQUIRED COMPONENTS system)
@@ -55,11 +59,12 @@ find_package(catkin REQUIRED COMPONENTS
## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
## Generate messages in the 'msg' folder
#add_message_files(
# FILES
# Marker.msg
# MarkerArray.msg
#)
add_message_files(
FILES
Point2D.msg
Marker.msg
MarkerArray.msg
)
## Generate services in the 'srv' folder
# add_service_files(
@@ -76,10 +81,11 @@ find_package(catkin REQUIRED COMPONENTS
# )
## Generate added messages and services with any dependencies listed here
#generate_messages(
# DEPENDENCIES
# std_msgs # Or other packages containing msgs
#)
generate_messages(
DEPENDENCIES
std_msgs
geometry_msgs
)
################################################
## Declare ROS dynamic reconfigure parameters ##
@@ -111,9 +117,9 @@ find_package(catkin REQUIRED COMPONENTS
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
# INCLUDE_DIRS include
INCLUDE_DIRS DEPENDS OpenCV
LIBRARIES aruco_pose
# CATKIN_DEPENDS other_catkin_pkg
CATKIN_DEPENDS message_runtime
# DEPENDS system_lib
)
@@ -126,17 +132,17 @@ catkin_package(
include_directories(
# include
${catkin_INCLUDE_DIRS}
${OpenCV_INCLUDE_DIRS}
)
## Declare a C++ library
add_library(${PROJECT_NAME}
src/aruco_pose.cpp
add_library(aruco_pose
src/aruco_detect.cpp
src/aruco_map.cpp
src/draw.cpp
)
## Add cmake target dependencies of the library
## as an example, code may need to be generated before libraries
## either from message generation or dynamic reconfigure
# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_dependencies(${PROJECT_NAME} aruco_pose_generate_messages_cpp)
## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
@@ -154,11 +160,9 @@ add_library(${PROJECT_NAME}
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
## Specify libraries to link a library or executable target against
link_directories(/opt/ros/kinetic/lib)
target_link_libraries(${PROJECT_NAME}
target_link_libraries(aruco_pose
${catkin_LIBRARIES}
"/opt/ros/kinetic/lib/libopencv_aruco3.so" # TODO: fix launch fails with .so loading
${OpenCV_LIBRARIES}
)
#############
@@ -169,7 +173,7 @@ target_link_libraries(${PROJECT_NAME}
# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
## Mark executable scripts (Python etc.) for installation
## in contrast to setup.py, you can choose the destination
## in contrast to setup.py, you can choose the destination
# install(PROGRAMS
# scripts/my_python_script
# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
@@ -208,3 +212,12 @@ target_link_libraries(${PROJECT_NAME}
## Add folders to be run by python nosetests
# catkin_add_nosetests(test)
if (CATKIN_ENABLE_TESTING)
find_package(rostest REQUIRED)
add_rostest(test/basic.test)
add_rostest(test/test_parser_pass.test)
add_rostest(test/test_parser_empty_map.test)
add_rostest(test/test_node_failure.test)
add_rostest(test/largemap.test)
endif()

120
aruco_pose/README.md Normal file
View File

@@ -0,0 +1,120 @@
# Positioning with ArUco markers
`aruco_pose` package consists of two nodelets: `aruco_detect` detects individual ArUco-markers and estimates their poses, `aruco_map` detects maps of markers using `aruco_detect` output.
## Quick start
To run a camera nodelet, markers and maps detector:
```bash
roslaunch aruco_pose sample.launch
```
You're going to need [`cv_camera`](http://wiki.ros.org/cv_camera) package installed.
## aruco_detect nodelet
`aruco_detect` detects ArUco markers on the image, publishes list of them (with poses), TF transformations, visualization markers and processed image for debugging.
It's recommended to run it within the same nodelet manager with the camera nodelet (e. g. [`cv_camera`](http://wiki.ros.org/cv_camera)).
### Parameters
* `~dictionary` (*int*)  ArUco dictionary (default: 2)
* 0 = DICT_4X4_50
* 1 = DICT_4X4_100,
* 2 = DICT_4X4_250,
* 3 = DICT_4X4_1000,
* 4 = DICT_5X5_50,
* 5 = DICT_5X5_100,
* 6 = DICT_5X5_250,
* 7 = DICT_5X5_1000,
* 8 = DICT_6X6_50,
* 9 = DICT_6X6_100,
* 10 = DICT_6X6_250,
* 11 = DICT_6X6_1000,
* 12 = DICT_7X7_50,
* 13 = DICT_7X7_100,
* 14 = DICT_7X7_250,
* 15 = DICT_7X7_1000,
* 16 = DICT_ARUCO_ORIGINAL
* `~estimate_poses` (*bool*)  estimate single markers' poses (default: true)
* `~send_tf` (*bool*)  send TF transforms (default: true)
* `~frame_id_prefix` (*string*) prefix for TF transforms names, marker's ID is appended (default: `aruco_`)
* `~length` (*double*) markers' sides length
* `~length_override` (*map*) lengths of markers with specified ids
* `~known_tilt` (*string*) known tilt (pitch and roll) of all the markers as a frame
### Topics
#### Subscribed
* `image_raw` (*sensor_msgs/Image*) camera image
* `camera_info` (*sensor_msgs/CameraInfo*) camera calibration info
#### Published
* `~markers` (*aruco_pose/MarkerArray*)  list of detected markers with their corners and poses
* `~visualization` (*visualization_msgs/MarkerArray*)  visualization markers for rviz
* `~debug` (*sensor_msgs/Image*)  debug image with detected markers
### Published transforms
* `<camera_frame>` => `<frame_id_prefix><id>` markers' poses
## aruco_map nodelet
`aruco_map` nodelet estimates position of markers map.
### Parameters
* `~map` path to text file with markers list
* `~frame_id` published frame id (default: `aruco_map`)
* `~known_tilt` debug image width
* `~image_width` debug image width (default: 2000)
* `~image_height` debug image height (default: 2000)
* `~image_margin`  debug image margin (default: 200)
* `~dictionary` (*int*)  ArUco dictionary (default: 2) - should be the same as `dictionary` parameter of `aruco_detect` nodelet
Map file has one marker per line with the following line format:
```
marker_id marker_length x y z yaw pitch roll
```
Where yaw, pitch and roll are extrinsic rotation around Z, Y, X axis, respectively.
See examples in [`map`](map/) directory.
### Topics
#### Subscribed
* `image_raw` (*sensor_msgs/Image*) camera image (used for debug image)
* `camera_info` (*sensor_msgs/CameraInfo*) camera calibration info (used for debug image)
* `markers` (*aruco_pose/MarkerArray*) list of markers detected by `aruco_pose` nodelet
#### Published
* `~pose` (*geometry_msgs/PoseWithCovarianceStamped*) estimated map pose
* `~image` (*sensor_msgs/Image*) planarized map image
* `~visualization` (*visualization_msgs/MarkerArray*) markers map visualization for rviz
* `~debug` (*sensor_msgs/Image*) debug image with detected markers and map axis
### Published transforms
* `<camera_frame>` => `<map_name>` markers map pose
## Running tests
Command for running tests:
```bash
catkin_make run_tests && catkin_test_results
```
## Copyright
Copyright © 2018 Copter Express Technologies. Author: Oleg Kalachev.
Distributed under MIT License (https://opensource.org/licenses/MIT).

View File

@@ -0,0 +1,26 @@
<launch>
<node pkg="nodelet" type="nodelet" name="nodelet_manager" args="manager"/>
<!-- camera node -->
<node pkg="nodelet" type="nodelet" name="main_camera" args="load cv_camera/CvCameraNodelet nodelet_manager">
<param name="frame_id" value="main_camera_optical"/>
<param name="camera_info_url" value="file://$(find aruco_pose)/test/camera_info.yaml" />
<param name="image_width" value="640"/>
<param name="image_height" value="480"/>
</node>
<!-- detect aruco markers -->
<node pkg="nodelet" clear_params="true" type="nodelet" name="aruco_detect" args="load aruco_pose/aruco_detect nodelet_manager">
<remap from="image_raw" to="main_camera/image_raw"/>
<remap from="camera_info" to="main_camera/camera_info"/>
<param name="length" value="0.33"/>
</node>
<!-- aruco map -->
<node pkg="nodelet" clear_params="true" type="nodelet" name="aruco_map" args="load aruco_pose/aruco_map nodelet_manager">
<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"/>
<param name="map" value="$(find aruco_pose)/map/map.txt"/>
</node>
</launch>

100
aruco_pose/map/cmit.txt Normal file
View File

@@ -0,0 +1,100 @@
0 0.33 0.0 9.0 0 0 0 0
1 0.33 1.0 9.0 0 0 0 0
2 0.33 2.0 9.0 0 0 0 0
3 0.33 3.0 9.0 0 0 0 0
4 0.33 4.0 9.0 0 0 0 0
5 0.33 5.0 9.0 0 0 0 0
6 0.33 6.0 9.0 0 0 0 0
7 0.33 7.0 9.0 0 0 0 0
8 0.33 8.0 9.0 0 0 0 0
9 0.33 9.0 9.0 0 0 0 0
10 0.33 0.0 8.0 0 0 0 0
11 0.33 1.0 8.0 0 0 0 0
12 0.33 2.0 8.0 0 0 0 0
13 0.33 3.0 8.0 0 0 0 0
14 0.33 4.0 8.0 0 0 0 0
15 0.33 5.0 8.0 0 0 0 0
16 0.33 6.0 8.0 0 0 0 0
#17 0.33 7.0 8.0 0 0 0 0
18 0.33 8.0 8.0 0 0 0 0
19 0.33 9.0 8.0 0 0 0 0
20 0.33 0.0 7.0 0 0 0 0
21 0.33 1.0 7.0 0 0 0 0
22 0.33 2.0 7.0 0 0 0 0
23 0.33 3.0 7.0 0 0 0 0
24 0.33 4.0 7.0 0 0 0 0
25 0.33 5.0 7.0 0 0 0 0
26 0.33 6.0 7.0 0 0 0 0
27 0.33 7.0 7.0 0 0 0 0
28 0.33 8.0 7.0 0 0 0 0
29 0.33 9.0 7.0 0 0 0 0
30 0.33 0.0 6.0 0 0 0 0
31 0.33 1.0 6.0 0 0 0 0
32 0.33 2.0 6.0 0 0 0 0
33 0.33 3.0 6.0 0 0 0 0
34 0.33 4.0 6.0 0 0 0 0
35 0.33 5.0 6.0 0 0 0 0
36 0.33 6.0 6.0 0 0 0 0
37 0.33 7.0 6.0 0 0 0 0
38 0.33 8.0 6.0 0 0 0 0
39 0.33 9.0 6.0 0 0 0 0
40 0.33 0.0 5.0 0 0 0 0
41 0.33 1.0 5.0 0 0 0 0
42 0.33 2.0 5.0 0 0 0 0
43 0.33 3.0 5.0 0 0 0 0
44 0.33 4.0 5.0 0 0 0 0
45 0.33 5.0 5.0 0 0 0 0
46 0.33 6.0 5.0 0 0 0 0
47 0.33 7.0 5.0 0 0 0 0
48 0.33 8.0 5.0 0 0 0 0
49 0.33 9.0 5.0 0 0 0 0
50 0.33 0.0 4.0 0 0 0 0
51 0.33 1.0 4.0 0 0 0 0
52 0.33 2.0 4.0 0 0 0 0
53 0.33 3.0 4.0 0 0 0 0
54 0.33 4.0 4.0 0 0 0 0
55 0.33 5.0 4.0 0 0 0 0
56 0.33 6.0 4.0 0 0 0 0
57 0.33 7.0 4.0 0 0 0 0
58 0.33 8.0 4.0 0 0 0 0
59 0.33 9.0 4.0 0 0 0 0
60 0.33 0.0 3.0 0 0 0 0
61 0.33 1.0 3.0 0 0 0 0
62 0.33 2.0 3.0 0 0 0 0
63 0.33 3.0 3.0 0 0 0 0
64 0.33 4.0 3.0 0 0 0 0
65 0.33 5.0 3.0 0 0 0 0
66 0.33 6.0 3.0 0 0 0 0
67 0.33 7.0 3.0 0 0 0 0
68 0.33 8.0 3.0 0 0 0 0
69 0.33 9.0 3.0 0 0 0 0
70 0.33 0.0 2.0 0 0 0 0
71 0.33 1.0 2.0 0 0 0 0
72 0.33 2.0 2.0 0 0 0 0
73 0.33 3.0 2.0 0 0 0 0
74 0.33 4.0 2.0 0 0 0 0
75 0.33 5.0 2.0 0 0 0 0
76 0.33 6.0 2.0 0 0 0 0
77 0.33 7.0 2.0 0 0 0 0
78 0.33 8.0 2.0 0 0 0 0
79 0.33 9.0 2.0 0 0 0 0
80 0.33 0.0 1.0 0 0 0 0
81 0.33 1.0 1.0 0 0 0 0
82 0.33 2.0 1.0 0 0 0 0
83 0.33 3.0 1.0 0 0 0 0
84 0.33 4.0 1.0 0 0 0 0
85 0.33 5.0 1.0 0 0 0 0
86 0.33 6.0 1.0 0 0 0 0
87 0.33 7.0 1.0 0 0 0 0
88 0.33 8.0 1.0 0 0 0 0
89 0.33 9.0 1.0 0 0 0 0
90 0.33 0.0 0.0 0 0 0 0
91 0.33 1.0 0.0 0 0 0 0
92 0.33 2.0 0.0 0 0 0 0
93 0.33 3.0 0.0 0 0 0 0
94 0.33 4.0 0.0 0 0 0 0
95 0.33 5.0 0.0 0 0 0 0
96 0.33 6.0 0.0 0 0 0 0
97 0.33 7.0 0.0 0 0 0 0
98 0.33 8.0 0.0 0 0 0 0
99 0.33 9.0 0.0 0 0 0 0

4
aruco_pose/map/map.txt Normal file
View File

@@ -0,0 +1,4 @@
1 0.33 0 0 0 0 0 0
2 0.33 1 0 0 0 0 0
3 0.33 0 1 0 0 0 0
4 0.33 1 1 0 0 0 0

View File

@@ -0,0 +1,8 @@
107 0.33 0 0 0 0 0 0
106 0.33 0.77 0 0 0 0 0
105 0.33 0 0.77 0 0 0 0
104 0.33 0.77 0.77 0 0 0 0
103 0.33 0 1.54 0 0 0 0
102 0.33 0.77 1.54 0 0 0 0
101 0.33 0 2.31 0 0 0 0
100 0.33 0.77 2.31 0 0 0 0

View File

@@ -0,0 +1,31 @@
14 0.365 0.000 0.0 0 0 0 0
15 0.365 1.335 0.0 0 0 0 0
30 0.365 2.865 0.0 0 0 0 0
31 0.365 4.200 0.0 0 0 0 0
12 0.365 0.000 1.8 0 0 0 0
13 0.365 1.335 1.8 0 0 0 0
28 0.365 2.865 1.8 0 0 0 0
29 0.365 4.200 1.8 0 0 0 0
10 0.365 0.000 3.6 0 0 0 0
11 0.365 1.335 3.6 0 0 0 0
26 0.365 2.865 3.6 0 0 0 0
27 0.365 4.200 3.6 0 0 0 0
8 0.365 0.000 5.4 0 0 0 0
9 0.365 1.335 5.4 0 0 0 0
24 0.365 2.865 5.4 0 0 0 0
25 0.365 4.200 5.4 0 0 0 0
6 0.365 0.000 7.2 0 0 0 0
7 0.365 1.335 7.2 0 0 0 0
22 0.365 2.865 7.2 0 0 0 0
23 0.365 4.200 7.2 0 0 0 0
4 0.365 0.000 9.0 0 0 0 0
5 0.365 1.335 9.0 0 0 0 0
20 0.365 2.865 9.0 0 0 0 0
21 0.365 4.200 9.0 0 0 0 0
2 0.365 0.000 10.8 0 0 0 0
3 0.365 1.335 10.8 0 0 0 0
18 0.365 2.865 10.8 0 0 0 0
19 0.365 4.200 10.8 0 0 0 0
1 0.365 0.000 12.6 0 0 0 0
0 0.365 1.335 12.6 0 0 0 0
16 0.365 2.865 12.6 0 0 0 0

View File

@@ -0,0 +1,7 @@
uint32 id
float32 length
geometry_msgs/Pose pose
Point2D c1
Point2D c2
Point2D c3
Point2D c4

View File

@@ -0,0 +1,2 @@
Header header
Marker[] markers

View File

@@ -0,0 +1,2 @@
float32 x
float32 y

View File

@@ -1,5 +1,8 @@
<library path="lib/libaruco_pose">
<class name="aruco_pose/aruco_pose" type="ArucoPose" base_class_type="nodelet::Nodelet">
<class name="aruco_pose/aruco_detect" type="ArucoDetect" base_class_type="nodelet::Nodelet">
<description/>
</class>
<class name="aruco_pose/aruco_map" type="ArucoMap" base_class_type="nodelet::Nodelet">
<description/>
</class>
</library>

View File

@@ -1,62 +1,40 @@
<?xml version="1.0"?>
<package>
<package format="2">
<name>aruco_pose</name>
<version>0.0.0</version>
<description>ArUco maps precise pose estimation nodelet</description>
<version>0.0.1</version>
<description>Positioning with ArUco markers</description>
<!-- One maintainer tag required, multiple allowed, one person per tag -->
<!-- Example: -->
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
<license>MIT</license>
<!--url type="website">http://wiki.ros.org/aruco_pose</url-->
<author email="okalachev@gmail.com">Oleg Kalachev</author>
<!-- One license tag required, multiple allowed, one license per tag -->
<!-- Commonly used license strings: -->
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
<license>TODO</license>
<!-- Url tags are optional, but multiple are allowed, one per tag -->
<!-- Optional attribute type can be: website, bugtracker, or repository -->
<!-- Example: -->
<!-- <url type="website">http://wiki.ros.org/aruco_pose</url> -->
<!-- Author tags are optional, multiple are allowed, one per tag -->
<!-- Authors do not have to be maintainers, but could be -->
<!-- Example: -->
<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
<!-- The *_depend tags are used to specify dependencies -->
<!-- Dependencies can be catkin packages or system dependencies -->
<!-- Examples: -->
<!-- Use build_depend for packages you need at compile time: -->
<!-- <build_depend>message_generation</build_depend> -->
<!-- Use buildtool_depend for build tool packages: -->
<!-- <buildtool_depend>catkin</buildtool_depend> -->
<!-- Use run_depend for packages you need at runtime: -->
<!-- <run_depend>message_runtime</run_depend> -->
<!-- Use test_depend for packages you need only for testing: -->
<!-- <test_depend>gtest</test_depend> -->
<buildtool_depend>catkin</buildtool_depend>
<build_depend>nodelet</build_depend>
<build_depend>roscpp</build_depend>
<build_depend>image_transport</build_depend>
<build_depend>cv_bridge</build_depend>
<build_depend>tf</build_depend>
<depend>roscpp</depend>
<depend>nodelet</depend>
<depend>tf</depend>
<depend>tf2</depend>
<depend>tf2_ros</depend>
<depend>tf2_geometry_msgs</depend>
<depend>opencv3</depend>
<depend>cv_bridge</depend>
<depend>image_transport</depend>
<depend>message_generation</depend>
<depend>message_runtime</depend>
<depend>std_msgs</depend>
<depend>geometry_msgs</depend>
<depend>visualization_msgs</depend>
<depend>sensor_msgs</depend>
<depend>rostest</depend>
<run_depend>nodelet</run_depend>
<run_depend>roscpp</run_depend>
<run_depend>image_transport</run_depend>
<run_depend>cv_bridge</run_depend>
<build_depend>tf</build_depend>
<test_depend>image_publisher</test_depend>
<test_depend>ros_pytest</test_depend>
<!-- The export tag contains other, unspecified, tags -->
<export>
<nodelet plugin="${prefix}/nodelet_plugins.xml" />
<nodelet plugin="${prefix}/nodelet_plugins.xml" />
<!-- Other tools can request additional information be placed here -->
</export>
</package>

View File

@@ -0,0 +1,346 @@
/*
* Detecting and pose estimation of ArUco markers
* Copyright (C) 2018 Copter Express Technologies
*
* Author: Oleg Kalachev <okalachev@gmail.com>
*
* Distributed under MIT License (available at https://opensource.org/licenses/MIT).
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*/
/*
* Code is based on https://github.com/UbiquityRobotics/fiducials, which is distributed
* under the BSD license.
*/
#include <math.h>
#include <vector>
#include <string>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <ros/ros.h>
#include <nodelet/nodelet.h>
#include <pluginlib/class_list_macros.h>
#include <tf/transform_datatypes.h>
#include <tf2_ros/buffer.h>
#include <tf2_ros/transform_listener.h>
#include <tf2_ros/transform_broadcaster.h>
#include <tf2_geometry_msgs/tf2_geometry_msgs.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <geometry_msgs/Vector3.h>
#include <geometry_msgs/Pose.h>
#include <geometry_msgs/PoseStamped.h>
#include <geometry_msgs/PoseWithCovarianceStamped.h>
#include <geometry_msgs/TransformStamped.h>
#include <visualization_msgs/Marker.h>
#include <visualization_msgs/MarkerArray.h>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/aruco.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <aruco_pose/Marker.h>
#include <aruco_pose/MarkerArray.h>
#include "utils.h"
using std::vector;
using cv::Mat;
class ArucoDetect : public nodelet::Nodelet {
private:
ros::NodeHandle nh_, nh_priv_;
tf2_ros::TransformBroadcaster br_;
tf2_ros::Buffer tf_buffer_;
tf2_ros::TransformListener tf_listener_{tf_buffer_};
cv::Ptr<cv::aruco::Dictionary> dictionary_;
cv::Ptr<cv::aruco::DetectorParameters> parameters_;
image_transport::Publisher debug_pub_;
image_transport::CameraSubscriber img_sub_;
ros::Publisher markers_pub_, vis_markers_pub_;
ros::Subscriber map_markers_sub_;
bool estimate_poses_, send_tf_, auto_flip_;
double length_;
std::unordered_map<int, double> length_override_;
std::string frame_id_prefix_, known_tilt_;
Mat camera_matrix_, dist_coeffs_;
aruco_pose::MarkerArray array_;
std::unordered_set<int> map_markers_ids_;
visualization_msgs::MarkerArray vis_array_;
public:
virtual void onInit()
{
nh_ = getNodeHandle();
nh_priv_ = getPrivateNodeHandle();
int dictionary;
nh_priv_.param("dictionary", dictionary, 2);
nh_priv_.param("estimate_poses", estimate_poses_, true);
nh_priv_.param("send_tf", send_tf_, true);
if (estimate_poses_ && !nh_priv_.getParam("length", length_)) {
NODELET_FATAL("can't estimate marker's poses as ~length parameter is not defined");
ros::shutdown();
}
readLengthOverride();
nh_priv_.param<std::string>("known_tilt", known_tilt_, "");
nh_priv_.param("auto_flip", auto_flip_, false);
nh_priv_.param<std::string>("frame_id_prefix", frame_id_prefix_, "aruco_");
camera_matrix_ = cv::Mat::zeros(3, 3, CV_64F);
dist_coeffs_ = cv::Mat::zeros(8, 1, CV_64F);
dictionary_ = cv::aruco::getPredefinedDictionary(static_cast<cv::aruco::PREDEFINED_DICTIONARY_NAME>(dictionary));
parameters_ = cv::aruco::DetectorParameters::create();
parameters_->cornerRefinementMethod = cv::aruco::CORNER_REFINE_SUBPIX;
image_transport::ImageTransport it(nh_);
image_transport::ImageTransport it_priv(nh_priv_);
map_markers_sub_ = nh_.subscribe("map_markers", 1, &ArucoDetect::mapMarkersCallback, this);
debug_pub_ = it_priv.advertise("debug", 1);
markers_pub_ = nh_priv_.advertise<aruco_pose::MarkerArray>("markers", 1);
vis_markers_pub_ = nh_priv_.advertise<visualization_msgs::MarkerArray>("visualization", 1);
img_sub_ = it.subscribeCamera("image_raw", 1, &ArucoDetect::imageCallback, this);
NODELET_INFO("ready");
}
private:
void imageCallback(const sensor_msgs::ImageConstPtr& msg, const sensor_msgs::CameraInfoConstPtr &cinfo)
{
Mat image = cv_bridge::toCvShare(msg, "bgr8")->image;
vector<int> ids;
vector<vector<cv::Point2f>> corners, rejected;
vector<cv::Vec3d> rvecs, tvecs;
vector<cv::Point3f> obj_points;
geometry_msgs::TransformStamped snap_to;
// Detect markers
cv::aruco::detectMarkers(image, dictionary_, corners, ids, parameters_, rejected);
array_.header.stamp = msg->header.stamp;
array_.header.frame_id = msg->header.frame_id;
array_.markers.clear();
if (ids.size() != 0) {
parseCameraInfo(cinfo, camera_matrix_, dist_coeffs_);
// Estimate individual markers' poses
if (estimate_poses_) {
cv::aruco::estimatePoseSingleMarkers(corners, length_, camera_matrix_, dist_coeffs_,
rvecs, tvecs);
// process length override, TODO: efficiency
if (!length_override_.empty()) {
for (unsigned int i = 0; i < ids.size(); i++) {
int id = ids[i];
auto item = length_override_.find(id);
if (item != length_override_.end()) { // found override
vector<cv::Vec3d> rvecs_current, tvecs_current;
vector<vector<cv::Point2f>> corners_current;
corners_current.push_back(corners[i]);
cv::aruco::estimatePoseSingleMarkers(corners_current, item->second,
camera_matrix_, dist_coeffs_,
rvecs_current, tvecs_current);
rvecs[i] = rvecs_current[0];
tvecs[i] = tvecs_current[0];
}
}
}
if (!known_tilt_.empty()) {
try {
snap_to = tf_buffer_.lookupTransform(msg->header.frame_id, known_tilt_,
msg->header.stamp, ros::Duration(0.02));
} catch (const tf2::TransformException& e) {
NODELET_WARN_THROTTLE(5, "can't snap: %s", e.what());
}
}
}
array_.markers.reserve(ids.size());
aruco_pose::Marker marker;
geometry_msgs::TransformStamped transform;
transform.header.stamp = msg->header.stamp;
transform.header.frame_id = msg->header.frame_id;
for (unsigned int i = 0; i < ids.size(); i++) {
marker.id = ids[i];
marker.length = getMarkerLength(marker.id);
fillCorners(marker, corners[i]);
if (estimate_poses_) {
fillPose(marker.pose, rvecs[i], tvecs[i]);
// snap orientation (if enabled and snap frame available)
if (!known_tilt_.empty() && !snap_to.header.frame_id.empty()) {
snapOrientation(marker.pose.orientation, snap_to.transform.rotation, auto_flip_);
}
// TODO: check IDs are unique
if (send_tf_) {
transform.child_frame_id = getChildFrameId(ids[i]);
// check if such static transform is in the map
if (map_markers_ids_.find(ids[i]) == map_markers_ids_.end()) {
transform.transform.rotation = marker.pose.orientation;
fillTranslation(transform.transform.translation, tvecs[i]);
br_.sendTransform(transform);
}
}
}
array_.markers.push_back(marker);
}
}
markers_pub_.publish(array_);
// Publish visualization markers
if (estimate_poses_ && vis_markers_pub_.getNumSubscribers() != 0) {
// Delete all markers
visualization_msgs::Marker vis_marker;
vis_marker.action = visualization_msgs::Marker::DELETEALL;
vis_array_.markers.clear();
vis_array_.markers.reserve(ids.size() + 1);
vis_array_.markers.push_back(vis_marker);
for (unsigned int i = 0; i < ids.size(); i++)
pushVisMarkers(msg->header.frame_id, msg->header.stamp, array_.markers[i].pose,
getMarkerLength(ids[i]), ids[i], i);
vis_markers_pub_.publish(vis_array_);
}
// Publish debug image
if (debug_pub_.getNumSubscribers() != 0) {
Mat debug = image.clone();
cv::aruco::drawDetectedMarkers(debug, corners, ids); // draw markers
if (estimate_poses_)
for (unsigned int i = 0; i < ids.size(); i++)
cv::aruco::drawAxis(debug, camera_matrix_, dist_coeffs_,
rvecs[i], tvecs[i], getMarkerLength(ids[i]));
cv_bridge::CvImage out_msg;
out_msg.header.frame_id = msg->header.frame_id;
out_msg.header.stamp = msg->header.stamp;
out_msg.encoding = sensor_msgs::image_encodings::BGR8;
out_msg.image = debug;
debug_pub_.publish(out_msg.toImageMsg());
}
}
inline void fillCorners(aruco_pose::Marker& marker, const vector<cv::Point2f>& corners) const
{
marker.c1.x = corners[0].x;
marker.c2.x = corners[1].x;
marker.c3.x = corners[2].x;
marker.c4.x = corners[3].x;
marker.c1.y = corners[0].y;
marker.c2.y = corners[1].y;
marker.c3.y = corners[2].y;
marker.c4.y = corners[3].y;
}
inline void fillPose(geometry_msgs::Pose& pose, const cv::Vec3d& rvec, const cv::Vec3d& tvec) const
{
pose.position.x = tvec[0];
pose.position.y = tvec[1];
pose.position.z = tvec[2];
double angle = norm(rvec);
cv::Vec3d axis = rvec / angle;
tf2::Quaternion q;
q.setRotation(tf2::Vector3(axis[0], axis[1], axis[2]), angle);
pose.orientation.w = q.w();
pose.orientation.x = q.x();
pose.orientation.y = q.y();
pose.orientation.z = q.z();
}
inline void fillTranslation(geometry_msgs::Vector3& translation, const cv::Vec3d& tvec) const
{
translation.x = tvec[0];
translation.y = tvec[1];
translation.z = tvec[2];
}
void pushVisMarkers(const std::string& frame_id, const ros::Time& stamp,
const geometry_msgs::Pose &pose, double length, int id, int index)
{
visualization_msgs::Marker marker;
marker.header.frame_id = frame_id;
marker.header.stamp = stamp;
marker.action = visualization_msgs::Marker::ADD;
marker.id = index;
// Marker
marker.ns = "aruco_marker";
marker.type = visualization_msgs::Marker::CUBE;
marker.scale.x = length;
marker.scale.y = length;
marker.scale.z = 0.001;
marker.color.r = 1;
marker.color.g = 1;
marker.color.b = 1;
marker.color.a = 0.9;
marker.pose = pose;
vis_array_.markers.push_back(marker);
// Label
marker.ns = "aruco_marker_label";
marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
marker.scale.z = length * 0.6;
marker.color.r = 0;
marker.color.g = 0;
marker.color.b = 0;
marker.color.a = 1;
marker.text = std::to_string(id);
marker.pose = pose;
vis_array_.markers.push_back(marker);
}
inline std::string getChildFrameId(int id) const
{
return frame_id_prefix_ + std::to_string(id);
}
void readLengthOverride()
{
std::map<std::string, double> length_override;
nh_priv_.getParam("length_override", length_override);
for (auto const& item : length_override) {
length_override_[std::stoi(item.first)] = item.second;
}
}
inline double getMarkerLength(int id)
{
auto item = length_override_.find(id);
if (item != length_override_.end()) {
return item->second;
} else {
return length_;
}
}
void mapMarkersCallback(const aruco_pose::MarkerArray& msg)
{
map_markers_ids_.clear();
for (auto const& marker : msg.markers) {
map_markers_ids_.insert(marker.id);
}
}
};
PLUGINLIB_EXPORT_CLASS(ArucoDetect, nodelet::Nodelet)

View File

@@ -0,0 +1,516 @@
/*
* Detecting and pose estimation of ArUco markers maps
* Copyright (C) 2018 Copter Express Technologies
*
* Author: Oleg Kalachev <okalachev@gmail.com>
*
* Distributed under MIT License (available at https://opensource.org/licenses/MIT).
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*/
/*
* Code is based on https://github.com/UbiquityRobotics/fiducials, which is distributed
* under the BSD license.
*/
#include <math.h>
#include <string>
#include <vector>
#include <fstream>
#include <algorithm>
#include <ros/ros.h>
#include <nodelet/nodelet.h>
#include <pluginlib/class_list_macros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <tf/transform_datatypes.h>
#include <tf2_ros/buffer.h>
#include <tf2_ros/transform_listener.h>
#include <tf2_ros/transform_broadcaster.h>
#include <tf2_ros/static_transform_broadcaster.h>
#include <tf2_geometry_msgs/tf2_geometry_msgs.h>
#include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h>
#include <message_filters/sync_policies/exact_time.h>
#include <geometry_msgs/TransformStamped.h>
#include <geometry_msgs/PoseWithCovarianceStamped.h>
#include <sensor_msgs/Image.h>
#include <visualization_msgs/Marker.h>
#include <visualization_msgs/MarkerArray.h>
#include <aruco_pose/MarkerArray.h>
#include <aruco_pose/Marker.h>
#include <opencv2/opencv.hpp>
#include <opencv2/aruco.hpp>
#include "draw.h"
#include "utils.h"
using std::vector;
using cv::Mat;
using sensor_msgs::Image;
using sensor_msgs::CameraInfo;
using aruco_pose::MarkerArray;
typedef message_filters::sync_policies::ExactTime<Image, CameraInfo, MarkerArray> SyncPolicy;
class ArucoMap : public nodelet::Nodelet {
private:
ros::NodeHandle nh_, nh_priv_;
ros::Publisher img_pub_, pose_pub_, markers_pub_, vis_markers_pub_;
image_transport::Publisher debug_pub_;
message_filters::Subscriber<Image> image_sub_;
message_filters::Subscriber<CameraInfo> info_sub_;
message_filters::Subscriber<MarkerArray> markers_sub_;
boost::shared_ptr<message_filters::Synchronizer<SyncPolicy> > sync_;
cv::Ptr<cv::aruco::Board> board_;
Mat camera_matrix_, dist_coeffs_;
geometry_msgs::TransformStamped transform_;
geometry_msgs::PoseWithCovarianceStamped pose_;
vector<geometry_msgs::TransformStamped> markers_transforms_;
aruco_pose::MarkerArray markers_;
tf2_ros::TransformBroadcaster br_;
tf2_ros::StaticTransformBroadcaster static_br_;
tf2_ros::Buffer tf_buffer_;
tf2_ros::TransformListener tf_listener_{tf_buffer_};
visualization_msgs::MarkerArray vis_array_;
std::string known_tilt_, map_, markers_frame_, markers_parent_frame_;
int image_width_, image_height_, image_margin_;
bool auto_flip_, image_axis_;
public:
virtual void onInit()
{
nh_ = getNodeHandle();
nh_priv_ = getPrivateNodeHandle();
image_transport::ImageTransport it_priv(nh_priv_);
// TODO: why image_transport doesn't work here?
img_pub_ = nh_priv_.advertise<sensor_msgs::Image>("image", 1, true);
markers_pub_ = nh_priv_.advertise<aruco_pose::MarkerArray>("markers", 1, true);
board_ = cv::makePtr<cv::aruco::Board>();
board_->dictionary = cv::aruco::getPredefinedDictionary(
static_cast<cv::aruco::PREDEFINED_DICTIONARY_NAME>(nh_priv_.param("dictionary", 2)));
camera_matrix_ = cv::Mat::zeros(3, 3, CV_64F);
dist_coeffs_ = cv::Mat::zeros(8, 1, CV_64F);
std::string type, map;
nh_priv_.param<std::string>("type", type, "map");
nh_priv_.param<std::string>("frame_id", transform_.child_frame_id, "aruco_map");
nh_priv_.param<std::string>("known_tilt", known_tilt_, "");
nh_priv_.param("auto_flip", auto_flip_, false);
nh_priv_.param("image_width", image_width_, 2000);
nh_priv_.param("image_height", image_height_, 2000);
nh_priv_.param("image_margin", image_margin_, 200);
nh_priv_.param("image_axis", image_axis_, true);
nh_priv_.param<std::string>("markers/frame_id", markers_parent_frame_, transform_.child_frame_id);
nh_priv_.param<std::string>("markers/child_frame_id_prefix", markers_frame_, "");
// createStripLine();
if (type == "map") {
param(nh_priv_, "map", map);
loadMap(map);
} else if (type == "gridboard") {
createGridBoard();
} else {
NODELET_FATAL("unknown type: %s", type.c_str());
ros::shutdown();
}
pose_pub_ = nh_priv_.advertise<geometry_msgs::PoseWithCovarianceStamped>("pose", 1);
vis_markers_pub_ = nh_priv_.advertise<visualization_msgs::MarkerArray>("visualization", 1, true);
debug_pub_ = it_priv.advertise("debug", 1);
image_sub_.subscribe(nh_, "image_raw", 1);
info_sub_.subscribe(nh_, "camera_info", 1);
markers_sub_.subscribe(nh_, "markers", 1);
sync_.reset(new message_filters::Synchronizer<SyncPolicy>(SyncPolicy(10), image_sub_, info_sub_, markers_sub_));
sync_->registerCallback(boost::bind(&ArucoMap::callback, this, _1, _2, _3));
publishMarkersFrames();
publishMarkers();
publishMapImage();
vis_markers_pub_.publish(vis_array_);
NODELET_INFO("ready");
}
void callback(const sensor_msgs::ImageConstPtr& image,
const sensor_msgs::CameraInfoConstPtr& cinfo,
const aruco_pose::MarkerArrayConstPtr& markers)
{
int valid = 0;
int count = markers->markers.size();
std::vector<int> ids;
std::vector<std::vector<cv::Point2f>> corners;
cv::Vec3d rvec, tvec;
parseCameraInfo(cinfo, camera_matrix_, dist_coeffs_);
if (markers->markers.empty()) goto publish_debug;
ids.reserve(count);
corners.reserve(count);
for(auto const &marker : markers->markers) {
ids.push_back(marker.id);
std::vector<cv::Point2f> marker_corners = {
cv::Point2f(marker.c1.x, marker.c1.y),
cv::Point2f(marker.c2.x, marker.c2.y),
cv::Point2f(marker.c3.x, marker.c3.y),
cv::Point2f(marker.c4.x, marker.c4.y)
};
corners.push_back(marker_corners);
}
if (known_tilt_.empty()) {
// simple estimation
valid = cv::aruco::estimatePoseBoard(corners, ids, board_, camera_matrix_, dist_coeffs_,
rvec, tvec, false);
if (!valid) goto publish_debug;
transform_.header.stamp = markers->header.stamp;
transform_.header.frame_id = markers->header.frame_id;
pose_.header = transform_.header;
fillPose(pose_.pose.pose, rvec, tvec);
fillTransform(transform_.transform, rvec, tvec);
} else {
Mat obj_points, img_points;
// estimation with "snapping"
cv::aruco::getBoardObjectAndImagePoints(board_, corners, ids, obj_points, img_points);
if (obj_points.empty()) goto publish_debug;
double center_x = 0, center_y = 0, center_z = 0;
alignObjPointsToCenter(obj_points, center_x, center_y, center_z);
valid = solvePnP(obj_points, img_points, camera_matrix_, dist_coeffs_, rvec, tvec, false);
if (!valid) goto publish_debug;
fillTransform(transform_.transform, rvec, tvec);
try {
geometry_msgs::TransformStamped snap_to = tf_buffer_.lookupTransform(markers->header.frame_id,
known_tilt_, markers->header.stamp, ros::Duration(0.02));
snapOrientation(transform_.transform.rotation, snap_to.transform.rotation, auto_flip_);
} catch (const tf2::TransformException& e) {
NODELET_WARN_THROTTLE(1, "can't snap: %s", e.what());
}
geometry_msgs::TransformStamped shift;
shift.transform.translation.x = -center_x;
shift.transform.translation.y = -center_y;
shift.transform.translation.z = -center_z;
shift.transform.rotation.w = 1;
tf2::doTransform(shift, transform_, transform_);
// for debug topic
tvec[0] = transform_.transform.translation.x;
tvec[1] = transform_.transform.translation.y;
tvec[2] = transform_.transform.translation.z;
transform_.header.stamp = markers->header.stamp;
transform_.header.frame_id = markers->header.frame_id;
pose_.header = transform_.header;
transformToPose(transform_.transform, pose_.pose.pose);
}
if (!transform_.child_frame_id.empty()) {
br_.sendTransform(transform_);
}
pose_pub_.publish(pose_);
publish_debug:
// publish debug image (even if no map detected)
if (debug_pub_.getNumSubscribers() > 0) {
Mat mat = cv_bridge::toCvCopy(image, "bgr8")->image; // copy image as we're planning to modify it
cv::aruco::drawDetectedMarkers(mat, corners, ids); // draw detected markers
if (valid) {
_drawAxis(mat, camera_matrix_, dist_coeffs_, rvec, tvec, 1.0); // draw board axis
}
cv_bridge::CvImage out_msg;
out_msg.header.frame_id = image->header.frame_id;
out_msg.header.stamp = image->header.stamp;
out_msg.encoding = sensor_msgs::image_encodings::BGR8;
out_msg.image = mat;
debug_pub_.publish(out_msg.toImageMsg());
}
}
void alignObjPointsToCenter(Mat &obj_points, double &center_x, double &center_y, double &center_z) const
{
// Align object points to the center of mass
double sum_x = 0;
double sum_y = 0;
double sum_z = 0;
for (int i = 0; i < obj_points.rows; i++) {
sum_x += obj_points.at<float>(i, 0);
sum_y += obj_points.at<float>(i, 1);
sum_z += obj_points.at<float>(i, 2);
}
center_x = sum_x / obj_points.rows;
center_y = sum_y / obj_points.rows;
center_z = sum_z / obj_points.rows;
for (int i = 0; i < obj_points.rows; i++) {
obj_points.at<float>(i, 0) -= center_x;
obj_points.at<float>(i, 1) -= center_y;
obj_points.at<float>(i, 2) -= center_z;
}
}
void loadMap(std::string filename)
{
std::ifstream f(filename);
std::string line;
if (!f.good()) {
NODELET_FATAL("%s - %s", strerror(errno), filename.c_str());
ros::shutdown();
}
while (std::getline(f, line)) {
int id;
double length, x, y, z, yaw, pitch, roll;
std::istringstream s(line);
// Read first character to see whether it's a comment
char first = 0;
if (!(s >> first)) {
// No non-whitespace characters, must be a blank line
continue;
}
if (first == '#') {
NODELET_DEBUG("Skipping line as a comment: %s", line.c_str());
continue;
} else if (isdigit(first)) {
// Put the digit back into the stream
// Note that this is a non-modifying putback, so this should work with istreams
// (see https://en.cppreference.com/w/cpp/io/basic_istream/putback)
s.putback(first);
} else {
// Probably garbage data; inform user and throw an exception, possibly killing nodelet
NODELET_FATAL("Malformed input: %s", line.c_str());
ros::shutdown();
throw std::runtime_error("Malformed input");
}
if (!(s >> id >> length >> x >> y)) {
NODELET_ERROR("Not enough data in line: %s; "
"Each marker must have at least id, length, x, y fields", line.c_str());
continue;
}
// Be less strict about z, yaw, pitch roll
if (!(s >> z)) {
NODELET_DEBUG("No z coordinate provided for marker %d, assuming 0", id);
z = 0;
}
if (!(s >> yaw)) {
NODELET_DEBUG("No yaw provided for marker %d, assuming 0", id);
yaw = 0;
}
if (!(s >> pitch)) {
NODELET_DEBUG("No pitch provided for marker %d, assuming 0", id);
pitch = 0;
}
if (!(s >> roll)) {
NODELET_DEBUG("No roll provided for marker %d, assuming 0", id);
roll = 0;
}
addMarker(id, length, x, y, z, yaw, pitch, roll);
}
NODELET_INFO("loading %s complete (%d markers)", filename.c_str(), static_cast<int>(board_->ids.size()));
}
void createGridBoard()
{
NODELET_INFO("generate gridboard");
NODELET_WARN("gridboard maps are deprecated");
int markers_x, markers_y, first_marker;
double markers_side, markers_sep_x, markers_sep_y;
std::vector<int> marker_ids;
nh_priv_.param<int>("markers_x", markers_x, 10);
nh_priv_.param<int>("markers_y", markers_y, 10);
nh_priv_.param<int>("first_marker", first_marker, 0);
param(nh_priv_, "markers_side", markers_side);
param(nh_priv_, "markers_sep_x", markers_sep_x);
param(nh_priv_, "markers_sep_y", markers_sep_y);
if (nh_priv_.getParam("marker_ids", marker_ids)) {
if ((unsigned int)(markers_x * markers_y) != marker_ids.size()) {
NODELET_FATAL("~marker_ids length should be equal to ~markers_x * ~markers_y");
ros::shutdown();
}
} else {
// Fill marker_ids automatically
marker_ids.resize(markers_x * markers_y);
for (int i = 0; i < markers_x * markers_y; i++)
{
marker_ids.at(i) = first_marker++;
}
}
double max_y = markers_y * markers_side + (markers_y - 1) * markers_sep_y;
for(int y = 0; y < markers_y; y++) {
for(int x = 0; x < markers_x; x++) {
double x_pos = x * (markers_side + markers_sep_x);
double y_pos = max_y - y * (markers_side + markers_sep_y) - markers_side;
NODELET_INFO("add marker %d %g %g", marker_ids[y * markers_y + x], x_pos, y_pos);
addMarker(marker_ids[y * markers_y + x], markers_side, x_pos, y_pos, 0, 0, 0, 0);
}
}
}
// void createStripLine()
// {
// visualization_msgs::Marker marker;
// marker.header.frame_id = transform_.child_frame_id;
// marker.action = visualization_msgs::Marker::ADD;
// marker.ns = "aruco_map_link";
// marker.type = visualization_msgs::Marker::LINE_STRIP;
// marker.scale.x = 0.02;
// marker.color.g = 1;
// marker.color.a = 0.8;
// marker.frame_locked = true;
// marker.pose.orientation.w = 1;
// vis_array_.markers.push_back(marker);
// }
void addMarker(int id, double length, double x, double y, double z,
double yaw, double pitch, double roll)
{
// Check whether the id is in range for current dictionary
int num_markers = board_->dictionary->bytesList.rows;
if (num_markers <= id) {
NODELET_ERROR("Marker id %d is not in dictionary; current dictionary contains %d markers. "
"Please see https://github.com/CopterExpress/clever/blob/master/aruco_pose/README.md#parameters for details",
id, num_markers);
return;
}
// Check if marker is already in the board
if (std::count(board_->ids.begin(), board_->ids.end(), id) > 0) {
NODELET_ERROR("Marker id %d is already in the map", id);
return;
}
// Create transform
tf::Quaternion q;
q.setRPY(roll, pitch, yaw);
tf::Transform transform(q, tf::Vector3(x, y, z));
/* marker's corners:
0 1
3 2
*/
double halflen = length / 2;
tf::Point p0(-halflen, halflen, 0);
tf::Point p1(halflen, halflen, 0);
tf::Point p2(halflen, -halflen, 0);
tf::Point p3(-halflen, -halflen, 0);
p0 = transform * p0;
p1 = transform * p1;
p2 = transform * p2;
p3 = transform * p3;
vector<cv::Point3f> obj_points = {
cv::Point3f(p0.x(), p0.y(), p0.z()),
cv::Point3f(p1.x(), p1.y(), p1.z()),
cv::Point3f(p2.x(), p2.y(), p2.z()),
cv::Point3f(p3.x(), p3.y(), p3.z())
};
board_->ids.push_back(id);
board_->objPoints.push_back(obj_points);
// Add marker's static transform
if (!markers_frame_.empty()) {
geometry_msgs::TransformStamped marker_transform;
marker_transform.header.frame_id = markers_parent_frame_;
marker_transform.child_frame_id = markers_frame_ + std::to_string(id);
tf::transformTFToMsg(transform, marker_transform.transform);
markers_transforms_.push_back(marker_transform);
}
// Add marker to array
aruco_pose::Marker marker;
marker.id = id;
marker.length = length;
marker.pose.position.x = x;
marker.pose.position.y = y;
marker.pose.position.z = z;
tf::quaternionTFToMsg(q, marker.pose.orientation);
markers_.markers.push_back(marker);
// Add visualization marker
visualization_msgs::Marker vis_marker;
vis_marker.header.frame_id = transform_.child_frame_id;
vis_marker.action = visualization_msgs::Marker::ADD;
vis_marker.id = vis_array_.markers.size();
vis_marker.ns = "aruco_map_marker";
vis_marker.type = visualization_msgs::Marker::CUBE;
vis_marker.scale.x = length;
vis_marker.scale.y = length;
vis_marker.scale.z = 0.001;
vis_marker.color.r = 1;
vis_marker.color.g = 0.5;
vis_marker.color.b = 0.5;
vis_marker.color.a = 0.8;
vis_marker.pose.position.x = x;
vis_marker.pose.position.y = y;
vis_marker.pose.position.z = z;
tf::quaternionTFToMsg(q, marker.pose.orientation);
vis_marker.frame_locked = true;
vis_array_.markers.push_back(vis_marker);
// Add linking line
// geometry_msgs::Point p;
// p.x = x;
// p.y = y;
// p.z = z;
// vis_array_.markers.at(0).points.push_back(p);
}
void publishMarkersFrames()
{
if (!markers_transforms_.empty()) {
static_br_.sendTransform(markers_transforms_);
}
}
void publishMarkers()
{
markers_pub_.publish(markers_);
}
void publishMapImage()
{
cv::Size size(image_width_, image_height_);
cv::Mat image;
cv_bridge::CvImage msg;
if (!board_->ids.empty()) {
_drawPlanarBoard(board_, size, image, image_margin_, 1, image_axis_);
msg.encoding = image_axis_ ? sensor_msgs::image_encodings::RGB8 : sensor_msgs::image_encodings::MONO8;
} else {
// empty map
image.create(size, CV_8UC1);
image.setTo(cv::Scalar::all(255));
msg.encoding = sensor_msgs::image_encodings::MONO8;
}
msg.image = image;
img_pub_.publish(msg.toImageMsg());
}
};
PLUGINLIB_EXPORT_CLASS(ArucoMap, nodelet::Nodelet)

View File

@@ -1,350 +0,0 @@
#include <algorithm>
#include <nodelet/nodelet.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <pluginlib/class_list_macros.h>
#include <geometry_msgs/TransformStamped.h>
#include <geometry_msgs/PoseStamped.h>
#include <geometry_msgs/PoseWithCovarianceStamped.h>
#include <visualization_msgs/MarkerArray.h>
#include <tf/transform_datatypes.h>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/aruco.hpp>
#include <opencv2/aruco/dictionary.hpp>
#include <stdio.h>
#include <tf/transform_broadcaster.h>
#include "util.h"
using std::vector;
using std::string;
namespace aruco_pose {
class ArucoPose : public nodelet::Nodelet {
tf::TransformBroadcaster br;
cv::Ptr<cv::aruco::Dictionary> dictionary;
cv::Ptr<cv::aruco::DetectorParameters> parameters;
cv::Ptr<cv::aruco::Board> board;
std::string frame_id_;
image_transport::CameraSubscriber img_sub;
image_transport::Publisher img_pub;
ros::Publisher marker_pub;
ros::Publisher pose_pub;
ros::NodeHandle nh_, nh_priv_;
virtual void onInit();
void createBoard();
cv::Point3f getObjPointsCenter(cv::Mat objPoints);
void detect(const sensor_msgs::ImageConstPtr&, const sensor_msgs::CameraInfoConstPtr&);
void parseCameraInfo(const sensor_msgs::CameraInfoConstPtr&, cv::Mat&, cv::Mat&);
tf::Transform aruco2tf(cv::Mat rvec, cv::Mat tvec);
};
void ArucoPose::onInit() {
ROS_INFO("Initializing aruco_pose");
nh_ = getNodeHandle();
nh_priv_ = getPrivateNodeHandle();
nh_priv_.param("frame_id", frame_id_, std::string("aruco_map"));
dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_1000);
parameters = cv::aruco::DetectorParameters::create();
try
{
createBoard();
}
catch (const std::exception &exc)
{
std::cerr << exc.what();
exit(0);
}
image_transport::ImageTransport it(nh_);
img_sub = it.subscribeCamera("image", 1, &ArucoPose::detect, this);
image_transport::ImageTransport it_priv(nh_priv_);
img_pub = it_priv.advertise("debug", 1);
pose_pub = nh_priv_.advertise<geometry_msgs::PoseStamped>("pose", 1);
ROS_INFO("aruco_pose nodelet inited");
}
cv::Ptr<cv::aruco::Board> createCustomGridBoard(int markersX, int markersY, float markerLength, float markerSeparationX, float markerSeparationY,
const cv::Ptr<cv::aruco::Dictionary> &dictionary, std::vector<int> ids) {
CV_Assert(markersX > 0 && markersY > 0 && markerLength > 0 && markerSeparationX > 0 && markerSeparationY > 0);
cv::Ptr<cv::aruco::Board> res = cv::makePtr<cv::aruco::Board>();
res->dictionary = dictionary;
size_t totalMarkers = (size_t) markersX * markersY;
res->ids = ids;
res->objPoints.reserve(totalMarkers);
// calculate Board objPoints
float maxY = (float)markersY * markerLength + (markersY - 1) * markerSeparationY;
for(int y = 0; y < markersY; y++) {
for(int x = 0; x < markersX; x++) {
std::vector< cv::Point3f > corners;
corners.resize(4);
corners[0] = cv::Point3f(x * (markerLength + markerSeparationX),
maxY - y * (markerLength + markerSeparationY), 0);
corners[1] = corners[0] + cv::Point3f(markerLength, 0, 0);
corners[2] = corners[0] + cv::Point3f(markerLength, -markerLength, 0);
corners[3] = corners[0] + cv::Point3f(0, -markerLength, 0);
res->objPoints.push_back(corners);
}
}
return res;
}
cv::Ptr<cv::aruco::Board> createCustomBoard(std::map<string, string> markers, const cv::Ptr<cv::aruco::Dictionary> &dictionary) {
cv::Ptr<cv::aruco::Board> res = cv::makePtr<cv::aruco::Board>();
res->dictionary = dictionary;
size_t total_markers = markers.size();
res->ids.reserve(total_markers);
res->objPoints.reserve(total_markers);
// Generate ids and objPoints
for(auto const &marker : markers) {
res->ids.push_back(std::stoi(marker.first));
vector<string> parts;
parts = strSplit(marker.second, " ");
float size = std::stof(parts.at(0));
float x = std::stof(parts.at(1));
float y = std::stof(parts.at(2));
float z = std::stof(parts.at(3));
float yaw = std::stof(parts.at(4));
float pitch = std::stof(parts.at(5));
float roll = std::stof(parts.at(6));
vector<cv::Point3f> corners;
corners.resize(4);
corners[0] = cv::Point3f(x - size / 2, y + size / 2, 0);
corners[1] = corners[0] + cv::Point3f(size, 0, 0);
corners[2] = corners[0] + cv::Point3f(size, -size, 0);
corners[3] = corners[0] + cv::Point3f(0, -size, 0);
// TODO: process yaw, pitch, roll
res->objPoints.push_back(corners);
}
return res;
}
#include "fix.cpp"
void ArucoPose::createBoard()
{
static auto map_image_pub = nh_priv_.advertise<sensor_msgs::Image>("map_image", 1, true);
cv_bridge::CvImage map_image_msg;
cv::Mat map_image;
std::string type;
nh_priv_.param<std::string>("type", type, "gridboard");
if (type == "gridboard")
{
ROS_INFO("Initialize gridboard");
int markers_x, markers_y, first_marker;
float markers_side, markers_sep_x, markers_sep_y;
std::vector<int> marker_ids;
nh_priv_.param<int>("markers_x", markers_x, 10);
nh_priv_.param<int>("markers_y", markers_y, 10);
nh_priv_.param<int>("first_marker", first_marker, 0);
if (!nh_priv_.getParam("markers_side", markers_side))
{
ROS_ERROR("gridboard: required parameter ~markers_side is not set.");
exit(1);
}
if (!nh_priv_.getParam("markers_sep_x", markers_sep_x))
{
if (!nh_priv_.getParam("markers_sep", markers_sep_x))
{
ROS_ERROR("gridboard: ~markers_sep_x or ~markers_sep parameters are required");
exit(1);
}
}
if (!nh_priv_.getParam("markers_sep_y", markers_sep_y))
{
if (!nh_priv_.getParam("markers_sep", markers_sep_y))
{
ROS_ERROR("gridboard: ~markers_sep_y or ~markers_sep parameters are required");
exit(1);
}
}
if (nh_priv_.getParam("marker_ids", marker_ids))
{
if (markers_x * markers_y != marker_ids.size())
{
ROS_FATAL("~marker_ids length should be equal to ~markers_x * ~markers_y");
exit(1);
}
}
else
{
// Fill marker_ids automatically
marker_ids.resize(markers_x * markers_y);
for(int i = 0; i < markers_x * markers_y; i++)
{
marker_ids.at(i) = first_marker++;
}
}
// Create grid board
board = createCustomGridBoard(markers_x, markers_y, markers_side, markers_sep_x, markers_sep_y, dictionary, marker_ids);
// Publish map image for debugging
_drawPlanarBoard(board, cv::Size(2000, 2000), map_image, 50, 1);
cv::cvtColor(map_image, map_image, CV_GRAY2BGR);
map_image_msg.encoding = sensor_msgs::image_encodings::BGR8;
map_image_msg.image = map_image;
map_image_pub.publish(map_image_msg.toImageMsg());
}
else if (type == "custom")
{
ROS_INFO("Initialize a custom board");
std::map<string, string> markers;
nh_priv_.getParam("markers", markers);
board = createCustomBoard(markers, dictionary);
ROS_INFO("Draw a custom board");
// Publish map image for debugging
_drawPlanarBoard(board, cv::Size(2000, 2000), map_image, 50, 1);
cv::cvtColor(map_image, map_image, CV_GRAY2BGR);
map_image_msg.encoding = sensor_msgs::image_encodings::BGR8;
map_image_msg.image = map_image;
map_image_pub.publish(map_image_msg.toImageMsg());
}
else
{
ROS_ERROR("Incorrect map type '%s'", type.c_str());
}
}
cv::Point3f ArucoPose::getObjPointsCenter(cv::Mat objPoints) {
float min_x = std::numeric_limits<float>::max();
float max_x = std::numeric_limits<float>::min();
float min_y = min_x, max_y = max_x;
for (int i = 0; i < objPoints.rows; i++) {
max_x = std::max(max_x, objPoints.at<float>(i, 0));
max_y = std::max(max_y, objPoints.at<float>(i, 1));
min_x = std::min(min_x, objPoints.at<float>(i, 0));
min_y = std::min(min_y, objPoints.at<float>(i, 1));
}
cv::Point3f res((min_x + max_x) / 2, (min_y + max_y) / 2, 0);
return res;
}
void ArucoPose::detect(const sensor_msgs::ImageConstPtr& msg, const sensor_msgs::CameraInfoConstPtr &cinfo) {
cv::Mat image = cv_bridge::toCvShare(msg, "bgr8")->image;
std::vector<int> markerIds;
std::vector<std::vector<cv::Point2f>> markerCorners;
std::vector<std::vector<cv::Point2f>> rejectedCandidates;
cv::aruco::detectMarkers(image, dictionary, markerCorners, markerIds, parameters, rejectedCandidates);
cv::Mat cameraMatrix(3, 3, CV_64F);
cv::Mat distCoeffs(8, 1, CV_64F);
parseCameraInfo(cinfo, cameraMatrix, distCoeffs);
int valid = 0;
cv::Mat rvec, tvec, objPoints;
if (markerIds.size() > 0) {
valid = _estimatePoseBoard(markerCorners, markerIds, board, cameraMatrix, distCoeffs,
rvec, tvec, false, objPoints);
if (valid) {
// Send map transform
tf::StampedTransform transform(aruco2tf(rvec, tvec), msg->header.stamp, cinfo->header.frame_id, frame_id_);
br.sendTransform(transform);
// Publish map pose
static geometry_msgs::PoseStamped ps;
ps.header.frame_id = frame_id_;
ps.header.stamp = msg->header.stamp;
ps.pose.orientation.w = 1;
pose_pub.publish(ps);
// Send reference point
cv::Point3f ref = getObjPointsCenter(objPoints);
tf::Vector3 ref_vector3 = tf::Vector3(ref.x, ref.y, ref.z);
tf::Quaternion q(0, 0, 0);
static tf::StampedTransform ref_transform;
ref_transform.stamp_ = msg->header.stamp;
ref_transform.frame_id_ = frame_id_;
ref_transform.child_frame_id_ = "aruco_map_reference";
ref_transform.setOrigin(ref_vector3);
ref_transform.setRotation(q);
br.sendTransform(ref_transform);
}
}
if (img_pub.getNumSubscribers() > 0)
{
cv::aruco::drawDetectedMarkers(image, markerCorners, markerIds); // draw markers
if (valid)
{
cv::aruco::drawAxis(image, cameraMatrix, distCoeffs, rvec, tvec, 0.3); // draw board axis
}
cv_bridge::CvImage out_msg;
out_msg.header.frame_id = msg->header.frame_id;
out_msg.header.stamp = msg->header.stamp;
out_msg.encoding = sensor_msgs::image_encodings::BGR8;
out_msg.image = image;
img_pub.publish(out_msg.toImageMsg());
}
}
void ArucoPose::parseCameraInfo(const sensor_msgs::CameraInfoConstPtr &cinfo, cv::Mat &cameraMat, cv::Mat &distCoeffs) {
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
cameraMat.at<double>(i, j) = cinfo->K[3 * i + j];
}
}
for (int k = 0; k < cinfo->D.size(); k++) {
distCoeffs.at<double>(k) = cinfo->D[k];
}
}
tf::Transform ArucoPose::aruco2tf(cv::Mat rvec, cv::Mat tvec) {
cv::Mat rot;
cv::Rodrigues(rvec, rot);
tf::Matrix3x3 tf_rot(rot.at<double>(0,0), rot.at<double>(0,1), rot.at<double>(0,2),
rot.at<double>(1,0), rot.at<double>(1,1), rot.at<double>(1,2),
rot.at<double>(2,0), rot.at<double>(2,1), rot.at<double>(2,2));
tf::Vector3 tf_orig(tvec.at<double>(0,0), tvec.at<double>(1,0), tvec.at<double>(2,0));
return tf::Transform(tf_rot, tf_orig);
}
PLUGINLIB_EXPORT_CLASS(ArucoPose, nodelet::Nodelet)
}

832
aruco_pose/src/draw.cpp Normal file
View File

@@ -0,0 +1,832 @@
// This code is basically taken from https://github.com/opencv/opencv_contrib/blob/master/modules/aruco/src/aruco.cpp
// with some improvements and fixes
#include "draw.h"
#include <math.h>
using namespace cv;
using namespace cv::aruco;
static void _cvProjectPoints2( const CvMat* object_points, const CvMat* rotation_vector,
const CvMat* translation_vector, const CvMat* camera_matrix,
const CvMat* distortion_coeffs, CvMat* image_points,
CvMat* dpdrot CV_DEFAULT(NULL), CvMat* dpdt CV_DEFAULT(NULL),
CvMat* dpdf CV_DEFAULT(NULL), CvMat* dpdc CV_DEFAULT(NULL),
CvMat* dpddist CV_DEFAULT(NULL),
double aspect_ratio CV_DEFAULT(0));
static void _projectPoints( InputArray objectPoints,
InputArray rvec, InputArray tvec,
InputArray cameraMatrix, InputArray distCoeffs,
OutputArray imagePoints,
OutputArray jacobian = noArray(),
double aspectRatio = 0 );
void _drawPlanarBoard(Board *_board, Size outSize, OutputArray _img, int marginSize,
int borderBits, bool drawAxis) {
CV_Assert(outSize.area() > 0);
CV_Assert(marginSize >= 0);
_img.create(outSize, drawAxis ? CV_8UC3 : CV_8UC1);
Mat out = _img.getMat();
out.setTo(Scalar::all(255));
out.adjustROI(-marginSize, -marginSize, -marginSize, -marginSize);
// calculate max and min values in XY plane
CV_Assert(_board->objPoints.size() > 0);
float minX, maxX, minY, maxY;
minX = maxX = _board->objPoints[0][0].x;
minY = maxY = _board->objPoints[0][0].y;
for(unsigned int i = 0; i < _board->objPoints.size(); i++) {
for(int j = 0; j < 4; j++) {
minX = min(minX, _board->objPoints[i][j].x);
maxX = max(maxX, _board->objPoints[i][j].x);
minY = min(minY, _board->objPoints[i][j].y);
maxY = max(maxY, _board->objPoints[i][j].y);
}
}
float sizeX = maxX - minX;
float sizeY = maxY - minY;
// proportion transformations
float xReduction = sizeX / float(out.cols);
float yReduction = sizeY / float(out.rows);
// determine the zone where the markers are placed
if(xReduction > yReduction) {
int nRows = int(sizeY / xReduction);
int rowsMargins = (out.rows - nRows) / 2;
out.adjustROI(-rowsMargins, -rowsMargins, 0, 0);
} else {
int nCols = int(sizeX / yReduction);
int colsMargins = (out.cols - nCols) / 2;
out.adjustROI(0, 0, -colsMargins, -colsMargins);
}
// now paint each marker
Dictionary &dictionary = *(_board->dictionary);
Mat marker;
Point2f outCorners[3];
Point2f inCorners[3];
for(unsigned int m = 0; m < _board->objPoints.size(); m++) {
// transform corners to markerZone coordinates
for(int j = 0; j < 3; j++) {
Point2f pf = Point2f(_board->objPoints[m][j].x, _board->objPoints[m][j].y);
// move top left to 0, 0
pf -= Point2f(minX, minY);
pf.x = pf.x / sizeX * float(out.cols);
pf.y = (1.0f - pf.y / sizeY) * float(out.rows);
outCorners[j] = pf;
}
// get marker
Size dst_sz(outCorners[2] - outCorners[0]); // assuming CCW order
// dst_sz.width = dst_sz.height = std::min(dst_sz.width, dst_sz.height); //marker should be square
double diag = std::round(std::hypot(dst_sz.width, dst_sz.height));
int side = std::round(diag / std::sqrt(2));
side = std::max(side, 10);
dictionary.drawMarker(_board->ids[m], side, marker, borderBits);
if (drawAxis) {
cvtColor(marker, marker, COLOR_GRAY2RGB);
}
// interpolate tiny marker to marker position in markerZone
inCorners[0] = Point2f(-0.5f, -0.5f);
inCorners[1] = Point2f(marker.cols - 0.5f, -0.5f);
inCorners[2] = Point2f(marker.cols - 0.5f, marker.rows - 0.5f);
// remove perspective
Mat transformation = getAffineTransform(inCorners, outCorners);
warpAffine(marker, out, transformation, out.size(), INTER_LINEAR,
BORDER_TRANSPARENT);
}
// draw axis
if (drawAxis) {
Size wholeSize; Point ofs;
out.locateROI(wholeSize, ofs);
auto out_copy = _img.getMat();
cv::Point center(ofs.x - minX / sizeX * float(out.cols), ofs.y + out.rows + minY / sizeY * float(out.rows));
int axis_points[3][2] = {{300, 0}, {0, -300}, {-150, 150}};
Point axis_names[3] = {Point(270, 50), Point(25, -270), Point(-160, 115)};
Scalar colors[] = {Scalar(255, 0, 0), Scalar(0, 255, 0), Scalar(0, 0, 255)};
String names[] = {"X", "Y", "Z"};
int r_half = 14;
int height = 55;
for(int poly = 2; poly >= 0; poly--){
double alpha = atan2(0 - axis_points[poly][0], 0 - axis_points[poly][1]);
float x_delta = r_half * cos(alpha);
float y_delta = r_half * sin(alpha);
Point polygon_vertices[1][3];
polygon_vertices[0][0] = center + Point(axis_points[poly][0] + x_delta, axis_points[poly][1] - y_delta);
polygon_vertices[0][1] = center + Point(axis_points[poly][0] - x_delta, axis_points[poly][1] + y_delta);
polygon_vertices[0][2] = center + Point(axis_points[poly][0] - sin(alpha) * height, axis_points[poly][1] - cos(alpha) * height);
const Point* ppt[1] = {polygon_vertices[0]};
int npt[] = {3};
fillPoly(out_copy, ppt, npt, 1, colors[poly]);
putText(out_copy, names[poly], center + axis_names[poly], FONT_HERSHEY_SIMPLEX, 1.2, colors[poly], 7);
line(out_copy, center, center + Point(axis_points[poly][0], axis_points[poly][1]), colors[poly], 10);
}
}
}
/* Draw a (potentially partially visible) line. */
static void linePartial(InputOutputArray image, Point3f p1, Point3f p2, const Scalar& color,
int thickness = 1, int lineType = LINE_8, int shift = 0)
{
// If both points are behind the screen, don't draw anything
if (p1.z <= 0 && p2.z <= 0) {
return;
}
Point2f p1p{p1.x, p1.y};
Point2f p2p{p2.x, p2.y};
// If points are on the different sides of the plane, compute intersection point
if (p1.z * p2.z < 0) {
// Compute intersection point with the screen
// We denote alpha as such:
// xi = (1 - alpha) * x1 + alpha * x2
// yi = (1 - alpha) * y1 + alpha * y2
// zi = (1 - alpha) * z1 + alpha * z2 = 0
// Thus, alpha can be expressed as
// alpha = z1 / (z1 - z2)
float alpha = p1.z / (p1.z - p2.z);
Point2f pi{(1 - alpha) * p1.x + alpha * p2.x, (1 - alpha) * p1.y + alpha * p2.y};
// Now, if z1 is negative, we draw the line from (xi, yi) to (x2, y2), else we draw from (x1, y1) to (xi, yi)
if (p1.z < 0) {
p1p = pi;
} else {
p2p = pi;
}
}
line(image, p1p, p2p, color, thickness, lineType, shift);
}
void _drawAxis(InputOutputArray _image, InputArray _cameraMatrix, InputArray _distCoeffs,
InputArray _rvec, InputArray _tvec, float length) {
CV_Assert(_image.getMat().total() != 0 &&
(_image.getMat().channels() == 1 || _image.getMat().channels() == 3));
CV_Assert(length > 0);
// project axis points
std::vector<Point3f> axisPoints;
axisPoints.push_back(Point3f(0, 0, 0));
axisPoints.push_back(Point3f(length, 0, 0));
axisPoints.push_back(Point3f(0, length, 0));
axisPoints.push_back(Point3f(0, 0, length));
std::vector<Point3f> imagePointsZ;
_projectPoints(axisPoints, _rvec, _tvec, _cameraMatrix, _distCoeffs, imagePointsZ);
// draw axis lines
linePartial(_image, imagePointsZ[0], imagePointsZ[1], Scalar(0, 0, 255), 3);
linePartial(_image, imagePointsZ[0], imagePointsZ[2], Scalar(0, 255, 0), 3);
linePartial(_image, imagePointsZ[0], imagePointsZ[3], Scalar(255, 0, 0), 3);
}
static CvMat _cvMat(const cv::Mat& m)
{
CvMat self;
CV_DbgAssert(m.dims <= 2);
self = cvMat(m.rows, m.dims == 1 ? 1 : m.cols, m.type(), m.data);
self.step = (int)m.step[0];
self.type = (self.type & ~cv::Mat::CONTINUOUS_FLAG) | (m.flags & cv::Mat::CONTINUOUS_FLAG);
return self;
}
static void _projectPoints( InputArray _opoints,
InputArray _rvec,
InputArray _tvec,
InputArray _cameraMatrix,
InputArray _distCoeffs,
OutputArray _ipoints,
OutputArray _jacobian,
double aspectRatio )
{
Mat opoints = _opoints.getMat();
int npoints = opoints.checkVector(3), depth = opoints.depth();
CV_Assert(npoints >= 0 && (depth == CV_32F || depth == CV_64F));
CvMat dpdrot, dpdt, dpdf, dpdc, dpddist;
CvMat *pdpdrot = 0, *pdpdt = 0, *pdpdf = 0, *pdpdc = 0, *pdpddist = 0;
CV_Assert(_ipoints.needed());
_ipoints.create(npoints, 1, CV_MAKETYPE(depth, 3), -1, true);
Mat imagePoints = _ipoints.getMat();
CvMat c_imagePoints = _cvMat(imagePoints);
CvMat c_objectPoints = _cvMat(opoints);
Mat cameraMatrix = _cameraMatrix.getMat();
Mat rvec = _rvec.getMat(), tvec = _tvec.getMat();
CvMat c_cameraMatrix = _cvMat(cameraMatrix);
CvMat c_rvec = _cvMat(rvec), c_tvec = _cvMat(tvec);
double dc0buf[5] = {0};
Mat dc0(5, 1, CV_64F, dc0buf);
Mat distCoeffs = _distCoeffs.getMat();
if (distCoeffs.empty())
distCoeffs = dc0;
CvMat c_distCoeffs = _cvMat(distCoeffs);
int ndistCoeffs = distCoeffs.rows + distCoeffs.cols - 1;
Mat jacobian;
if (_jacobian.needed())
{
_jacobian.create(npoints * 2, 3 + 3 + 2 + 2 + ndistCoeffs, CV_64F);
jacobian = _jacobian.getMat();
pdpdrot = &(dpdrot = _cvMat(jacobian.colRange(0, 3)));
pdpdt = &(dpdt = _cvMat(jacobian.colRange(3, 6)));
pdpdf = &(dpdf = _cvMat(jacobian.colRange(6, 8)));
pdpdc = &(dpdc = _cvMat(jacobian.colRange(8, 10)));
pdpddist = &(dpddist = _cvMat(jacobian.colRange(10, 10 + ndistCoeffs)));
}
_cvProjectPoints2(&c_objectPoints, &c_rvec, &c_tvec, &c_cameraMatrix, &c_distCoeffs,
&c_imagePoints, pdpdrot, pdpdt, pdpdf, pdpdc, pdpddist, aspectRatio);
}
namespace _detail
{
template <typename FLOAT>
void computeTiltProjectionMatrix(FLOAT tauX,
FLOAT tauY,
Matx<FLOAT, 3, 3>* matTilt = 0,
Matx<FLOAT, 3, 3>* dMatTiltdTauX = 0,
Matx<FLOAT, 3, 3>* dMatTiltdTauY = 0,
Matx<FLOAT, 3, 3>* invMatTilt = 0)
{
FLOAT cTauX = cos(tauX);
FLOAT sTauX = sin(tauX);
FLOAT cTauY = cos(tauY);
FLOAT sTauY = sin(tauY);
Matx<FLOAT, 3, 3> matRotX = Matx<FLOAT, 3, 3>(1,0,0,0,cTauX,sTauX,0,-sTauX,cTauX);
Matx<FLOAT, 3, 3> matRotY = Matx<FLOAT, 3, 3>(cTauY,0,-sTauY,0,1,0,sTauY,0,cTauY);
Matx<FLOAT, 3, 3> matRotXY = matRotY * matRotX;
Matx<FLOAT, 3, 3> matProjZ = Matx<FLOAT, 3, 3>(matRotXY(2,2),0,-matRotXY(0,2),0,matRotXY(2,2),-matRotXY(1,2),0,0,1);
if (matTilt)
{
// Matrix for trapezoidal distortion of tilted image sensor
*matTilt = matProjZ * matRotXY;
}
if (dMatTiltdTauX)
{
// Derivative with respect to tauX
Matx<FLOAT, 3, 3> dMatRotXYdTauX = matRotY * Matx<FLOAT, 3, 3>(0,0,0,0,-sTauX,cTauX,0,-cTauX,-sTauX);
Matx<FLOAT, 3, 3> dMatProjZdTauX = Matx<FLOAT, 3, 3>(dMatRotXYdTauX(2,2),0,-dMatRotXYdTauX(0,2),
0,dMatRotXYdTauX(2,2),-dMatRotXYdTauX(1,2),0,0,0);
*dMatTiltdTauX = (matProjZ * dMatRotXYdTauX) + (dMatProjZdTauX * matRotXY);
}
if (dMatTiltdTauY)
{
// Derivative with respect to tauY
Matx<FLOAT, 3, 3> dMatRotXYdTauY = Matx<FLOAT, 3, 3>(-sTauY,0,-cTauY,0,0,0,cTauY,0,-sTauY) * matRotX;
Matx<FLOAT, 3, 3> dMatProjZdTauY = Matx<FLOAT, 3, 3>(dMatRotXYdTauY(2,2),0,-dMatRotXYdTauY(0,2),
0,dMatRotXYdTauY(2,2),-dMatRotXYdTauY(1,2),0,0,0);
*dMatTiltdTauY = (matProjZ * dMatRotXYdTauY) + (dMatProjZdTauY * matRotXY);
}
if (invMatTilt)
{
FLOAT inv = 1./matRotXY(2,2);
Matx<FLOAT, 3, 3> invMatProjZ = Matx<FLOAT, 3, 3>(inv,0,inv*matRotXY(0,2),0,inv,inv*matRotXY(1,2),0,0,1);
*invMatTilt = matRotXY.t()*invMatProjZ;
}
}
}
static const char* cvDistCoeffErr = "Distortion coefficients must be 1x4, 4x1, 1x5, 5x1, 1x8, 8x1, 1x12, 12x1, 1x14 or 14x1 floating-point vector";
static void _cvProjectPoints2Internal( const CvMat* objectPoints,
const CvMat* r_vec,
const CvMat* t_vec,
const CvMat* A,
const CvMat* distCoeffs,
CvMat* imagePoints, CvMat* dpdr CV_DEFAULT(NULL),
CvMat* dpdt CV_DEFAULT(NULL), CvMat* dpdf CV_DEFAULT(NULL),
CvMat* dpdc CV_DEFAULT(NULL), CvMat* dpdk CV_DEFAULT(NULL),
CvMat* dpdo CV_DEFAULT(NULL),
double aspectRatio CV_DEFAULT(0) )
{
Ptr<CvMat> matM, _m;
Ptr<CvMat> _dpdr, _dpdt, _dpdc, _dpdf, _dpdk;
Ptr<CvMat> _dpdo;
int i, j, count;
int calc_derivatives;
const CvPoint3D64f* M;
CvPoint3D64f* m;
double r[3], R[9], dRdr[27], t[3], a[9], k[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}, fx, fy, cx, cy;
Matx33d matTilt = Matx33d::eye();
Matx33d dMatTiltdTauX(0,0,0,0,0,0,0,-1,0);
Matx33d dMatTiltdTauY(0,0,0,0,0,0,1,0,0);
CvMat _r, _t, _a = cvMat( 3, 3, CV_64F, a ), _k;
CvMat matR = cvMat( 3, 3, CV_64F, R ), _dRdr = cvMat( 3, 9, CV_64F, dRdr );
double *dpdr_p = 0, *dpdt_p = 0, *dpdk_p = 0, *dpdf_p = 0, *dpdc_p = 0;
double* dpdo_p = 0;
int dpdr_step = 0, dpdt_step = 0, dpdk_step = 0, dpdf_step = 0, dpdc_step = 0;
int dpdo_step = 0;
bool fixedAspectRatio = aspectRatio > FLT_EPSILON;
if( !CV_IS_MAT(objectPoints) || !CV_IS_MAT(r_vec) ||
!CV_IS_MAT(t_vec) || !CV_IS_MAT(A) ||
/*!CV_IS_MAT(distCoeffs) ||*/ !CV_IS_MAT(imagePoints) )
CV_Error( CV_StsBadArg, "One of required arguments is not a valid matrix" );
int total = objectPoints->rows * objectPoints->cols * CV_MAT_CN(objectPoints->type);
if(total % 3 != 0)
{
//we have stopped support of homogeneous coordinates because it cause ambiguity in interpretation of the input data
CV_Error( CV_StsBadArg, "Homogeneous coordinates are not supported" );
}
count = total / 3;
if( CV_IS_CONT_MAT(objectPoints->type) &&
(CV_MAT_DEPTH(objectPoints->type) == CV_32F || CV_MAT_DEPTH(objectPoints->type) == CV_64F)&&
((objectPoints->rows == 1 && CV_MAT_CN(objectPoints->type) == 3) ||
(objectPoints->rows == count && CV_MAT_CN(objectPoints->type)*objectPoints->cols == 3) ||
(objectPoints->rows == 3 && CV_MAT_CN(objectPoints->type) == 1 && objectPoints->cols == count)))
{
matM.reset(cvCreateMat( objectPoints->rows, objectPoints->cols, CV_MAKETYPE(CV_64F,CV_MAT_CN(objectPoints->type)) ));
cvConvert(objectPoints, matM);
}
else
{
// matM = cvCreateMat( 1, count, CV_64FC3 );
// cvConvertPointsHomogeneous( objectPoints, matM );
CV_Error( CV_StsBadArg, "Homogeneous coordinates are not supported" );
}
if( CV_IS_CONT_MAT(imagePoints->type) &&
(CV_MAT_DEPTH(imagePoints->type) == CV_32F || CV_MAT_DEPTH(imagePoints->type) == CV_64F) &&
((imagePoints->rows == 1 && CV_MAT_CN(imagePoints->type) == 3) ||
(imagePoints->rows == count && CV_MAT_CN(imagePoints->type)*imagePoints->cols == 3) ||
(imagePoints->rows == 3 && CV_MAT_CN(imagePoints->type) == 1 && imagePoints->cols == count)))
{
_m.reset(cvCreateMat( imagePoints->rows, imagePoints->cols, CV_MAKETYPE(CV_64F,CV_MAT_CN(imagePoints->type)) ));
cvConvert(imagePoints, _m);
}
else
{
// _m = cvCreateMat( 1, count, CV_64FC2 );
CV_Error( CV_StsBadArg, "Homogeneous coordinates are not supported" );
}
M = (CvPoint3D64f*)matM->data.db;
m = (CvPoint3D64f*)_m->data.db;
if( (CV_MAT_DEPTH(r_vec->type) != CV_64F && CV_MAT_DEPTH(r_vec->type) != CV_32F) ||
(((r_vec->rows != 1 && r_vec->cols != 1) ||
r_vec->rows*r_vec->cols*CV_MAT_CN(r_vec->type) != 3) &&
((r_vec->rows != 3 && r_vec->cols != 3) || CV_MAT_CN(r_vec->type) != 1)))
CV_Error( CV_StsBadArg, "Rotation must be represented by 1x3 or 3x1 "
"floating-point rotation vector, or 3x3 rotation matrix" );
if( r_vec->rows == 3 && r_vec->cols == 3 )
{
_r = cvMat( 3, 1, CV_64FC1, r );
cvRodrigues2( r_vec, &_r );
cvRodrigues2( &_r, &matR, &_dRdr );
cvCopy( r_vec, &matR );
}
else
{
_r = cvMat( r_vec->rows, r_vec->cols, CV_MAKETYPE(CV_64F,CV_MAT_CN(r_vec->type)), r );
cvConvert( r_vec, &_r );
cvRodrigues2( &_r, &matR, &_dRdr );
}
if( (CV_MAT_DEPTH(t_vec->type) != CV_64F && CV_MAT_DEPTH(t_vec->type) != CV_32F) ||
(t_vec->rows != 1 && t_vec->cols != 1) ||
t_vec->rows*t_vec->cols*CV_MAT_CN(t_vec->type) != 3 )
CV_Error( CV_StsBadArg,
"Translation vector must be 1x3 or 3x1 floating-point vector" );
_t = cvMat( t_vec->rows, t_vec->cols, CV_MAKETYPE(CV_64F,CV_MAT_CN(t_vec->type)), t );
cvConvert( t_vec, &_t );
if( (CV_MAT_TYPE(A->type) != CV_64FC1 && CV_MAT_TYPE(A->type) != CV_32FC1) ||
A->rows != 3 || A->cols != 3 )
CV_Error( CV_StsBadArg, "Instrinsic parameters must be 3x3 floating-point matrix" );
cvConvert( A, &_a );
fx = a[0]; fy = a[4];
cx = a[2]; cy = a[5];
if( fixedAspectRatio )
fx = fy*aspectRatio;
if( distCoeffs )
{
if( !CV_IS_MAT(distCoeffs) ||
(CV_MAT_DEPTH(distCoeffs->type) != CV_64F &&
CV_MAT_DEPTH(distCoeffs->type) != CV_32F) ||
(distCoeffs->rows != 1 && distCoeffs->cols != 1) ||
(distCoeffs->rows*distCoeffs->cols*CV_MAT_CN(distCoeffs->type) != 4 &&
distCoeffs->rows*distCoeffs->cols*CV_MAT_CN(distCoeffs->type) != 5 &&
distCoeffs->rows*distCoeffs->cols*CV_MAT_CN(distCoeffs->type) != 8 &&
distCoeffs->rows*distCoeffs->cols*CV_MAT_CN(distCoeffs->type) != 12 &&
distCoeffs->rows*distCoeffs->cols*CV_MAT_CN(distCoeffs->type) != 14) )
CV_Error( CV_StsBadArg, cvDistCoeffErr );
_k = cvMat( distCoeffs->rows, distCoeffs->cols,
CV_MAKETYPE(CV_64F,CV_MAT_CN(distCoeffs->type)), k );
cvConvert( distCoeffs, &_k );
if(k[12] != 0 || k[13] != 0)
{
_detail::computeTiltProjectionMatrix(k[12], k[13],
&matTilt, &dMatTiltdTauX, &dMatTiltdTauY);
}
}
if( dpdr )
{
if( !CV_IS_MAT(dpdr) ||
(CV_MAT_TYPE(dpdr->type) != CV_32FC1 &&
CV_MAT_TYPE(dpdr->type) != CV_64FC1) ||
dpdr->rows != count*2 || dpdr->cols != 3 )
CV_Error( CV_StsBadArg, "dp/drot must be 2Nx3 floating-point matrix" );
if( CV_MAT_TYPE(dpdr->type) == CV_64FC1 )
{
_dpdr.reset(cvCloneMat(dpdr));
}
else
_dpdr.reset(cvCreateMat( 2*count, 3, CV_64FC1 ));
dpdr_p = _dpdr->data.db;
dpdr_step = _dpdr->step/sizeof(dpdr_p[0]);
}
if( dpdt )
{
if( !CV_IS_MAT(dpdt) ||
(CV_MAT_TYPE(dpdt->type) != CV_32FC1 &&
CV_MAT_TYPE(dpdt->type) != CV_64FC1) ||
dpdt->rows != count*2 || dpdt->cols != 3 )
CV_Error( CV_StsBadArg, "dp/dT must be 2Nx3 floating-point matrix" );
if( CV_MAT_TYPE(dpdt->type) == CV_64FC1 )
{
_dpdt.reset(cvCloneMat(dpdt));
}
else
_dpdt.reset(cvCreateMat( 2*count, 3, CV_64FC1 ));
dpdt_p = _dpdt->data.db;
dpdt_step = _dpdt->step/sizeof(dpdt_p[0]);
}
if( dpdf )
{
if( !CV_IS_MAT(dpdf) ||
(CV_MAT_TYPE(dpdf->type) != CV_32FC1 && CV_MAT_TYPE(dpdf->type) != CV_64FC1) ||
dpdf->rows != count*2 || dpdf->cols != 2 )
CV_Error( CV_StsBadArg, "dp/df must be 2Nx2 floating-point matrix" );
if( CV_MAT_TYPE(dpdf->type) == CV_64FC1 )
{
_dpdf.reset(cvCloneMat(dpdf));
}
else
_dpdf.reset(cvCreateMat( 2*count, 2, CV_64FC1 ));
dpdf_p = _dpdf->data.db;
dpdf_step = _dpdf->step/sizeof(dpdf_p[0]);
}
if( dpdc )
{
if( !CV_IS_MAT(dpdc) ||
(CV_MAT_TYPE(dpdc->type) != CV_32FC1 && CV_MAT_TYPE(dpdc->type) != CV_64FC1) ||
dpdc->rows != count*2 || dpdc->cols != 2 )
CV_Error( CV_StsBadArg, "dp/dc must be 2Nx2 floating-point matrix" );
if( CV_MAT_TYPE(dpdc->type) == CV_64FC1 )
{
_dpdc.reset(cvCloneMat(dpdc));
}
else
_dpdc.reset(cvCreateMat( 2*count, 2, CV_64FC1 ));
dpdc_p = _dpdc->data.db;
dpdc_step = _dpdc->step/sizeof(dpdc_p[0]);
}
if( dpdk )
{
if( !CV_IS_MAT(dpdk) ||
(CV_MAT_TYPE(dpdk->type) != CV_32FC1 && CV_MAT_TYPE(dpdk->type) != CV_64FC1) ||
dpdk->rows != count*2 || (dpdk->cols != 14 && dpdk->cols != 12 && dpdk->cols != 8 && dpdk->cols != 5 && dpdk->cols != 4 && dpdk->cols != 2) )
CV_Error( CV_StsBadArg, "dp/df must be 2Nx14, 2Nx12, 2Nx8, 2Nx5, 2Nx4 or 2Nx2 floating-point matrix" );
if( !distCoeffs )
CV_Error( CV_StsNullPtr, "distCoeffs is NULL while dpdk is not" );
if( CV_MAT_TYPE(dpdk->type) == CV_64FC1 )
{
_dpdk.reset(cvCloneMat(dpdk));
}
else
_dpdk.reset(cvCreateMat( dpdk->rows, dpdk->cols, CV_64FC1 ));
dpdk_p = _dpdk->data.db;
dpdk_step = _dpdk->step/sizeof(dpdk_p[0]);
}
if( dpdo )
{
if( !CV_IS_MAT( dpdo ) || ( CV_MAT_TYPE( dpdo->type ) != CV_32FC1
&& CV_MAT_TYPE( dpdo->type ) != CV_64FC1 )
|| dpdo->rows != count * 2 || dpdo->cols != count * 3 )
CV_Error( CV_StsBadArg, "dp/do must be 2Nx3N floating-point matrix" );
if( CV_MAT_TYPE( dpdo->type ) == CV_64FC1 )
{
_dpdo.reset( cvCloneMat( dpdo ) );
}
else
_dpdo.reset( cvCreateMat( 2 * count, 3 * count, CV_64FC1 ) );
cvZero(_dpdo);
dpdo_p = _dpdo->data.db;
dpdo_step = _dpdo->step / sizeof( dpdo_p[0] );
}
calc_derivatives = dpdr || dpdt || dpdf || dpdc || dpdk || dpdo;
for( i = 0; i < count; i++ )
{
double X = M[i].x, Y = M[i].y, Z = M[i].z;
double x = R[0]*X + R[1]*Y + R[2]*Z + t[0];
double y = R[3]*X + R[4]*Y + R[5]*Z + t[1];
double z = R[6]*X + R[7]*Y + R[8]*Z + t[2];
double r2, r4, r6, a1, a2, a3, cdist, icdist2;
double xd, yd, xd0, yd0, invProj;
Vec3d vecTilt;
Vec3d dVecTilt;
Matx22d dMatTilt;
Vec2d dXdYd;
double z0 = z;
z = z ? 1./z : 1;
x *= z; y *= z;
r2 = x*x + y*y;
r4 = r2*r2;
r6 = r4*r2;
a1 = 2*x*y;
a2 = r2 + 2*x*x;
a3 = r2 + 2*y*y;
cdist = 1 + k[0]*r2 + k[1]*r4 + k[4]*r6;
icdist2 = 1./(1 + k[5]*r2 + k[6]*r4 + k[7]*r6);
xd0 = x*cdist*icdist2 + k[2]*a1 + k[3]*a2 + k[8]*r2+k[9]*r4;
yd0 = y*cdist*icdist2 + k[2]*a3 + k[3]*a1 + k[10]*r2+k[11]*r4;
// additional distortion by projecting onto a tilt plane
vecTilt = matTilt*Vec3d(xd0, yd0, 1);
invProj = vecTilt(2) ? 1./vecTilt(2) : 1;
xd = invProj * vecTilt(0);
yd = invProj * vecTilt(1);
m[i].x = xd*fx + cx;
m[i].y = yd*fy + cy;
m[i].z = z; // Just put the projected Z coordinate here, we mainly care about the sign
if( calc_derivatives )
{
if( dpdc_p )
{
dpdc_p[0] = 1; dpdc_p[1] = 0; // dp_xdc_x; dp_xdc_y
dpdc_p[dpdc_step] = 0;
dpdc_p[dpdc_step+1] = 1;
dpdc_p += dpdc_step*2;
}
if( dpdf_p )
{
if( fixedAspectRatio )
{
dpdf_p[0] = 0; dpdf_p[1] = xd*aspectRatio; // dp_xdf_x; dp_xdf_y
dpdf_p[dpdf_step] = 0;
dpdf_p[dpdf_step+1] = yd;
}
else
{
dpdf_p[0] = xd; dpdf_p[1] = 0;
dpdf_p[dpdf_step] = 0;
dpdf_p[dpdf_step+1] = yd;
}
dpdf_p += dpdf_step*2;
}
for (int row = 0; row < 2; ++row)
for (int col = 0; col < 2; ++col)
dMatTilt(row,col) = matTilt(row,col)*vecTilt(2)
- matTilt(2,col)*vecTilt(row);
double invProjSquare = (invProj*invProj);
dMatTilt *= invProjSquare;
if( dpdk_p )
{
dXdYd = dMatTilt*Vec2d(x*icdist2*r2, y*icdist2*r2);
dpdk_p[0] = fx*dXdYd(0);
dpdk_p[dpdk_step] = fy*dXdYd(1);
dXdYd = dMatTilt*Vec2d(x*icdist2*r4, y*icdist2*r4);
dpdk_p[1] = fx*dXdYd(0);
dpdk_p[dpdk_step+1] = fy*dXdYd(1);
if( _dpdk->cols > 2 )
{
dXdYd = dMatTilt*Vec2d(a1, a3);
dpdk_p[2] = fx*dXdYd(0);
dpdk_p[dpdk_step+2] = fy*dXdYd(1);
dXdYd = dMatTilt*Vec2d(a2, a1);
dpdk_p[3] = fx*dXdYd(0);
dpdk_p[dpdk_step+3] = fy*dXdYd(1);
if( _dpdk->cols > 4 )
{
dXdYd = dMatTilt*Vec2d(x*icdist2*r6, y*icdist2*r6);
dpdk_p[4] = fx*dXdYd(0);
dpdk_p[dpdk_step+4] = fy*dXdYd(1);
if( _dpdk->cols > 5 )
{
dXdYd = dMatTilt*Vec2d(
x*cdist*(-icdist2)*icdist2*r2, y*cdist*(-icdist2)*icdist2*r2);
dpdk_p[5] = fx*dXdYd(0);
dpdk_p[dpdk_step+5] = fy*dXdYd(1);
dXdYd = dMatTilt*Vec2d(
x*cdist*(-icdist2)*icdist2*r4, y*cdist*(-icdist2)*icdist2*r4);
dpdk_p[6] = fx*dXdYd(0);
dpdk_p[dpdk_step+6] = fy*dXdYd(1);
dXdYd = dMatTilt*Vec2d(
x*cdist*(-icdist2)*icdist2*r6, y*cdist*(-icdist2)*icdist2*r6);
dpdk_p[7] = fx*dXdYd(0);
dpdk_p[dpdk_step+7] = fy*dXdYd(1);
if( _dpdk->cols > 8 )
{
dXdYd = dMatTilt*Vec2d(r2, 0);
dpdk_p[8] = fx*dXdYd(0); //s1
dpdk_p[dpdk_step+8] = fy*dXdYd(1); //s1
dXdYd = dMatTilt*Vec2d(r4, 0);
dpdk_p[9] = fx*dXdYd(0); //s2
dpdk_p[dpdk_step+9] = fy*dXdYd(1); //s2
dXdYd = dMatTilt*Vec2d(0, r2);
dpdk_p[10] = fx*dXdYd(0);//s3
dpdk_p[dpdk_step+10] = fy*dXdYd(1); //s3
dXdYd = dMatTilt*Vec2d(0, r4);
dpdk_p[11] = fx*dXdYd(0);//s4
dpdk_p[dpdk_step+11] = fy*dXdYd(1); //s4
if( _dpdk->cols > 12 )
{
dVecTilt = dMatTiltdTauX * Vec3d(xd0, yd0, 1);
dpdk_p[12] = fx * invProjSquare * (
dVecTilt(0) * vecTilt(2) - dVecTilt(2) * vecTilt(0));
dpdk_p[dpdk_step+12] = fy*invProjSquare * (
dVecTilt(1) * vecTilt(2) - dVecTilt(2) * vecTilt(1));
dVecTilt = dMatTiltdTauY * Vec3d(xd0, yd0, 1);
dpdk_p[13] = fx * invProjSquare * (
dVecTilt(0) * vecTilt(2) - dVecTilt(2) * vecTilt(0));
dpdk_p[dpdk_step+13] = fy * invProjSquare * (
dVecTilt(1) * vecTilt(2) - dVecTilt(2) * vecTilt(1));
}
}
}
}
}
dpdk_p += dpdk_step*2;
}
if( dpdt_p )
{
double dxdt[] = { z, 0, -x*z }, dydt[] = { 0, z, -y*z };
for( j = 0; j < 3; j++ )
{
double dr2dt = 2*x*dxdt[j] + 2*y*dydt[j];
double dcdist_dt = k[0]*dr2dt + 2*k[1]*r2*dr2dt + 3*k[4]*r4*dr2dt;
double dicdist2_dt = -icdist2*icdist2*(k[5]*dr2dt + 2*k[6]*r2*dr2dt + 3*k[7]*r4*dr2dt);
double da1dt = 2*(x*dydt[j] + y*dxdt[j]);
double dmxdt = (dxdt[j]*cdist*icdist2 + x*dcdist_dt*icdist2 + x*cdist*dicdist2_dt +
k[2]*da1dt + k[3]*(dr2dt + 4*x*dxdt[j]) + k[8]*dr2dt + 2*r2*k[9]*dr2dt);
double dmydt = (dydt[j]*cdist*icdist2 + y*dcdist_dt*icdist2 + y*cdist*dicdist2_dt +
k[2]*(dr2dt + 4*y*dydt[j]) + k[3]*da1dt + k[10]*dr2dt + 2*r2*k[11]*dr2dt);
dXdYd = dMatTilt*Vec2d(dmxdt, dmydt);
dpdt_p[j] = fx*dXdYd(0);
dpdt_p[dpdt_step+j] = fy*dXdYd(1);
}
dpdt_p += dpdt_step*2;
}
if( dpdr_p )
{
double dx0dr[] =
{
X*dRdr[0] + Y*dRdr[1] + Z*dRdr[2],
X*dRdr[9] + Y*dRdr[10] + Z*dRdr[11],
X*dRdr[18] + Y*dRdr[19] + Z*dRdr[20]
};
double dy0dr[] =
{
X*dRdr[3] + Y*dRdr[4] + Z*dRdr[5],
X*dRdr[12] + Y*dRdr[13] + Z*dRdr[14],
X*dRdr[21] + Y*dRdr[22] + Z*dRdr[23]
};
double dz0dr[] =
{
X*dRdr[6] + Y*dRdr[7] + Z*dRdr[8],
X*dRdr[15] + Y*dRdr[16] + Z*dRdr[17],
X*dRdr[24] + Y*dRdr[25] + Z*dRdr[26]
};
for( j = 0; j < 3; j++ )
{
double dxdr = z*(dx0dr[j] - x*dz0dr[j]);
double dydr = z*(dy0dr[j] - y*dz0dr[j]);
double dr2dr = 2*x*dxdr + 2*y*dydr;
double dcdist_dr = (k[0] + 2*k[1]*r2 + 3*k[4]*r4)*dr2dr;
double dicdist2_dr = -icdist2*icdist2*(k[5] + 2*k[6]*r2 + 3*k[7]*r4)*dr2dr;
double da1dr = 2*(x*dydr + y*dxdr);
double dmxdr = (dxdr*cdist*icdist2 + x*dcdist_dr*icdist2 + x*cdist*dicdist2_dr +
k[2]*da1dr + k[3]*(dr2dr + 4*x*dxdr) + (k[8] + 2*r2*k[9])*dr2dr);
double dmydr = (dydr*cdist*icdist2 + y*dcdist_dr*icdist2 + y*cdist*dicdist2_dr +
k[2]*(dr2dr + 4*y*dydr) + k[3]*da1dr + (k[10] + 2*r2*k[11])*dr2dr);
dXdYd = dMatTilt*Vec2d(dmxdr, dmydr);
dpdr_p[j] = fx*dXdYd(0);
dpdr_p[dpdr_step+j] = fy*dXdYd(1);
}
dpdr_p += dpdr_step*2;
}
if( dpdo_p )
{
double dxdo[] = { z * ( R[0] - x * z * z0 * R[6] ),
z * ( R[1] - x * z * z0 * R[7] ),
z * ( R[2] - x * z * z0 * R[8] ) };
double dydo[] = { z * ( R[3] - y * z * z0 * R[6] ),
z * ( R[4] - y * z * z0 * R[7] ),
z * ( R[5] - y * z * z0 * R[8] ) };
for( j = 0; j < 3; j++ )
{
double dr2do = 2 * x * dxdo[j] + 2 * y * dydo[j];
double dr4do = 2 * r2 * dr2do;
double dr6do = 3 * r4 * dr2do;
double da1do = 2 * y * dxdo[j] + 2 * x * dydo[j];
double da2do = dr2do + 4 * x * dxdo[j];
double da3do = dr2do + 4 * y * dydo[j];
double dcdist_do
= k[0] * dr2do + k[1] * dr4do + k[4] * dr6do;
double dicdist2_do = -icdist2 * icdist2
* ( k[5] * dr2do + k[6] * dr4do + k[7] * dr6do );
double dxd0_do = cdist * icdist2 * dxdo[j]
+ x * icdist2 * dcdist_do + x * cdist * dicdist2_do
+ k[2] * da1do + k[3] * da2do + k[8] * dr2do
+ k[9] * dr4do;
double dyd0_do = cdist * icdist2 * dydo[j]
+ y * icdist2 * dcdist_do + y * cdist * dicdist2_do
+ k[2] * da3do + k[3] * da1do + k[10] * dr2do
+ k[11] * dr4do;
dXdYd = dMatTilt * Vec2d( dxd0_do, dyd0_do );
dpdo_p[i * 3 + j] = fx * dXdYd( 0 );
dpdo_p[dpdo_step + i * 3 + j] = fy * dXdYd( 1 );
}
dpdo_p += dpdo_step * 2;
}
}
}
if( _m != imagePoints )
cvConvert( _m, imagePoints );
if( _dpdr != dpdr )
cvConvert( _dpdr, dpdr );
if( _dpdt != dpdt )
cvConvert( _dpdt, dpdt );
if( _dpdf != dpdf )
cvConvert( _dpdf, dpdf );
if( _dpdc != dpdc )
cvConvert( _dpdc, dpdc );
if( _dpdk != dpdk )
cvConvert( _dpdk, dpdk );
if( _dpdo != dpdo )
cvConvert( _dpdo, dpdo );
}
static void _cvProjectPoints2( const CvMat* objectPoints,
const CvMat* r_vec,
const CvMat* t_vec,
const CvMat* A,
const CvMat* distCoeffs,
CvMat* imagePoints, CvMat* dpdr,
CvMat* dpdt, CvMat* dpdf,
CvMat* dpdc, CvMat* dpdk,
double aspectRatio )
{
_cvProjectPoints2Internal( objectPoints, r_vec, t_vec, A, distCoeffs, imagePoints, dpdr, dpdt,
dpdf, dpdc, dpdk, NULL, aspectRatio );
}

9
aruco_pose/src/draw.h Normal file
View File

@@ -0,0 +1,9 @@
#include <cmath>
#include <ros/ros.h>
#include <opencv2/opencv.hpp>
#include <opencv2/aruco.hpp>
void _drawPlanarBoard(cv::aruco::Board *_board, cv::Size outSize, cv::OutputArray _img,
int marginSize, int borderBits, bool drawAxis); // editorconfig-checker-disable-line
void _drawAxis(cv::InputOutputArray image, cv::InputArray cameraMatrix, cv::InputArray distCoeffs,
cv::InputArray rvec, cv::InputArray tvec, float length); // editorconfig-checker-disable-line

View File

@@ -1,145 +0,0 @@
using namespace cv;
using namespace cv::aruco;
// Temporal fix!
// TODO: remove
// fix strange bug in our OpenCV version
void _getBoardObjectAndImagePoints(const Ptr<aruco::Board> &board, InputArrayOfArrays detectedCorners,
InputArray detectedIds, OutputArray objPoints, OutputArray imgPoints) {
CV_Assert(board->ids.size() == board->objPoints.size());
CV_Assert(detectedIds.total() == detectedCorners.total());
size_t nDetectedMarkers = detectedIds.total();
std::vector< Point3f > objPnts;
objPnts.reserve(nDetectedMarkers);
std::vector< Point2f > imgPnts;
imgPnts.reserve(nDetectedMarkers);
// look for detected markers that belong to the board and get their information
for(unsigned int i = 0; i < nDetectedMarkers; i++) {
int currentId = detectedIds.getMat().ptr< int >(0)[i];
for(unsigned int j = 0; j < board->ids.size(); j++) {
if(currentId == board->ids[j]) {
for(int p = 0; p < 4; p++) {
objPnts.push_back(board->objPoints[j][p]);
imgPnts.push_back(detectedCorners.getMat(i).ptr< Point2f >(0)[p]);
}
}
}
}
// create output
Mat(objPnts).copyTo(objPoints);
Mat(imgPnts).copyTo(imgPoints);
}
int _estimatePoseBoard(InputArrayOfArrays _corners, InputArray _ids, const Ptr<aruco::Board> &board,
InputArray _cameraMatrix, InputArray _distCoeffs, OutputArray _rvec,
OutputArray _tvec, bool useExtrinsicGuess, Mat &objPoints) {
CV_Assert(_corners.total() == _ids.total());
// get object and image points for the solvePnP function
Mat /*objPoints, */imgPoints;
_getBoardObjectAndImagePoints(board, _corners, _ids, objPoints, imgPoints);
CV_Assert(imgPoints.total() == objPoints.total());
if(objPoints.total() == 0) // 0 of the detected markers in board
return 0;
// std::cout << "objPoints: " << objPoints << std::endl;
// std::cout << "imgPoints: " << imgPoints << std::endl;
solvePnP(objPoints, imgPoints, _cameraMatrix, _distCoeffs, _rvec, _tvec, useExtrinsicGuess);
// divide by four since all the four corners are concatenated in the array for each marker
return (int)objPoints.total() / 4;
}
void _drawPlanarBoard(Board *_board, Size outSize, OutputArray _img, int marginSize,
int borderBits) {
CV_Assert(outSize.area() > 0);
CV_Assert(marginSize >= 0);
_img.create(outSize, CV_8UC1);
Mat out = _img.getMat();
out.setTo(Scalar::all(255));
out.adjustROI(-marginSize, -marginSize, -marginSize, -marginSize);
// calculate max and min values in XY plane
CV_Assert(_board->objPoints.size() > 0);
float minX, maxX, minY, maxY;
minX = maxX = _board->objPoints[0][0].x;
minY = maxY = _board->objPoints[0][0].y;
for(unsigned int i = 0; i < _board->objPoints.size(); i++) {
for(int j = 0; j < 4; j++) {
minX = min(minX, _board->objPoints[i][j].x);
maxX = max(maxX, _board->objPoints[i][j].x);
minY = min(minY, _board->objPoints[i][j].y);
maxY = max(maxY, _board->objPoints[i][j].y);
}
}
float sizeX = maxX - minX;
float sizeY = maxY - minY;
// proportion transformations
float xReduction = sizeX / float(out.cols);
float yReduction = sizeY / float(out.rows);
// determine the zone where the markers are placed
if(xReduction > yReduction) {
int nRows = int(sizeY / xReduction);
int rowsMargins = (out.rows - nRows) / 2;
out.adjustROI(-rowsMargins, -rowsMargins, 0, 0);
} else {
int nCols = int(sizeX / yReduction);
int colsMargins = (out.cols - nCols) / 2;
out.adjustROI(0, 0, -colsMargins, -colsMargins);
}
// now paint each marker
Dictionary &dictionary = *(_board->dictionary);
Mat marker;
Point2f outCorners[3];
Point2f inCorners[3];
for(unsigned int m = 0; m < _board->objPoints.size(); m++) {
// transform corners to markerZone coordinates
for(int j = 0; j < 3; j++) {
Point2f pf = Point2f(_board->objPoints[m][j].x, _board->objPoints[m][j].y);
// move top left to 0, 0
pf -= Point2f(minX, minY);
pf.x = pf.x / sizeX * float(out.cols);
pf.y = (1.0f - pf.y / sizeY) * float(out.rows);
outCorners[j] = pf;
}
// get marker
Size dst_sz(outCorners[2] - outCorners[0]); // assuming CCW order
dst_sz.width = dst_sz.height = std::min(dst_sz.width, dst_sz.height); //marker should be square
dictionary.drawMarker(_board->ids[m], dst_sz.width, marker, borderBits);
if((outCorners[0].y == outCorners[1].y) && (outCorners[1].x == outCorners[2].x)) {
// marker is aligned to image axes
marker.copyTo(out(Rect(outCorners[0], dst_sz)));
continue;
}
// interpolate tiny marker to marker position in markerZone
inCorners[0] = Point2f(-0.5f, -0.5f);
inCorners[1] = Point2f(marker.cols - 0.5f, -0.5f);
inCorners[2] = Point2f(marker.cols - 0.5f, marker.rows - 0.5f);
// remove perspective
Mat transformation = getAffineTransform(inCorners, outCorners);
warpAffine(marker, out, transformation, out.size(), INTER_LINEAR,
BORDER_TRANSPARENT);
}
}

53
aruco_pose/src/genmap.py Executable file
View File

@@ -0,0 +1,53 @@
#!/usr/bin/env python
# Copyright (C) 2018 Copter Express Technologies
#
# Author: Oleg Kalachev <okalachev@gmail.com>
#
# Distributed under MIT License (available at https://opensource.org/licenses/MIT).
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
"""Markers map generator
Generate map file for aruco_map nodelet.
Usage:
genmap.py <length> <x> <y> <dist_x> <dist_y> <first> [--top-left]
genmap.py (-h | --help)
Options:
<length> Marker side length
<x> Marker count along X axis
<y> Marker count along Y axis
<dist_x> Distance between markers along X axis
<dist_y> Distance between markers along Y axis
<first> First marker ID
--top-left First marker is on top-left (not bottom-left)
"""
from __future__ import print_function
from docopt import docopt
arguments = docopt(__doc__)
length = float(arguments['<length>'])
first = int(arguments['<first>'])
markers_x = int(arguments['<x>'])
markers_y = int(arguments['<y>'])
dist_x = float(arguments['<dist_x>'])
dist_y = float(arguments['<dist_y>'])
top_left = arguments['--top-left']
max_y = (markers_y - 1) * dist_y
for y in range(markers_y):
for x in range(markers_x):
pos_x = x * dist_x
pos_y = y * dist_y
if top_left:
pos_y = max_y - pos_y
print('{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t'.format(first, length, pos_x, pos_y, 0, 0, 0, 0))
first += 1

View File

@@ -1,20 +0,0 @@
#pragma once
#include <vector>
#include <string>
std::vector<std::string> strSplit(const std::string& str, const std::string& delim)
{
std::vector<std::string> tokens;
size_t prev = 0, pos = 0;
do
{
pos = str.find(delim, prev);
if (pos == std::string::npos) pos = str.length();
std::string token = str.substr(prev, pos-prev);
if (!token.empty()) tokens.push_back(token);
prev = pos + delim.length();
}
while (pos < str.length() && prev < str.length());
return tokens;
}

139
aruco_pose/src/utils.h Normal file
View File

@@ -0,0 +1,139 @@
/*
* Utility functions
* Copyright (C) 2018 Copter Express Technologies
*
* Author: Oleg Kalachev <okalachev@gmail.com>
*
* Distributed under MIT License (available at https://opensource.org/licenses/MIT).
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*/
#pragma once
#include <cmath>
#include <ros/ros.h>
#include <tf/transform_datatypes.h>
#include <geometry_msgs/Quaternion.h>
#include <geometry_msgs/Pose.h>
#include <geometry_msgs/Vector3.h>
#include <sensor_msgs/CameraInfo.h>
#include <opencv2/opencv.hpp>
// Read required param or shutdown the node
template<typename T>
static void param(ros::NodeHandle nh, const std::string& param_name, T& param_val)
{
if (!nh.getParam(param_name, param_val)) {
ROS_FATAL("Required param %s is not defined", param_name.c_str());
ros::shutdown();
}
}
static void parseCameraInfo(const sensor_msgs::CameraInfoConstPtr& cinfo, cv::Mat& matrix, cv::Mat& dist)
{
for (unsigned int i = 0; i < 3; ++i)
for (unsigned int j = 0; j < 3; ++j)
matrix.at<double>(i, j) = cinfo->K[3 * i + j];
for (unsigned int k = 0; k < cinfo->D.size(); k++)
dist.at<double>(k) = cinfo->D[k];
}
inline void rotatePoint(cv::Point3f& p, cv::Point3f origin, float angle)
{
float s = sin(angle);
float c = cos(angle);
// translate point back to origin:
p.x -= origin.x;
p.y -= origin.y;
// rotate point
float xnew = p.x * c - p.y * s;
float ynew = p.x * s + p.y * c;
// translate point back:
p.x = xnew + origin.x;
p.y = ynew + origin.y;
}
inline void fillPose(geometry_msgs::Pose& pose, const cv::Vec3d& rvec, const cv::Vec3d& tvec)
{
pose.position.x = tvec[0];
pose.position.y = tvec[1];
pose.position.z = tvec[2];
double angle = norm(rvec);
cv::Vec3d axis = rvec / angle;
tf2::Quaternion q;
q.setRotation(tf2::Vector3(axis[0], axis[1], axis[2]), angle);
pose.orientation.w = q.w();
pose.orientation.x = q.x();
pose.orientation.y = q.y();
pose.orientation.z = q.z();
}
inline void fillTransform(geometry_msgs::Transform& transform, const cv::Vec3d& rvec, const cv::Vec3d& tvec)
{
transform.translation.x = tvec[0];
transform.translation.y = tvec[1];
transform.translation.z = tvec[2];
double angle = norm(rvec);
cv::Vec3d axis = rvec / angle;
tf2::Quaternion q;
q.setRotation(tf2::Vector3(axis[0], axis[1], axis[2]), angle);
transform.rotation.w = q.w();
transform.rotation.x = q.x();
transform.rotation.y = q.y();
transform.rotation.z = q.z();
}
inline void fillTranslation(geometry_msgs::Vector3& translation, const cv::Vec3d& tvec)
{
translation.x = tvec[0];
translation.y = tvec[1];
translation.z = tvec[2];
}
inline bool isFlipped(tf::Quaternion& q)
{
double yaw, pitch, roll;
tf::Matrix3x3(q).getEulerYPR(yaw, pitch, roll);
return (abs(pitch) > M_PI / 2) || (abs(roll) > M_PI / 2);
}
/* Set roll and pitch from "from" to "to", keeping yaw */
inline void snapOrientation(geometry_msgs::Quaternion& to, const geometry_msgs::Quaternion& from, bool auto_flip = false)
{
tf::Quaternion _from, _to;
tf::quaternionMsgToTF(from, _from);
tf::quaternionMsgToTF(to, _to);
if (auto_flip) {
if (!isFlipped(_from)) {
static const tf::Quaternion flip = tf::createQuaternionFromRPY(M_PI, 0, 0);
_from *= flip; // flip "from"
}
}
auto diff = tf::Matrix3x3(_to).transposeTimes(tf::Matrix3x3(_from));
double _, yaw;
diff.getRPY(_, _, yaw);
auto q = tf::createQuaternionFromRPY(0, 0, -yaw);
_from = _from * q; // set yaw from "to" to "from"
tf::quaternionTFToMsg(_from, to); // set "from" to "to"
}
inline void transformToPose(const geometry_msgs::Transform& transform, geometry_msgs::Pose& pose)
{
pose.position.x = transform.translation.x;
pose.position.y = transform.translation.y;
pose.position.z = transform.translation.z;
pose.orientation = transform.rotation;
}

204
aruco_pose/test/basic.py Executable file
View File

@@ -0,0 +1,204 @@
import rospy
import pytest
import tf2_ros
import tf2_geometry_msgs
from geometry_msgs.msg import PoseWithCovarianceStamped
from sensor_msgs.msg import Image
from aruco_pose.msg import MarkerArray
from visualization_msgs.msg import MarkerArray as VisMarkerArray
@pytest.fixture
def node():
return rospy.init_node('aruco_pose_test', anonymous=True)
@pytest.fixture
def tf_buffer():
buf = tf2_ros.Buffer()
tf2_ros.TransformListener(buf)
return buf
def approx(expected):
return pytest.approx(expected, abs=1e-4) # compare floats more roughly
def test_markers(node):
markers = rospy.wait_for_message('aruco_detect/markers', MarkerArray, timeout=5)
assert len(markers.markers) == 5
assert markers.header.frame_id == 'main_camera_optical'
assert markers.markers[0].id == 2
assert markers.markers[0].length == approx(0.33)
assert markers.markers[0].pose.position.x == approx(0.36706567854)
assert markers.markers[0].pose.position.y == approx(0.290484516644)
assert markers.markers[0].pose.position.z == approx(2.18787602301)
assert markers.markers[0].pose.orientation.x == approx(0.993997406299)
assert markers.markers[0].pose.orientation.y == approx(-0.00532003481626)
assert markers.markers[0].pose.orientation.z == approx(-0.107390951553)
assert markers.markers[0].pose.orientation.w == approx(0.0201999263402)
assert markers.markers[0].c1.x == approx(415.557739258)
assert markers.markers[0].c1.y == approx(335.557739258)
assert markers.markers[0].c2.x == approx(509.442260742)
assert markers.markers[0].c2.y == approx(335.557739258)
assert markers.markers[0].c3.x == approx(509.442260742)
assert markers.markers[0].c3.y == approx(429.442260742)
assert markers.markers[0].c4.x == approx(415.557739258)
assert markers.markers[0].c4.y == approx(429.442260742)
assert markers.markers[4].id == 3
assert markers.markers[4].length == approx(0.1)
assert markers.markers[4].pose.position.x == approx(-0.1805169666)
assert markers.markers[4].pose.position.y == approx(-0.200697302327)
assert markers.markers[4].pose.position.z == approx(0.585767514823)
assert markers.markers[4].pose.orientation.x == approx(-0.961738074009)
assert markers.markers[4].pose.orientation.y == approx(-0.0375180244707)
assert markers.markers[4].pose.orientation.z == approx(-0.0115387773672)
assert markers.markers[4].pose.orientation.w == approx(0.271144115664)
assert markers.markers[4].c1.x == approx(129.557723999)
assert markers.markers[4].c1.y == approx(49.557723999)
assert markers.markers[4].c2.x == approx(223.442276001)
assert markers.markers[4].c2.y == approx(49.557723999)
assert markers.markers[4].c3.x == approx(223.442276001)
assert markers.markers[4].c3.y == approx(143.442276001)
assert markers.markers[4].c4.x == approx(129.557723999)
assert markers.markers[4].c4.y == approx(143.442276001)
assert markers.markers[1].id == 1
assert markers.markers[1].length == approx(0.33)
assert markers.markers[3].id == 4
assert markers.markers[3].length == approx(0.33)
assert markers.markers[2].id == 100
assert markers.markers[2].length == approx(0.33)
assert markers.markers[2].pose.position.x == approx(-1.37600105389)
assert markers.markers[2].pose.position.y == approx(-0.323028530991)
assert markers.markers[2].pose.position.z == approx(2.94611272668)
assert markers.markers[2].pose.orientation.x == approx(-0.955543925678)
assert markers.markers[2].pose.orientation.y == approx(0.0458801909197)
assert markers.markers[2].pose.orientation.z == approx(-0.249604946264)
assert markers.markers[2].pose.orientation.w == approx(-0.150093920537)
assert markers.markers[2].c1.x == approx(52.557723999)
assert markers.markers[2].c1.y == approx(205.557723999)
assert markers.markers[2].c2.x == approx(113.442276001)
assert markers.markers[2].c2.y == approx(205.557723999)
assert markers.markers[2].c3.x == approx(113.442276001)
assert markers.markers[2].c3.y == approx(265.442260742)
assert markers.markers[2].c4.x == approx(52.557723999)
assert markers.markers[2].c4.y == approx(265.442260742)
def test_markers_frames(node, tf_buffer):
marker_2 = tf_buffer.lookup_transform('main_camera_optical', 'aruco_2', rospy.Time(), rospy.Duration(5))
assert marker_2.transform.translation.x == approx(0.36706567854)
assert marker_2.transform.translation.y == approx(0.290484516644)
assert marker_2.transform.translation.z == approx(2.18787602301)
assert marker_2.transform.rotation.x == approx(0.993997406299)
assert marker_2.transform.rotation.y == approx(-0.00532003481626)
assert marker_2.transform.rotation.z == approx(-0.107390951553)
assert marker_2.transform.rotation.w == approx(0.0201999263402)
def test_map_markers_frames(node, tf_buffer):
stamp = rospy.get_rostime()
timeout = rospy.Duration(5)
marker_1 = tf_buffer.lookup_transform('aruco_map', 'aruco_in_map_1', stamp, timeout)
assert marker_1.transform.translation.x == approx(0)
assert marker_1.transform.translation.y == approx(0)
assert marker_1.transform.translation.z == approx(0)
marker_4 = tf_buffer.lookup_transform('aruco_map', 'aruco_in_map_4', stamp, timeout)
assert marker_4.transform.translation.x == approx(1)
assert marker_4.transform.translation.y == approx(1)
assert marker_4.transform.translation.z == approx(0)
marker_12 = tf_buffer.lookup_transform('aruco_map', 'aruco_in_map_12', stamp, timeout)
assert marker_12.transform.translation.x == approx(0.2)
assert marker_12.transform.translation.y == approx(0.5)
assert marker_12.transform.translation.z == approx(0)
def test_visualization(node):
vis = rospy.wait_for_message('aruco_detect/visualization', VisMarkerArray, timeout=5)
assert len(vis.markers) == 11
def test_debug(node):
img = rospy.wait_for_message('aruco_detect/debug', Image, timeout=5)
assert img.width == 640
assert img.height == 480
assert img.header.frame_id == 'main_camera_optical'
def test_map(node):
pose = rospy.wait_for_message('aruco_map/pose', PoseWithCovarianceStamped, timeout=5)
assert pose.header.frame_id == 'main_camera_optical'
assert pose.pose.pose.position.x == approx(-0.629167753342)
assert pose.pose.pose.position.y == approx(0.293822650809)
assert pose.pose.pose.position.z == approx(2.12641343155)
assert pose.pose.pose.orientation.x == approx(-0.998383794799)
assert pose.pose.pose.orientation.y == approx(-5.20919098575e-06)
assert pose.pose.pose.orientation.z == approx(-0.0300861070302)
assert pose.pose.pose.orientation.w == approx(0.0482143590507)
def test_map_image(node):
img = rospy.wait_for_message('aruco_map/image', Image, timeout=5)
assert img.width == 2000
assert img.height == 2000
assert img.encoding in ('mono8', 'rgb8')
def test_map_markers(node):
markers = rospy.wait_for_message('aruco_map/markers', MarkerArray, timeout=5)
assert markers.markers[0].id == 1
assert markers.markers[1].id == 2
assert markers.markers[2].id == 3
assert markers.markers[3].id == 4
assert markers.markers[4].id == 10
assert markers.markers[5].id == 11
assert markers.markers[6].id == 12
assert markers.markers[0].pose.position.x == 0
assert markers.markers[0].pose.position.y == 0
assert markers.markers[0].pose.position.z == 0
assert markers.markers[0].pose.orientation.x == 0
assert markers.markers[0].pose.orientation.y == 0
assert markers.markers[0].pose.orientation.z == 0
assert markers.markers[0].pose.orientation.w == 1
assert markers.markers[0].length == approx(0.33)
assert markers.markers[1].pose.position.x == 1
assert markers.markers[1].pose.position.y == 0
assert markers.markers[1].pose.position.z == 0
assert markers.markers[1].pose.orientation.x == 0
assert markers.markers[1].pose.orientation.y == 0
assert markers.markers[1].pose.orientation.z == 0
assert markers.markers[1].pose.orientation.w == 1
assert markers.markers[1].length == approx(0.33)
assert markers.markers[2].pose.position.x == 0
assert markers.markers[2].pose.position.y == 1
assert markers.markers[2].pose.position.z == 0
assert markers.markers[2].pose.orientation.x == 0
assert markers.markers[2].pose.orientation.y == 0
assert markers.markers[2].pose.orientation.z == 0
assert markers.markers[2].pose.orientation.w == 1
assert markers.markers[2].length == approx(0.33)
assert markers.markers[3].pose.position.x == 1
assert markers.markers[3].pose.position.y == 1
assert markers.markers[3].pose.position.z == 0
assert markers.markers[3].pose.orientation.x == 0
assert markers.markers[3].pose.orientation.y == 0
assert markers.markers[3].pose.orientation.z == 0
assert markers.markers[3].pose.orientation.w == 1
assert markers.markers[3].length == approx(0.33)
assert markers.markers[4].pose.position.x == approx(0.5)
assert markers.markers[4].pose.position.y == 2
assert markers.markers[4].pose.position.z == 0
assert markers.markers[4].pose.orientation.x == 0
assert markers.markers[4].pose.orientation.y == 0
assert markers.markers[4].pose.orientation.z == approx(0.5646424733950354)
assert markers.markers[4].pose.orientation.w == approx(0.8253356149096783)
assert markers.markers[4].length == approx(0.5)
def test_map_visualization(node):
vis = rospy.wait_for_message('aruco_map/visualization', VisMarkerArray, timeout=5)
def test_map_debug(node):
img = rospy.wait_for_message('aruco_map/debug', Image, timeout=5)

View File

@@ -0,0 +1,31 @@
<launch>
<node pkg="image_publisher" type="image_publisher" name="main_camera" args="$(find aruco_pose)/test/map.png">
<param name="frame_id" value="main_camera_optical"/>
<param name="publish_rate" value="10"/>
<param name="camera_info_url" value="file://$(find aruco_pose)/test/camera_info.yaml" />
</node>
<node pkg="nodelet" type="nodelet" name="nodelet_manager" args="manager" required="true"/>
<node pkg="nodelet" clear_params="true" type="nodelet" name="aruco_detect" args="load aruco_pose/aruco_detect nodelet_manager" required="true">
<remap from="image_raw" to="main_camera/image_raw"/>
<remap from="camera_info" to="main_camera/camera_info"/>
<param name="length" value="0.33"/>
<param name="length_override/3" value="0.1"/>
<param name="estimate_poses" value="true"/>
<param name="send_tf" value="true"/>
</node>
<node name="aruco_map" pkg="nodelet" type="nodelet" args="load aruco_pose/aruco_map nodelet_manager" clear_params="true" required="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"/>
<param name="type" value="map"/>
<param name="map" value="$(find aruco_pose)/test/basic.txt"/>
<param name="markers/frame_id" value="aruco_map"/>
<param name="markers/child_frame_id_prefix" value="aruco_in_map_"/>
</node>
<param name="test_module" value="$(find aruco_pose)/test/basic.py"/>
<test test-name="aruco_pose_test" pkg="ros_pytest" type="ros_pytest_runner"/>
</launch>

11
aruco_pose/test/basic.txt Normal file
View File

@@ -0,0 +1,11 @@
# Default markers
1 0.33 0 0 0 0 0 0
2 0.33 1 0 0 0 0 0
3 0.33 0 1 0 0 0 0
4 0.33 1 1 0 0 0 0
# Marker with non-zero yaw rotation
10 0.5 0.5 2 0 1.2 0 0
# Marker with non-zero pitch and roll rotation
11 0.2 0.5 0.5 0 0.0 -1 1
# Marker with yaw, pitch and roll rotation
12 0.4 0.2 0.5 0 0.1 -1.2 -0.5

View File

@@ -0,0 +1,21 @@
# some random camera calibration for testing
image_width: 640
image_height: 480
camera_name: test_camera
camera_matrix:
rows: 3
cols: 3
data: [643.229809, 0.000000, 356.811289, 0.000000, 644.318982, 299.150067, 0.000000, 0.000000, 1.000000]
distortion_model: plumb_bob
distortion_coefficients:
rows: 1
cols: 5
data: [-0.422907, 0.202567, 0.000781, 0.000447, 0.000000]
rectification_matrix:
rows: 3
cols: 3
data: [1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000]
projection_matrix:
rows: 3
cols: 4
data: [567.010193, 0.000000, 366.677428, 0.000000, 0.000000, 594.591980, 307.043423, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000]

26
aruco_pose/test/largemap.py Executable file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env python
import sys
import unittest
import json
import rospy
import rostest
from sensor_msgs.msg import Image
from visualization_msgs.msg import MarkerArray as VisMarkerArray
class TestArucoPose(unittest.TestCase):
def setUp(self):
rospy.init_node('test_aruco_largemap', anonymous=True)
def test_map_image(self):
img = rospy.wait_for_message('aruco_map/image', Image, timeout=5)
self.assertEqual(img.width, 2000)
self.assertEqual(img.height, 2000)
self.assertIn(img.encoding, ('mono8', 'rgb8'))
def test_map_visualization(self):
vis = rospy.wait_for_message('aruco_map/visualization', VisMarkerArray, timeout=5)
rostest.rosrun('aruco_pose', 'test_aruco_largemap', TestArucoPose, sys.argv)

View File

@@ -0,0 +1,13 @@
<launch>
<node pkg="nodelet" type="nodelet" name="nodelet_manager" args="manager" required="true"/>
<node name="aruco_map" pkg="nodelet" type="nodelet" args="load aruco_pose/aruco_map nodelet_manager" clear_params="true" required="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"/>
<param name="type" value="map"/>
<param name="map" value="$(find aruco_pose)/test/largemap.txt"/>
</node>
<test test-name="test_aruco_pose_largemap" pkg="aruco_pose" type="largemap.py"/>
</launch>

View File

@@ -0,0 +1,11 @@
0 0.2 0 0 0 0 0 0
1 0.2 10 0 0 0 0 0
2 0.2 20 0 0 0 0 0
3 0.2 30 0 0 0 0 0
4 0.2 40 0 0 0 0 0
5 0.2 50 0 0 0 0 0
6 0.2 60 0 0 0 0 0
7 0.2 70 0 0 0 0 0
8 0.2 80 0 0 0 0 0
9 0.2 90 0 0 0 0 0
10 0.2 100 0 0 0 0 0

BIN
aruco_pose/test/map.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,13 @@
import rospy
import pytest
from visualization_msgs.msg import MarkerArray as VisMarkerArray
@pytest.fixture
def node():
return rospy.init_node('aruco_pose_test', anonymous=True)
def test_node_failure(node):
with pytest.raises(rospy.exceptions.ROSException):
rospy.wait_for_message('aruco_map/visualization', VisMarkerArray, timeout=5)

View File

@@ -0,0 +1,14 @@
<launch>
<node pkg="nodelet" type="nodelet" name="nodelet_manager" args="manager"/>
<node name="aruco_map" pkg="nodelet" type="nodelet" args="load aruco_pose/aruco_map nodelet_manager" clear_params="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"/>
<param name="type" value="map"/>
<param name="map" value="$(find aruco_pose)/test/test_node_failure.txt"/>
</node>
<param name="test_module" value="$(find aruco_pose)/test/test_node_failure.py"/>
<test test-name="test_node_failure" pkg="ros_pytest" type="ros_pytest_runner"/>
</launch>

View File

@@ -0,0 +1,4 @@
# Any garbage data (pretty much anything apart from a comment starting with a hash starting
# with a hash sign or a number) will be interpreted as garbage data; the node should fail
# after reading it.
// Don't try to put your comments this way, it will kill your node!

View File

@@ -0,0 +1,13 @@
import rospy
import pytest
from visualization_msgs.msg import MarkerArray as VisMarkerArray
@pytest.fixture
def node():
return rospy.init_node('aruco_pose_test_empty_map', anonymous=True)
def test_empty_map(node):
markers = rospy.wait_for_message('aruco_map/visualization', VisMarkerArray, timeout=5)
assert len(markers.markers) == 0

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