Compare commits

...

156 Commits
v0.6 ... v0.9

Author SHA1 Message Date
Oleg Kalachev
8dc4e6e0b9 docs 2018-08-19 19:07:49 +03:00
Oleg Kalachev
360ce5c77b docs: little improvements 2018-08-19 19:05:34 +03:00
Oleg Kalachev
4b6d630f5c docs: little improvements 2018-08-19 19:01:39 +03:00
Oleg Kalachev
47d4b3d8a8 docs: little improvements 2018-08-19 18:58:12 +03:00
Oleg Kalachev
162d9d05cc rc: use web for statustext notifications 2018-08-18 00:41:12 +03:00
Oleg Kalachev
4f114184bf Improvements to selfcheck node 2018-08-17 18:03:51 +03:00
Oleg Kalachev
810e44563c docs: small fixes 2018-08-15 21:14:59 +03:00
Oleg Kalachev
704aaf163c docs: add mavlink packet structure example 2018-08-15 21:07:16 +03:00
Smirnov Artem
55988650a6 Fix links 2018-08-13 22:55:24 +03:00
Smirnov Artem
eb499512ee docs: Fix links 2018-08-13 22:45:02 +03:00
Smirnov Artem
794310550c Update README.md 2018-08-13 21:19:14 +03:00
Oleg Kalachev
280db083b4 image: build clever package in Release mode 2018-08-13 16:50:10 +03:00
Oleg Kalachev
d5353a5bef docs: small fix 2018-08-11 05:30:04 +03:00
Oleg Kalachev
fc428d45b9 Add pymavlink library 2018-08-11 05:16:01 +03:00
Oleg Kalachev
19181facdb docs: small fixes 2018-08-11 05:09:21 +03:00
Oleg Kalachev
8813fce63f docs: small fixes 2018-08-11 05:06:51 +03:00
Oleg Kalachev
ac8090ae8b docs: small improvement 2018-08-11 00:38:55 +03:00
Oleg Kalachev
53e644a5f7 docs: add some capitalization info to markdownlint config 2018-08-10 22:20:40 +03:00
Oleg Kalachev
a325156e71 docs: add markdownlint config 2018-08-10 22:10:04 +03:00
Oleg Kalachev
05e1875eec docs: small fix 2018-08-10 21:15:25 +03:00
Oleg Kalachev
98d1ad8494 docs: small changes to ros.md 2018-08-10 21:14:54 +03:00
Oleg Kalachev
ef6b8727b9 docs: add info on /etc/clever_version file 2018-08-10 19:19:25 +03:00
Andrei Korigodski
d7ced0f9c4 docs: fix typo in ros.md 2018-08-10 18:41:18 +03:00
Oleg Kalachev
d76ef207fe Rough attempt to disable glossary links 2018-08-10 18:27:55 +03:00
Oleg Kalachev
fdf6eadfcd docs: disable glossary (attempt #2) 2018-08-10 18:10:16 +03:00
Oleg Kalachev
4e4f02404f Disable glossary links 2018-08-10 17:50:39 +03:00
Oleg Kalachev
42c942514f docs: add glossary 2018-08-10 17:27:38 +03:00
Oleg Kalachev
a6b0ac43e9 docs: small fixes 2018-08-10 01:21:43 +03:00
Oleg Kalachev
0893eb85bc docs: add some info on ROS 2018-08-10 01:17:48 +03:00
Oleg Kalachev
e817e3c7a5 docs: add some links 2018-08-10 00:39:27 +03:00
Oleg Kalachev
32f98fa70e docs: small fixes 2018-08-09 23:25:44 +03:00
Oleg Kalachev
66bdffc747 docs: add some info about MAVLink protocol 2018-08-09 22:59:45 +03:00
Oleg Kalachev
5d353125d2 docs: add some useful snippets 2018-08-09 22:59:45 +03:00
Smirnov Artem
7f2d4344e3 image_builder: fix doc 2018-08-09 13:18:57 +03:00
Oleg Kalachev
4736871524 rc: todo 2018-08-09 03:48:38 +03:00
Oleg Kalachev
bcd88d6d4d rc: fix low battery notification throttling 2018-08-09 03:48:21 +03:00
Oleg Kalachev
8ffe74b772 selfcheck: some todos 2018-08-06 20:33:12 +03:00
Oleg Kalachev
57ae4c304f Add experimental selfcheck node 2018-08-06 20:28:46 +03:00
Smirnov Artem
8be77ab7d9 image_builder: don't remove build-dir in catkin_ws 2018-08-06 16:56:19 +03:00
Oleg Kalachev
8c193b913f docs: fix params files links 2018-08-06 14:36:13 +03:00
Oleg Kalachev
4fac517a1e rc: fake GCS heartbeats to make PX4 send STATUSTEXT messages 2018-08-06 01:59:14 +03:00
Oleg Kalachev
4f7061351f rc: update clever logo 2018-08-02 20:29:29 +03:00
Oleg Kalachev
decc5ecae6 Force gitbook update 2018-07-31 14:01:01 +03:00
Oleg Kalachev
f06fae6885 docs: add link to App Store (RC) 2018-07-31 13:52:44 +03:00
Artem Smirnov
8d46f51c66 image_builder: add service symlink to /lib/systemd/system 2018-07-27 13:23:02 +03:00
Oleg Kalachev
601ef0848d rc: use /mavros/statustext/recv topic for STATUSTEXT messages 2018-07-25 23:01:52 +03:00
Oleg Kalachev
3b0dd46ca6 Decrease conn/timeout to 8 seconds 2018-07-25 15:40:38 +03:00
Oleg Kalachev
16b2e1903a Fix udp and udp-b bridge settings 2018-07-25 15:40:38 +03:00
Smirnov Artem
36d7a95d34 Merge pull request #58 from urpylka/rm_mount_point
image_builder: fix pack 4
2018-07-25 14:33:11 +04:00
Artem Smirnov
1d82e195ec image_builder: add checkout to GWBT_REF 2018-07-25 12:55:18 +03:00
Artem Smirnov
78cae0c69a image_builder: fix vars syntax 2018-07-25 12:55:18 +03:00
Oleg Kalachev
2b46ee27f2 docs: small fix 2018-07-25 12:26:43 +03:00
Oleg Kalachev
de44400749 Merge branch 'master' of github.com:CopterExpress/clever 2018-07-25 12:01:47 +03:00
Oleg Kalachev
55e40bd6c3 docs: add mobile rc page [wip] 2018-07-25 12:01:38 +03:00
Artem Smirnov
124950d7e4 image_builder: remove MOUNT_POINT
I changed CONST-PATH to dynamic dir by mktemp
2018-07-24 19:05:04 +03:00
Smirnov Artem
199104ca83 Merge pull request #57 from urpylka/master
image_builder: fix pack
2018-07-24 16:33:19 +04:00
Artem Smirnov
e5552e0a4b image_builder: replace old archive 2018-07-24 15:16:56 +03:00
Oleg Kalachev
bfb0aa7961 Force gitbook update 2018-07-16 23:34:00 +03:00
Smirnov Artem
44d83bdcf8 Merge pull request #56 from Yuliya1404/master
added description of project and links to telegtam chats
2018-07-11 22:41:12 +03:00
Yuliya1404
d960e57cf9 docs: small fix 2018-07-11 15:47:38 +03:00
Yuliya1404
30ec03ef4d docs: added description of project and links on telegram chat 2018-07-11 15:28:34 +03:00
Smirnov Artem
c2c27b1577 docs: added build status icon 2018-07-08 15:09:51 +03:00
Oleg Kalachev
c0449ccf59 docs update 2018-07-07 17:58:33 +03:00
Oleg Kalachev
ea933ce3d1 docs: small fix 2018-07-07 17:57:02 +03:00
Oleg Kalachev
327666385b docs: small fix 2018-07-07 17:55:54 +03:00
Oleg Kalachev
8ea511b293 docs: firmware.md fixes 2018-07-07 17:54:09 +03:00
Oleg Kalachev
c510fe5cf0 Merge branch 'master' of github.com:CopterExpress/clever 2018-07-07 17:50:47 +03:00
Oleg Kalachev
dab70937f5 docs: add article about px4 firmware uploading 2018-07-07 17:50:42 +03:00
Smirnov Artem
fec4859cfe image_builder: enable the lirc-rpi module for uart 2018-07-06 22:10:58 +03:00
Oleg Kalachev
63ecc3b713 image: fix libpoco-dev version 2018-07-06 22:02:53 +03:00
Oleg Kalachev
d3a08c60d7 Merge pull request #54 from Yuliya1404/master
docs: changed metod materials
2018-07-06 17:25:51 +03:00
Oleg Kalachev
322eb1e255 image: add tcpdump and libpoco-dev 2018-07-06 04:37:00 +03:00
Oleg Kalachev
22d4f3c3e7 docs: small fixes 2018-07-05 03:07:52 +03:00
Oleg Kalachev
008750b1d9 docs: add systemd/roslaunch documentation 2018-07-05 03:03:16 +03:00
Oleg Kalachev
506767f32f docs: add some info to gps article 2018-07-05 02:50:45 +03:00
Oleg Kalachev
aaa673de92 simple_offboard: add global alt to get_telemetry service 2018-07-05 02:50:35 +03:00
Oleg Kalachev
43237d8ff4 GCS bridges config and documentation improvements 2018-07-05 02:10:53 +03:00
Oleg Kalachev
9681fc9a87 Merge branch 'master' of github.com:CopterExpress/clever 2018-07-04 20:29:45 +03:00
Oleg Kalachev
76c3e96f76 Enable mavros respawn by default 2018-07-04 20:26:47 +03:00
shish1404
1e66afa6a4 docs: changed test 2018-06-29 22:14:46 +03:00
shish1404
41c59e8e49 docs: added videos 2018-06-29 18:49:22 +03:00
shish1404
225e3d7936 docs: changed label 2018-06-29 18:48:53 +03:00
Artem Smirnov
204dd97b00 image_builder: remove date from image name 2018-06-26 19:49:42 +03:00
Artem Smirnov
27bfecc737 image_builder: add information about new partitions 2018-06-25 19:33:11 +03:00
Smirnov Artem
8cdb131a19 Merge pull request #53 from urpylka/master
image_builder: fix pack
2018-06-25 14:53:51 +03:00
Artem Smirnov
c9042588f0 image_builder: enable shrinker by default 2018-06-25 13:28:44 +03:00
Oleg Kalachev
342eaec49a gitbook: fix ya-metrika 2018-06-25 03:13:17 +03:00
Oleg Kalachev
77b3d28e3b gitbook: add ya-metrika 2018-06-25 03:00:04 +03:00
Smirnov Artem
357b38b5e7 image_builder: add text for /etc/fstab 2018-06-23 21:12:06 +03:00
Artem Smirnov
a99a1c7540 image_builder: change PARTUUID to /dev/mmcblk0p2 2018-06-23 20:44:30 +03:00
Artem Smirnov
6742ba332a image_builder: add fixed version for deb-packages 2018-06-22 15:31:26 +03:00
Smirnov Artem
c5916fea7c Merge pull request #52 from urpylka/master
image_builder fix-pack
2018-06-21 23:44:08 +03:00
Smirnov Artem
7a4958f8e9 Merge branch 'master' into master 2018-06-21 23:43:35 +03:00
Artem Smirnov
b71a96faee image_builder: add param for discover packages 2018-06-21 21:54:47 +03:00
Artem Smirnov
24e79f0169 image_builder: add autosizer.sh to build.Jenkinsfile 2018-06-21 18:24:02 +03:00
Artem Smirnov
76e887407a image_builder: add argument for set FREE SPACE 2018-06-21 18:24:02 +03:00
Artem Smirnov
0d0c8e54f4 image_builder: add image-shrinker 2018-06-21 18:24:02 +03:00
Artem Smirnov
06a01f7e32 image_builder: return devel dir to catkin_ws
needed for roscd
2018-06-21 18:24:02 +03:00
Artem Smirnov
f564d20c5b image_builder: add fixed rosinstall file 2018-06-21 18:24:02 +03:00
Artem Smirnov
85afded6b4 image_builder: move install mjpg-streamer to soft-install 2018-06-19 15:51:26 +03:00
Artem Smirnov
7e84853c37 image_builder: small echo fix 2018-06-19 13:39:37 +03:00
Artem Smirnov
c3c324158f image_builder: fix for add environment 2018-06-18 20:51:29 +03:00
Artem Smirnov
1e2fd40c05 image_builder: remove build & devel dirs 2018-06-18 20:42:47 +03:00
Artem Smirnov
6a7f78a218 image_builder: add "yes" flag 2018-06-18 20:42:47 +03:00
Smirnov Artem
0b637e56d7 image_builder: change param to const 2018-06-18 20:42:47 +03:00
Artem Smirnov
63f44a5a3f image_builder: remove unused code from image_config.sh 2018-06-18 20:42:47 +03:00
Artem Smirnov
83ce14e31b image_builder: merge arguments in resize_fs 2018-06-18 20:42:47 +03:00
Artem Smirnov
8162357ce6 image_builder: catkin_init_workspace not needed 2018-06-18 20:42:47 +03:00
Oleg Kalachev
ba0e9cf9c5 Change udp connection timeout to 10 2018-06-18 19:40:34 +03:00
Oleg Kalachev
8d1072d97d docs: add info about virtual joustick in qgroundcontrol 2018-06-14 02:04:22 +03:00
Oleg Kalachev
ffd4fdf2dc docs: add illustration to listener command usage 2018-06-14 01:01:17 +03:00
Oleg Kalachev
d279f04a1f docs: more 2018-06-13 16:39:48 +03:00
Oleg Kalachev
77e8c858a0 docs: another fixes 2018-06-13 16:34:57 +03:00
Oleg Kalachev
f6edf15011 docs: little fixes 2018-06-13 16:33:52 +03:00
Oleg Kalachev
b50c34b19c docs: add flight logs article 2018-06-13 16:29:55 +03:00
Oleg Kalachev
874f206e2a Somes fixes to iOS app 2018-06-09 20:33:40 +03:00
Oleg Kalachev
fd262fdb6a Add .editorconfig 2018-06-09 20:26:18 +03:00
Oleg Kalachev
2cb17985d4 Merge branch 'master' of github.com:CopterExpress/clever 2018-06-09 19:21:11 +03:00
Oleg Kalachev
2daa6f108a Update to iOS app 2018-06-09 16:12:57 +03:00
Oleg Kalachev
2e0d92c0d5 image: restore .vimrc 2018-06-09 03:41:41 +03:00
Oleg Kalachev
1a0d61af7c docs: small fixes 2018-06-09 02:28:45 +03:00
Oleg Kalachev
eb9fc6140b Merge branch 'master' of github.com:CopterExpress/clever 2018-06-08 20:14:43 +03:00
Oleg Kalachev
b0d72030fa docs: working on rc docs 2018-06-08 20:13:42 +03:00
Oleg Kalachev
db27d422ae docs: working on rc docs 2018-06-08 20:06:44 +03:00
Oleg Kalachev
d6ec597fe2 docs: working on rc docs 2018-06-08 00:52:12 +03:00
Oleg Kalachev
0fe319f430 Set udp bridge connection timeout to 20 2018-06-06 18:17:24 +03:00
Oleg Kalachev
2616b49e82 Merge branch 'master' of github.com:CopterExpress/clever 2018-06-06 18:09:47 +03:00
Oleg Kalachev
c2fd26db56 Support mavros udp-pb bridge 2018-06-06 18:09:38 +03:00
Artem Smirnov
71bd59fe3d image_builder: change "catkin init" to "catkin_init_workspace" 2018-06-05 17:41:38 +03:00
Oleg Kalachev
5b84fe63dd docs: remove disquss 2018-06-03 15:11:24 +03:00
Smirnov Artem
40782063c4 image_builder: Added GWBT_URL parameter
Added GWBT_URL parameter for automatic insert that to field on manual run of build
2018-06-02 14:55:53 +03:00
Smirnov Artem
580eb2400c docs: update wifi.md 2018-05-31 17:12:15 +03:00
Smirnov Artem
4666e443cb Update microsd_images.md 2018-05-31 16:54:41 +03:00
Smirnov Artem
d52c1701e4 Merge pull request #49 from urpylka/wifi_doc
docs: add network & wifi conf
2018-05-31 16:24:50 +03:00
Smirnov Artem
4a543c75f7 image_builder: use dnsmasq as default dhcp-server (#48) 2018-05-31 16:22:45 +03:00
Smirnov Artem
0b15f4ffd5 Update network.md 2018-05-31 16:16:06 +03:00
Oleg Kalachev
0f6e24d07f Changes to network.md 2018-05-31 16:15:51 +03:00
Artem Smirnov
7110ef1420 docs: add network & wifi conf 2018-05-31 16:04:35 +03:00
Oleg Kalachev
a56cef65d5 docs: modes changes 2018-05-30 16:35:09 +03:00
Oleg Kalachev
f58be1ff6f docs: small change 2018-05-30 16:11:07 +03:00
Oleg Kalachev
b1a788864c docs: some styling 2018-05-30 16:09:06 +03:00
Oleg Kalachev
fe468d911b docs: small change 2018-05-30 16:05:45 +03:00
Oleg Kalachev
ef8e1c0478 docs: some styling 2018-05-30 16:04:14 +03:00
Oleg Kalachev
710c4fb33e docs: add some units 2018-05-30 15:56:18 +03:00
Oleg Kalachev
3ef8656bcd docs: add link to px4 releases page 2018-05-30 15:50:53 +03:00
Oleg Kalachev
251e15f503 docs: add some units 2018-05-30 15:44:03 +03:00
Smirnov Artem
eb2f9d9c2b docs: add UDP support to GCS-bridge (#47) 2018-05-18 18:12:54 +03:00
Oleg Kalachev
dfcd3ea693 Merge branch 'master' of github.com:CopterExpress/clever 2018-05-13 23:01:14 +03:00
Oleg Kalachev
7260128dfd docs: note about yaw=NaN 2018-05-13 23:01:06 +03:00
Oleg Kalachev
d4e783c96f snippets: get_distance_global 2018-05-13 20:10:41 +03:00
Oleg Kalachev
c57a342053 Fix to readme 2018-05-12 17:03:25 +03:00
Oleg Kalachev
9ed9af2d04 Some fixes to readme 2018-05-12 17:02:48 +03:00
Oleg Kalachev
295b9c98d1 docs: rework images article 2018-05-12 16:58:54 +03:00
Oleg Kalachev
8f4de0e08f Merge branch 'master' of github.com:CopterExpress/clever 2018-05-10 22:33:16 +03:00
Oleg Kalachev
8f53301b79 simple_offboard: correct axes for calculating yaw for setpoints 2018-05-10 22:32:45 +03:00
Oleg Kalachev
6372ef8c22 simple_offboard: Tait-Bryan z-y-x angles for pitch, roll and yaw 2018-05-10 22:31:56 +03:00
101 changed files with 3543 additions and 1799 deletions

13
.editorconfig Normal file
View File

@@ -0,0 +1,13 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
[*.{py,cpp,h,swift,launch}]
indent_style = space
indent_size = 4
[*.{js,html}]
indent_style = tab

22
.markdownlint.json Normal file
View File

@@ -0,0 +1,22 @@
{
"MD003": false,
"MD013": false,
"MD033": false,
"MD034": false,
"MD044": {
"names": [
"MAVLink",
"ROS",
"Python",
"C++",
"PX4",
"WireShark",
"Wi-Fi",
"Raspberry Pi",
"PixHawk",
"PixRacer",
"ArUco"
],
"code_blocks": false
}
}

View File

@@ -4,16 +4,17 @@
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 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 [Robokross-2016](https://www.youtube.com/watch?v=dGbDaz_VmYU) and [Robokross-2017](https://youtu.be/AQnd2CRczbQ) competitions and many others. 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:** **The main documentation in Russian is available [on our Gitbook](https://clever.copterexpress.com/).**
**https://copterexpress.gitbooks.io/clever/content/**
Use it to learn how to assemble, configure, pilot and program autonomous CLEVER drone. Use it to learn how to assemble, configure, pilot and program autonomous CLEVER drone.
## Preconfigured RPi 3 image ## Preconfigured RPi 3 image
Preconfigured image for Raspberry Pi 3 with installed and configured software, ready to fly, is available [here](https://copterexpress.gitbooks.io/clever/content/docs/microsd_images.html). **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/)
Image includes: Image includes:
@@ -24,7 +25,7 @@ Image includes:
* mavros * mavros
* CLEVER software bundle for autonomous drone control * CLEVER software bundle for autonomous drone control
API description in Russian for autonomous flights is available [here](https://copterexpress.gitbooks.io/clever/simple_offboard.html). API description (in Russian) for autonomous flights is available [on GitBook](https://copterexpress.gitbooks.io/clever/simple_offboard.html).
## Manual installation ## Manual installation

View File

@@ -9,6 +9,5 @@ target 'cleverrc' do
# Pods for cleverrc # Pods for cleverrc
pod 'SwiftSocket', '~> 2.0' pod 'SwiftSocket', '~> 2.0'
pod 'NotificationBannerSwift'
end end

View File

@@ -139,7 +139,7 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastSwiftUpdateCheck = 0920; LastSwiftUpdateCheck = 0920;
LastUpgradeCheck = 0920; LastUpgradeCheck = 0930;
ORGANIZATIONNAME = "Copter Express"; ORGANIZATIONNAME = "Copter Express";
TargetAttributes = { TargetAttributes = {
7C51653C20139237004D1F4D = { 7C51653C20139237004D1F4D = {
@@ -294,6 +294,7 @@
CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES; CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
@@ -301,6 +302,7 @@
CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -351,6 +353,7 @@
CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES; CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
@@ -358,6 +361,7 @@
CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -1,95 +1,111 @@
{ {
"images" : [ "images" : [
{ {
"idiom" : "iphone",
"size" : "20x20", "size" : "20x20",
"idiom" : "iphone",
"filename" : "cleverrc40.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "iphone",
"size" : "20x20", "size" : "20x20",
"idiom" : "iphone",
"filename" : "clever60.png",
"scale" : "3x" "scale" : "3x"
}, },
{ {
"idiom" : "iphone",
"size" : "29x29", "size" : "29x29",
"idiom" : "iphone",
"filename" : "clever58.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "iphone",
"size" : "29x29", "size" : "29x29",
"idiom" : "iphone",
"filename" : "clever87.png",
"scale" : "3x" "scale" : "3x"
}, },
{ {
"idiom" : "iphone",
"size" : "40x40", "size" : "40x40",
"idiom" : "iphone",
"filename" : "clever80.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "iphone",
"size" : "40x40", "size" : "40x40",
"idiom" : "iphone",
"filename" : "clever120.png",
"scale" : "3x" "scale" : "3x"
}, },
{ {
"size" : "60x60", "size" : "60x60",
"idiom" : "iphone", "idiom" : "iphone",
"filename" : "cleverios180.png", "filename" : "clever120-1.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"size" : "60x60", "size" : "60x60",
"idiom" : "iphone", "idiom" : "iphone",
"filename" : "cleverios180-1.png", "filename" : "clever180-1.png",
"scale" : "3x" "scale" : "3x"
}, },
{ {
"idiom" : "ipad",
"size" : "20x20", "size" : "20x20",
"idiom" : "ipad",
"filename" : "clever20.png",
"scale" : "1x" "scale" : "1x"
}, },
{ {
"idiom" : "ipad",
"size" : "20x20", "size" : "20x20",
"idiom" : "ipad",
"filename" : "clever40.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "ipad",
"size" : "29x29", "size" : "29x29",
"idiom" : "ipad",
"filename" : "clever29.png",
"scale" : "1x" "scale" : "1x"
}, },
{ {
"idiom" : "ipad",
"size" : "29x29", "size" : "29x29",
"idiom" : "ipad",
"filename" : "clever58-1.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "ipad",
"size" : "40x40", "size" : "40x40",
"idiom" : "ipad",
"filename" : "clever40-1.png",
"scale" : "1x" "scale" : "1x"
}, },
{ {
"idiom" : "ipad",
"size" : "40x40", "size" : "40x40",
"idiom" : "ipad",
"filename" : "clever80-1.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "ipad",
"size" : "76x76", "size" : "76x76",
"idiom" : "ipad",
"filename" : "clever76.png",
"scale" : "1x" "scale" : "1x"
}, },
{ {
"idiom" : "ipad",
"size" : "76x76", "size" : "76x76",
"idiom" : "ipad",
"filename" : "clever152.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "ipad",
"size" : "83.5x83.5", "size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "clever167.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "ios-marketing",
"size" : "1024x1024", "size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "clever1024.png",
"scale" : "1x" "scale" : "1x"
} }
], ],

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 659 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 867 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 867 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 867 B

View File

@@ -5,7 +5,7 @@
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string> <string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>Clever RC</string> <string>CLEVER RC</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string> <string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
@@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.0</string> <string>1.0</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1</string> <string>5</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>UILaunchStoryboardName</key> <key>UILaunchStoryboardName</key>

View File

@@ -10,12 +10,13 @@ import UIKit
import WebKit import WebKit
import SwiftSocket import SwiftSocket
import NotificationBannerSwift import NotificationBannerSwift
import AudioToolbox.AudioServices
class ViewController: UIViewController, WKScriptMessageHandler { class ViewController: UIViewController, WKScriptMessageHandler {
@IBOutlet weak var webView: WKWebView! @IBOutlet weak var webView: WKWebView!
let impactGenerator = UIImpactFeedbackGenerator(style: .medium) let impactGenerator = UIImpactFeedbackGenerator(style: .medium)
let notificationGenerator = UINotificationFeedbackGenerator() let notificationGenerator = UINotificationFeedbackGenerator()
let udpSocket = UDPClient(address:"255.255.255.255", port: 35602) let udpSocket = UDPClient(address: "255.255.255.255", port: 35602)
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
@@ -24,6 +25,7 @@ class ViewController: UIViewController, WKScriptMessageHandler {
UIApplication.shared.isIdleTimerDisabled = true UIApplication.shared.isIdleTimerDisabled = true
// Setup webview event handlers // Setup webview event handlers
webView.scrollView.bounces = false;
webView.configuration.userContentController.add(self, name: "control") webView.configuration.userContentController.add(self, name: "control")
webView.configuration.userContentController.add(self, name: "controlStart") webView.configuration.userContentController.add(self, name: "controlStart")
webView.configuration.userContentController.add(self, name: "lowBattery") webView.configuration.userContentController.add(self, name: "lowBattery")
@@ -56,18 +58,28 @@ class ViewController: UIViewController, WKScriptMessageHandler {
} else if (message.name == "lowBattery") { } else if (message.name == "lowBattery") {
// Got low battery notification // Got low battery notification
print("Low battery notification") print("Low battery notification")
notificationGenerator.notificationOccurred(.warning) tapticNotify()
} else if (message.name == "notification") { } else if (message.name == "notification") {
// Got notification message // Got notification message
print(message) print(message)
let m = message.body as! NSDictionary; tapticNotify()
let level = m["level"] as! Int }
if level == 4 { }
let banner = NotificationBanner(title: m["msg"] as! String, style: .warning)
banner.show() func tapticNotify() {
} else { if let feedbackSupportLevel = UIDevice.current.value(forKey: "_feedbackSupportLevel") as? Int {
let banner = NotificationBanner(title: m["msg"] as! String, style: .danger) switch feedbackSupportLevel {
banner.show() case 2:
// 2nd Generation Taptic Engine w/ Haptic Feedback (iPhone 7/7+)
notificationGenerator.notificationOccurred(.warning)
case 1:
// 1st Generation Taptic Engine (iPhone 6S/6S+)
let peek = SystemSoundID(1519)
AudioServicesPlaySystemSound(peek)
case 0:
// No Taptic Engine
break
default: break
} }
} }
} }

View File

@@ -1,84 +1,57 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" <svg
viewBox="0 0 52.5 52.5" enable-background="new 0 0 52.5 52.5" xml:space="preserve"> xmlns:dc="http://purl.org/dc/elements/1.1/"
<g> xmlns:cc="http://creativecommons.org/ns#"
<path fill="white" fill-opacity="0.5" d="M35.7,17.2c0.3-0.3,0.5-0.7,0.7-1.1c0.2-0.4,0.3-0.9,0.3-1.4c0-0.5-0.1-1-0.3-1.4c-0.2-0.5-0.5-0.9-0.8-1.3 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
c-0.4-0.4-0.9-0.7-1.4-0.9c-0.6-0.2-1.2-0.3-1.8-0.2c-0.5,0.1-0.9,0.2-1.3,0.4c-0.2,0.1-0.4,0.3-0.6,0.4L30.2,12 xmlns:svg="http://www.w3.org/2000/svg"
c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.3,0.2-0.4,0.2c-0.1,0.1-0.3,0.1-0.4,0.2c-0.1,0-0.2,0.1-0.4,0.1c-0.1,0-0.2,0-0.3,0 xmlns="http://www.w3.org/2000/svg"
c-0.6,0.1-1.3-0.1-1.9-0.4c-0.2-0.1-0.4-0.2-0.6-0.4c0,0-0.1-0.1-0.1-0.1c0,0-0.1-0.1-0.1-0.1c0,0,0,0-0.1-0.1 viewBox="0 0 69.988266 69.987198"
c-0.1-0.1-0.1-0.2-0.1-0.3c0,0,0,0,0-0.1l0-6.5c-0.5-0.6-1.1-1.1-1.7-1.6c-0.9-0.7-1.9-1.4-3-1.8c-0.9-0.4-1.8-0.7-2.7-1 height="69.987198"
c-0.9-0.2-1.7-0.3-2.6-0.4c-0.9-0.1-1.8,0-2.7,0.1c-0.7,0.1-1.5,0.2-2.2,0.5C9.4,0.9,8.1,1.5,7,2.2C6.2,2.7,5.4,3.3,4.7,3.9 width="69.988266"
C4,4.6,3.4,5.3,2.8,6c-0.5,0.7-1,1.4-1.3,2.2C1.1,9,0.8,9.8,0.6,10.6c-0.2,0.7-0.4,1.4-0.4,2.1C0,13.7,0,14.6,0,15.6 xml:space="preserve"
c0,0.8,0.2,1.7,0.4,2.5c0.2,0.9,0.5,1.7,0.8,2.5C1.8,21.8,2.5,23,3.4,24c0.3,0.4,0.7,0.8,1,1.1c0.2,0.2,0.3,0.3,0.5,0.5H11 id="svg2"
c0.1-0.1,0.1-0.2,0.1-0.2c0-0.1,0.1-0.1,0.1-0.2c0-0.1,0.1-0.1,0.1-0.2c0.1-0.4,0.2-0.8,0.1-1.1c0-0.1,0-0.1,0-0.2 version="1.1"><metadata
c0-0.1-0.1-0.1-0.1-0.2c0-0.1-0.1-0.2-0.2-0.2c0,0-0.1-0.1-0.1-0.1l0,0c0,0,0-0.1-0.1-0.1c0,0,0,0,0,0l-0.1-0.1 id="metadata8"><rdf:RDF><cc:Work
c-0.1-0.1-0.2-0.3-0.3-0.4c-0.2-0.3-0.4-0.7-0.5-1c-0.1-0.3-0.2-0.7-0.3-1c-0.1-0.6-0.1-1.1,0-1.7c0.1-0.5,0.3-1,0.5-1.5 rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
c0.3-0.5,0.6-0.9,1-1.3c0.4-0.4,0.9-0.7,1.4-0.9c0.6-0.2,1.2-0.4,1.8-0.4c0.7,0,1.3,0.1,1.9,0.3c0.7,0.2,1.3,0.6,1.8,1.1 rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
c0.5,0.5,1,1.1,1.3,1.8c0.2,0.4,0.3,0.7,0.3,1.1c0.1,0.4,0.1,0.8,0.1,1.3c0,0.4-0.1,0.8-0.2,1.1c-0.1,0.3-0.3,0.7-0.4,1 id="defs6"><clipPath
c-0.1,0.2-0.2,0.3-0.3,0.5c0,0.1-0.1,0.1-0.1,0.2l0,0l0,0l0,0.1c0,0,0,0.1-0.1,0.1l-0.1,0.1c0,0-0.1,0.1-0.1,0.1 id="clipPath18"
c-0.1,0.1-0.1,0.1-0.1,0.2c0,0.1-0.1,0.1-0.1,0.2c0,0.1,0,0.1,0,0.2c-0.1,0.3-0.1,0.7,0.1,1.1c0,0.1,0,0.1,0.1,0.2 clipPathUnits="userSpaceOnUse"><path
c0,0.1,0.1,0.1,0.1,0.2c0,0.1,0.1,0.2,0.2,0.3h7.2l0-7.5c0,0,0,0,0-0.1c0-0.1,0-0.1,0.1-0.2c0-0.1,0.1-0.1,0.1-0.2 id="path16"
c0,0,0.1-0.1,0.1-0.1l0.1,0c0.1-0.1,0.2-0.1,0.3-0.2c0.5-0.3,1-0.5,1.6-0.6c0.2,0,0.3,0,0.5,0c0,0,0.1,0,0.1,0c0.1,0,0.1,0,0.2,0 d="M 0,52.49 H 52.491 V 0 H 0 Z" /></clipPath></defs><g
c0.1,0,0.2,0,0.4,0.1c0.3,0.1,0.7,0.2,0.9,0.4c0.1,0.1,0.2,0.1,0.3,0.2c0,0,0.1,0.1,0.1,0.1l0,0l-0.1,0.1c0,0,0,0,0,0l0.1-0.1 transform="matrix(1.3333333,0,0,-1.3333333,0,69.9872)"
l0.2,0.2c0.1,0.1,0.2,0.2,0.4,0.2c0.2,0.1,0.5,0.3,0.8,0.4c0.7,0.2,1.4,0.3,2,0.1c0.4-0.1,0.7-0.2,1.1-0.4 id="g10"><g
C35.1,17.7,35.4,17.5,35.7,17.2z"/> id="g12"><g
<g> clip-path="url(#clipPath18)"
<polygon points="41.6,29.7 41.6,29.7 41.6,29.6 41.6,29.6 "/> id="g14"><g
<path fill="white" fill-opacity="0.5" d="M28.6,49.2c0.9,0.8,2,1.4,3,1.9c0.8,0.4,1.7,0.7,2.6,0.9c0.9,0.2,1.8,0.4,2.7,0.4c0.9,0.1,1.9,0,2.8-0.1 transform="translate(35.6531,35.3361)"
c0.7-0.1,1.4-0.2,2.1-0.4c1.3-0.4,2.5-0.9,3.6-1.6c0.8-0.5,1.6-1.1,2.3-1.7c0.7-0.7,1.4-1.4,2-2.2c0.5-0.6,0.9-1.3,1.2-2 id="g20"><path
c0.4-0.8,0.7-1.7,1-2.5c0.2-0.6,0.3-1.3,0.4-1.9c0.1-1,0.2-2,0.1-3c0-0.8-0.2-1.6-0.3-2.4c-0.2-0.9-0.5-1.7-0.8-2.6 id="path22"
c-0.5-1.2-1.2-2.4-2.1-3.4c-0.3-0.4-0.6-0.8-1-1.1l-0.5-0.5h-6.1l-0.2,0.3c0,0.1-0.1,0.1-0.1,0.2c0,0.1-0.1,0.1-0.1,0.2 style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
c-0.1,0.4-0.2,0.8-0.1,1.1c0,0.1,0,0.1,0,0.2c0,0.1,0.1,0.1,0.1,0.2c0,0.1,0.1,0.2,0.2,0.3c0,0,0.1,0.1,0.1,0.1l0,0 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
c0,0,0,0.1,0.1,0.1l0,0.1l0.1-0.1l0,0l0,0l0,0l0,0l0,0l0.1,0.1c0.2,0.2,0.3,0.4,0.5,0.7c0.3,0.5,0.5,1,0.6,1.5 transform="translate(41.5882,22.8337)"
c0.1,0.7,0.1,1.5,0,2.2c-0.2,0.6-0.4,1.2-0.8,1.8c-0.3,0.4-0.7,0.8-1.1,1.1c-0.4,0.3-0.8,0.5-1.3,0.7c-0.5,0.2-1,0.3-1.5,0.3 id="g24"><path
c-0.5,0-0.9,0-1.3-0.1c-0.5-0.1-1-0.3-1.4-0.6c-0.5-0.3-1-0.7-1.3-1.1c-0.4-0.5-0.7-1-0.9-1.6c-0.2-0.6-0.3-1.3-0.2-2 id="path26"
c0-0.4,0.1-0.7,0.2-1c0.1-0.4,0.3-0.8,0.5-1.1c0.1-0.2,0.2-0.3,0.3-0.5c0-0.1,0.1-0.1,0.1-0.2l0.1,0c0,0,0,0,0,0l-0.1-0.1l0.1-0.1 style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
c0,0,0-0.1,0.1-0.1l0.1-0.1c0,0,0.1-0.1,0.1-0.1c0-0.1,0.1-0.1,0.1-0.2c0-0.1,0.1-0.1,0.1-0.2c0-0.1,0-0.1,0-0.2 d="M 0,0 V 0 L 0.053,0.044 0.013,0.018 Z" /></g><g
c0.1-0.3,0.1-0.7-0.1-1.1c0-0.1,0-0.1-0.1-0.2c0-0.1-0.1-0.2-0.1-0.2c0-0.1-0.1-0.2-0.1-0.2h-7.2l0,7.5c0,0,0,0,0,0.1 transform="translate(28.5515,3.2736)"
c0,0.1-0.1,0.2-0.1,0.3c0,0,0,0.1-0.1,0.1c0,0-0.1,0.1-0.1,0.1c0,0,0,0-0.1,0c-0.1,0.1-0.3,0.2-0.4,0.3c-0.6,0.4-1.3,0.6-1.9,0.6 id="g28"><path
c-0.1,0-0.2,0-0.3,0c-0.1,0-0.2,0-0.3,0c-0.4-0.1-0.7-0.2-1-0.4c-0.1-0.1-0.2-0.2-0.3-0.2c0,0-0.1-0.1-0.1-0.1h0l0,0l0,0 id="path30"
c0,0-0.1-0.1-0.1-0.1L22,34.8c-0.2-0.2-0.4-0.3-0.6-0.4c-0.4-0.2-0.9-0.3-1.3-0.4c-0.3,0-0.7,0-1,0.1c-0.3,0.1-0.5,0.1-0.8,0.2 style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
c-0.5,0.2-1,0.5-1.3,0.9c-0.3,0.4-0.6,0.8-0.8,1.3C16,37,15.9,37.5,15.9,38c0,0.5,0.1,0.9,0.3,1.3c0.2,0.4,0.4,0.7,0.7,1 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
c0.3,0.3,0.6,0.5,1,0.7c0.3,0.2,0.7,0.3,1,0.4c0.4,0.1,0.9,0.1,1.4,0c0.2,0,0.5-0.1,0.7-0.2c0.3-0.1,0.5-0.2,0.7-0.4 transform="translate(22.2707,17.571)"
c0.1-0.1,0.2-0.2,0.3-0.3l0.1-0.1l0,0l0,0c0,0,0,0,0,0l0.1-0.1c0.1,0,0.1-0.1,0.2-0.1c0.1-0.1,0.2-0.2,0.3-0.2 id="g32"><path
c0.3-0.2,0.6-0.3,0.9-0.3c0.2,0,0.3,0,0.5,0h0.1c0.2,0,0.3,0,0.5,0c0.5,0.1,1,0.3,1.5,0.6c0.1,0.1,0.2,0.1,0.3,0.2l0.1,0 id="path34"
c0,0,0.1,0.1,0.1,0.1c0,0.1,0.1,0.1,0.1,0.2c0,0.1,0,0.1,0.1,0.2c0,0,0,0,0,0.1l0,0v6.5C27.4,48.2,28,48.7,28.6,49.2z"/> style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
<polygon points="22.3,34.9 22.3,34.9 22.3,34.9 22.3,34.9 "/> d="m 0,0 v -0.008 l 0.011,0.019 v 0 z" /></g><g
</g> transform="translate(40.657,22.3049)"
<g> id="g36"><path
<polygon points="40.7,30.2 40.7,30.2 40.7,30.2 "/> id="path38"
<path fill="white" fill-opacity="0.5" d="M49.2,24c0.7-0.9,1.3-1.8,1.8-2.9c0.4-0.7,0.7-1.5,0.9-2.3c0.2-0.8,0.4-1.7,0.5-2.6c0.2-1.7,0.1-3.4-0.3-5 style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
c-0.3-1.3-0.8-2.6-1.5-3.8c-0.4-0.7-0.9-1.4-1.4-2.1c-0.6-0.7-1.3-1.4-2-2c-0.6-0.5-1.3-1-2-1.4c-0.8-0.4-1.5-0.8-2.3-1.1 d="M 0,0 Z" /></g><g
c-1-0.4-2-0.6-3.1-0.7C39.3,0.1,38.9,0,38.5,0c-0.2,0-0.4,0-0.6,0h-0.1c-0.5,0-0.9,0-1.4,0.1c-0.8,0.1-1.7,0.2-2.5,0.4 transform="translate(49.1867,28.5134)"
c-0.9,0.2-1.7,0.6-2.5,0.9c-0.8,0.4-1.5,0.8-2.2,1.3c-0.6,0.4-1.1,0.9-1.6,1.4c-0.2,0.2-0.5,0.5-0.7,0.7V11 id="g40"><path
c0.1,0.1,0.2,0.1,0.2,0.1c0.1,0,0.1,0.1,0.2,0.1c0.1,0,0.1,0.1,0.2,0.1c0.4,0.1,0.8,0.2,1.1,0.1c0.1,0,0.1,0,0.2,0 id="path42"
c0.1,0,0.1-0.1,0.2-0.1c0.1,0,0.2-0.1,0.3-0.2c0,0,0.1-0.1,0.1-0.1l0,0c0,0,0.1,0,0.1-0.1l0.1-0.1c0.2-0.1,0.3-0.2,0.5-0.3 style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
c0.3-0.2,0.7-0.4,1-0.5c0.3-0.1,0.6-0.2,1-0.2c0.6-0.1,1.1-0.1,1.7,0c0.5,0.1,1,0.3,1.5,0.5c0.5,0.3,0.9,0.6,1.3,1 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>
c0.4,0.4,0.7,0.9,0.9,1.4c0.2,0.6,0.4,1.2,0.4,1.8c0,0.6-0.1,1.3-0.3,1.9c-0.2,0.7-0.6,1.3-1,1.8c-0.5,0.5-1.1,1-1.8,1.3 </g></g></g></svg>
c-0.4,0.1-0.7,0.3-1.1,0.3c-0.4,0.1-0.8,0.1-1.3,0.1c-0.4,0-0.7-0.1-1.1-0.2c-0.4-0.1-0.7-0.3-1-0.5c-0.2-0.1-0.3-0.2-0.5-0.3
c-0.1,0-0.1-0.1-0.2-0.1l-0.1-0.1c0,0-0.1,0-0.1-0.1c0,0-0.1-0.1-0.1-0.1c0,0-0.1-0.1-0.1-0.1c-0.1-0.1-0.1-0.1-0.2-0.1
c-0.1,0-0.1-0.1-0.2-0.1c-0.1,0-0.1,0-0.2,0C28.4,18,28,18,27.6,18.1c-0.1,0-0.1,0-0.2,0.1c-0.1,0-0.2,0.1-0.2,0.1
c-0.1,0-0.2,0.1-0.2,0.1v7.2l7.5,0c0,0,0,0,0.1,0c0.1,0,0.2,0.1,0.3,0.1c0,0,0.1,0,0.1,0.1c0,0,0.1,0.1,0.1,0.1l0.1,0.1
c0.1,0.1,0.2,0.3,0.3,0.4c0.4,0.6,0.6,1.3,0.6,1.9c0,0.1,0,0.2,0,0.3c0,0.1,0,0.2,0,0.3c-0.1,0.4-0.2,0.7-0.4,1
c-0.1,0.1-0.2,0.2-0.2,0.3c0,0-0.1,0.1-0.1,0.1l0,0l0,0l-0.2,0.2c-0.1,0.1-0.2,0.2-0.2,0.3c-0.1,0.2-0.3,0.5-0.3,0.7
c-0.2,0.7-0.3,1.4-0.1,2c0.1,0.4,0.2,0.7,0.4,1.1c0.2,0.4,0.5,0.7,0.8,0.9c0.3,0.3,0.7,0.5,1.1,0.7c0.4,0.2,0.9,0.3,1.4,0.3
c0,0,0,0,0,0c0.5,0,1-0.1,1.4-0.3c0.5-0.2,0.9-0.5,1.3-0.8c0.4-0.4,0.7-0.9,0.9-1.4c0.2-0.6,0.3-1.2,0.2-1.8
c-0.1-0.5-0.2-0.9-0.5-1.3c-0.1-0.2-0.3-0.4-0.4-0.6l-0.1-0.1l0,0l0,0l0,0l0,0l0-0.1l0,0l-0.1,0.1l-0.1-0.1
c-0.1-0.1-0.1-0.1-0.1-0.2c-0.1-0.1-0.2-0.3-0.2-0.4c-0.1-0.1-0.1-0.3-0.2-0.4c0-0.1-0.1-0.2-0.1-0.4c0-0.1,0-0.2,0-0.3
c-0.1-0.6,0.1-1.3,0.4-1.9c0.1-0.2,0.2-0.4,0.4-0.6c0,0,0.1-0.1,0.1-0.1c0,0,0.1-0.1,0.1-0.1c0,0,0.1,0,0.1-0.1
c0.1-0.1,0.2-0.1,0.3-0.1c0,0,0,0,0.1,0l0,0h6.5C48.2,25.1,48.7,24.5,49.2,24z"/>
</g>
</g>
<g id="XMLID_14_">
</g>
<g id="XMLID_15_">
</g>
<g id="XMLID_16_">
</g>
<g id="XMLID_17_">
</g>
<g id="XMLID_18_">
</g>
<g id="XMLID_19_">
</g>
</svg>

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -17,6 +17,7 @@
<div class="stick-pointer"></div> <div class="stick-pointer"></div>
</div> </div>
</div> </div>
<div class="notifications"></div>
<script src="main.js" type="text/javascript"></script> <script src="main.js" type="text/javascript"></script>
<script src="telemetry.js" type="text/javascript"></script> <script src="telemetry.js" type="text/javascript"></script>
</body> </body>

View File

@@ -7,6 +7,10 @@ html, body {
color: rgba(255, 255, 255, 0.9); color: rgba(255, 255, 255, 0.9);
} }
* {
user-select: none;
}
.stick { .stick {
border-radius: 50%; border-radius: 50%;
width: 5cm; width: 5cm;
@@ -72,7 +76,8 @@ body.armed .telemetry .mode {
body.low-battery .battery { body.low-battery .battery {
color: #ff554b; color: #ff554b;
animation: scale 0.3s 1 ease-in-out} animation: scale 0.3s 1 ease-in-out
}
.logo { .logo {
position: absolute; position: absolute;
@@ -89,3 +94,32 @@ body.low-battery .battery {
user-select: none; user-select: none;
pointer-events: 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

@@ -1,6 +1,7 @@
var url = 'ws://192.168.11.1:9090'; var url = 'ws://192.168.11.1:9090';
var modeEl = document.querySelector('.telemetry .mode'); var modeEl = document.querySelector('.telemetry .mode');
var batteryEl = document.querySelector('.battery'); var batteryEl = document.querySelector('.battery');
var notificationsEl = document.querySelector('.notifications');
var ros = new ROSLIB.Ros({ url: url }); var ros = new ROSLIB.Ros({ url: url });
@@ -35,10 +36,14 @@ new ROSLIB.Topic({
}); });
function notifyLowBattery() { function notifyLowBattery() {
console.log('low battery');
callNativeApp('lowBattery'); callNativeApp('lowBattery');
body.classList.remove('low-battery');
void body.offsetWidth; // trick for repeating animation
body.classList.add('low-battery');
} }
notifyLowBatteryThrottled = throttle(notifyLowBattery, 10000); notifyLowBatteryThrottled = throttle(notifyLowBattery, 15000);
new ROSLIB.Topic({ new ROSLIB.Topic({
ros: ros, ros: ros,
@@ -50,29 +55,50 @@ new ROSLIB.Topic({
batteryEl.innerHTML = (message.cell_voltage[0].toFixed(2) + ' V') || ''; batteryEl.innerHTML = (message.cell_voltage[0].toFixed(2) + ' V') || '';
if (message.cell_voltage[0] < LOW_BATTERY) { if (message.cell_voltage[0] < LOW_BATTERY) {
console.log('low battery'); notifyLowBatteryThrottled();
callNativeApp('lowBattery');
body.classList.remove('low-battery');
void body.offsetWidth; // trick for repeating animation
body.classList.add('low-battery');
} else { } else {
body.classList.remove('low-battery'); 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({ new ROSLIB.Topic({
ros: ros, ros: ros,
name: '/rosout_agg', name: '/mavros/statustext/recv',
messageType: 'rosgraph_msgs/Log' messageType: 'mavros_msgs/StatusText'
}).subscribe(function(message) { }).subscribe(function(message) {
var BLACKLIST = ['CMD: ', 'PR: ', 'DROPPED']; var BLACKLIST = ['CMD: ', 'PR: ', 'DROPPED', 'Clock skew detected', 'MANUAL CONTROL LOST'];
if(message.level >= 4) { if (message.severity <= 4) {
if (BLACKLIST.some(function(e) { if (BLACKLIST.some(function(e) {
return message.msg.indexOf(e) != -1; return message.text.indexOf(e) != -1;
})) { })) {
console.log('Filtered out message ' + message.msg); console.log('Filtered out message ' + message.text);
return; return;
} }
notify(message.text, message.severity);
callNativeApp('notification', message); callNativeApp('notification', message);
} }
}); });

View File

@@ -4,13 +4,19 @@
"author": "Copter Express", "author": "Copter Express",
"language": "ru", "language": "ru",
"root": "docs/", "root": "docs/",
"plugins": ["youtube", "richquotes", "disqus", "versions"], "plugins": ["youtube", "richquotes", "versions", "yametrika"],
"pluginsConfig": { "pluginsConfig": {
"disqus": { "disqus": {
"shortName": "coex-clever" "shortName": "coex-clever"
}, },
"versions": { "versions": {
"type": "tags" "type": "tags"
},
"yametrika": {
"id": 49359238
} }
},
"structure": {
"glossary": "_GLOSSARY.md"
} }
} }

View File

@@ -3,9 +3,9 @@
<arg name="fcu_ip" default="127.0.0.1"/> <arg name="fcu_ip" default="127.0.0.1"/>
<arg name="gcs_bridge" default="tcp"/> <arg name="gcs_bridge" default="tcp"/>
<arg name="viz" default="true"/> <arg name="viz" default="true"/>
<arg name="respawn" default="false"/> <arg name="respawn" default="true"/>
<node pkg="mavros" type="mavros_node" name="mavros" required="false" clear_params="true" respawn="$(arg respawn)" respawn_delay="3" output="screen"> <node pkg="mavros" type="mavros_node" name="mavros" required="false" clear_params="true" respawn="$(arg respawn)" respawn_delay="5" output="screen">
<!-- UART connection --> <!-- UART connection -->
<param name="fcu_url" value="/dev/ttyAMA0:921600" if="$(eval fcu_conn is None or fcu_conn == 'uart')"/> <param name="fcu_url" value="/dev/ttyAMA0:921600" if="$(eval fcu_conn is None or fcu_conn == 'uart')"/>
@@ -17,9 +17,12 @@
<!-- gcs bridge --> <!-- gcs bridge -->
<param name="gcs_url" value="tcp-l://0.0.0.0:5760" if="$(eval gcs_bridge == 'tcp')"/> <param name="gcs_url" value="tcp-l://0.0.0.0:5760" if="$(eval gcs_bridge == 'tcp')"/>
<param name="gcs_url" value="udp://@192.168.11.14:14550" if="$(eval gcs_bridge == 'udp')"/> <!-- TODO: fix --> <param name="gcs_url" value="udp://0.0.0.0:14550@14550" if="$(eval gcs_bridge == 'udp')"/>
<param name="gcs_url" value="udp-b://192.168.11.1:14550@" if="$(eval gcs_bridge == 'udp-b')"/> <param name="gcs_url" value="udp-b://$(env ROS_IP):14550@14550" if="$(eval gcs_bridge == 'udp-b')"/>
<param name="gcs_url" value="udp-pb://$(env ROS_IP):14550@14550" if="$(eval gcs_bridge == 'udp-pb')"/>
<param name="gcs_url" value="" if="$(eval not gcs_bridge)"/> <param name="gcs_url" value="" if="$(eval not gcs_bridge)"/>
<param name="gcs_quiet_mode" value="true"/>
<param name="conn/timeout" value="8"/>
<!-- default px4 params --> <!-- default px4 params -->
<rosparam command="load" file="$(find mavros)/launch/px4_config.yaml"/> <rosparam command="load" file="$(find mavros)/launch/px4_config.yaml"/>

View File

@@ -1,2 +1,3 @@
flask==0.12.2 flask==0.12.2
geopy==1.11.0 geopy==1.11.0
pymavlink==2.2.10

View File

@@ -10,6 +10,7 @@
#include "std_msgs/String.h" #include "std_msgs/String.h"
#include "mavros_msgs/State.h" #include "mavros_msgs/State.h"
#include "mavros_msgs/ManualControl.h" #include "mavros_msgs/ManualControl.h"
#include "mavros_msgs/Mavlink.h"
struct ControlMessage struct ControlMessage
{ {
@@ -27,6 +28,9 @@ public:
std::thread t(&RC::socketThread, this); std::thread t(&RC::socketThread, this);
t.detach(); t.detach();
std::thread gcst(&RC::fakeGCSThread, this);
gcst.detach();
initLatchedState(); initLatchedState();
} }
@@ -35,6 +39,7 @@ private:
ros::Subscriber state_sub; ros::Subscriber state_sub;
ros::Publisher state_pub; ros::Publisher state_pub;
ros::Timer state_timeout_timer; ros::Timer state_timeout_timer;
ros::Time last_manual_control{0};
mavros_msgs::StateConstPtr state_msg; mavros_msgs::StateConstPtr state_msg;
void handleState(const mavros_msgs::StateConstPtr& state) void handleState(const mavros_msgs::StateConstPtr& state)
@@ -70,6 +75,37 @@ private:
state_pub.publish(unknown_state); state_pub.publish(unknown_state);
} }
void fakeGCSThread()
{
// Awful workaround for fixing PX4 not sending STATUSTEXTs
// if there is no GCS hearbeats.
// TODO: use timer
// TODO: remove, when PX4 get this fixed.
ros::Publisher mavlink_pub = nh.advertise<mavros_msgs::Mavlink>("mavlink/to", 1);
// HEARTBEAT from GCS message
mavros_msgs::Mavlink hb;
hb.framing_status = mavros_msgs::Mavlink::FRAMING_OK;
hb.magic = mavros_msgs::Mavlink::MAVLINK_V20;
hb.len = 9;
hb.incompat_flags = 0;
hb.compat_flags = 0;
hb.seq = 0;
hb.sysid = 255;
hb.compid = 0;
hb.checksum = 26460;
hb.payload64.push_back(342282393542983680);
hb.payload64.push_back(3);
ros::Rate rate(1);
while (ros::ok()) {
if (ros::Time::now() - last_manual_control < ros::Duration(8)) {
mavlink_pub.publish(hb);
}
rate.sleep();
}
}
int createSocket(int port) int createSocket(int port)
{ {
int sockfd = socket(AF_INET, SOCK_DGRAM, 0); int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
@@ -123,6 +159,8 @@ private:
manual_control_msg.z = msg->z; manual_control_msg.z = msg->z;
manual_control_msg.r = msg->r; manual_control_msg.r = msg->r;
manual_control_pub.publish(manual_control_msg); manual_control_pub.publish(manual_control_msg);
last_manual_control = ros::Time::now();
} }
} }
}; };

109
clever/src/selfcheck.py Executable file
View File

@@ -0,0 +1,109 @@
#!/usr/bin/env python
import rospy
from std_srvs.srv import Trigger
from sensor_msgs.msg import Image, CameraInfo, NavSatFix, Imu
from mavros_msgs.msg import State
from geometry_msgs.msg import PoseStamped, TwistStamped
# TODO: roscore is running
# TODO: local_origin, fcu, fcu_horiz
# TODO: rc service
# TODO: perform commander check in PX4
rospy.init_node('selfcheck')
def check_fcu():
try:
state = rospy.wait_for_message('mavros/state', State, timeout=3)
if not state.connected:
raise Exception('No connection to the FCU')
except rospy.ROSException:
raise Exception('No MAVROS state')
def check_camera(name):
try:
rospy.wait_for_message(name + '/image_raw', Image, timeout=3)
except rospy.ROSException:
raise Exception('No %s camera images' % name)
try:
rospy.wait_for_message(name + '/camera_info', CameraInfo, timeout=3)
except rospy.ROSException:
raise Exception('No %s camera camera info' % name)
def check_aruco():
try:
rospy.wait_for_message('aruco_pose/debug', Image, timeout=3)
except rospy.ROSException:
raise Exception('No aruco_pose/debug topic')
def check_simpleoffboard():
try:
rospy.wait_for_service('navigate', timeout=3)
rospy.wait_for_service('get_telemetry', timeout=3)
rospy.wait_for_service('land', timeout=3)
except rospy.ROSException:
raise Exception('No simple_offboard services')
def check_imu():
try:
rospy.wait_for_message('mavros/imu/data', Imu, timeout=3)
except rospy.ROSException:
raise Exception('No IMU data')
def check_local_position():
try:
rospy.wait_for_message('mavros/local_position/pose', PoseStamped, timeout=3)
except rospy.ROSException:
raise Exception('No local position')
def check_velocity():
try:
velocity = rospy.wait_for_message('mavros/local_position/velocity', TwistStamped, timeout=3)
horiz = math.hypot(velocity.twist.linear.x, velocity.twist.linear.y)
vert = velocity.twist.linear.z
if abs(horiz) > 0.1:
raise Exception('Horizontal velocity estimation is %s m/s; is the copter staying still?' % horiz)
if abs(vert) > 0.1:
raise Exception('Vertical velocity estimation is %s m/s; is the copter staying still?' % vert)
except rospy.ROSException:
raise Exception('No velocity estimation')
def check_global_position():
try:
rospy.wait_for_message('mavros/global_position/global', PoseStamped, timeout=3)
except rospy.ROSException:
raise Exception('No global position')
def check(name, fn):
try:
fn()
rospy.loginfo('%s: OK', name)
except BaseException as e:
rospy.logwarn('%s: %s', name, str(e))
def selfcheck():
check('FCU', check_fcu)
check('Simple offboard node', check_simpleoffboard)
check('Main camera node', lambda: check_camera('main_camera'))
check('aruco_pose/debug topic', check_aruco)
check('IMU data', check_imu)
check('Local position', check_local_position)
check('Velocity estimation', check_velocity)
check('Global position (GPS)', check_global_position)
if __name__ == '__main__':
rospy.loginfo('Performing selfcheck...')
selfcheck()

View File

@@ -188,7 +188,7 @@ def get_publisher_and_message(req, stamp, continued=True, update_frame=True):
PT.IGNORE_AFX + PT.IGNORE_AFY + PT.IGNORE_AFZ + PT.IGNORE_AFX + PT.IGNORE_AFY + PT.IGNORE_AFZ +
(PT.IGNORE_YAW if yaw_rate_flag else PT.IGNORE_YAW_RATE), (PT.IGNORE_YAW if yaw_rate_flag else PT.IGNORE_YAW_RATE),
position=setpoint, position=setpoint,
yaw=euler_from_orientation(current_nav_finish.pose.orientation)[2] - math.pi / 2, yaw=euler_from_orientation(current_nav_finish.pose.orientation, 'szyx')[2] - math.pi / 2,
yaw_rate=req.yaw_rate) yaw_rate=req.yaw_rate)
return position_pub, msg return position_pub, msg
@@ -207,7 +207,7 @@ def get_publisher_and_message(req, stamp, continued=True, update_frame=True):
PT.IGNORE_AFX + PT.IGNORE_AFY + PT.IGNORE_AFZ + PT.IGNORE_AFX + PT.IGNORE_AFY + PT.IGNORE_AFZ +
(PT.IGNORE_YAW if yaw_rate_flag else PT.IGNORE_YAW_RATE), (PT.IGNORE_YAW if yaw_rate_flag else PT.IGNORE_YAW_RATE),
position=pose_local.pose.position, position=pose_local.pose.position,
yaw=euler_from_orientation(pose_local.pose.orientation)[2] - math.pi / 2, yaw=euler_from_orientation(pose_local.pose.orientation, 'szyx')[2] - math.pi / 2,
yaw_rate=req.yaw_rate) yaw_rate=req.yaw_rate)
return position_pub, msg return position_pub, msg
@@ -225,7 +225,7 @@ def get_publisher_and_message(req, stamp, continued=True, update_frame=True):
PT.IGNORE_AFX + PT.IGNORE_AFY + PT.IGNORE_AFZ + PT.IGNORE_AFX + PT.IGNORE_AFY + PT.IGNORE_AFZ +
(PT.IGNORE_YAW if yaw_rate_flag else PT.IGNORE_YAW_RATE), (PT.IGNORE_YAW if yaw_rate_flag else PT.IGNORE_YAW_RATE),
velocity=vector_local.vector, velocity=vector_local.vector,
yaw=euler_from_orientation(pose_local.pose.orientation)[2] - math.pi / 2, yaw=euler_from_orientation(pose_local.pose.orientation, 'szyx')[2] - math.pi / 2,
yaw_rate=req.yaw_rate) yaw_rate=req.yaw_rate)
return position_pub, msg return position_pub, msg
@@ -348,6 +348,7 @@ def get_telemetry(req):
'z': float('nan'), 'z': float('nan'),
'lat': float('nan'), 'lat': float('nan'),
'lon': float('nan'), 'lon': float('nan'),
'alt': float('nan'),
'vx': float('nan'), 'vx': float('nan'),
'vy': float('nan'), 'vy': float('nan'),
'vz': float('nan'), 'vz': float('nan'),
@@ -368,11 +369,9 @@ def get_telemetry(req):
res['x'] = p.pose.position.x res['x'] = p.pose.position.x
res['y'] = p.pose.position.y res['y'] = p.pose.position.y
res['z'] = p.pose.position.z res['z'] = p.pose.position.z
# Get yaw in the request's frame_in
_, _, res['yaw'] = euler_from_orientation(p.pose.orientation) # Calculate roll pitch and yaw as Tait-Bryan angles, order z-y-x
# Calculate pitch and roll as angles between the pose and fcu_horiz res['yaw'], res['pitch'], res['roll'] = euler_from_orientation(p.pose.orientation, axes='rzyx')
attitude_pose = tf_buffer.transform(pose, 'fcu_horiz', TRANSFORM_TIMEOUT)
res['roll'], res['pitch'], _ = euler_from_orientation(attitude_pose.pose.orientation)
if velocity: if velocity:
v = Vector3Stamped() v = Vector3Stamped()
@@ -391,6 +390,7 @@ def get_telemetry(req):
if global_position and stamp - global_position.header.stamp < rospy.Duration(5): if global_position and stamp - global_position.header.stamp < rospy.Duration(5):
res['lat'] = global_position.latitude res['lat'] = global_position.latitude
res['lon'] = global_position.longitude res['lon'] = global_position.longitude
res['alt'] = global_position.altitude
if state: if state:
res['connected'] = state.connected res['connected'] = state.connected

View File

@@ -6,8 +6,8 @@ def orientation_from_quaternion(q):
return Quaternion(*q) return Quaternion(*q)
def orientation_from_euler(roll, pitch, yaw): def orientation_from_euler(roll, pitch, yaw, axes='rzyx'):
q = t.quaternion_from_euler(roll, pitch, yaw) q = t.quaternion_from_euler(roll, pitch, yaw, axes)
return orientation_from_quaternion(q) return orientation_from_quaternion(q)
@@ -15,9 +15,9 @@ def quaternion_from_orientation(o):
return o.x, o.y, o.z, o.w return o.x, o.y, o.z, o.w
def euler_from_orientation(o): def euler_from_orientation(o, axes='rzyx'):
q = quaternion_from_orientation(o) q = quaternion_from_orientation(o)
return t.euler_from_quaternion(q) return t.euler_from_quaternion(q, axes)
def vector3_from_point(p): def vector3_from_point(p):

View File

@@ -7,8 +7,9 @@ string mode
float32 x float32 x
float32 y float32 y
float32 z float32 z
float32 lat float64 lat
float32 lon float64 lon
float32 alt
float32 vx float32 vx
float32 vy float32 vy
float32 vz float32 vz

View File

@@ -1,4 +1,6 @@
Использование внешнего 3G-модема Использование внешнего 3G-модема
=== ===
Использование внешнего 3G-модема на Raspberry возможно с помощью пакета `sakis3g`.
TODO TODO

View File

@@ -11,6 +11,10 @@
Для того, чтобы научиться собирать, настраивать, пилотировать и программировать автономный дрон «Клевер», воспользуйтесь этим учебником. Для того, чтобы научиться собирать, настраивать, пилотировать и программировать автономный дрон «Клевер», воспользуйтесь этим учебником.
Если вы детально изучили наш gitbook, но так и не нашли ответа на свой вопрос, напишите в чат техподдержки и наши специалисты вам с радостью ответят: https://t.me/COEXHelpdesk.
Также у нас есть чат для программистов, которые разрабатывают под PX4, автономную навигацию в помещениях и рои дронов https://t.me/DroneCode.
Образ для Raspberry Pi Образ для Raspberry Pi
---------------------- ----------------------
@@ -20,7 +24,7 @@
* Raspbian Stretch * Raspbian Stretch
* ROS Kinetic * ROS Kinetic
* Настроенную работу с сетью * Настроенную [работу с сетью](network.md)
* OpenCV * OpenCV
* mavros * mavros
* Набор ПО для работы с Клевером * Набор ПО для работы с Клевером

View File

@@ -1,6 +1,7 @@
# Summary # Summary
* [Введение](README.md) * [Введение](README.md)
* [Глоссарий](glossary.md)
* [Сборка](assemble.md) * [Сборка](assemble.md)
* [Первоначальная настройка](setup.md) * [Первоначальная настройка](setup.md)
* [Полетные режимы](modes.md) * [Полетные режимы](modes.md)
@@ -9,6 +10,8 @@
* [Подключение Raspberry Pi к PixHawk](connection.md) * [Подключение Raspberry Pi к PixHawk](connection.md)
* [Подключение по Wi-Fi](wifi.md) * [Подключение по Wi-Fi](wifi.md)
* [Работа с QGroundControl через Wi-Fi](gcs_bridge.md) * [Работа с QGroundControl через Wi-Fi](gcs_bridge.md)
* [Прошивка PixHawk/PixRacer](firmware.md)
* [Пилотирование со смартфона](rc.md)
* [SSH-доступ](ssh.md) * [SSH-доступ](ssh.md)
* [Неисправности радиоаппаратуры](radioerrors.md) * [Неисправности радиоаппаратуры](radioerrors.md)
* [Безопасность](safety.md) * [Безопасность](safety.md)
@@ -26,13 +29,21 @@
* [Визуализация с помощью rviz](rviz.md) * [Визуализация с помощью rviz](rviz.md)
* [Работа с SITL](sitl.md) * [Работа с SITL](sitl.md)
* [Подключение GPS](gps.md) * [Подключение GPS](gps.md)
* [Автозапуск ПО](autolaunch.md)
* [Использование 3G-модема](3g.md) * [Использование 3G-модема](3g.md)
* [Устройство сети RPi](network.md)
* [Работа с логами PX4](flight_logs.md)
* [Протокол MAVLink](mavlink.md)
* [Типы силовых разъемов](connectortypes.md)
* [Ошибки радиоаппаратуры](radioerrors1.md)
* [Настройка PID](calibratePID.md)
* Учебник * Учебник
* [Уроки](lessons.md) * [Теория и видеоуроки](lessons.md)
* [Учебно-методическое пособие](metod.md) * [Учебно-методическое пособие](metod.md)
* [Контрольные и проверочные материалы](tests.md) * [Контрольные и проверочные материалы](tests.md)
* [Другое](drugoe.md) * [Другое](drugoe.md)
* [CopterHack-2017](copterhack2017.md) * [CopterHack-2017](copterhack2017.md)
* [Прошивка ESC контроллеров с помощью Arduino](esc_firmware.md) * [Прошивка ESC контроллеров с помощью Arduino](esc_firmware.md)
* [Работа со светодиодной лентой](leds.md) * [Работа со светодиодной лентой](leds.md)
* [Проекты на базе коптера "Клевер"](projects.md)
* [Полезные ссылки](links.md) * [Полезные ссылки](links.md)

View File

@@ -110,7 +110,7 @@ _Примечание_: указанное выше определение пр
Для правильной работы Vision Position Estimation необходимо \(через [QGroundControl](gcs_bridge.md)\) убедиться, что: Для правильной работы Vision Position Estimation необходимо \(через [QGroundControl](gcs_bridge.md)\) убедиться, что:
* Для PixHawk: Установлена прошивка с LPE \(local position estimator\). Для PixRacer: параметр `SYS_MC_EST_GROUP` установлен в `local_position_estimator, attitude_estimator_q`. * Для PixHawk: Установлена прошивка с LPE \(local position estimator\). Для PixHawk необходимо [скачать прошивку `px4fmu-v2_lpe.px4`](https://github.com/PX4/Firmware/releases). Для PixRacer параметр `SYS_MC_EST_GROUP` должен быть установлен в `local_position_estimator, attitude_estimator_q`.
* В параметре `LPE_FUSION` включены **только** флажки `vision position`, `vision yaw`, `land detector`. Итоговое значение _28_. * В параметре `LPE_FUSION` включены **только** флажки `vision position`, `vision yaw`, `land detector`. Итоговое значение _28_.
* Выключен компас: `ATT_W_MAG` = 0 * Выключен компас: `ATT_W_MAG` = 0
* Вес угла по рысканью по зрению: `ATT_W_EXT_HDG` = 0.5 * Вес угла по рысканью по зрению: `ATT_W_EXT_HDG` = 0.5
@@ -122,7 +122,7 @@ _Примечание_: указанное выше определение пр
* `LNDMC_THR_RANGE` = 0.5 * `LNDMC_THR_RANGE` = 0.5
* `LNDMC_Z_VEL_MAX` = 1 m/s * `LNDMC_Z_VEL_MAX` = 1 m/s
Для простоты настройки можно воспользоваться готовым файлом настроек для [Clever 2](https://github.com/CopterExpress/clever/blob/masterassets/Clever2LPE_160118.params) или для [Clever 3](https://github.com/CopterExpress/clever/blob/masterassets/Clever3_LPE_020218.params) и вгрузить его в контроллер с помощью меню Tools - Load from file из раздела Parameters в QGroundControl. Для простоты настройки можно воспользоваться готовым файлом настроек для [Clever 2](https://github.com/CopterExpress/clever/blob/master/docs/assets/Clever2LPE_160118.params) или для [Clever 3](https://github.com/CopterExpress/clever/blob/master/docs/assets/Clever3_LPE_020218.params) и вгрузить его в контроллер с помощью меню Tools - Load from file из раздела Parameters в QGroundControl.
![](assets/Screenshot from 2018-02-27 22-30-50.png) ![](assets/Screenshot from 2018-02-27 22-30-50.png)

BIN
docs/assets/3dmodel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

46
docs/assets/appstore.svg Executable file
View File

@@ -0,0 +1,46 @@
<svg id="livetype" xmlns="http://www.w3.org/2000/svg" width="119.66407" height="40" viewBox="0 0 119.66407 40">
<title>Download_on_the_App_Store_Badge_US-UK_RGB_blk_4SVG_092917</title>
<g>
<g>
<g>
<path d="M110.13477,0H9.53468c-.3667,0-.729,0-1.09473.002-.30615.002-.60986.00781-.91895.0127A13.21476,13.21476,0,0,0,5.5171.19141a6.66509,6.66509,0,0,0-1.90088.627A6.43779,6.43779,0,0,0,1.99757,1.99707,6.25844,6.25844,0,0,0,.81935,3.61816a6.60119,6.60119,0,0,0-.625,1.90332,12.993,12.993,0,0,0-.1792,2.002C.00587,7.83008.00489,8.1377,0,8.44434V31.5586c.00489.3105.00587.6113.01515.9219a12.99232,12.99232,0,0,0,.1792,2.0019,6.58756,6.58756,0,0,0,.625,1.9043A6.20778,6.20778,0,0,0,1.99757,38.001a6.27445,6.27445,0,0,0,1.61865,1.1787,6.70082,6.70082,0,0,0,1.90088.6308,13.45514,13.45514,0,0,0,2.0039.1768c.30909.0068.6128.0107.91895.0107C8.80567,40,9.168,40,9.53468,40H110.13477c.3594,0,.7246,0,1.084-.002.3047,0,.6172-.0039.9219-.0107a13.279,13.279,0,0,0,2-.1768,6.80432,6.80432,0,0,0,1.9082-.6308,6.27742,6.27742,0,0,0,1.6172-1.1787,6.39482,6.39482,0,0,0,1.1816-1.6143,6.60413,6.60413,0,0,0,.6191-1.9043,13.50643,13.50643,0,0,0,.1856-2.0019c.0039-.3106.0039-.6114.0039-.9219.0078-.3633.0078-.7246.0078-1.0938V9.53613c0-.36621,0-.72949-.0078-1.09179,0-.30664,0-.61426-.0039-.9209a13.5071,13.5071,0,0,0-.1856-2.002,6.6177,6.6177,0,0,0-.6191-1.90332,6.46619,6.46619,0,0,0-2.7988-2.7998,6.76754,6.76754,0,0,0-1.9082-.627,13.04394,13.04394,0,0,0-2-.17676c-.3047-.00488-.6172-.01074-.9219-.01269-.3594-.002-.7246-.002-1.084-.002Z" style="fill: #a6a6a6"/>
<path d="M8.44483,39.125c-.30468,0-.602-.0039-.90429-.0107a12.68714,12.68714,0,0,1-1.86914-.1631,5.88381,5.88381,0,0,1-1.65674-.5479,5.40573,5.40573,0,0,1-1.397-1.0166,5.32082,5.32082,0,0,1-1.02051-1.3965,5.72186,5.72186,0,0,1-.543-1.6572,12.41351,12.41351,0,0,1-.1665-1.875c-.00634-.2109-.01464-.9131-.01464-.9131V8.44434S.88185,7.75293.8877,7.5498a12.37039,12.37039,0,0,1,.16553-1.87207,5.7555,5.7555,0,0,1,.54346-1.6621A5.37349,5.37349,0,0,1,2.61183,2.61768,5.56543,5.56543,0,0,1,4.01417,1.59521a5.82309,5.82309,0,0,1,1.65332-.54394A12.58589,12.58589,0,0,1,7.543.88721L8.44532.875H111.21387l.9131.0127a12.38493,12.38493,0,0,1,1.8584.16259,5.93833,5.93833,0,0,1,1.6709.54785,5.59374,5.59374,0,0,1,2.415,2.41993,5.76267,5.76267,0,0,1,.5352,1.64892,12.995,12.995,0,0,1,.1738,1.88721c.0029.2832.0029.5874.0029.89014.0079.375.0079.73193.0079,1.09179V30.4648c0,.3633,0,.7178-.0079,1.0752,0,.3252,0,.6231-.0039.9297a12.73126,12.73126,0,0,1-.1709,1.8535,5.739,5.739,0,0,1-.54,1.67,5.48029,5.48029,0,0,1-1.0156,1.3857,5.4129,5.4129,0,0,1-1.3994,1.0225,5.86168,5.86168,0,0,1-1.668.5498,12.54218,12.54218,0,0,1-1.8692.1631c-.2929.0068-.5996.0107-.8974.0107l-1.084.002Z"/>
</g>
<g id="_Group_" data-name="&lt;Group&gt;">
<g id="_Group_2" data-name="&lt;Group&gt;">
<g id="_Group_3" data-name="&lt;Group&gt;">
<path id="_Path_" data-name="&lt;Path&gt;" d="M24.76888,20.30068a4.94881,4.94881,0,0,1,2.35656-4.15206,5.06566,5.06566,0,0,0-3.99116-2.15768c-1.67924-.17626-3.30719,1.00483-4.1629,1.00483-.87227,0-2.18977-.98733-3.6085-.95814a5.31529,5.31529,0,0,0-4.47292,2.72787c-1.934,3.34842-.49141,8.26947,1.3612,10.97608.9269,1.32535,2.01018,2.8058,3.42763,2.7533,1.38706-.05753,1.9051-.88448,3.5794-.88448,1.65876,0,2.14479.88448,3.591.8511,1.48838-.02416,2.42613-1.33124,3.32051-2.66914a10.962,10.962,0,0,0,1.51842-3.09251A4.78205,4.78205,0,0,1,24.76888,20.30068Z" style="fill: #fff"/>
<path id="_Path_2" data-name="&lt;Path&gt;" d="M22.03725,12.21089a4.87248,4.87248,0,0,0,1.11452-3.49062,4.95746,4.95746,0,0,0-3.20758,1.65961,4.63634,4.63634,0,0,0-1.14371,3.36139A4.09905,4.09905,0,0,0,22.03725,12.21089Z" style="fill: #fff"/>
</g>
</g>
<g>
<path d="M42.30227,27.13965h-4.7334l-1.13672,3.35645H34.42727l4.4834-12.418h2.083l4.4834,12.418H43.438ZM38.0591,25.59082h3.752l-1.84961-5.44727h-.05176Z" style="fill: #fff"/>
<path d="M55.15969,25.96973c0,2.81348-1.50586,4.62109-3.77832,4.62109a3.0693,3.0693,0,0,1-2.84863-1.584h-.043v4.48438h-1.8584V21.44238H48.4302v1.50586h.03418a3.21162,3.21162,0,0,1,2.88281-1.60059C53.645,21.34766,55.15969,23.16406,55.15969,25.96973Zm-1.91016,0c0-1.833-.94727-3.03809-2.39258-3.03809-1.41992,0-2.375,1.23047-2.375,3.03809,0,1.82422.95508,3.0459,2.375,3.0459C52.30227,29.01563,53.24953,27.81934,53.24953,25.96973Z" style="fill: #fff"/>
<path d="M65.12453,25.96973c0,2.81348-1.50586,4.62109-3.77832,4.62109a3.0693,3.0693,0,0,1-2.84863-1.584h-.043v4.48438h-1.8584V21.44238H58.395v1.50586h.03418A3.21162,3.21162,0,0,1,61.312,21.34766C63.60988,21.34766,65.12453,23.16406,65.12453,25.96973Zm-1.91016,0c0-1.833-.94727-3.03809-2.39258-3.03809-1.41992,0-2.375,1.23047-2.375,3.03809,0,1.82422.95508,3.0459,2.375,3.0459C62.26711,29.01563,63.21438,27.81934,63.21438,25.96973Z" style="fill: #fff"/>
<path d="M71.71047,27.03613c.1377,1.23145,1.334,2.04,2.96875,2.04,1.56641,0,2.69336-.80859,2.69336-1.91895,0-.96387-.67969-1.541-2.28906-1.93652l-1.60937-.3877c-2.28027-.55078-3.33887-1.61719-3.33887-3.34766,0-2.14258,1.86719-3.61426,4.51855-3.61426,2.624,0,4.42285,1.47168,4.4834,3.61426h-1.876c-.1123-1.23926-1.13672-1.9873-2.63379-1.9873s-2.52148.75684-2.52148,1.8584c0,.87793.6543,1.39453,2.25488,1.79l1.36816.33594c2.54785.60254,3.60645,1.626,3.60645,3.44238,0,2.32324-1.85059,3.77832-4.79395,3.77832-2.75391,0-4.61328-1.4209-4.7334-3.667Z" style="fill: #fff"/>
<path d="M83.34621,19.2998v2.14258h1.72168v1.47168H83.34621v4.99121c0,.77539.34473,1.13672,1.10156,1.13672a5.80752,5.80752,0,0,0,.61133-.043v1.46289a5.10351,5.10351,0,0,1-1.03223.08594c-1.833,0-2.54785-.68848-2.54785-2.44434V22.91406H80.16262V21.44238H81.479V19.2998Z" style="fill: #fff"/>
<path d="M86.065,25.96973c0-2.84863,1.67773-4.63867,4.29395-4.63867,2.625,0,4.29492,1.79,4.29492,4.63867,0,2.85645-1.66113,4.63867-4.29492,4.63867C87.72609,30.6084,86.065,28.82617,86.065,25.96973Zm6.69531,0c0-1.9541-.89551-3.10742-2.40137-3.10742s-2.40039,1.16211-2.40039,3.10742c0,1.96191.89453,3.10645,2.40039,3.10645S92.76027,27.93164,92.76027,25.96973Z" style="fill: #fff"/>
<path d="M96.18606,21.44238h1.77246v1.541h.043a2.1594,2.1594,0,0,1,2.17773-1.63574,2.86616,2.86616,0,0,1,.63672.06934v1.73828a2.59794,2.59794,0,0,0-.835-.1123,1.87264,1.87264,0,0,0-1.93652,2.083v5.37012h-1.8584Z" style="fill: #fff"/>
<path d="M109.3843,27.83691c-.25,1.64355-1.85059,2.77148-3.89844,2.77148-2.63379,0-4.26855-1.76465-4.26855-4.5957,0-2.83984,1.64355-4.68164,4.19043-4.68164,2.50488,0,4.08008,1.7207,4.08008,4.46582v.63672h-6.39453v.1123a2.358,2.358,0,0,0,2.43555,2.56445,2.04834,2.04834,0,0,0,2.09082-1.27344Zm-6.28223-2.70215h4.52637a2.1773,2.1773,0,0,0-2.2207-2.29785A2.292,2.292,0,0,0,103.10207,25.13477Z" style="fill: #fff"/>
</g>
</g>
</g>
<g id="_Group_4" data-name="&lt;Group&gt;">
<g>
<path d="M37.82619,8.731a2.63964,2.63964,0,0,1,2.80762,2.96484c0,1.90625-1.03027,3.002-2.80762,3.002H35.67092V8.731Zm-1.22852,5.123h1.125a1.87588,1.87588,0,0,0,1.96777-2.146,1.881,1.881,0,0,0-1.96777-2.13379h-1.125Z" style="fill: #fff"/>
<path d="M41.68068,12.44434a2.13323,2.13323,0,1,1,4.24707,0,2.13358,2.13358,0,1,1-4.24707,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C44.57522,13.99463,45.01369,13.42432,45.01369,12.44434Z" style="fill: #fff"/>
<path d="M51.57326,14.69775h-.92187l-.93066-3.31641h-.07031l-.92676,3.31641h-.91309l-1.24121-4.50293h.90137l.80664,3.436h.06641l.92578-3.436h.85254l.92578,3.436h.07031l.80273-3.436h.88867Z" style="fill: #fff"/>
<path d="M53.85354,10.19482H54.709v.71533h.06641a1.348,1.348,0,0,1,1.34375-.80225,1.46456,1.46456,0,0,1,1.55859,1.6748v2.915h-.88867V12.00586c0-.72363-.31445-1.0835-.97168-1.0835a1.03294,1.03294,0,0,0-1.0752,1.14111v2.63428h-.88867Z" style="fill: #fff"/>
<path d="M59.09377,8.437h.88867v6.26074h-.88867Z" style="fill: #fff"/>
<path d="M61.21779,12.44434a2.13346,2.13346,0,1,1,4.24756,0,2.1338,2.1338,0,1,1-4.24756,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C64.11232,13.99463,64.5508,13.42432,64.5508,12.44434Z" style="fill: #fff"/>
<path d="M66.4009,13.42432c0-.81055.60352-1.27783,1.6748-1.34424l1.21973-.07031v-.38867c0-.47559-.31445-.74414-.92187-.74414-.49609,0-.83984.18213-.93848.50049h-.86035c.09082-.77344.81836-1.26953,1.83984-1.26953,1.12891,0,1.76563.562,1.76563,1.51318v3.07666h-.85547v-.63281h-.07031a1.515,1.515,0,0,1-1.35254.707A1.36026,1.36026,0,0,1,66.4009,13.42432Zm2.89453-.38477v-.37646l-1.09961.07031c-.62012.0415-.90137.25244-.90137.64941,0,.40527.35156.64111.835.64111A1.0615,1.0615,0,0,0,69.29543,13.03955Z" style="fill: #fff"/>
<path d="M71.34816,12.44434c0-1.42285.73145-2.32422,1.86914-2.32422a1.484,1.484,0,0,1,1.38086.79h.06641V8.437h.88867v6.26074h-.85156v-.71143h-.07031a1.56284,1.56284,0,0,1-1.41406.78564C72.0718,14.772,71.34816,13.87061,71.34816,12.44434Zm.918,0c0,.95508.4502,1.52979,1.20313,1.52979.749,0,1.21191-.583,1.21191-1.52588,0-.93848-.46777-1.52979-1.21191-1.52979C72.72121,10.91846,72.26613,11.49707,72.26613,12.44434Z" style="fill: #fff"/>
<path d="M79.23,12.44434a2.13323,2.13323,0,1,1,4.24707,0,2.13358,2.13358,0,1,1-4.24707,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C82.12453,13.99463,82.563,13.42432,82.563,12.44434Z" style="fill: #fff"/>
<path d="M84.66945,10.19482h.85547v.71533h.06641a1.348,1.348,0,0,1,1.34375-.80225,1.46456,1.46456,0,0,1,1.55859,1.6748v2.915H87.605V12.00586c0-.72363-.31445-1.0835-.97168-1.0835a1.03294,1.03294,0,0,0-1.0752,1.14111v2.63428h-.88867Z" style="fill: #fff"/>
<path d="M93.51516,9.07373v1.1416h.97559v.74854h-.97559V13.2793c0,.47168.19434.67822.63672.67822a2.96657,2.96657,0,0,0,.33887-.02051v.74023a2.9155,2.9155,0,0,1-.4834.04541c-.98828,0-1.38184-.34766-1.38184-1.21582v-2.543h-.71484v-.74854h.71484V9.07373Z" style="fill: #fff"/>
<path d="M95.70461,8.437h.88086v2.48145h.07031a1.3856,1.3856,0,0,1,1.373-.80664,1.48339,1.48339,0,0,1,1.55078,1.67871v2.90723H98.69v-2.688c0-.71924-.335-1.0835-.96289-1.0835a1.05194,1.05194,0,0,0-1.13379,1.1416v2.62988h-.88867Z" style="fill: #fff"/>
<path d="M104.76125,13.48193a1.828,1.828,0,0,1-1.95117,1.30273A2.04531,2.04531,0,0,1,100.73,12.46045a2.07685,2.07685,0,0,1,2.07617-2.35254c1.25293,0,2.00879.856,2.00879,2.27V12.688h-3.17969v.0498a1.1902,1.1902,0,0,0,1.19922,1.29,1.07934,1.07934,0,0,0,1.07129-.5459Zm-3.126-1.45117h2.27441a1.08647,1.08647,0,0,0-1.1084-1.1665A1.15162,1.15162,0,0,0,101.63527,12.03076Z" style="fill: #fff"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

BIN
docs/assets/ball.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

BIN
docs/assets/bridge_udp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 KiB

BIN
docs/assets/calculation.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
docs/assets/detal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 KiB

BIN
docs/assets/detal1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 KiB

BIN
docs/assets/detal2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 KiB

BIN
docs/assets/elements.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

BIN
docs/assets/elements1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

BIN
docs/assets/finalball.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 KiB

BIN
docs/assets/flightplot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

BIN
docs/assets/listener.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 KiB

BIN
docs/assets/safetyball.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
docs/assets/stmrev.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

BIN
docs/assets/table.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

59
docs/autolaunch.md Normal file
View File

@@ -0,0 +1,59 @@
Автозапускаемое ПО
===
systemd
---
Основная документация: [https://wiki.archlinux.org/index.php/Systemd_(Русский)](https://wiki.archlinux.org/index.php/Systemd_(Русский)).
Все автоматически стартуемое ПО Клевера запускается в виде systemd-сервиса `clever.service`.
Сервис может быть перезапущен командой `systemctl`:
```bash
sudo systemctl restart clever
```
Текстовый вывод ПО можно просмотреть с помощью команды `journalctl`:
```bash
journalctl -u clever
```
Для того, запустить ПО Клевера непосредственно в текущей консольной сессии, вы можете использовать `roslaunch`:
```bash
sudo systemctl stop clever
roslaunch clever clever.launch
```
Вы можете выключить автозапуск ПО Клевера с помощью команды `disable`:
```bash
sudo systemctl disable clever
```
roslaunch
---
Основная документация: http://wiki.ros.org/roslaunch.
Список объявленных для запуска нод / программ указывается в файле `/home/pi/catkin_ws/src/clever/clever/launch/clever.launch`.
Вы можете добавить собственную ноду в список автозапускаемых. Для этого разместите ваш запускаемый файл (например, `my_program.py`) в каталог `/home/pi/catkin_ws/src/clever/clever/src`. Затем добавьте запуск вашей ноды в `clever.launch`, например:
```xml
<node name="my_program" pkg="clever" type="my_program.py" output="screen"/>
```
Запускаемый файл должен иметь *permission* на запуск:
```bash
chmod +x my_program.py
```
При использовании скриптовых языков вначале файла должен стоять [shebang](https://ru.wikipedia.org/wiki/Шебанг_(Unix)), например:
```bash
#!/usr/bin/env python
```

View File

@@ -26,6 +26,6 @@
* ОС [Raspbian Jessie](https://www.raspberrypi.org/downloads/raspbian/) * ОС [Raspbian Jessie](https://www.raspberrypi.org/downloads/raspbian/)
* Фреймворк [ROS](ros.md) * Фреймворк [ROS](ros.md)
* Пакет [MAVROS](mavros.md) для связи с PixHawk по MAVLINK * Пакет [MAVROS](mavros.md) для связи с PixHawk по [MAVLink](mavlink.md)
* Дополнительные пакеты ROS: web_video_server, usb_cam, rosbridge_suite и другие * Дополнительные пакеты ROS: web_video_server, usb_cam, rosbridge_suite и другие
* Пакет программ clever_bundle * Пакет программ clever_bundle

View File

@@ -13,9 +13,10 @@
``` ```
Фрейм камеры задается таким образом, что: Фрейм камеры задается таким образом, что:
* x указывает направо на изображении;
* y указывает вниз на изображении; * **<font color=red>x</font>** указывает направо на изображении;
* z указывает от плоскости матрицы камеры. * **<font color=green>y</font>** указывает вниз на изображении;
* **<font color=blue>z</font>** указывает от плоскости матрицы камеры.
Сдвиги задаются в метрах, углы задаются в радианах. Корректность установленной трансформации может быть проверена с использованием [rviz](rviz.md). Сдвиги задаются в метрах, углы задаются в радианах. Корректность установленной трансформации может быть проверена с использованием [rviz](rviz.md).

View File

@@ -5,13 +5,12 @@
Убедиться в работоспособности подключения, выполнив на Raspberry Pi: Убедиться в работоспособности подключения, выполнив на Raspberry Pi:
``` ```bash
rostopic echo /mavros/state rostopic echo /mavros/state
``` ```
Поле `connected` должно содержать значение `True`. Поле `connected` должно содержать значение `True`.
Подключение по USB Подключение по USB
--- ---

View File

@@ -2,40 +2,40 @@
Хорошая статья, которая объясняет принцип работы ESC \(Electric speed controller\) регуляторов: [http://www.avmodels.ru/engines/electric/esc.html](http://www.avmodels.ru/engines/electric/esc.html) Хорошая статья, которая объясняет принцип работы ESC \(Electric speed controller\) регуляторов: [http://www.avmodels.ru/engines/electric/esc.html](http://www.avmodels.ru/engines/electric/esc.html)
#### Зачем перепрошивать? ## Зачем перепрошивать?
Иногда требуется поменять один из параметров регулятора, например направление вращения мотора, минимальная и максимальная скважности PPM сигнала на входе контроллера, уровень громкости звуковых сигналов, издаваемых мотором или время, через которое регулятор начинает напоминать, что он включён. Иногда требуется поменять один из параметров регулятора, например направление вращения мотора, минимальная и максимальная скважности PPM сигнала на входе контроллера, уровень громкости звуковых сигналов, издаваемых мотором или время, через которое регулятор начинает напоминать, что он включён.
#### Программа для прошивки регуляторов ## Программа для прошивки регуляторов
Для прошивки самых разнообразных ESC регуляторов существует программа [BLHeliSuite](https://github.com/4712/BLHeliSuite) \(для Windows\). Для прошивки самых разнообразных ESC регуляторов существует программа [BLHeliSuite](https://github.com/4712/BLHeliSuite) \(для Windows\).
Для запуска программы \(BLHeliSuite.exe\) необходимо распаковать архивы BLHeliAtmelHEX.zip и BLHeliSilabsHEX.zip в папку с программой. Для запуска программы \(BLHeliSuite.exe\) необходимо распаковать архивы BLHeliAtmelHEX.zip и BLHeliSilabsHEX.zip в папку с программой.
#### Программатор для прошивки регуляторов. ## Программатор для прошивки регуляторов
Чтобы прошить регулятор, необходим программатор, который умеет общаться с контроллером регулятора по 1-wire протоколу. Один из способов добыть программатор - взять подвернувшуюся под руку ардуинку и прошить её специальной прошивкой. В BLHeliSuite есть инструмент для создания интерфейсов программаторов. Чтобы прошить регулятор, необходим программатор, который умеет общаться с контроллером регулятора по 1-wire протоколу. Один из способов добыть программатор - взять подвернувшуюся под руку ардуинку и прошить её специальной прошивкой. В BLHeliSuite есть инструмент для создания интерфейсов программаторов.
Создание программатора на примере Arduino Mega. Создание программатора на примере Arduino Mega.
1. Запустите программу BLHeliSuite и выберите вкладку Make interfaces. 1. Запустите программу BLHeliSuite и выберите вкладку Make interfaces.
![](assets/BLHeliSuite_SiLabs_ESC_Setup_2.png) ![](assets/BLHeliSuite_SiLabs_ESC_Setup_2.png)
2. Подключите Arduino к компьютеру, при необходимости посмотрите в диспетчере устройств номер COM порта, к которому подключена плата. 2. Подключите Arduino к компьютеру, при необходимости посмотрите в диспетчере устройств номер COM порта, к которому подключена плата.
3. Нажмите Arduino 4way-interface в разделе Make Arduino Interface Boards и выберите файл прошивки. После выбора файла начнётся прошивка контроллера. 3. Нажмите Arduino 4way-interface в разделе Make Arduino Interface Boards и выберите файл прошивки. После выбора файла начнётся прошивка контроллера.
![](assets/BLHeliSuite_Make_Interfaces.png) ![](assets/BLHeliSuite_Make_Interfaces.png)
![](assets/BLHeliSuite_Interface_Options.png) ![](assets/BLHeliSuite_Interface_Options.png)
![](assets/BLHeliSuite_Arduino_Select_Firmware.png) ![](assets/BLHeliSuite_Arduino_Select_Firmware.png)
4. После прошивки Arduino вернитесь на вкладку Silabs ESC Setup и подключитесь к Arduino, предварительно выбрав интерфейс программатора 4way-if и COM порт Arduino. 4. После прошивки Arduino вернитесь на вкладку Silabs ESC Setup и подключитесь к Arduino, предварительно выбрав интерфейс программатора 4way-if и COM порт Arduino.
![](assets/BLHeliSuite_4way-if_Select.png) ![](assets/BLHeliSuite_4way-if_Select.png)
![](assets/BLHeliSuite_ESC_Setup_Connect.png) ![](assets/BLHeliSuite_ESC_Setup_Connect.png)
#### Подключение ESC регуляторов к Arduino. ## Подключение ESC регуляторов к Arduino
Для прошивки или изменения настроек регуляторов необходимо подключить сигнальные порты (обычно белого цвета) ESC регуляторов к портам Arduino, предварительно посмотрев в мануале (см. рисунок ниже), какие порты используются для соединения с регуляторами. Так же нужно соединить GND Arduino с землёй одного из регуляторов (обычно черного цвета). Регуляторы должны быть подключены к питанию, а если к регуляторам подключены моторы, **на них не должно быть винтов**. Для прошивки или изменения настроек регуляторов необходимо подключить сигнальные порты (обычно белого цвета) ESC регуляторов к портам Arduino, предварительно посмотрев в мануале (см. рисунок ниже), какие порты используются для соединения с регуляторами. Так же нужно соединить GND Arduino с землёй одного из регуляторов (обычно черного цвета). Регуляторы должны быть подключены к питанию, а если к регуляторам подключены моторы, **на них не должно быть винтов**.
@@ -43,7 +43,7 @@
В случае с Arduino Mega, сигнальные порты регуляторов подключаются к портам D43-D49 и D51. В случае с Arduino Mega, сигнальные порты регуляторов подключаются к портам D43-D49 и D51.
#### Изменение настроек ESC регуляторов. ## Изменение настроек ESC регуляторов
Для загрузки информации о версии прошивки и настроек регуляторов нужно нажать на кнопку Check. Для загрузки информации о версии прошивки и настроек регуляторов нужно нажать на кнопку Check.
@@ -64,15 +64,15 @@
Для отображения настроек со всех регуляторов одновременно можно воспользоваться вкладкой ESC Overview. Для отображения настроек со всех регуляторов одновременно можно воспользоваться вкладкой ESC Overview.
#### Прошивка ESC регуляторов. ## Прошивка ESC регуляторов
Файлы с прошивками регуляторов находятся [здесь](https://github.com/cleanflight/blheli-multishot/tree/master/BLHeli_S%20SiLabs/Hex%20Files). Файлы с прошивками регуляторов находятся [здесь](https://github.com/cleanflight/blheli-multishot/tree/master/BLHeli_S%20SiLabs/Hex%20Files).
Для перепрошивки регуляторов нужно нажать на кнопку Flash BLHeli и выбрать файл прошивки с типом контроллера, название которого указано в рамке названия прошивки и находится сверху во вкладке Silabs ESC Setup (в случае контроллера, который используется в конструкторе Клевер 2, это A-H-70). Для перепрошивки регуляторов нужно нажать на кнопку Flash BLHeli и выбрать файл прошивки с типом контроллера, название которого указано в рамке названия прошивки и находится сверху во вкладке Silabs ESC Setup (в случае контроллера, который используется в конструкторе Клевер 2, это A-H-70).
Для перепрошивки отдельного регулятора нужно сделать все остальные неактивными. Для перепрошивки отдельного регулятора нужно сделать все остальные неактивными.
#### Видеоинструкция по перепрошивке ESC регуляторов ## Видеоинструкция по перепрошивке ESC регуляторов
Для лучшего понимания того, что описано в статье, рекомендуем посмотреть наглядное руководство по подключению электроники и прошивке регуляторов на английском языке на [youtube](https://www.youtube.com/watch?v=i6lhMcQLRSU&feature=youtu.be). Для лучшего понимания того, что описано в статье, рекомендуем посмотреть наглядное руководство по подключению электроники и прошивке регуляторов на английском языке на [youtube](https://www.youtube.com/watch?v=i6lhMcQLRSU&feature=youtu.be).

View File

@@ -0,0 +1,53 @@
Прошивка PixHawk / PixRacer
===
PixHawk или PixRacer можно прошить, используя QGroundControl или утилиты командной строки.
Различные варианты сборок стабильных прошивок PX4 можно скачать в разделе [Releases на GitHub](https://github.com/PX4/Firmware/releases).
В названии файла прошивки кодируется информации о целевой плате и варианте сборки. Примеры:
* `px4fmu-v2_default.px4` — прошивка для PixHawk с EKF2.
* `px4fmu-v2_lpe.px4` — прошивка для PixHawk с LPE.
* `px4fmu-v4_default.px4` — прошивка для PixRacer с EKF2 и LPE (*Клевер 3*).
* `px4fmu-v3_default.px4` — прошивка для более новых версий PixHawk (чип ревизии 3, см. илл. + Bootloader v5) с EKF2 и LPE.
![](assets/stmrev.jpg)
> **Note** Для загрузки `px4fmu-v3_default.px4` может понадобиться использование команды `force_upload` из командной строки.
QGroundControl
---
В QGroundControl откройте раздел Firmware. **После** этого подключите PixHawk / PixRacer по USB.
Выберите PX4 Flight Stack. Для скачивания и загрузки стандартной прошивки (вариант с EKF2 для PixHawk) выберите пункт меню "Standard Version", для загрузки собственного файла прошивки выберите пункт "Custom firmware file...", затем нажмите OK.
> **Warning** Не отключайте USB-кабель до окончания процесса прошивки.
TODO: Иллюстрация.
Командная строка
---
PX4 может быть собран из исходников и загружен в плату автоматически из командной строки.
Для это склонируйте репозиторий PX4:
```bash
git clone https://github.com/PX4/Firmware.git
```
Выберите необходимую версию (тэг) с помощью `git checkout`. Затем соберите и загрузите прошивку:
```
make px4fmu-v4_default upload
```
Где `px4fmu-v4_default` – требуемый вариант прошивки.
Для загрузки прошивки `v3` в PixHawk может понадобиться команда `force_upload`:
```
make px4fmu-v3_default force-upload
```

55
docs/flight_logs.md Normal file
View File

@@ -0,0 +1,55 @@
Логи и топики PX4
===
Для детального анализа поведения прошивки PX4 можно просмотреть полетные логи. Полетные логи представляют собой сообщения в [uORB-топиках](https://dev.px4.io/en/middleware/uorb.html), записанные в файл с раширением `.ulg`. Лог-файл можно скачать с помощью QGroundControl по Wi-Fi или USB во вкладке *Log Download*:
![](assets/download-log.png)
Также необходимые `.ulg`-файлы можно скопировать непосредственно с MicroSD-карты, находившейся в полетном контроллере.
Анализ
---
Лог-файл можно анализировать с помомщью программы FlightPlot. Актуальную версию программы можно [скачать](https://github.com/PX4/FlightPlot/releases) на GitHub.
В программе можно просмотреть полный список записанных топиков (*Fields List*). В нем нужно выбрать необходимые топики, после чего они появятся на графике:
![](assets/flightplot.png)
Основные топики в PX4
---
[uORB](https://dev.px4.io/en/middleware/uorb.html) представляет собой pubsub механизм, аналогичный ROS-топикам, однако сильно упрощенный и подходящий для embedded-среды.
Полный список топиков можно узнать в исходном коде проекта [в каталоге `msg`](https://github.com/PX4/Firmware/tree/master/msg).
Список некоторых топиков:
* **vehicle_status** состояние коптера (режим и т. д.);
* **vehicle_local_position** локальная позиция коптера;
* **vehicle_attitude** – ориентация коптера;
* **vehicle_local_position_setpoint**  целевая точка (setpoint) коптера по позиции;
* **vehicle_global_position** – глобальная позиция коптера;
* **vehicle_vision_position** – полученная визуальная позиция коптера, аналог MAVLink пакета `VISION_POSITION_ESTIMATE` или MAVROS-топика `/mavros/vision_position_estimate/pose`;
* **att_pos_mocap** – полученная MOCAP-позиция коптера, аналог MAVLink пакета `ATT_POS_MOCAP` или MAVROS-топика `/mavros/mocap/pose`;
* **actuator_controls** сигналы на моторы;
* **vehicle_land_detected** – статус Land-detector'а;
Мониторинг топиков в режиме реального времени
---
Для более новых версий платы PixHawk (`px4fmu-v3`), а также для плат PixRacer, в прошивку включен модуль `topic_listener`, который позволяет просматривать значения топиков в режиме реального времени (в том числе в полете).
Для ее использования нужно выбрать вкладку Mavlink Console в QGroundControl:
![](assets/listener.png)
Команда `list_topics` выводит список топиков, доступных для просмотра (включена только в [SITL](sitl.md)).
Команда `listener <название топика>` выводит текущее значение в топике. Существует третий опциональный параметр, который определяет количество сообщений, которые необходимо вывести.
Примеры команд:
`listener vehicle_local_position`
`listener vehicle_attitude 5`

View File

@@ -1,51 +1,72 @@
Использование QGroundControl через Wi-Fi Использование QGroundControl через Wi-Fi
=== ===
Возможен контроль, управление и настройка полетного контроллера квадрокоптера с помощью программы QGroundControl по Wi-Fi. Для этого необходимо подключиться к Wi-Fi сети `CLEVER-xxxx`. ![](assets/qground.png)
Возможны контроль, управление, калибровка и настройка полетного контроллера квадрокоптера с помощью программы QGroundControl по Wi-Fi.
Для этого необходимо подключиться к Wi-Fi сети `CLEVER-xxxx`.
После чего в launch-файле Клевера `/home/pi/catkin_ws/src/clever/clever/launch/clever.launch` выбрать один из преднастроенных режимов бриджа.
После изменения launch-файла необходимо перезагрузить сервис clever:
```(bash)
sudo systemctl restart clever
```
TCP-бридж TCP-бридж
--- ---
Необходимо убедиться с в launch-файле Клевера (`~/catkin_ws/src/clever/clever/launch/clever.launch`) включен TCP GCS Bridge: Изменить параметр `gcs_bridge` в launch-файле:
```xml ```xml
<arg name="gcs_bridge" default="tcp"/> <arg name="gcs_bridge" default="tcp"/>
``` ```
При изменени launch-файла необходимо перезагрузить сервис `clever`: Затем в программе QGroundControl нужно выбрать Application Settings > Comm Links > Add. Создать подключение со следующими настройками:
```bash
sudo systemctl restart clever
```
Затем в программе QGroundControl нужно выбрать Application Settings -> Comm Links -> Add. Создать подключение со следующими настройками:
![](assets/bridge_tcp.png) ![](assets/bridge_tcp.png)
Затем необходимо выбрать в списке подключений "Clever" и нажать "Connect". После этого можно будет настраивать, калибровать и просматривать состояние квадкоптера без проводов: Затем необходимо выбрать в списке подключений "Clever" и нажать "Connect".
![](assets/qground.png) UDP бридж (с автоматическим подключением)
UDP broadcast-бридж
--- ---
Для использования UDP broadcast-бриджа необходимо установить параметр `gcs_bridge` в значение `udp-b`: Изменить параметр gcs_bridge в launch-файле:
```xml ```xml
<arg name="gcs_bridge" default="udp-b"/> <arg name="gcs_bridge" default="udp-b"/>
``` ```
При изменени launch-файла необходимо перезагрузить сервис `clever`: При открытии программы QGroundControl соединение должно установиться автоматически.
```bash
sudo systemctl restart clever
```
При использовании UDB broadcast-бриджа достаточно подключиться к Wi-Fi сети Клевера. QGroundControl должен подключиться к коптеру автоматически. UDP-бридж (без автоматического подключения)
> **Note** UDP broadcast-бридж работает быстрее, чем TCP-бридж, но связь в нем менее стабильная: иногда могут возникать проблемы при загрузке миссии на коптер, а также при калибровке сенсоров.
UDP-бридж
--- ---
TODO Изменить параметр `gcs_bridge` в launch-файле:
```xml
<arg name="gcs_bridge" default="udp"/>
```
Затем в программе QGroundControl нужно выбрать Application Settings > Comm Links > Add. Создать подключение со следующими настройками:
![](assets/bridge_udp.png)
Затем необходимо выбрать в списке подключений "CLEVER" и нажать "Connect".
UDP broadcast-бридж
---
> **Hint** Особенностью UDP broadcast-бриджа является возможность просмотра телеметрии дрона одновременно с нескольких устройств (например с телефона и компьютера). Также он хорошо подходит для организации сети из устройств при помощи роутера.
Изменить параметр `gcs_bridge` в launch-файле:
```xml
<arg name="gcs_bridge" default="udp-pb"/>
```
При открытии программы QGroundControl соединение должно установиться автоматически.

66
docs/glossary.md Normal file
View File

@@ -0,0 +1,66 @@
# Глоссарий
## Квадрокоптер
Беспилотный летательный аппарат с 4-мя винтами и электронной системной стабилизации.
## Мультикоптер
Беспилотный летательный аппарат с электронной системой стабилизации и числом винтов, равным 3 (трикоптер), 4 (квадрокоптер), 6 (гексакоптер), 8 (октокоптер) или более.
## Полетный контроллер / автопилот
**1\.** Специализированная плата, спроектированная для управления мультикоптером, самолетом или другим аппаратом. Примеры:
PixHawk, Ardupilot, Naze32, CC3D.
**2\.** Программное обеспечение для платы управления мультикоптером. Примеры: PX4, APM, CleanFlight.
## Мотор
Электродвигатель, который вращает винты мультикоптера. Обычно используются бесколлекторные электродвигатели. Такие двигатели подключаются к ESC.
## ESC / регулятор двигателя / "регуль"
Electronic Speed Controller. Специализированная плата, которая управляет скоростью вращения бесколлекторного электродвигателя. Управляется полетным контроллером при помощи широтно-импульсной модуляции (ШИМ).
ESC имеет прошивку, которая определяет особенности его работы.
## Пульт / аппаратура радиоуправления / "аппа"
Пульт для управления квадрокоптером, работающий по радиоканалу. Для работы пульта к полетном контроллеру необходимо подключить ресивер.
Клевером, также, можно [управлять со смартфона](rc.md).
## Телеметрия
**1\.** Передача данных о состоянии квадрокоптера или другого аппарата на расстояние.
**2\.** Совокупность данных о состоянии аппарата, так таковая (высота, ориентация, глобальные координаты и т. д.).
**3\.** Система для передачи данных о состоянии аппарата или команд для него по воздуху. Примеры: радиомодемы (RFD900, 3DR Radio Modem), Wi-Fi модули (ESP-07). Raspberry Pi на Клевере также может быть использован в качестве модуля для телемерии: [использование QGroundControl через Wi-Fi](gcs_bridge.md).
## Арминг
Armed состояние коптера готовности к полету. При поднятии стика газа либо при посылке внешней команды с целевой точкой – коптер полетит. Обычно коптер начинает вращать винтами при переходе в состояние "armed" даже если стик газа находится внизу.
Противолположным состоянием является Disarmed.
## PX4
Популярный полетный контроллер с открытым исходным кодом, работащий на платах PixHawk, PixRacer и других. PX4 рекомендуется для использования на Клевере.
## APM / ArduPilot
Полетный контроллер с открытым исходным кодом, изначально созданный для платы Arduino. Впоследствии был портирован на PixHawk, PixRacer и другие платы.
## MAVLink
Протокол для взаимодействия дронов, наземных станций и других аппаратов по радиоканалам. Обычно именно этот протокол используется для телеметрии.
## ROS
Популярный фреймворк для написания сложных роботехнических приложений.
## MAVROS
Библиотека-связующее звено между аппаратом, работающем по протоколу MAVLink, и ROS.

View File

@@ -2,8 +2,21 @@
=== ===
При подключении GPS появляются следующие возможности: При подключении GPS появляются следующие возможности:
* Удерживание коптером позиции при полете на улице * Удерживание коптером позиции при полете на улице
* Программирование автономных миссий в программе QGroundControl * Программирование автономных миссий в программе QGroundControl
* Полеты на глобальные точки в автономном режиме при помощи модуля [simple offboard](simple_offboard.md). * Полеты на глобальные точки в автономном режиме при помощи модуля [simple offboard](simple_offboard.md).
TODO Полезные ссылки:
* https://docs.px4.io/en/assembly/quick_start_pixhawk.html
* http://ardupilot.org/copter/docs/common-pixhawk-wiring-and-quick-start.html
* http://ardupilot.org/copter/docs/common-installing-3dr-ublox-gps-compass-module.html
Подключение
---
GPS-модуль подключается к разъемам "GPS" и "I2C" (компас) полетного контроллера.
При подключении GPS, необходимо заново откалибровать магнитометры в программе QGroundControl, подключившись по [Wi-Fi](wifi.md) или USB.
Далее, необходимо включить GPS в параметре `EKF2_AID_MASK` (при использовании EKF2) или `LPE_FUSION` (при использовании LPE).

View File

@@ -1,6 +1,6 @@
## Работа со светодиодной лентой на Raspberry 3 # Работа со светодиодной лентой на Raspberry 3
#### Подключение и определение типа ленты ## Подключение и определение типа ленты
Есть два основных типа адресуемых светодиодов: WS2812 и WS2812B. Принцип управления один и тот же, однако тайминги разные. Найдите на ленте чип светодиода и определите сколько у него ножек: 6 или 4. Если ножек 6, то это WS2812, если 4 - то WS2812B или его аналог SK6812. Есть два основных типа адресуемых светодиодов: WS2812 и WS2812B. Принцип управления один и тот же, однако тайминги разные. Найдите на ленте чип светодиода и определите сколько у него ножек: 6 или 4. Если ножек 6, то это WS2812, если 4 - то WS2812B или его аналог SK6812.
@@ -16,7 +16,7 @@
Типы лент для обозначения ленты в коде описаны в [файле](https://github.com/jgarff/rpi_ws281x/blob/master/ws2811.h). Основные типы лент - это WS2812\_STRIP \(для WS2812\) и SK6812\_STRIP \(для WS2812B или SK6812\). Типы лент для обозначения ленты в коде описаны в [файле](https://github.com/jgarff/rpi_ws281x/blob/master/ws2811.h). Основные типы лент - это WS2812\_STRIP \(для WS2812\) и SK6812\_STRIP \(для WS2812B или SK6812\).
#### Установка библиотеки для работы со светодиодной лентой ## Установка библиотеки для работы со светодиодной лентой
Определите папку, в которой будут находиться файлы библиотеки, и открыть путь к этой папке в терминале. По-умолчанию можно использовать домашнюю папку, для перехода в неё нужно выполнить команду Определите папку, в которой будут находиться файлы библиотеки, и открыть путь к этой папке в терминале. По-умолчанию можно использовать домашнюю папку, для перехода в неё нужно выполнить команду
@@ -51,7 +51,7 @@ sudo python ./setup.py build
sudo python ./setup.py install sudo python ./setup.py install
``` ```
#### Пример программы для светодиодной ленты на RPI3 ## Пример программы для светодиодной ленты на RPI3
Откройте в текстовом редакторе файл strandtest.py из папки python/examples \(находится в папке с библиотекой\) Откройте в текстовом редакторе файл strandtest.py из папки python/examples \(находится в папке с библиотекой\)
@@ -96,7 +96,7 @@ sudo python strandtest.py
Права администратора необходимы для выполнения скрипта, т.к. без них нет доступа к функциям прерывания, которые использует библиотека для работы с лентой. Права администратора необходимы для выполнения скрипта, т.к. без них нет доступа к функциям прерывания, которые использует библиотека для работы с лентой.
#### Совместимость с ROS и python ## Совместимость с ROS и python
При запуске программы с помощью sudo пользовательское окружение изменяется и появляются ошибки импорта библиотек, т.к. в окружении отсутствуют необходимые пути. Чтобы добавить в окружение пути к библиотекам python и пакетам ROS, необходимо добавить в файл /etc/sudoers следующие строки: При запуске программы с помощью sudo пользовательское окружение изменяется и появляются ошибки импорта библиотек, т.к. в окружении отсутствуют необходимые пути. Чтобы добавить в окружение пути к библиотекам python и пакетам ROS, необходимо добавить в файл /etc/sudoers следующие строки:
@@ -107,7 +107,7 @@ Defaults env_keep += "ROS_ROOT"
Defaults env_keep += "ROS_MASTER_URI" Defaults env_keep += "ROS_MASTER_URI"
``` ```
#### Функции для работы со светодиодной лентой ## Функции для работы со светодиодной лентой
Для подключения библиотеки и её корректной работы требуется подключить следующие модули: neopixels - для работы ленты, time - для управления задержками, sys и signal для прерываний и формирования управляющего сигнала. Для подключения библиотеки и её корректной работы требуется подключить следующие модули: neopixels - для работы ленты, time - для управления задержками, sys и signal для прерываний и формирования управляющего сигнала.
@@ -144,23 +144,23 @@ pydoc neopixel
```(bash) ```(bash)
Help on module neopixel: Help on module neopixel:
NAME NAME
neopixel neopixel
DESCRIPTION DESCRIPTION
# Adafruit NeoPixel library port to the rpi_ws281x library. # Adafruit NeoPixel library port to the rpi_ws281x library.
# Author: Tony DiCola (tony@tonydicola.com) # Author: Tony DiCola (tony@tonydicola.com)
CLASSES CLASSES
__builtin__.object __builtin__.object
Adafruit_NeoPixel Adafruit_NeoPixel
class Adafruit_NeoPixel(__builtin__.object) class Adafruit_NeoPixel(__builtin__.object)
| Methods defined here: | Methods defined here:
| |
| __del__(self) | __del__(self)
| |
| __init__(self, num, pin, freq_hz=800000, dma=5, invert=False) | __init__(self, num, pin, freq_hz=800000, dma=5, invert=False)
| Class to represent a NeoPixel/WS281x LED display. Num should be the | Class to represent a NeoPixel/WS281x LED display. Num should be the
| number of pixels in the display, and pin should be the GPIO pin connected | number of pixels in the display, and pin should be the GPIO pin connected
@@ -168,38 +168,38 @@ pydoc neopixel
| parameters are freq, the frequency of the display signal in hertz (default | parameters are freq, the frequency of the display signal in hertz (default
| 800khz), dma, the DMA channel to use (default 5), and invert, a boolean | 800khz), dma, the DMA channel to use (default 5), and invert, a boolean
| specifying if the signal line should be inverted (default False). | specifying if the signal line should be inverted (default False).
| |
| begin(self) | begin(self)
| Initialize library, must be called once before other functions are | Initialize library, must be called once before other functions are
| called. | called.
| |
| getPixelColor(self, n) | getPixelColor(self, n)
| Get the 24-bit RGB color value for the LED at position n. | Get the 24-bit RGB color value for the LED at position n.
| |
| getPixels(self) | getPixels(self)
| Return an object which allows access to the LED display data as if | Return an object which allows access to the LED display data as if
| it were a sequence of 24-bit RGB values. | it were a sequence of 24-bit RGB values.
| |
| numPixels(self) | numPixels(self)
| Return the number of pixels in the display. | Return the number of pixels in the display.
| |
| setBrightness(self, brightness) | setBrightness(self, brightness)
| Scale each LED in the buffer by the provided brightness. A brightness | Scale each LED in the buffer by the provided brightness. A brightness
| of 0 is the darkest and 255 is the brightest. Note that scaling can have | of 0 is the darkest and 255 is the brightest. Note that scaling can have
| quantization issues (i.e. blowing out to white or black) if used repeatedly! | quantization issues (i.e. blowing out to white or black) if used repeatedly!
| |
| setPixelColor(self, n, color) | setPixelColor(self, n, color)
| Set LED at position n to the provided 24-bit color value (in RGB order). | Set LED at position n to the provided 24-bit color value (in RGB order).
| |
| setPixelColorRGB(self, n, red, green, blue) | setPixelColorRGB(self, n, red, green, blue)
| Set LED at position n to the provided red, green, and blue color. | Set LED at position n to the provided red, green, and blue color.
| Each color component should be a value from 0 to 255 (where 0 is the | Each color component should be a value from 0 to 255 (where 0 is the
| lowest intensity and 255 is the highest intensity). | lowest intensity and 255 is the highest intensity).
| |
| show(self) | show(self)
| Update the display with the data from the LED buffer. | Update the display with the data from the LED buffer.
| |
FUNCTIONS FUNCTIONS
Color(red, green, blue) Color(red, green, blue)
Convert the provided red, green, blue color to a 24-bit color value. Convert the provided red, green, blue color to a 24-bit color value.
@@ -207,7 +207,7 @@ pydoc neopixel
and 255 is the highest intensity. and 255 is the highest intensity.
``` ```
#### Почему именно так и можно ли по-другому? ## Почему именно так и можно ли по-другому?
Основные типы лент, которые используются для Clever3, это WS2812, WS2812B и SK6812 \(аналог WS2812B\). Они управляются по одному и тому же принципу: для массива светодиодов в ленте отправляется пакет данных по 24 бита на светодиод; каждый светодиод считывает первые 24 бита из пришедших к нему данных и устанавливает соответствующий цвет, остальные данные он отправляет следующему светодиоду в ленте. Нули и единицы задаются разными сочетаниями длительностей высокого и низкого уровня в импульсе. Основные типы лент, которые используются для Clever3, это WS2812, WS2812B и SK6812 \(аналог WS2812B\). Они управляются по одному и тому же принципу: для массива светодиодов в ленте отправляется пакет данных по 24 бита на светодиод; каждый светодиод считывает первые 24 бита из пришедших к нему данных и устанавливает соответствующий цвет, остальные данные он отправляет следующему светодиоду в ленте. Нули и единицы задаются разными сочетаниями длительностей высокого и низкого уровня в импульсе.
@@ -227,4 +227,3 @@ pydoc neopixel
3. Если нам важна и работа аудио, и подключение к SPI устройств кроме лед ленты, то можно управлять лентой по каналу PCM \(GPIO 21 или 31\). При этом никаких дополнительных манипуляций с распберри не требуется. 3. Если нам важна и работа аудио, и подключение к SPI устройств кроме лед ленты, то можно управлять лентой по каналу PCM \(GPIO 21 или 31\). При этом никаких дополнительных манипуляций с распберри не требуется.
Исходя из вышеперечисленных способов управления лентой, наилучшим вариантом, позволяющим управлять лентой, сохранить работоспособность встроенной аудиосистемы и возможность подключения всяческих устройств и датчиков по SPI, является управление по каналу PCM \(GPIO 21\) с использованием 10 канала DMA. Исходя из вышеперечисленных способов управления лентой, наилучшим вариантом, позволяющим управлять лентой, сохранить работоспособность встроенной аудиосистемы и возможность подключения всяческих устройств и датчиков по SPI, является управление по каналу PCM \(GPIO 21\) с использованием 10 канала DMA.

View File

@@ -1,26 +1,51 @@
Оглавление # Теория
=======
[**Урок №1** «Знакомство. Принципы проектирования и строение мультикоптеров»](lesson1.md) [**Урок №1** «Знакомство. Принципы проектирования и строение мультикоптеров»](https://github.com/CopterExpress/clever/blob/master/docs/lesson1.md)
[**Урок №2** «Основы электричества»](lesson2.md) [**Урок №2** «Основы электричества»](https://github.com/CopterExpress/clever/blob/master/docs/lesson2.md)
[**Урок №3** «Теория пайки»](lesson3.md) [**Урок №3** «Теория пайки»](https://github.com/CopterExpress/clever/blob/master/docs/lesson3.md)
[**Урок №4** «Аэродинамика полета. Пропеллер»](lesson4.md) [**Урок №4** «Аэродинамика полета. Пропеллер»](https://github.com/CopterExpress/clever/blob/master/docs/lesson4.md)
[**Урок №5** «Бесколлекторные двигатели и регуляторы их хода»](lesson5.md) [**Урок №5** «Бесколлекторные двигатели и регуляторы их хода»](https://github.com/CopterExpress/clever/blob/master/docs/lesson5.md)
[**Урок №6** «Основы электромагнетизма. Типы двигателей»](lesson6.md) [**Урок №6** «Основы электромагнетизма. Типы двигателей»](https://github.com/CopterExpress/clever/blob/master/docs/lesson6.md)
[**Урок №7** «Принцип работы, типы и устройство аккумуляторов»](lesson7.md) [**Урок №7** «Принцип работы, типы и устройство аккумуляторов»](https://github.com/CopterExpress/clever/blob/master/docs/lesson7.md)
[**Урок №8** «Управление полётом мультикоптера. Принцип функционирования полётного контроллера. ПИД регуляторы»](lesson8.md) [**Урок №8** «Управление полётом мультикоптера. Принцип функционирования полётного контроллера. ПИД регуляторы»](https://github.com/CopterExpress/clever/blob/master/docs/lesson8.md)
[**Урок №9** «Основы радиосвязи. Принцип работы радиоаппаратуры управления»](lesson9.md) [**Урок №9** «Основы радиосвязи. Принцип работы радиоаппаратуры управления»](https://github.com/CopterExpress/clever/blob/master/docs/lesson9.md)
[**Урок №10** «Аналоговая и цифровая видеотрансляция. Применяемые камеры, радиопередатчики иприёмники»](lesson10.md) [**Урок №10** «Аналоговая и цифровая видеотрансляция. Применяемые камеры, радиопередатчики иприёмники»](https://github.com/CopterExpress/clever/blob/master/docs/lesson10.md)
Видеоуроки ## Видеоуроки
----------
Немного о видах коптеров
<iframe width="560" height="315" src="https://www.youtube.com/embed/LFOmZZwg-PE" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
Часть 1
<iframe width="560" height="315" src="https://www.youtube.com/embed/e9Z1pjW0vQU" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
Часть 2
<iframe width="560" height="315" src="https://www.youtube.com/embed/jWMGSgiLD_E" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
Часть 3
<iframe width="560" height="315" src="https://www.youtube.com/embed/WhxxXD4b1MY" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
Часть 4
<iframe width="560" height="315" src="https://www.youtube.com/embed/jkA9F9lSWDM" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
Часть 5
<iframe width="560" height="315" src="https://www.youtube.com/embed/Cz7EbJ1-xMw" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
Часть 6
<iframe width="560" height="315" src="https://www.youtube.com/embed/v00oNVzwICg" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

179
docs/mavlink.md Normal file
View File

@@ -0,0 +1,179 @@
# MAVLink
Основная документация: https://mavlink.io/en/.
MAVLink – это протокол для организации связи между автономными летательными и транспортными системами (дронами, самолетами, автомобилями). Проктол MAVLink лежит в основе взаимодействия между PixHawk и Raspberry Pi.
В Клевер включено 2 обертки над этим протоколом: [MAVROS](mavros.md) и [simple_offboard](simple_offboard.md).
Код для отправки произвольного MAVLink сообщения можно найти в [примерах](snippets.md).
## Основные концепции
### Канал связи
Протокол MAVLink может быть использован поверх следующих каналов связи:
* последовательное соединение (UART, USB и др.);
* UDP (Wi-Fi, Ethernet, 3G, LTE);
* TCP (Wi-Fi, Ethernet, 3G, LTE).
### Сообщение
MAVLink-сообщение это отдельная "порция" данных, передаваемая между устройствами. Отдельное MAVLink-сообщение содержит информацию о состоянии дрона (или другого устройства) или команду для дрона.
Примеры MAVLink-сообщений:
* `ATTITUDE`, `ATTITUDE_QUATERNION` ориентация квадрокоптера в пространстве;
* `LOCAL_POSITION_NED` локальная позиция квадрокоптера;
* `GLOBAL_POSITION_INT` глобальная позиция квадрокоптера (широта/долгота/высота);
* `COMMAND_LONG` команда для квадрокоптера (взлететь, сесть, переключить режим и т. д.).
Полный список MAVLink-сообщений можно посмотреть в [документации MAVLink](http://mavlink.org/messages/common).
### Система, компонент системы
Каждое устройство (дрон, базовая станция и т. д.) имеет ID в сети MAVLink. В PX4 MAVLink ID менятся с помощью параметра `MAV_SYS_ID`. Каждое MAVLink сообщение содержит поле с ID системы-отправителя. Кроме того, некоторые сообщения (например, `COMMAND_LONG`) содержат также ID системы-получателя.
Помимо ID систем, сообщения могут содержать ID компонента-отправителя и компонента-получателя. Примеры компонентов системы: полетный контроллер, внешняя камера, управляющий бортовой компьютер (Raspberry Pi в случае Клевера) и т. д.
### Пример пакета
Пример структуры MAVLink-пакета с сообщением `COMMAND_LONG`:
<table>
<tr>
<th></th>
<th>Поле</th>
<th>Длина</th>
<th>Имя</th>
<th>Комментарий</th>
</tr>
<tr>
<td rowspan="8"><div style="transform: rotate(-90deg)">Заголовок</div></td>
<td><code>magic</code></td>
<td>1 байт</td>
<td>Метка начала</td>
<td>0xFD для MAVLink 2.0</td>
</tr>
<tr>
<td><code>len</code></td>
<td>1 байт</td>
<td>Размер данных</td>
<td></td>
</tr>
<tr>
<td><code>incompat_flags</code></td>
<td>1 байт</td>
<td>Обратно несовместимые флаги</td>
<td>На данный момент не используется</td>
</tr>
<tr>
<td><code>compat_flags</code></td>
<td>1 байт</td>
<td>Обратно совместимые флаги</td>
<td>На данный момент не используется</td>
</tr>
<tr>
<td><code>seq</code></td>
<td>1 байт</td>
<td>Порядковый номер сообщения</td>
<td></td>
</tr>
<tr>
<td><code>sysid</code></td>
<td>1 байт</td>
<td>ID системы-отправителя</td>
<td></td>
</tr>
<tr>
<td><code>compid</code></td>
<td>1 байт</td>
<td>ID компонента-отправителя</td>
<td></td>
</tr>
<tr>
<td><code>msgid</code></td>
<td>3 байта</td>
<td>ID сообщения</td>
<td></td>
</tr>
<tr style="background: #fffee6">
<td rowspan="11"><div style="transform: rotate(-90deg)">Данные (пример)</div></td>
<td><code>target_system</code></td>
<td>1 байт</td>
<td>ID системы-получателя</td>
<td></td>
</tr>
<tr style="background: #fffee6">
<td><code>target_component</code></td>
<td>1 байт</td>
<td>ID компонента–получателя</td>
<td></td>
</tr>
<tr style="background: #fffee6">
<td><code>command</code></td>
<td>2 байта</td>
<td>ID команды</td>
<td></td>
</tr>
<tr style="background: #fffee6">
<td><code>confirmation</code></td>
<td>1 байт</td>
<td>Номер для подтверждения</td>
<td></td>
</tr>
<tr style="background: #fffee6">
<td><code>param1</code></td>
<td>4 байта</td>
<td>Параметр 1</td>
<td rowspan="7">Число с плавающей точкой одинарной точности</td>
</tr>
<tr style="background: #fffee6">
<td><code>param2</code></td>
<td>4 байта</td>
<td>Параметр 2</td>
</tr>
<tr style="background: #fffee6">
<td><code>param3</code></td>
<td>4 байта</td>
<td>Параметр 3</td>
</tr>
<tr style="background: #fffee6">
<td><code>param4</code></td>
<td>4 байта</td>
<td>Параметр 4</td>
</tr>
<tr style="background: #fffee6">
<td><code>param5</code></td>
<td>4 байта</td>
<td>Параметр 5</td>
</tr>
<tr style="background: #fffee6">
<td><code>param6</code></td>
<td>4 байта</td>
<td>Параметр 6</td>
</tr>
<tr style="background: #fffee6">
<td><code>param7</code></td>
<td>4 байта</td>
<td>Параметр 7</td>
</tr>
<tr>
<td></td>
<td><code>checksum</code></td>
<td>2 байта</td>
<td>Контрольная сумма</td>
<td></td>
</tr>
<tr>
<td></td>
<td><code>signature</code></td>
<td>13 байт</td>
<td>Сигнатура (опционально)</td>
<td>Позволяет убедиться, что пакет не был скомпроментирован.
Обычно не используется.</td>
</tr>
</table>
<span style="background: #fffee6">Желтым</span> цветом выделены поля данных (полезной нагрузки). Для каждого типа сообщения существует свой набор таких полей.

View File

@@ -1,12 +1,14 @@
# MAVROS # MAVROS
Основная статья: [http://wiki.ros.org/mavros](http://wiki.ros.org/mavros) Основная документация: [http://wiki.ros.org/mavros](http://wiki.ros.org/mavros)
MAVROS \(MAVLink + ROS\) — это пакет для ROS, предоставляющий возможность управлять беспилотниками по протоколу MAVLink. MAVROS поддерживает полетные стеки PX4 и APM. Связь организовывается по UART, USB, TCP или UDP. MAVROS \(MAVLink + ROS\) — это пакет для ROS, предоставляющий возможность управлять беспилотниками по протоколу [MAVLink](mavlink.md). MAVROS поддерживает полетные стеки PX4 и APM. Связь организовывается по UART, USB, TCP или UDP.
MAVROS подписывается определенные ROS-топики в ожидании команд, публикует в другие топики телеметрию, и предоставляет сервисы. MAVROS подписывается определенные ROS-топики в ожидании команд, публикует в другие топики телеметрию, и предоставляет сервисы.
Узел mavros автоматически запускается в launch-файле Клевера. Для [настройки типа подключения](connection.md) см. аргумент `fcu_conn`. Нода MAVROS автоматически запускается в launch-файле Клевера. Для [настройки типа подключения](connection.md) см. аргумент `fcu_conn`.
> **Note** Упрощенное взаимодействие с коптером возможно с использованием пакета [`simple_offboard`](simple_offboard.md).
## Основные сервисы ## Основные сервисы
@@ -18,7 +20,7 @@ MAVROS подписывается определенные ROS-топики в
`/mavros/state` — статус подключения к полетному контроллеру. Режим полетного контроллера. `/mavros/state` — статус подключения к полетному контроллеру. Режим полетного контроллера.
`/mavros/local_position/pose` — локальная позиция коптера в системе координат ENU. `/mavros/local_position/pose` — локальная позиция коптера в системе координат ENU и его ориентация.
`/mavros/local_position/velocity` — текущая скорость в локальных координатах. Угловые скорости. `/mavros/local_position/velocity` — текущая скорость в локальных координатах. Угловые скорости.
@@ -28,6 +30,8 @@ MAVROS подписывается определенные ROS-топики в
`/mavros/global_position/rel_alt` — относительная высота \(относительно высоты включения моторов\). `/mavros/global_position/rel_alt` — относительная высота \(относительно высоты включения моторов\).
Просмотр сообщений, публикуемых в топики возможен с помощью утилиты `rostopic`, например `rostopic echo /mavros/state`. Подробнее см. [работа с ROS](ros.md).
## Основные топики для публикации ## Основные топики для публикации
`/mavros/setpoint_position/local` — установить целевую позицию и рысканье \(yaw\) беспилотника \(в системе координат ENU\). `/mavros/setpoint_position/local` — установить целевую позицию и рысканье \(yaw\) беспилотника \(в системе координат ENU\).
@@ -45,6 +49,3 @@ MAVROS подписывается определенные ROS-топики в
`/mavros/setpoint_raw/attitude` — отправка пакета [SET\_ATTITUDE\_TARGET](https://pixhawk.ethz.ch/mavlink/#SET_ATTITUDE_TARGET). Позвлояет установить целевую ориенатацию /угловые скорости и уровень газа. Выбор устанавливаемых величин осуществляется с помощью поля `type_mask` `/mavros/setpoint_raw/attitude` — отправка пакета [SET\_ATTITUDE\_TARGET](https://pixhawk.ethz.ch/mavlink/#SET_ATTITUDE_TARGET). Позвлояет установить целевую ориенатацию /угловые скорости и уровень газа. Выбор устанавливаемых величин осуществляется с помощью поля `type_mask`
`/mavros/setpoint_raw/global` — отправка пакета [SET\_POSITION\_TARGET\_GLOBAL\_INT](https://pixhawk.ethz.ch/mavlink/#SET_POSITION_TARGET_GLOBAL_INT). Позволяет установить целевую позицию в глобальных координатах \(ширина, долгота, высота\), а также скорости полета. **Не поддерживается в PX4** \([issue](https://github.com/PX4/Firmware/issues/7552)\). `/mavros/setpoint_raw/global` — отправка пакета [SET\_POSITION\_TARGET\_GLOBAL\_INT](https://pixhawk.ethz.ch/mavlink/#SET_POSITION_TARGET_GLOBAL_INT). Позволяет установить целевую позицию в глобальных координатах \(ширина, долгота, высота\), а также скорости полета. **Не поддерживается в PX4** \([issue](https://github.com/PX4/Firmware/issues/7552)\).
[Упрощенное управление коптером с помощью Simple Offboard](simple_offboard.md).

View File

@@ -7,93 +7,47 @@
Учебно-методическое пособие Учебно-методическое пособие
--------------------------- ---------------------------
[Урок 1. «Знакомство. Принципы проектирования и строение мультикоптеров»](metodmaterials.md) [Урок 1. «Знакомство. Принципы проектирования и строение мультикоптеров»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 2. «Основы электричества»](metodmaterials.md) [Урок 2. «Основы электричества»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 3. «Теория пайки»](metodmaterials.md) [Урок 3. «Теория пайки»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 4. «Аэродинамика полета. Пропеллер»](metodmaterials.md) [Урок 4. «Аэродинамика полета. Пропеллер»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 5. «Основы электромагнетизма. Типы двигателей»](metodmaterials.md) [Урок 5. «Основы электромагнетизма. Типы двигателей»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 6. «Бесколлекторные двигатели и регуляторы их хода»](metodmaterials.md) [Урок 6. «Бесколлекторные двигатели и регуляторы их хода»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 7. «Принцип работы, типы и устройство аккумуляторов»](metodmaterials.md) [Урок 7. «Принцип работы, типы и устройство аккумуляторов»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 8. «Управление полётом мультикоптера. Принцип функционирования полетного контроллера. ПИД регуляторы»](metodmaterials.md) [Урок 8. «Управление полётом мультикоптера. Принцип функционирования полетного контроллера. ПИД регуляторы»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 9. «Основы радиосвязи. Принцип работы радиоаппаратуры управления»](metodmaterials.md) [Урок 9. «Основы радиосвязи. Принцип работы радиоаппаратуры управления»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 10. «Аналоговая и цифровая видеотрансляция. Применяемые камеры, радиопередатчики и приёмники»](metodmaterials.md) [Урок 10. «Аналоговая и цифровая видеотрансляция. Применяемые камеры, радиопередатчики и приёмники»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 11. «Техника безопасности при сборке и настройке коптеров, при подготовке к вылету. Техника безопасности при работе с аккумуляторами»](metodmaterials.md) [Урок 11. «Техника безопасности при сборке и настройке коптеров, при подготовке к вылету. Техника безопасности при работе с аккумуляторами»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 12. «Теория ручного визуального пилотирования»](metodmaterials.md) [Урок 12. «Теория ручного визуального пилотирования»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 13. «Техника безопасности при летной эксплуатации коптера»](metodmaterials.md) [Урок 13. «Техника безопасности при летной эксплуатации коптера»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 14. «Обучение лётному мастерству»](metodmaterials.md) [Урок 14. «Обучение лётному мастерству»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 15. «Основы радиоэлектроники, схемотехники и макетирования электрических схем»](metodmaterials.md) [Урок 15. «Основы радиоэлектроники, схемотехники и макетирования электрических схем»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 16. «Основы работы с аналоговым и цифровым сигналом»](metodmaterials.md) [Урок 16. «Основы работы с аналоговым и цифровым сигналом»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 17. «Основы работы с лабораторным оборудованием»](metodmaterials.md) [Урок 17. «Основы работы с лабораторным оборудованием»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 18. «Теория FPV полетов»](metodmaterials.md) [Урок 18. «Теория FPV полетов»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 19. «История автономных полетов. Развитие автопилотов в авиации»](metodmaterials.md) [Урок 19. «История автономных полетов. Развитие автопилотов в авиации»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 20. «Основы программирование на языке Python»](metodmaterials.md) [Урок 20. «Основы программирование на языке Python»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 21. «Знакомство с компьютером Raspberry Pi»](metodmaterials.md) [Урок 21. «Знакомство с компьютером Raspberry Pi»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
[Урок 22. «Управление автономным дроном: теория»](metodmaterials.md) [Урок 22. «Управление автономным дроном: теория»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
Контрольные вопросы и тесты к разделам
------------------
[Урок 1. «Знакомство. Принципы проектирования и строение мультикоптеров»](tests.md)
[Урок 2. «Основы электричества»](tests.md)
[Урок 3. «Теория пайки»](tests.md)
[Урок 4. «Аэродинамика полета. Пропеллер»](tests.md)
[Урок 5. «Основы электромагнетизма. Типы двигателей»](tests.md)
[Урок 6. «Бесколлекторные двигатели и регуляторы их хода»](tests.md)
[Урок 7. «Принцип работы, типы и устройство аккумуляторов»](tests.md)
[Урок 8. «Управление полётом мультикоптера. Принцип функционирования полетного контроллера. ПИД регуляторы»](tests.md)
[Урок 9. «Основы радиосвязи. Принцип работы радиоаппаратуры управления»](tests.md)
[Урок 10. «Аналоговая и цифровая видеотрансляция. Применяемые камеры, радиопередатчики и приёмники»](tests.md)
[Урок 11. «Техника безопасности при сборке и настройке коптеров, при подготовке к вылету. Техника безопасности при работе с аккумуляторами»](tests.md)
[Урок 12. «Теория ручного визуального пилотирования»](tests.md)
[Урок 13. «Техника безопасности при летной эксплуатации коптера»](tests.md)
[Урок 14. «Обучение лётному мастерству»](tests.md)
[Урок 15. «Основы радиоэлектроники, схемотехники и макетирования электрических схем»](tests.md)
[Урок 16. «Основы работы с аналоговым и цифровым сигналом»](tests.md)
[Урок 17. «Основы работы с лабораторным оборудованием»](tests.md)
[Урок 18. «Теория FPV полетов»](tests.md)
[Урок 19. «История автономных полетов. Развитие автопилотов в авиации»](tests.md)
[Урок 20. «Основы программирование на языке Python»](tests.md)
[Урок 21. «Знакомство с компьютером Raspberry Pi»](tests.md)
[Урок 22. «Управление автономным дроном: теория»](tests.md)

View File

@@ -12,8 +12,7 @@
* об истории и тенденциях развития беспилотных летательных аппаратов; о том как можно улучшить их характеристики; * об истории и тенденциях развития беспилотных летательных аппаратов; о том как можно улучшить их характеристики;
* правила техники безопасности при эксплуатации БПЛА; * правила техники безопасности при эксплуатации БПЛА;
* основные компоненты коптеров; * основные компоненты коптеров;
* конструктивные особенности различных моделей, сооружений и * конструктивные особенности различных моделей, сооружений и механизмов;
механизмов;
* компьютерные среды для настройки полетных контроллеров; * компьютерные среды для настройки полетных контроллеров;
* основы аэродинамики полета; * основы аэродинамики полета;
* основы электричества, радиоэлектроники; * основы электричества, радиоэлектроники;
@@ -51,7 +50,9 @@
**Подведение итогов** **Подведение итогов**
Подведение итогов по курсу проводится в 3 этапа: Ниже предложен один из вариантов подведения итогов курса.
Финальное мероприятие включает 3 раздела:
1. Итоговый тест (см. [проверочные задания](tests.md)). 1. Итоговый тест (см. [проверочные задания](tests.md)).
2. Финальная гонка. 2. Финальная гонка.

View File

@@ -1,21 +1,23 @@
# Образ для Raspberry Pi # Образ для Raspberry Pi
## Установка образа операционной системы на MicroSD карту
Для установки образа воспользуйтесь утилитой [Etcher](https://etcher.io):
[![Etcher](https://etcher.io/static/screenshot.gif)
](https://etcher.io)
## Образы
На образе установлены: На образе установлены:
* Raspbian Stretch * Raspbian Stretch
* ROS Kinetic * ROS Kinetic
* [Пакет ПО для Клевера](https://github.com/CopterExpress/clever_bundle) * [Пакет ПО для Клевера](https://github.com/CopterExpress/clever)
|Версия|Дата|Ссылка|Примечания| **Свежую версию образа можно [скачать на GitHub в разделе Releases](https://github.com/CopterExpress/clever/releases).**
|-|-|-|-|
|0.2|24.01.18|[Скачать](https://yadi.sk/d/n_Krnor03RkntU)|| ## Установка образа ОС на MicroSD карту
|0.1|15.12.17|[Скачать](https://drive.google.com/open?id=1Gtj_0iB7dFuorfUKAUUV8ImjmkZCkvc7)||
Для установки образа воспользуйтесь утилитой [Etcher](https://etcher.io).
[![Etcher](https://etcher.io/static/screenshot.gif)](https://etcher.io)
## Версия образа
Версию установленного образа можно узнать в файле `/etc/clever_version`:
```bash
cat /etc/clever_version
```

View File

@@ -22,16 +22,16 @@ PX4
### С использованием дополнительных датчиков (ASSISTED) ### С использованием дополнительных датчиков (ASSISTED)
* **ALTCTL** — управление скоростью изменения высоты полета, углами по тангажу и крену и угловой скоростью по рысканью. Используется барометр (или иной датчик высоты). * **ALTCTL** (ALTITUDE) — управление скоростью изменения высоты полета, углами по тангажу и крену и угловой скоростью по рысканью. Используется барометр (или иной датчик высоты).
* **POSCTL** — управление скоростями набора высоты, скоростью движения вперед/назад и вправо/влево, угловой скоростью по рысканью. Наиболее простой для полетов режим. Используется барометр, GPS, компьютерное зрение, другие датчики. * **POSCTL** (POSITION) — управление скоростями набора высоты, скоростью движения вперед/назад и вправо/влево, угловой скоростью по рысканью. Наиболее простой для полетов режим. Используется барометр, GPS, компьютерное зрение, другие датчики.
### Автоматический полет (AUTO) ### Автоматический полет (AUTO)
В режиме автоматического полета квадрокоптер игнорирует сигналы с пульта. В режиме автоматического полета квадрокоптер игнорирует сигналы с пульта.
* **AUTO.MISSION** PX4 выполняет заранее загруженную в квадрокоптер миссию (миссия загружается с помощью QGroundControl, или по MAVLINK используя MAVROS). * **AUTO.MISSION** PX4 выполняет заранее загруженную в квадрокоптер миссию (миссия загружается с помощью QGroundControl, или по [MAVLink](mavlink.md) используя [MAVROS](mavros.md).
* **AUTO.RTL** – коптер автоматически вовращается в точку взлета. * **AUTO.RTL** – коптер автоматически вовращается в точку взлета.
* **AUTO.LAND** – коптер выполняет посадку. * **AUTO.LAND** – коптер выполняет посадку.

286
docs/network.md Normal file
View File

@@ -0,0 +1,286 @@
# Настройка Wi-Fi
Wi-Fi адаптер на Raspberry Pi имеет два основных режима работы:
1. **Режим клиента** RPi подключается к существующей Wi-Fi сети.
2. **Режим точки доступа** RPi создает Wi-Fi сеть, к которой вы можете подключиться.
При использовании [образа для RPi](microsd_images.md) по умолчанию Wi-Fi адаптер работает в [режиме точки доступа](wifi.md).
## Инструкция для переключения адаптера в режим клиента
1\. Выключите службу `dnsmasq`.
```bash
sudo systemctl stop dnsmasq
sudo systemctl disable dnsmasq
```
2\. Включите получение IP адреса на беспроводном интерфейсе DHCP клиентом.
Для этого удалите следующие строки
```
interface wlan0
static ip_address=192.168.11.1/24
```
из файла `/etc/dhcpcd.conf` вручную или введите следующие команды.
```bash
sudo sed -i 's/interface wlan0//' /etc/dhcpcd.conf
sudo sed -i 's/static ip_address=192.168.11.1\/24//' /etc/dhcpcd.conf
```
3\. Настройте `wpa_supplicant` для подключения к существующей точке доступа.
```bash
cat << EOF | sudo tee /etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=GB
network={
ssid="CLEVER"
psk="cleverwifi"
}
EOF
```
где `CLEVER` название сети, а `cleverwifi` пароль.
4\. Перезапустите службу `dhcpcd`.
```bash
sudo systemctl restart dhcpcd
```
## Инструкция для переключения адаптера в режим точки доступа
1\. Включите статический IP адрес на беспроводном интерфейсе.
Для этого добавьте следующие строки
```
interface wlan0
static ip_address=192.168.11.1/24
```
в файл `/etc/dhcpcd.conf` вручную или введите следующую команду
```bash
cat << EOF | sudo tee -a /etc/dhcpcd.conf
interface wlan0
static ip_address=192.168.11.1/24
EOF
```
2\. Настроите wpa_supplicant на работу в режиме точки доступа.
```bash
cat << EOF | sudo tee /etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=GB
network={
ssid="CLEVER-$(head -c 100 /dev/urandom | xxd -ps -c 100 | sed -e 's/[^0-9]//g' | cut -c 1-4)"
psk="cleverwifi"
mode=2
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP
group=CCMP
auth_alg=OPEN
}
EOF
```
3\. Перезагрузите службу `dhcpcd`.
```bash
sudo systemctl restart dhcpcd
```
4\. Включите службу `dnsmasq`.
```bash
sudo systemctl enable dnsmasq
sudo systemctl start dnsmasq
```
___
Ниже вы можете узнать больше о том, как устроена работа с сетью на RPi.
# Устройство сети RPi
Работа сети на образе **2017-11-29-raspbian-stretch-lite** поддерживается двумя предустановленными службами:
* **networking** — служба включает все сетевые интерфейсы в момент запуска [5].
* **dhcpcd** — служба обеспечивает настройку адресации и маршрутризации на интерфейсах, полученных динамически или указаных в файле настроек статически.
Для работы в режиме роутера (точки доступа) RPi необходим DHCP сервер. Он служит для автоматической выдачи настроек текущей сети подключившимся клиентам. В роли такого сервера может выступать `isc-dhcp-server` или `dnsmasq`.
## dhcpcd
Начиная с Raspbian Jesse настройки сети больше не задаются в файле `/etc/network/interfaces`. Теперь за выдачу адресации и настройку маршрутизации отвечает `dhcpcd` [4].
По умолчанию на всех интерфейсах включен dhcp-клиент. Настройки интерфейсов меняются в файле `/etc/dhcpcd.conf`. Для того, чтобы поднять точку доступа необходимо прописать статический ip-адрес. Для этого в конец файла необходимо добавить следующие строки:
```
interface wlan0
static ip_address=192.168.11.1/24
```
> **Note** Если интерфейс является беспроводным (wlan), то служба `dhcpcd` триггерит `wpa_supplicant` [13], который в свою очередь работает непосредственно с wifi-адаптером и переводит его в заданное состояние.
## wpa_supplicant
**wpa_supplicant** служба конфигурирует Wi-Fi адаптер. Служба `wpa_supplicant` работает не как самостоятельная (хотя как таковая существует), а запускается как дочерний процесс от `dhcpcd`.
Конфигурационный файл по умолчанию должен иметь путь `/etc/wpa_supplicant/wpa_supplicant.conf`.
Пример конфигурационного файла:
```
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=GB
network={
ssid=\"CLEVER-SMIRNOV\"
psk=\"cleverwifi\"
mode=2
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP
group=CCMP
auth_alg=OPEN
}
```
Внутри конфига указываются общие настройки `wpa_supplicant` и параметры для настройки адаптера. Также конфигурационный файл содержит секции `network` основные настройки Wi-Fi сети такие как SSID сети, пароль, режим работы адаптера. Таких блоков может быть несколько, но используется первый рабочий. Например, если вы указали в первом блоке подключение к некоторой недоступной сети, то адаптер будет настроен следующей удачной секцией, если такая есть. Подробнее о синтаксисе `wpa_supplicant.conf` [TODO WIKI].
### wpa_passphrase
`wpa_passphrase` утилита для создания секции `network`.
```bash
wpa_passphrase SSID PASSWORD
```
После выполнения команды скопируйте полученную секцию в ваш конфигурационный файл. Можно удалить закоментированное поле `psk` и оставить только поле с хешем пароля, либо наоборот.
```bash
network={
ssid="SSID"
#psk="PASSWORD"
psk=c2161655c6ba444d8df94cbbf4e9c5c4c61fc37702b9c66ed37aee1545a5a333
}
```
### Несколько Wi-Fi адаптеров
В системе может быть несколько Wi-Fi адаптеров. Если для них корректно подключены драйвера, то их можно увидеть вызвав `ifconfig` (например wlan0 и wlan1).
Если у вас несколько адаптеров, для всех будет использоваться одна и таже самая рабочая секция `network`. Это связано с тем, что для каждого интерфейса, `dhcpcd` отдельно создает по дочернему процессу `wpa_supplicant`, в котором выполняется один тот же код (т. к. конфиг один и тот же).
Для работы нескольких адаптеров с отдельными настройками для каждого, в стандартном вызываемом скрипте `dhcpcd` реализован механизм запуска разных конфигурационных скриптов. Для его использования необходимо переименовать стандартный файл конфига по следующему образцу: `wpa_supplicant-<имя интерфейса>.conf`, например `wpa_supplicant-wlan0.conf`.
Для применения настроек необходимо перезапустить родительский процесс - службу `dhcpcd`. Сделать это можно следующей командой:
```bash
sudo systemctl restart dhcpcd
```
## DHCP сервер
### dnsmasq-base
`dnsmasq-base` консольная утилита, не являющаяся службой, для использования dnsmasq как службы надо установить пакет `dnsmasq`.
```bash
sudo apt install dnsmasq-base
```
```bash
# Вызов dnsmasq-base
sudo dnsmasq --interface=wlan0 --address=/clever/coex/192.168.11.1 --no-daemon --dhcp-range=192.168.11.100,192.168.11.200,12h --no-hosts --filterwin2k --bogus-priv --domain-needed --quiet-dhcp6 --log-queries
# Подробнее о dnsmasq-base
dnsmasq --help
# или
man dnsmasq
```
### dnsmasq
```bash
sudo apt install dnsmasq
```
```bash
cat << EOF | sudo tee -a /etc/dnsmasq.conf
interface=wlan0
address=/clever/coex/192.168.11.1
dhcp-range=192.168.11.100,192.168.11.200,12h
no-hosts
filterwin2k
bogus-priv
domain-needed
quiet-dhcp6
EOF
```
### isc-dhcp-server
```bash
sudo apt install isc-dhcp-server
```
```bash
# https://www.shellhacks.com/ru/sed-find-replace-string-in-file/
sed -i 's/INTERFACESv4=\"\"/INTERFACESv4=\"wlan0\"/' /etc/default/isc-dhcp-server
```
```bash
cat << EOF | sudo tee /etc/dhcp/dhcpd.conf
subnet 192.168.11.0 netmask 255.255.255.0 {
range 192.168.11.11 192.168.11.254;
#option domain-name-servers 8.8.8.8;
#option domain-name "rpi.local";
option routers 192.168.11.1;
option broadcast-address 192.168.11.255;
default-lease-time 600;
max-lease-time 7200;
}
EOF
```
```bash
cat << EOF | sudo tee /etc/network/if-up.d/isc-dhcp-server && sudo chmod +x /etc/network/if-up.d/isc-dhcp-server
#!/bin/sh
if [ "\$IFACE" = "--all" ];
then sleep 10 && systemctl start isc-dhcp-server.service &
fi
EOF
```
## Ссылки
1. [habr.com: Linux WiFi из командной строки с wpa_supplicant](https://habr.com/post/315960/)
2. [wiki.archlinux.org: WPA supplicant (Русский)](https://wiki.archlinux.org/index.php/WPA_supplicant_(Русский))
3. [blog.hoxnox.com: WiFi access point with wpa_supplicant](http://blog.hoxnox.com/gentoo/wifi-hotspot.html)
4. [dmitrysnotes.ru: Raspberry Pi 3. Присвоение статического IP-адреса](http://dmitrysnotes.ru/raspberry-pi-3-prisvoenie-staticheskogo-ip-adresa)
5. [thegeekdiary.com: Linux OS Service network](https://www.thegeekdiary.com/linux-os-service-network/)
6. [frillip.com: USING YOUR NEW RASPBERRY PI 3 AS A WIFI ACCESS POINT WITH HOSTAPD](https://frillip.com/using-your-raspberry-pi-3-as-a-wifi-access-point-with-hostapd/) (также здесь есть инструкция по настройке форвардинга для использования RPi в качестве шлюза для выхода в интернет)
7. [habr.com: Настраиваем ddns-сервер на GNU/Linux Debian 6](https://habr.com/sandbox/30433/) (Хорошая статья по настройке ddns-сервера на основе `bind` и `isc-dhcp-server`)
8. [pro-gram.ru: Установка и настройка DHCP сервера на Ubuntu 16.04.](https://pro-gram.ru/dhcp-server-ubuntu.html) (Настройка isc-dhcp-server)
9. [expert-orda.ru: Настройка DHCP-сервера на Ubuntu](http://expert-orda.ru/posts/liuxnewbie/125--dhcp-ubuntu) (Настройка isc-dhcp-server)
10. [academicfox.com: Raspberry Pi беспроводная точка доступа (WiFi access point)](http://academicfox.com/raspberry-pi-besprovodnaya-tochka-dostupa-wifi-access-point/) (Настройка маршрутов, hostapd, isc-dhcp-server)
11. [weworkweplay.com: Automatically connect a Raspberry Pi to a Wifi network](http://weworkweplay.com/play/automatically-connect-a-raspberry-pi-to-a-wifi-network/) (Есть настройки для создания открытой точки доступа)
12. [wiki.archlinux.org: WPA supplicant](https://wiki.archlinux.org/index.php/WPA%20supplicant)
13. [wiki.archlinux.org: dhcpcd](https://wiki.archlinux.org/index.php/Dhcpcd#10-wpa_supplicant) (dhcpcd hook wpa_supplicant)

94
docs/projects.md Normal file
View File

@@ -0,0 +1,94 @@
# Шаровая защита коптера
1. Введение
Наверное, летать в помещениях приходилось каждому, кто брал в руки коптер. Подобные полеты сопряжены с немалым риском повредить коптер о стены и различные предметы. Даже полеты на относительно больших пространствах связаны с рисками удариться о препятствие: на пути коптера может встать ствол дерева или здание — что уж говорить о полетах в замкнутых пространствах. Подобные «краш-тесты» не очень приятный момент, который может оказаться в лучшем случае причиной потери внушительной суммы денег на ремонт, а в худшем — и вовсе утраты коптера. Тем более неприятны такие ситуации для новичка, который не может своевременно увернуться от препятствия и только учится летать.
Это все подвигло нас к поиску решений. К сожалению, перерыв весь интернет, мы не нашли достаточно легкого и простого в изготовлении решения для простых пользователей, а главное — такого, которое будет всем по карману. Например, защита по контуру пропеллеров неплохо предохраняет сами пропеллеры, но при малейшем касании о препятствие коптер переворачивается и падает. В общем, защита либо не оберегала коптер полностью, либо выглядела несуразно и была слишком узко доступна.
![safetyball](assets/safetyball.png)
Нами было принято сложное решение: придется делать ее полностью самим и почти с нуля, а также поставлена цель сделать ее простой в изготовлении и максимально легкой.
2. Разработка
В результате поиска решения, удовлетворяющего всем нашим требованиям, мы остановились на нескольких схожих вариантах. Было решено сделать защиту в форме полуправильного многогранника (примерами могут служить фуллерен, молекула углерода, или фигура пентакисдодекаэдр) — его мы и выбрали как самый приятный глазу. Кроме того, такая защита легко масштабируема под нужный размер.
При создании такой фигуры используются два вида ребер (далее — лучей): короткие и длинные, их длины рассчитываются исходя из нужного диаметра вписанной в многогранник сферы. Для лучшего понимания я вставлю все необходимые формулы ниже из «Википедии».
![calculation](assets/calculation.png)
С угловыми соединениями (фитингами), тоже не все просто: их также два вида — с пятью гранями при вершине (пять лучей исходят из вершины) и с шестью гранями (шесть лучей исходят из вершины).
3. Первые модели
Была составлена спецификация для удобства контроля процесса изготовления, и мы приступили к моделированию.
Сделав несложные расчеты под нужные размеры, мы построили модели в Inventor CAD.
В ходе проектирования мы столкнулись с проблемами в моделировании угловых соединений, но они были решены упрощением конструкции, а разность углов компенсируется гибкостью материалов. Таким образом, все соединения сидят в небольшом натяге.
![table](assets/table.png)
![elements](assets/elements.png)
(Элементы крепления защиты к корпусу)
![elements1](assets/elements1.png)
4. Материалы
В ходе проектирования встал вопрос, из чего же все-таки сделать такую защиту, чтобы получилось легко и прочно. Ответ пришел, как всегда, совершенно неожиданно. На глаза попались шпажки из бамбука: они достаточно тонкие, чтобы не повлиять на аэродинамику, имеют достаточную гибкость и при этом достаточно прочные. Далее возник вопрос, из чего и как делать фитинги. Конечно же, 3D-печать! 3D-принтер — это вообще незаменимая вещь, тем более для тех, кто любит что-то делать сам. К тому же они из-за не самой высокой цены получили достаточно широкое распространение. На таком принтере можно делать изделия почти любой сложности. То, что надо!
Готовые модели переводим в .stl, закидываем в слайсер (в нашем случае — Cura), вводим настройки под конкретный принтер и пластик и ставим на печать.
Для уменьшения веса был выбран ABC-пластик как один из самых легких и доступных.
![3dmodel](assets/3dmodel.png)
Шпажки были порезаны на расчетные длины и подготовлены к последующей работе.
5. Сборка и установка
После того как все было напечатано и порезано, настало время собирать защиту.
![detal](assets/detal.png)
Сборка здесь самый ответственный момент, так как требует специального алгоритма.
Из пятилучевого фитинга выходят только короткие лучи, в то время как из шестилучевого — только каждая вторая длинная.
Сборка:
1. Вначале собираем все пятилучевые вершины.
2. На каждый луч, исходящий из пятилучевой вершины, надеваем шестилучевую.
3. Соединяем между собой шестилучевые фитинги длинными шпажками.
4. Присоединяем уже собранные пятилучевые вершины к шестилучевым, учитывая, что в шестилучевом фитинге короткие и длинные лучи чередуются.
5. Повторяем процесс для каждой пятилучевой вершины, пока шар не соберется.
После сборки разделяем шар на две полусферы, устанавливаем крепления на коптер, смотрим, что все подходит.
![detal1](assets/detal1.png)
![detal2](assets/detal2.png)
(Пример установки креплений)
Теперь полусферы можно проклеивать. Между собой полусферы не склеиваются — это нужно для установки коптера внутрь. Мы в качестве клея использовали растворитель для пластиков «Дихлорэтан», но с тем же успехом можно использовать и любой быстросохнущий клей для полимеров.
После высыхания защита готова к установке и первым пробным полетам!
![finalball](assets/finalball.png)
(Пока еще без креплений)
![ball](assets/ball.png)
6. Первые полеты
Мы делали защиту под коптер «Клевер 2», являющийся обучающим пособием по сборке и настройке квадрокоптеров, и на него она устанавливается без доработок. Защита весит на 70 г больше (139 грамм), чем стандартная, и на управляемость и время полета почти не влияет.
Отдельно стоит сказать, что излишние вибрации, если таковые имеются, можно убрать путем более жесткого крепления защиты к коптеру.
В итоге получилась необычная защита для коптера с небольшим весом и интересным дизайном, открывающая новые горизонты для полетов в тех местах, где летать для коптера раньше было опасно.

View File

@@ -9,13 +9,14 @@ Raspberry Pi означает «малиновый пирог». Этот сво
* оперативная память 512 Мб; * оперативная память 512 Мб;
* есть USB -разъемы (один или два в зависимости от модели); м * есть USB -разъемы (один или два в зависимости от модели); м
* наиболее применяемая модель мини-компьютера Raspberry Pi модель В - это модель В на с поддержкой Ethernet. * наиболее применяемая модель мини-компьютера Raspberry Pi модель В - это модель В на с поддержкой Ethernet.
Сферы применения компьютера Raspberry Pi достаточно широки, ведь это всё-таки вполне полноценный компьютер. Если вам нужна машина для решения несложных задач, которые не требуют применения мощных ресурсов в плане вычисления, то вы смело можете подключать к устройству Raspberry Pi стандартные элементы компьютера: монитор; мышь; клавиатуру; Сферы применения компьютера Raspberry Pi достаточно широки, ведь это всё-таки вполне полноценный компьютер. Если вам нужна машина для решения несложных задач, которые не требуют применения мощных ресурсов в плане вычисления, то вы смело можете подключать к устройству Raspberry Pi стандартные элементы компьютера: монитор; мышь; клавиатуру;
Вообще, Raspberry Pi очень популярная платформа, на которой можно реализовать множество проектов, таких как Вообще, Raspberry Pi очень популярная платформа, на которой можно реализовать множество проектов, таких как
* сервер домашней автоматизации (или система «умный дом») * сервер домашней автоматизации (или система «умный дом»)
* сервер хранения данных (NAS) * сервер хранения данных (NAS)
* домашний медиа-сервер * домашний медиа-сервер
* «мозговой центр» для автоматизированных станков или роботов * «мозговой центр» для автоматизированных станков или роботов
Собственно, в последнем качестве мы и будем его использовать, благодаря возможности подключения его к автопилоту Pixhawk. Собственно, в последнем качестве мы и будем его использовать, благодаря возможности подключения его к автопилоту PixHawk.

View File

@@ -1,16 +1,29 @@
Мобильный пульт Управление Клевером со смартфона
=== ===
Возможно управлять квадрокоптером в мобильного пульта через Wi-Fi. Он разработан в виде приложения для iOS и Android (TODO). Также существует упрощенная версия в виде [веб-страницы](#веб-версия). <a href="https://itunes.apple.com/ru/app/clever-rc/id1396166572?mt=8"><img src="assets/appstore.svg"></a>
Для управления Клевером со смартфона через Wi-Fi необходимо установить приложение  [iOS](https://itunes.apple.com/ru/app/clever-rc/id1396166572?mt=8), Android (*work-in-progress*).
![](assets/IMG_4397.PNG) ![](assets/IMG_4397.PNG)
> **Warning** Мобильный пульт предназначен в первую очередь для полетов в помещении на дальность не более 10-15 м. Большое количество Wi-Fi сетей также может ухудшить отзывчивость и дальность пульта. > **Warning** Мобильный пульт предназначен в первую очередь для полетов в помещении на дальность не более 10-15 м. Большое количество Wi-Fi сетей также может ухудшить отзывчивость и дальность пульта.
Для включения бэкенда пульта, установите [образ Clever на RPi](microsd_images.md), а также убедитесь, что он включен в launch-файле Клевера (`~/catkin_ws/src/clever/clever/launch/clever.launch`): Также управление со смартфона [доступно в мобильной версия приложения](https://docs.qgroundcontrol.com/en/SettingsView/VirtualJoystick.html) QGroundControl.
Настройка
---
> **Note** Мобильный пульт конфликтует с реальной аппаратурой радиоуправления. Во время использования мобильного пульта она должна быть выключена.
Установите [образ Clever на RPi](microsd_images.md). Для работы приложения параметры `rosbridge` и `rc` в launch-файле (`~/catkin_ws/src/clever/clever/launch/clever.launch`) должны быть включены:
```xml ```xml
<arg name="rc" value="true"/> <arg name="rosbridge" default="true"/>
```
```xml
<arg name="rc" default="true"/>
``` ```
При изменении launch-файла необходимо перезапустить пакет `clever`: При изменении launch-файла необходимо перезапустить пакет `clever`:
@@ -21,19 +34,23 @@ sudo systemctl restart clever
Также необходимо убедиться, что PX4-параметр `COM_RC_IN_MODE` установлен в значение `0` (RC Transmitter). Также необходимо убедиться, что PX4-параметр `COM_RC_IN_MODE` установлен в значение `0` (RC Transmitter).
> **Note** Мобильный пульт конфликтует с реальной аппаратурой радиоуправления. Во время использования мобильного пульта она должны быть выключена. Дополнительные параметры PX4:
Для управления коптером установите приложение на смартфон, подключитесь с Wi-Fi сети Клевера (`CLEVER-xxxx`), затем запустите приложение. * `COM_RC_LOSS_T` таймаут для определения потери сигнала пульта (мобильного или физического). Рекомендуется увеличение таймаута до нескольких секунд.
* `NAV_RCL_ACT` действие при потере сигнала пульта.
Стики на экране приложения работают также, как и реальные стики. Для арминга коптера подержите левый стик в правом нижнем углу на протяжении нескольких секунд. Для дизарминга – в левом нижнем углу. > **Note** Мобильный пульт конфликтует с реальной аппаратурой радиоуправления. Во время использования мобильного пульта она должна быть выключена.
Пульт отображает текущий [режим PX4](modes.md) а также уровень заряда батареи. При низком значении заряда батареи телефон будет вибрировать. Подключение
> **Note** Если интерфейс пульта отображает явно неправильное напряжение (напр. > 5 V), проверьте, что значение PX4-параметра `BAT_N_CELLS` соответствует реальному количество элементов батареи. Если отображаемое напряжение все равно неверно, откалибруйте батарею (TODO: ссылка).
> **Note** Если вместо режима PX4 отображается текст "DISCONNECTED FROM FCU", проверьте [подключение Raspberry Pi к PixHawk](connection.md).
Веб-версия
--- ---
TODO Подключите смартфон к [Wi-Fi](wifi.md) сети Клевера (`CLEVER-xxxx`). Приложение должно подключиться с коптеру автоматически. При успешном подключении должны отобразиться текущий [режим](modes.ms) и заряд батареи.
Стики на экране приложения работают так же, как и реальные стики. Для арма коптера подержите левый стик в правом нижнем углу на протяжении нескольких секунд. Для дизарма – в левом нижнем углу.
Неисправности
---
* Если интерфейс пульта отображает явно неправильное напряжение (напр. > 5 V), проверьте, что значение PX4-параметра `BAT_N_CELLS` соответствует реальному количество элементов батареи. Если отображаемое напряжение все равно неверно, откалибруйте батарею (TODO: ссылка).
* Если вместо режима PX4 отображается текст "DISCONNECTED FROM FCU", проверьте [подключение Raspberry Pi к PixHawk](connection.md).

View File

@@ -1,15 +1,19 @@
ROS: основные концепции ROS
==== ===
Основная статья: http://wiki.ros.org Основная статья: http://wiki.ros.org
TODO ROS – это широко используемый фреймворк для создания сложных и распределенных роботехнических систем.
Установка Установка
--- ---
Основная статья: http://wiki.ros.org/kinetic/Installation/Ubuntu Основная статья: http://wiki.ros.org/kinetic/Installation/Ubuntu
ROS уже установлен на [образе для RPi](microsd_images.md).
Для использования ROS на компьютере рекомендуется ОС Ubuntu Linux (либо виртуальная машина, например [Parallels Desktop Lite](https://itunes.apple.com/ru/app/parallels-desktop-lite/id1085114709?mt=12) или [VirtualBox](https://www.virtualbox.org)).
Концепции Концепции
--- ---
@@ -17,15 +21,86 @@ TODO
Основная статья: http://wiki.ros.org/Nodes Основная статья: http://wiki.ros.org/Nodes
ROS-нода это специальная программа (обычно написанная на Python или C++), которая взаимодействует с другими нодами посредством ROS-топиков и ROS-сервисов. Разделение сложных роботехнических систем на изолированные ноды дает определеные преимущества: понижается связанность кода, повышается переиспользуемость и надежность.
Очень многие роботехнические библиотеки и драйвера выполнены именно в виде ROS-нод.
Для того, чтобы превратить обычную программу в ROS-ноду, необходимо подключить к ней библиотеку `rospy` или `roscpp` и добавить инициализирующий код.
Пример ROS-ноды на языке Python:
```python
import rospy
rospy.init_node('my_ros_node') # имя ROS-ноды
rospy.spin() # входим в бесонечный цикл...
```
### Топики ### Топики
Основная статья: http://wiki.ros.org/Topics Основная статья: http://wiki.ros.org/Topics
Топик это именованная шина данных, по которой ноды обмениваются сообщениями. Любая нода может *опубликовать* сообщение в произвольный топик, а также *подписаться* на произвольный топик.
Пример публикации сообщения типа [`std_msgs/String`](http://docs.ros.org/api/std_msgs/html/msg/String.html) (строка) в топик `/foo` на языке Python:
```python
from std_msgs.msg import String
# ...
foo_pub = rospy.Publisher('/foo', String, queue_size=1) # создаем Publisher'а
foo_pub.publish(data='Hello, world!') # публикуем сообщение
```
Пример подписки на топик `/foo`:
```python
def foo_callback(msg):
print msg.data
# Подписываемся. При получении сообщения в топик /foo будет вызвана функция foo_callback.
rospy.Subscriber('/foo', String, foo_callback)
```
Также, существует возможность работы с топиками с помощью утилиты `rostopic`. Например, с помощью следующей команды можно просматривать сообщения, публикуемые в топик `/mavros/state`:
```bash
rostopic echo /mavros/state
```
### Сервисы ### Сервисы
Основная статья: http://wiki.ros.org/Services Основная статья: http://wiki.ros.org/Services
Mavros Сервис – это некоторый аналог функции, которая может быть вызвана из одной ноды, а обработана в другой. У сервиса есть имя, аналогичное имени топика, и 2 типа сообщений: тип запроса и тип ответа.
Пример вызова ROS-сервиса из языка Python:
```python
from clever.srv import GetTelemetry
# ...
# Создаем обертку над сервисом get_telemetry пакета clever с типом GetTelemetry:
get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry)
# Вызываем сервис и получаем телеметрию квадрокоптера:
telemetry = get_telemetry()
```
С сервисами можно также работать при помощи утилиты `rosservice`. Так можно вызвать сервис `/get_telemetry` из командной строки:
```bash
rosservice call /get_telemetry "{frame_id: ''}"
```
Больше примеров использования сервисов для автономных полетов квадрокоптера Клевер можно посмотреть в [документации ноды simple_offboard](simple_offboard.md).
Работа на нескольких машинах
--- ---
Основная статья: http://wiki.ros.org/mavros Преимуществом использования ROS явлется возможность распределения нод на несколько машин в сети. Например, ноду, осуществляющую распознование образом на изображении можно запустить на более мощном компьютере; ноду, управляющую коптером можно запустить непосредствено на Raspberry Pi, подключенном к полетому контроллеру и т. д.
Для запуска ноды

View File

@@ -1,9 +1,7 @@
Simple offboard Simple offboard
=== ===
> **Warning** Это описание API версии 0.5. См. [описание API предыдущих версий](https://github.com/CopterExpress/clever/blob/67051b21a05b12e2e9e519cb640565bccb80fbe3/docs/simple_offboard.md). Модуль `simple_offboard` пакета `clever` предназначен для упрощенного программирования автономного дрона ([режим](modes.md) `OFFBOARD`). Он позволяет устанавливать желаемые полетные задачи и автоматически трансформирует [систему координат](frames.md).
Модуль `simple_offboard` пакета `clever` предназначен для упрощенного программирования автономного дрона (режим `OFFBOARD`). Он позволяет устанавливать желаемые полетные задачи и автоматически трансформирует [систему координат](frames.md).
`simple_offboard` является высокоуровневым способом взаимодействия с полетным контроллером. Для более низкоуровневой работы см. [mavros](mavros.md). `simple_offboard` является высокоуровневым способом взаимодействия с полетным контроллером. Для более низкоуровневой работы см. [mavros](mavros.md).
@@ -11,12 +9,12 @@ Simple offboard
Общие для сервисов параметры: Общие для сервисов параметры:
* `auto_arm` = `true`/`false` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит, если находится на полу!**) * `auto_arm` = `true`/`false` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит**);
* `frame_id` — система координат в TF2, в которой заданы координаты и рысканье (yaw), [описание систем координат](frames.md); * `frame_id` — система координат в TF2, в которой заданы координаты и рысканье (yaw), [описание систем координат](frames.md);
* `update_frame` — считать ли систему координат изменяющейся (например, `false` для `local_origin`, `fcu`, `fcu_horiz`, `true` для `marker_map`); * `update_frame` — считать ли систему координат изменяющейся (например, `false` для `local_origin`, `fcu`, `fcu_horiz`, `true` для `marker_map`);
* `x`, `y` горизонтальные координаты в системе координат `frame_id`; * `x`, `y` горизонтальные координаты в системе координат `frame_id` *(м)*;
* `z` — высота в системе координат `frame_id`; * `z` — высота в системе координат `frame_id` *(м)*;
* `lat`, `lon` широта и долгота градусах); * `lat`, `lon` широта и долгота *(градусы)*;
* `yaw` — рысканье в радианах в системе координат `frame_id` (0 коптер смотрит по оси X); * `yaw` — рысканье в радианах в системе координат `frame_id` (0 коптер смотрит по оси X);
* `yaw_rate` — угловая скорость по рысканью в радианах в секунду (против часовой), `yaw` должен быть установлен в NaN; * `yaw_rate` — угловая скорость по рысканью в радианах в секунду (против часовой), `yaw` должен быть установлен в NaN;
* `thrust` — уровень газа от 0 (нет газа) до 1 (полный газ). * `thrust` — уровень газа от 0 (нет газа) до 1 (полный газ).
@@ -68,18 +66,19 @@ release = rospy.ServiceProxy('release', Trigger)
* `frame_id` – фрейм; * `frame_id` – фрейм;
* `connected` есть ли подключение к <abbr title="Flight Control Unit, полетный контроллер">FCU</abbr>; * `connected` есть ли подключение к <abbr title="Flight Control Unit, полетный контроллер">FCU</abbr>;
* `armed` состояние `armed` винтов (винты включены, если true); * `armed` состояние `armed` винтов (винты включены, если true);
* `mode` - текущий [полетный режим](modes.md); * `mode` текущий [полетный режим](modes.md);
* `x, y, z` – локальная позиция коптера; * `x, y, z` – локальная позиция коптера *(м)*;
* `lat, lon` широта, долгота (при наличии [gps](gps.md)); * `lat, lon` широта, долгота *(градусы)*, необходимо наличие [GPS](gps.md);
* `vx, vy, vz` скорость коптера; * `alt` высота в глобальной системе координат (стандарт [WGS-84](https://ru.wikipedia.org/wiki/WGS_84), не <abbr title="Above Mean Sea Level, выше среднего уровня моря">AMSL</abbr>!), необходимо наличие [GPS](gps.md);
* `pitch`  угол по тангажу (радианы); * `vx, vy, vz` скорость коптера *(м/с)*;
* `roll` угол по крену (радианы); * `pitch`  угол по тангажу *(радианы)*;
* `roll` угол по крену *(радианы)*;
* `yaw` – угол по рысканью в фрейме `frame_id`; * `yaw` – угол по рысканью в фрейме `frame_id`;
* `pitch_rate` – угловая скорость по тангажу (*work in progress*); * `pitch_rate` – угловая скорость по тангажу *(рад/с)*;
* `roll_rate` – угловая скорость по крену (*work in progress*); * `roll_rate` – угловая скорость по крену *(рад/с)*;
* `yaw_rate` – угловая скорость по рысканью (*work in progress*); * `yaw_rate` – угловая скорость по рысканью *(рад/с)*;
* `voltage` общее напряжение аккумулятора; * `voltage` общее напряжение аккумулятора *(В)*;
* `cell_voltage` напряжение аккумулятора на ячейку. * `cell_voltage` напряжение аккумулятора на ячейку *(В)*.
> **Note** Недоступные по каким-то причинам поля будут содержать в себе значения `NaN`. > **Note** Недоступные по каким-то причинам поля будут содержать в себе значения `NaN`.
@@ -119,13 +118,15 @@ rosservice call /get_telemetry "{frame_id: ''}"
Параметры: Параметры:
* `x`, `y`, `z` координаты в системе `frame_id`; * `x`, `y`, `z` координаты в системе `frame_id` *(м)*;
* `yaw` угол по рысканью; * `yaw` угол по рысканью *(радианы)*;
* `yaw_rate` угловая скорость по рысканью (при установке yaw в `NaN`); * `yaw_rate` угловая скорость по рысканью (применяется при установке yaw в `NaN`) *(рад/с)*;
* `speed` скорость полета (скорость движения setpoint); * `speed` скорость полета (скорость движения setpoint) *(м/с)*;
* `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит, если находится на полу!**); * `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит**);
* `frame_id`, `update_frame`. * `frame_id`, `update_frame`.
> **Note** Для полета без изменения угла по рыскаью достаточно установить `yaw` в `NaN` (значение угловой скорости по-умолчанию 0).
Взлет на высоту 1.5 м со скоростью взлета 0.5 м/с: Взлет на высоту 1.5 м со скоростью взлета 0.5 м/с:
```python ```python
@@ -180,14 +181,16 @@ rosservice call /navigate "{x: 0.0, y: 0.0, z: 2, yaw: 0.0, yaw_rate: 0.0, speed
Параметры: Параметры:
* `lat`, `lon` широта и долгота; * `lat`, `lon` широта и долгота *(градусы)*;
* `z` высота в системе координат `frame_id`; * `z` высота в системе координат `frame_id` *(м)*;
* `yaw` угол по рысканью; * `yaw` угол по рысканью *(радианы)*;
* `yaw_rate` угловая скорость по рысканью (при установке yaw в `NaN`); * `yaw_rate` угловая скорость по рысканью (при установке yaw в `NaN`) *(рад/с)*;
* `speed` скорость полета (скорость движения setpoint); * `speed` скорость полета (скорость движения setpoint) *(м/с)*;
* `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит, если находится на полу!**); * `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит**);
* `frame_id`, `update_frame`. * `frame_id`, `update_frame`.
> **Note** Для полета без изменения угла по рыскаью достаточно установить `yaw` в `NaN` (значение угловой скорости по-умолчанию 0).
Полет в глобальную точку со скоростью 5 м/с, оставаясь на текущей высоте (`yaw` установится в 0, коптер сориентируется передом на восток): Полет в глобальную точку со скоростью 5 м/с, оставаясь на текущей высоте (`yaw` установится в 0, коптер сориентируется передом на восток):
```python ```python
@@ -210,15 +213,14 @@ rosservice call /navigate_global "{lat: 55.707033, lon: 37.725010, z: 0.0, yaw:
Установить цель по позиции и рысканью. Данный сервис следует использовать при необходимости задания продолжающегося потока целевых точек, например, для полета по сложным траекториям (круговой, дугообразной и т. д.). Установить цель по позиции и рысканью. Данный сервис следует использовать при необходимости задания продолжающегося потока целевых точек, например, для полета по сложным траекториям (круговой, дугообразной и т. д.).
> **Hint** Для полета на точку по прямой или взлета используйте более высокоуровневый сервис `navigate`. > **Hint** Для полета на точку по прямой или взлета используйте более высокоуровневый сервис [`navigate`](#navigate).
Параметры: Параметры:
* `x`, `y`, `z` координаты точки в системе координат `frame_id`; * `x`, `y`, `z` координаты точки в системе координат `frame_id` *(м)*;
* `yaw` угол по рысканью; * `yaw` угол по рысканью *(радианы)*;
* `yaw_rate` угловая скорость по рысканью (при установке yaw в NaN); * `yaw_rate` угловая скорость по рысканью (при установке yaw в NaN) *(рад/с)*;
* `speed` скорость полета (скорость движения setpoint); * `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит**);
* `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит, если находится на полу!**);
* `frame_id`, `update_frame`. * `frame_id`, `update_frame`.
Зависнуть на месте: Зависнуть на месте:
@@ -249,10 +251,10 @@ set_position(x=0, y=0, z=0, frame_id='fcu_horiz', yaw=float('nan'), yaw_rate=0.5
Установить скорости и рысканье. Установить скорости и рысканье.
* `vx`, `vy`, `vz` требуемая скорость полета; * `vx`, `vy`, `vz` требуемая скорость полета *(м/с)*;
* `yaw` угол по рысканью; * `yaw` угол по рысканью *(радианы)*;
* `yaw_rate` угловая скорость по рысканью (при установке yaw в NaN); * `yaw_rate` угловая скорость по рысканью (при установке yaw в NaN) *(рад/с)*;
* `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит, если находится на полу!**); * `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит**);
* `frame_id`, `update_frame`. * `frame_id`, `update_frame`.
> **Note** Параметр `frame_id` определяет только ориентацию результирующего вектора скорости, но не его длину. > **Note** Параметр `frame_id` определяет только ориентацию результирующего вектора скорости, но не его длину.
@@ -277,9 +279,9 @@ set_velocity(vx=0.4, vy=0.0, vz=0, yaw=float('nan'), yaw_rate=0.4, frame_id='fcu
Параметры: Параметры:
* `pitch`, `roll`, `yaw` – необходимый угол по тангажу, крену и рысканью (рад.); * `pitch`, `roll`, `yaw` – необходимый угол по тангажу, крену и рысканью *(радианы)*;
* `thrust` – уровень газа от 0 (нет газа) до 1 (полный газ); * `thrust` – уровень газа от 0 (нет газа) до 1 (полный газ);
* `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит, если находится на полу!**); * `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит**);
* `frame_id`, `update_frame`. * `frame_id`, `update_frame`.
### set_rates ### set_rates
@@ -288,9 +290,9 @@ set_velocity(vx=0.4, vy=0.0, vz=0, yaw=float('nan'), yaw_rate=0.4, frame_id='fcu
Параметры: Параметры:
* `pitch_rate`, `roll_rate`, `yaw_rate` – угловая скорость по танажу, крену и рыканью (рад/с); * `pitch_rate`, `roll_rate`, `yaw_rate` – угловая скорость по танажу, крену и рыканью *(рад/с)*;
* `thrust` уровень газа от 0 (нет газа) до 1 (полный газ). * `thrust` уровень газа от 0 (нет газа) до 1 (полный газ).
* `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит, если находится на полу!**); * `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит**);
### land ### land

View File

@@ -20,6 +20,15 @@ def get_distance(x1, y1, z1, x2, y2, z2):
--- ---
Функция для приблизительного определения расстояния (в метрах) между двумя глобальными координатами (широта/долгота):
```python
def get_distance_global(lat1, lon1, lat2, lon2):
return math.hypot(lat1 - lat2, lon1 - lon2) * 1.113195e5
```
---
Взлет и ожидание окончания взлета: Взлет и ожидание окончания взлета:
```python ```python
@@ -66,6 +75,8 @@ while True:
Рассчет общего угла коптера к горизонту: Рассчет общего угла коптера к горизонту:
TODO: fix
```python ```python
telem = get_telemetry() telem = get_telemetry()
@@ -96,6 +107,57 @@ while not rospy.is_shutdown():
--- ---
Пример подписки на топики из MAVROS:
```python
from geometry_msgs.msg import PoseStamped, TwistStamped
from sensor_msgs.msg import BatteryState
from mavros_msgs.msg import RCIn
# ...
def state_update(pose):
# Обработка новых данных о позиции коптера
pass
# Остальные функции-обработчики
# ...
rospy.Subscriber('/mavros/local_position/pose', PoseStamped, pose_update)
rospy.Subscriber('/mavros/local_position/velocity', TwistStamped, velocity_update)
rospy.Subscriber('/mavros/battery', BatteryState, battery_update)
rospy.Subscriber('mavros/rc/in', RCIn, rc_callback)
```
Информацию по топикам MAVROS см. по [ссылке](mavros.md).
---
Пример отправки произвольного [MAVLink-сообщения](mavlink.md) коптеру:
```python
# ...
from mavros_msgs.msg import Mavlink
from mavros import mavlink
from pymavlink import mavutil
# ...
mavlink_pub = rospy.Publisher('mavlink/to', Mavlink, queue_size=1)
# Отправка сообщения HEARTBEAT:
msg = mavutil.mavlink.MAVLink_heartbeat_message(mavutil.mavlink.MAV_TYPE_GCS, 0, 0, 0, 0, 0)
msg.pack(mavutil.mavlink.MAVLink('', 2, 1))
ros_msg = mavlink.convert_to_rosmsg(msg)
mavlink_pub.publish(ros_msg)
```
---
Реакция на переключение режима на пульте радиоуправления (может быть использовано для запуска автономного полета, см. [пример](https://gist.github.com/okalachev/b709f04522d2f9af97e835baedeb806b)): Реакция на переключение режима на пульте радиоуправления (может быть использовано для запуска автономного полета, см. [пример](https://gist.github.com/okalachev/b709f04522d2f9af97e835baedeb806b)):
```python ```python

File diff suppressed because it is too large Load Diff

View File

@@ -29,4 +29,3 @@ http://192.168.11.1:8080/stream_viewer?topic=/main_camera/image_raw&quality=1
Также доступны параметры `width`, `height` и другие. Подробнее о `web_video_server`: http://wiki.ros.org/web_video_server. Также доступны параметры `width`, `height` и другие. Подробнее о `web_video_server`: http://wiki.ros.org/web_video_server.
TODO: иллюстрации. TODO: иллюстрации.

View File

@@ -5,4 +5,4 @@
Пароль: `cleverwifi`. Пароль: `cleverwifi`.
TODO: иллюстрация. Для изменения настроек Wi-Fi или получения более детальной информации о устройстве сети на Raspberri Pi прочитайте эту [статью](network.md).

View File

@@ -4,7 +4,7 @@ pipeline {
string(name: 'GWBT_REF', defaultValue: "master") string(name: 'GWBT_REF', defaultValue: "master")
string(name: 'GWBT_URL', defaultValue: "https://github.com/CopterExpress/clever.git") string(name: 'GWBT_URL', defaultValue: "https://github.com/CopterExpress/clever.git")
string(name: 'GWBT_FILE', defaultValue: "") string(name: 'GWBT_FILE', defaultValue: "")
string(name: 'IMAGE_NAME', defaultValue: "\$(cat ${GWBT_FILE} | jq '.repository.name' -r)_${params.GWBT_REF}_\$(cat ${GWBT_FILE} | jq '.release.published_at' -r).img") string(name: 'IMAGE_NAME', defaultValue: "\$(cat ${GWBT_FILE} | jq '.repository.name' -r)-${params.GWBT_REF}.img")
string(name: 'GWBT_EVENT', defaultValue: 'release') string(name: 'GWBT_EVENT', defaultValue: 'release')
booleanParam(name: 'ONLY_PUBLISH', defaultValue: false, description: 'ONLY PUBLISH') booleanParam(name: 'ONLY_PUBLISH', defaultValue: false, description: 'ONLY PUBLISH')
string(name: 'BUILD_DIR', defaultValue: '/mnt/hdd_builder/workspace', description: 'Build workspace') string(name: 'BUILD_DIR', defaultValue: '/mnt/hdd_builder/workspace', description: 'Build workspace')

View File

@@ -6,7 +6,19 @@ sudo apt-get install unzip zip git python-pip jq curl
sudo pip install YaDiskClient sudo pip install YaDiskClient
``` ```
2. Mount HDD 2. Mount HDD
> TODO ```bash
nano /etc/fstab
```
```
proc /proc proc defaults 0 0
PARTUUID=37665771-01 /boot vfat defaults 0 2
PARTUUID=37665771-02 / ext4 defaults,noatime 0 1
# a swapfile is not a swap partition, no line here
# use dphys-swapfile swap[on|off] for that
/dev/sdb1 none swap sw 0 0
/dev/sdb2 /mnt/hdd_system ext4 defaults,acl 0 0
/dev/sdb3 /mnt/hdd_builder ext4 defaults,acl 0 0
```
3. Enable swap on HDD 3. Enable swap on HDD
> TODO: > TODO:
@@ -32,7 +44,7 @@ sudo systemctl disable dphys-swapfile
"password":"PASS", "password":"PASS",
"url":"https://api.github.com/repos/CopterExpress/clever/releases/" "url":"https://api.github.com/repos/CopterExpress/clever/releases/"
} }
}
``` ```
6. Add webhook to release on your github project 6. Add webhook to release on your github project
> TODO > TODO
@@ -67,3 +79,11 @@ sudo systemctl start jenkins
## Requirements ## Requirements
* Jenkins (BlueOcean plugin, optional) * Jenkins (BlueOcean plugin, optional)
## Troubleshooting
If JDK not installed:
```bash
sudo apt-get install default-jdk
```

103
image_builder/autosizer.sh Executable file
View File

@@ -0,0 +1,103 @@
#!/bin/bash
set -e
if [ $(whoami) != "root" ]; then
echo \
&& echo "********************************************************************" \
&& echo "******************** This should be run as root ********************" \
&& echo "********************************************************************" \
&& echo \
&& exit 1
fi
if [[ -z $1 ]]; then
echo "================================================================================"
echo -e "\033[0;31m\033[1mAutomatic Image file resizer\033[0m\033[0m"
echo -e "\033[0;31m\033[1mDescription:\033[0m\033[0m This script shrink your image to 10MiB free space"
echo -e "if you didn't set FREE_SPACE in MiB (see usage below)."
echo -e "\033[0;31m\033[1mAuthors:\033[0m\033[0m Artem Smirnov @urpylka, SirLagz"
echo
echo -e "\033[0;31m\033[1mUsage:\033[0m\033[0m ./autosizer.sh PATH_TO_IMAGE FREE_SPACE"
echo
echo -e "\033[0;31m\033[1mRequirements:\033[0m\033[0m parted, losetup, e2fsck, resize2fs, bc, truncate"
echo "================================================================================"
exit 0
fi
echo "================================================================================"
strImgFile=$1
echo -e "\033[0;31m\033[1mPath to image: $strImgFile\033[0m\033[0m"
echo "================================================================================"
if [[ ! -e $strImgFile ]]; then
echo -e "\033[0;31m\033[1mError: File doesn't exist\033[0m\033[0m"
echo
exit 1
fi
echo "================================================================================"
partinfo=`parted -m $strImgFile unit B print`
echo -e "\033[0;31m\033[1mPartition information:\033[0m\033[0m\n$partinfo"
echo "================================================================================"
partnumber=`echo "$partinfo" | grep ext4 | awk -F: '{ print $1 }'`
echo -e "\033[0;31m\033[1mPartition number: $partnumber\033[0m\033[0m"
echo "================================================================================"
partstart=`echo "$partinfo" | grep ext4 | awk -F: '{ print substr($2,0,length($2)-1) }'`
echo -e "\033[0;31m\033[1mPartition start: $partstart (bytes)\033[0m\033[0m"
echo "================================================================================"
loopback=`losetup -f --show -o $partstart $strImgFile`
echo -e "\033[0;31m\033[1mLoopback device: $loopback\033[0m\033[0m"
echo "================================================================================"
set +e
e2fsck -fvy $loopback
set -e
echo "================================================================================"
minsize=`resize2fs -P $loopback | awk -F': ' '{ print $2 }'`
#minsize=`resize2fs -P $loopback 2> /dev/null | awk -F': ' '{ print $2 }'`
echo -e "\033[0;31m\033[1mMinsize: $minsize (4KiB)\033[0m\033[0m"
echo "================================================================================"
# Default add 10MiB free space to image, if $2 doesn't set
FREE_SPACE=${2:-10}
FREE_SPACE=$(($FREE_SPACE*1024*1024/4096))
minsize=`echo "$minsize+$FREE_SPACE" | bc`
echo -e "\033[0;31m\033[1mMinsize + $FREE_SPACE (4KiB): $minsize (4KiB)\033[0m\033[0m"
echo "================================================================================"
resize2fs -p $loopback $minsize
sleep 1
losetup -d $loopback
echo "================================================================================"
partnewsize=`echo "$minsize * 4096" | bc`
echo -e "\033[0;31m\033[1mNew size of part: $minsize (4KiB) = $partnewsize (bytes)\033[0m\033[0m"
echo "================================================================================"
newpartend=`echo "$partstart + $partnewsize" | bc`
echo -e "\033[0;31m\033[1mNew end of part (Part start + part new size):\033[0m\033[0m"
echo -e "\033[0;31m\033[1m$partstart (bytes) + $partnewsize (bytes) = $newpartend (bytes)\033[0m\033[0m"
echo "================================================================================"
part1=`parted $strImgFile rm 2`
echo "================================================================================"
part2=`parted $strImgFile unit B mkpart primary $partstart $newpartend`
echo "================================================================================"
endresult=`parted -m $strImgFile unit B print free | tail -1 | awk -F: '{ print substr($2,0,length($2)-1) }'`
echo -e "\033[0;31m\033[1mSize of result image: $endresult (bytes)\033[0m\033[0m"
echo "================================================================================"
truncate -s $endresult $strImgFile
echo "================================================================================"
partinfo=`parted -m $strImgFile unit B print`
echo -e "\033[0;31m\033[1mPartition information:\033[0m\033[0m\n$partinfo"
echo "================================================================================"

View File

@@ -6,10 +6,15 @@ pipeline {
string(name: 'IMAGE_VERSION', defaultValue: 'no_version', description: 'Image version') string(name: 'IMAGE_VERSION', defaultValue: 'no_version', description: 'Image version')
string(name: 'BUILD_DIR', defaultValue: '/mnt/hdd_builder/workspace', description: 'Build workspace') string(name: 'BUILD_DIR', defaultValue: '/mnt/hdd_builder/workspace', description: 'Build workspace')
string(name: 'MOUNT_POINT', defaultValue: '/mnt/hdd_builder/image', description: 'Mount point')
string(name: 'RPI_DONWLOAD_URL', defaultValue: 'https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2017-12-01/2017-11-29-raspbian-stretch-lite.zip') string(name: 'RPI_DONWLOAD_URL', defaultValue: 'https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2017-12-01/2017-11-29-raspbian-stretch-lite.zip')
// TODO: Add mirrorparameters // TODO: Add mirrorparameters
string(name: 'GWBT_URL', defaultValue: 'https://github.com/CopterExpress/clever.git')
// Experimental function
booleanParam(name: 'SHRINK', defaultValue: true, description: 'SHRINK IMAGE')
booleanParam(name: 'DISCOVER_ROS_PACKAGES', defaultValue: false, description: 'DISCOVER ROS PACKAGES')
} }
environment { environment {
DEBIAN_FRONTEND = 'noninteractive' DEBIAN_FRONTEND = 'noninteractive'
@@ -27,7 +32,7 @@ pipeline {
SIZE = '7G' SIZE = '7G'
} }
steps { steps {
sh "$WORKSPACE/image_builder/image_config.sh resize_fs $SIZE ${params.BUILD_DIR} ${params.IMAGE_NAME}" sh "$WORKSPACE/image_builder/image_config.sh resize_fs ${params.BUILD_DIR}/${params.IMAGE_NAME} $SIZE"
} }
} }
stage('Initialize image') { stage('Initialize image') {
@@ -36,7 +41,7 @@ pipeline {
} }
// TODO: Transfer apps.sh initialisation code here // TODO: Transfer apps.sh initialisation code here
steps { steps {
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE ${params.IMAGE_VERSION} \$(basename ${params.RPI_DONWLOAD_URL})" sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} $WORKSPACE/$EXECUTE_FILE ${params.IMAGE_VERSION} \$(basename ${params.RPI_DONWLOAD_URL})"
} }
} }
stage('Hardware setup') { stage('Hardware setup') {
@@ -44,7 +49,7 @@ pipeline {
EXECUTE_FILE = 'image_builder/scripts/hardware_setup.sh' EXECUTE_FILE = 'image_builder/scripts/hardware_setup.sh'
} }
steps { steps {
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE" sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} $WORKSPACE/$EXECUTE_FILE"
} }
} }
stage('Software install') { stage('Software install') {
@@ -52,7 +57,7 @@ pipeline {
EXECUTE_FILE = 'image_builder/scripts/software_install.sh' EXECUTE_FILE = 'image_builder/scripts/software_install.sh'
} }
steps { steps {
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE" sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} $WORKSPACE/$EXECUTE_FILE"
} }
} }
stage('Network setup') { stage('Network setup') {
@@ -60,17 +65,30 @@ pipeline {
EXECUTE_FILE = 'image_builder/scripts/network_setup.sh' EXECUTE_FILE = 'image_builder/scripts/network_setup.sh'
} }
steps { steps {
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE" sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} $WORKSPACE/$EXECUTE_FILE"
} }
} }
stage('Install ROS') { stage('Install ROS') {
environment { environment {
EXECUTE_FILE = 'image_builder/scripts/ros_install.sh' EXECUTE_FILE = 'image_builder/scripts/ros_install.sh'
MOVE_FILE = 'image_builder/kinetic-ros-coex.rosinstall'
MOVE_TO = '/home/pi/ros_catkin_ws'
} }
steps { steps {
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE" sh "if ! ${params.DISCOVER_ROS_PACKAGES}; then $WORKSPACE/image_builder/image_config.sh copy_to_chroot ${params.BUILD_DIR}/${params.IMAGE_NAME} $WORKSPACE/$MOVE_FILE $MOVE_TO; fi"
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} $WORKSPACE/$EXECUTE_FILE ${params.GWBT_URL} ${params.GWBT_REF} ${params.DISCOVER_ROS_PACKAGES}"
} }
} }
// TODO: Add finalising step, transfer mirror removal from ros.sh // TODO: Add finalising step, transfer mirror removal from ros.sh
stage('Shrink image') {
environment {
EXECUTE_FILE = 'image_builder/scripts/change_boot_part.sh'
}
when { expression { return params.SHRINK } }
steps {
sh "$WORKSPACE/image_builder/autosizer.sh ${params.BUILD_DIR}/${params.IMAGE_NAME}"
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} $WORKSPACE/$EXECUTE_FILE"
}
}
} }
} }

View File

@@ -15,24 +15,24 @@ get_image() {
# TEMPLATE: get_image $BUILD_DIR $RPI_DONWLOAD_URL $IMAGE_NAME # TEMPLATE: get_image $BUILD_DIR $RPI_DONWLOAD_URL $IMAGE_NAME
local RPI_ZIP_NAME=$(basename $2) local RPI_ZIP_NAME=$(basename $2)
if [ ! -e "$1/$RPI_ZIP_NAME" ]; if [ ! -e "$1/${RPI_ZIP_NAME}" ];
then then
echo "$(date) | 1. Downloading original Linux distribution" echo "$(date) | 1. Downloading original Linux distribution"
wget -nv -O $1/$RPI_ZIP_NAME $2 wget -nv -O $1/${RPI_ZIP_NAME} $2
echo "$(date) | Downloading complete" echo "$(date) | Downloading complete"
else else
echo "$(date) | 1. Linux distribution already donwloaded" echo "$(date) | 1. Linux distribution already donwloaded"
fi fi
echo "$(date) | 2. Unzipping Linux distribution image" echo "$(date) | 2. Unzipping Linux distribution image"
local RPI_IMAGE_NAME=$(echo $RPI_ZIP_NAME | sed 's/zip/img/') local RPI_IMAGE_NAME=$(echo ${RPI_ZIP_NAME} | sed 's/zip/img/')
unzip -p $1/$RPI_ZIP_NAME $RPI_IMAGE_NAME > $1/$3 unzip -p $1/${RPI_ZIP_NAME} ${RPI_IMAGE_NAME} > $1/$3
echo "$(date) | Unzipping complete" echo "$(date) | Unzipping complete"
} }
resize_fs() { resize_fs() {
# STATIC FUNCTION # STATIC FUNCTION
# TEMPLATE: resize_fs $SIZE $BUILD_DIR $IMAGE_NAME # TEMPLATE: resize_fs $IMAGE_PATH $SIZE
# Partitions numbers # Partitions numbers
local BOOT_PARTITION=1 local BOOT_PARTITION=1
@@ -58,50 +58,31 @@ resize_fs() {
# TODO: Check sfdisk exit code # TODO: Check sfdisk exit code
echo -e "\033[0;31m\033[1mTruncate image\033[0m\033[0m" \ echo -e "\033[0;31m\033[1mTruncate image\033[0m\033[0m" \
&& truncate -s$1 $2/$3 \ && truncate -s$2 $1 \
&& echo "Mount loop-image: $2/$3" \ && echo "Mount loop-image: $1" \
&& local DEV_IMAGE=$(losetup -Pf $2/$3 --show) \ && local DEV_IMAGE=$(losetup -Pf $1 --show) \
&& sleep 0.5 \ && sleep 0.5 \
&& echo -e "\033[0;31m\033[1mMount loop-image: $1\033[0m\033[0m" \ && echo -e "\033[0;31m\033[1mMount loop-image: $1\033[0m\033[0m" \
&& echo ", +" | sfdisk -N 2 $DEV_IMAGE \ && echo ", +" | sfdisk -N ${ROOT_PARTITION} ${DEV_IMAGE} \
&& sleep 0.5 \ && sleep 0.5 \
&& losetup -d $DEV_IMAGE \ && losetup -d ${DEV_IMAGE} \
&& sleep 0.5 \ && sleep 0.5 \
&& local DEV_IMAGE=$(losetup -Pf $2/$3 --show) \ && local DEV_IMAGE=$(losetup -Pf $1 --show) \
&& sleep 0.5 \ && sleep 0.5 \
&& echo -e "\033[0;31m\033[1mCheck & repair filesystem after expand partition\033[0m\033[0m" \ && echo -e "\033[0;31m\033[1mCheck & repair filesystem after expand partition\033[0m\033[0m" \
&& e2fsck -fvy "${DEV_IMAGE}p${ROOT_PARTITION}" \ && e2fsck -fvy "${DEV_IMAGE}p${ROOT_PARTITION}" \
&& echo -e "\033[0;31m\033[1mExpand filesystem\033[0m\033[0m" \ && echo -e "\033[0;31m\033[1mExpand filesystem\033[0m\033[0m" \
&& resize2fs "${DEV_IMAGE}p${ROOT_PARTITION}" \ && resize2fs "${DEV_IMAGE}p${ROOT_PARTITION}" \
&& echo -e "\033[0;31m\033[1mUmount loop-image\033[0m\033[0m" \ && echo -e "\033[0;31m\033[1mUmount loop-image\033[0m\033[0m" \
&& losetup -d $DEV_IMAGE && losetup -d ${DEV_IMAGE}
set -e set -e
} }
burn_image() {
# STATIC FUNCTION
# TEMPLATE: burn_image $IMAGE_PATH $MICROSD_DEV
echo -e "\033[0;31m\033[1mBurn image\033[0m\033[0m" \
&& dd if=$1 of=$2 \
&& echo -e "\033[0;31m\033[1mBurn image finished!\033[0m\033[0m"
}
burn_and_reboot() {
# STATIC FUNCTION
# TEMPLATE: burn_and_reboot $IMAGE_PATH $MICROSD_DEV
burn_image $1 $2 \
&& reboot
}
mount_system() { mount_system() {
# STATIC FUNCTION # STATIC FUNCTION
# TEMPLATE: mount_system $IMAGE $MOUNT_POINT # TEMPLATE: mount_system $IMAGE
# Partitions numbers # Partitions numbers
local BOOT_PARTITION=1 local BOOT_PARTITION=1
@@ -117,48 +98,49 @@ mount_system() {
local DEV_IMAGE=$(losetup -Pf $1 --show) local DEV_IMAGE=$(losetup -Pf $1 --show)
sleep 0.5 sleep 0.5
echo -e "\033[0;31m\033[1mMount dirs $2 & $2/boot\033[0m\033[0m" # Get temp directory to mount image
#mount $3 $2 local MOUNT_POINT=$(mktemp -d)
#mount $4 $2/boot
mount "${DEV_IMAGE}p${ROOT_PARTITION}" $2 echo -e "\033[0;31m\033[1mMount dirs ${MOUNT_POINT} & ${MOUNT_POINT}/boot\033[0m\033[0m"
mount "${DEV_IMAGE}p${BOOT_PARTITION}" $2/boot mount "${DEV_IMAGE}p${ROOT_PARTITION}" ${MOUNT_POINT}
mount "${DEV_IMAGE}p${BOOT_PARTITION}" ${MOUNT_POINT}/boot
echo -e "\033[0;31m\033[1mBind system dirs\033[0m\033[0m" echo -e "\033[0;31m\033[1mBind system dirs\033[0m\033[0m"
# https://github.com/debian-pi/raspbian-ua-netinst/issues/314 # https://github.com/debian-pi/raspbian-ua-netinst/issues/314
echo "Mounting /proc in chroot... " echo "Mounting /proc in chroot... "
if [ ! -d $2/proc ] ; then if [ ! -d ${MOUNT_POINT}/proc ] ; then
mkdir -p $2/proc \ mkdir -p ${MOUNT_POINT}/proc \
&& echo "Created $2/proc" && echo "Created ${MOUNT_POINT}/proc"
fi fi
mount -t proc -o nosuid,noexec,nodev proc $2/proc \ mount -t proc -o nosuid,noexec,nodev proc ${MOUNT_POINT}/proc \
&& echo "OK" && echo "OK"
echo "Mounting /sys in chroot... " echo "Mounting /sys in chroot... "
if [ ! -d $2/sys ] ; then if [ ! -d ${MOUNT_POINT}/sys ] ; then
mkdir -p $2/sys \ mkdir -p ${MOUNT_POINT}/sys \
&& echo "Created $2/sys" && echo "Created ${MOUNT_POINT}/sys"
fi fi
mount -t sysfs -o nosuid,noexec,nodev sysfs $2/sys \ mount -t sysfs -o nosuid,noexec,nodev sysfs ${MOUNT_POINT}/sys \
&& echo "OK" && echo "OK"
echo "Mounting /dev/ and /dev/pts in chroot... " \ echo "Mounting /dev/ and /dev/pts in chroot... " \
&& mkdir -p -m 755 $2/dev/pts \ && mkdir -p -m 755 ${MOUNT_POINT}/dev/pts \
&& mount -t devtmpfs -o mode=0755,nosuid devtmpfs $2/dev \ && mount -t devtmpfs -o mode=0755,nosuid devtmpfs ${MOUNT_POINT}/dev \
&& mount -t devpts -o gid=5,mode=620 devpts $2/dev/pts \ && mount -t devpts -o gid=5,mode=620 devpts ${MOUNT_POINT}/dev/pts \
&& echo "OK" && echo "OK"
# mount -t devpts none "$2/dev/pts" -o ptmxmode=0666,newinstance # mount -t devpts none "${MOUNT_POINT}/dev/pts" -o ptmxmode=0666,newinstance
# ln -fs "pts/ptmx" "$2/dev/ptmx" # ln -fs "pts/ptmx" "${MOUNT_POINT}/dev/ptmx"
# mount -o bind /dev $2/dev # mount -o bind /dev ${MOUNT_POINT}/dev
# mount -t proc proc $2/proc # mount -t proc proc ${MOUNT_POINT}/proc
# mount -t devpts devpts $2/dev/pts # mount -t devpts devpts ${MOUNT_POINT}/dev/pts
# mount -t proc proc $2/proc # mount -t proc proc ${MOUNT_POINT}/proc
# mount -t sysfs sys $2/sys # mount -t sysfs sys ${MOUNT_POINT}/sys
# mount --bind /dev $2/dev # mount --bind /dev ${MOUNT_POINT}/dev
echo -e "\033[0;31m\033[1mCopy DNS records\033[0m\033[0m" \ echo -e "\033[0;31m\033[1mCopy DNS records\033[0m\033[0m" \
&& cp -L /etc/resolv.conf $2/etc/resolv.conf && cp -L /etc/resolv.conf ${MOUNT_POINT}/etc/resolv.conf
# https://wiki.archlinux.org/index.php/Change_root_(%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9) # https://wiki.archlinux.org/index.php/Change_root_(%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9)
# http://www.unix-lab.org/posts/chroot/ # http://www.unix-lab.org/posts/chroot/
@@ -167,15 +149,15 @@ mount_system() {
# http://unixteam.ru/content/virtualizaciya-ili-zapuskaem-prilozhenie-v-chroot-okruzhenii-razmyshleniya # http://unixteam.ru/content/virtualizaciya-ili-zapuskaem-prilozhenie-v-chroot-okruzhenii-razmyshleniya
# http://help.ubuntu.ru/wiki/%D0%B2%D0%BE%D1%81%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_grub # http://help.ubuntu.ru/wiki/%D0%B2%D0%BE%D1%81%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_grub
echo -e "\033[0;31m\033[1mEnter chroot\033[0m\033[0m" \ echo -e "\033[0;31m\033[1mEnter chroot\033[0m\033[0m" \
&& chroot $2 /bin/bash && chroot ${MOUNT_POINT} /bin/bash
umount_system $2 $DEV_IMAGE umount_system ${MOUNT_POINT} ${DEV_IMAGE}
} }
execute() { execute() {
# STATIC FUNCTION # STATIC FUNCTION
# TEMPLATE: execute $IMAGE $MOUNT_POINT $EXECUTE_FILE ... # TEMPLATE: execute $IMAGE $EXECUTE_FILE ...
# Partitions numbers # Partitions numbers
local BOOT_PARTITION=1 local BOOT_PARTITION=1
@@ -185,50 +167,87 @@ execute() {
local DEV_IMAGE=$(losetup -Pf $1 --show) local DEV_IMAGE=$(losetup -Pf $1 --show)
sleep 0.5 sleep 0.5
echo -e "\033[0;31m\033[1mMount dirs $2 & $2/boot\033[0m\033[0m" # Get temp directory to mount image
mount "${DEV_IMAGE}p${ROOT_PARTITION}" $2 local MOUNT_POINT=$(mktemp -d)
mount "${DEV_IMAGE}p${BOOT_PARTITION}" $2/boot
echo -e "\033[0;31m\033[1mMount dirs ${MOUNT_POINT} & ${MOUNT_POINT}/boot\033[0m\033[0m"
mount "${DEV_IMAGE}p${ROOT_PARTITION}" ${MOUNT_POINT}
mount "${DEV_IMAGE}p${BOOT_PARTITION}" ${MOUNT_POINT}/boot
echo -e "\033[0;31m\033[1mBind system dirs\033[0m\033[0m" echo -e "\033[0;31m\033[1mBind system dirs\033[0m\033[0m"
echo "Mounting /proc in chroot... " echo "Mounting /proc in chroot... "
if [ ! -d $2/proc ] ; then if [ ! -d ${MOUNT_POINT}/proc ] ; then
mkdir -p $2/proc mkdir -p ${MOUNT_POINT}/proc
echo "Created $2/proc" echo "Created ${MOUNT_POINT}/proc"
fi fi
mount -t proc -o nosuid,noexec,nodev proc $2/proc \ mount -t proc -o nosuid,noexec,nodev proc ${MOUNT_POINT}/proc \
&& echo "OK" && echo "OK"
echo "Mounting /sys in chroot... " echo "Mounting /sys in chroot... "
if [ ! -d $2/sys ] ; then if [ ! -d ${MOUNT_POINT}/sys ] ; then
mkdir -p $2/sys mkdir -p ${MOUNT_POINT}/sys
echo "Created $2/sys" echo "Created ${MOUNT_POINT}/sys"
fi fi
mount -t sysfs -o nosuid,noexec,nodev sysfs $2/sys \ mount -t sysfs -o nosuid,noexec,nodev sysfs ${MOUNT_POINT}/sys \
&& echo "OK" && echo "OK"
echo "Mounting /dev/ and /dev/pts in chroot... " \ echo "Mounting /dev/ and /dev/pts in chroot... " \
&& mkdir -p -m 755 $2/dev/pts \ && mkdir -p -m 755 ${MOUNT_POINT}/dev/pts \
&& mount -t devtmpfs -o mode=0755,nosuid devtmpfs $2/dev \ && mount -t devtmpfs -o mode=0755,nosuid devtmpfs ${MOUNT_POINT}/dev \
&& mount -t devpts -o gid=5,mode=620 devpts $2/dev/pts \ && mount -t devpts -o gid=5,mode=620 devpts ${MOUNT_POINT}/dev/pts \
&& echo "OK" && echo "OK"
echo -e "\033[0;31m\033[1mCopy DNS records\033[0m\033[0m" \ echo -e "\033[0;31m\033[1mCopy DNS records\033[0m\033[0m" \
&& cp -L /etc/resolv.conf $2/etc/resolv.conf && cp -L /etc/resolv.conf ${MOUNT_POINT}/etc/resolv.conf
echo -e "\033[0;31m\033[1m$(date) | Enter chroot\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | Enter chroot\033[0m\033[0m"
script_name=$(basename $3) local script_name=$(basename $2)
script_path_root="$2/root/$script_name" local script_path_root="${MOUNT_POINT}/root/${script_name}"
# Copy script into chroot fs # Copy script into chroot fs
# TODO: Find more suitable location for temporary script storage # TODO: Find more suitable location for temporary script storage
cp "$3" "$script_path_root" cp "$2" "${script_path_root}"
# Its important to save arguments (direct ${@:4} causes problems) # Its important to save arguments (direct ${@:4} causes problems)
script_args="${@:4}" script_args="${@:3}"
# Run script in chroot with additional arguments # Run script in chroot with additional arguments
chroot $2 /bin/sh -c "/root/$script_name $script_args" chroot ${MOUNT_POINT} /bin/sh -c "/root/${script_name} ${script_args}"
# Removing script from chroot fs # Removing script from chroot fs
rm "$script_path_root" rm "${script_path_root}"
umount_system $2 $DEV_IMAGE umount_system ${MOUNT_POINT} ${DEV_IMAGE}
}
copy_to_chroot() {
# STATIC FUNCTION
# TEMPLATE: copy_to_chroot $IMAGE $MOVE_FILE $MOVE_TO
# Partitions numbers
local BOOT_PARTITION=1
local ROOT_PARTITION=2
echo -e "\033[0;31m\033[1mMount loop-image: $1\033[0m\033[0m"
local DEV_IMAGE=$(losetup -Pf $1 --show)
sleep 0.5
# Get temp directory to mount image
local MOUNT_POINT=$(mktemp -d)
echo -e "\033[0;31m\033[1mMount dirs ${MOUNT_POINT} & ${MOUNT_POINT}/boot\033[0m\033[0m"
mount "${DEV_IMAGE}p${ROOT_PARTITION}" ${MOUNT_POINT}
mount "${DEV_IMAGE}p${BOOT_PARTITION}" ${MOUNT_POINT}/boot
echo -e "\033[0;31m\033[1m$(date) | Enter chroot\033[0m\033[0m"
file_name=$(basename $2)
file_path_root="${MOUNT_POINT}$3/${file_name}"
# Copy script into chroot fs
# TODO: Find more suitable location for temporary script storage
if [ ! -d ${file_path_root} ] ; then
mkdir -p ${file_path_root} \
&& echo "Created ${file_path_root}"
fi
cp "$2" "${file_path_root}"
umount_system ${MOUNT_POINT} ${DEV_IMAGE}
} }
umount_system() { umount_system() {
@@ -268,51 +287,6 @@ umount_system() {
losetup -d $2 losetup -d $2
} }
install_docker() {
# STATIC FUNCTION
# TEMPLATE: install_docker $IMAGE $MOUNT_POINT
# https://askubuntu.com/questions/485567/unexpected-end-of-file
mount_system $1 $2 << EOF
#!/bin/bash
# https://www.raspberrypi.org/blog/docker-comes-to-raspberry-pi/
curl -sSL https://get.docker.com | sh
usermod -aG docker pi
systemctl enable docker
service docker start
docker pull smirart/rpi-ros:sshd
docker run -di --restart unless-stopped -p 192.168.0.121:2202:22 -t smirart/rpi-ros:sshd
EOF
}
test_docker() {
# STATIC FUNCTION
# TEMPLATE: test_docker $IMAGE $MOUNT_POINT
mount_system $1 $2 << EOF
#!/bin/bash
# https://www.raspberrypi.org/blog/docker-comes-to-raspberry-pi/
service docker start
sleep 1
docker images
docker ps -a
EOF
}
# очистить history
# https://askubuntu.com/questions/191999/how-to-clear-bash-history-completely
# cat /dev/null > ~/.bash_history && history -c && exit
#
# screen in chroot
# getty tty
# https://stackoverflow.com/questions/19104894/screen-must-be-connected-to-a-terminal/25646444
#
# docker in chroot
# service docker start
# https://forums.docker.com/t/cannot-connect-to-the-docker-daemon-is-the-docker-daemon-running-on-this-host/8925/17
publish_image() { publish_image() {
# STATIC FUNCTION # STATIC FUNCTION
@@ -328,6 +302,8 @@ publish_image() {
echo -e "\033[0;31m\033[1m$(date) | Zipping complete!\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | Zipping complete!\033[0m\033[0m"
else else
echo -e "\033[0;31m\033[1m$(date) | Zip-archive already created\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | Zip-archive already created\033[0m\033[0m"
cd $1 && rm $2.zip && zip $2.zip $2
echo -e "\033[0;31m\033[1m$(date) | Old archive was deleted & create new\033[0m\033[0m"
fi fi
echo -e "\033[0;31m\033[1m$(date) | Upload image\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | Upload image\033[0m\033[0m"
@@ -379,30 +355,30 @@ echo "\$5: $5"
echo "\$6: $6" echo "\$6: $6"
echo "\$7: $7" echo "\$7: $7"
# test_docker
# install_docker
# burn_image
case "$1" in case "$1" in
mount_system) mount_system)
# mount_system $IMAGE $MOUNT_POINT # mount_system $IMAGE
mount_system $2 $3;; mount_system $2;;
get_image) get_image)
# get_image $BUILD_DIR $RPI_DONWLOAD_URL $IMAGE_NAME # get_image $BUILD_DIR $RPI_DONWLOAD_URL $IMAGE_NAME
get_image $2 $3 $4;; get_image $2 $3 $4;;
resize_fs) resize_fs)
# resize_fs $SIZE $BUILD_DIR $IMAGE_NAME # resize_fs $IMAGE_PATH $SIZE
resize_fs $2 $3 $4 $5;; resize_fs $2 $3;;
publish_image) publish_image)
# publish_image $BUILD_DIR $IMAGE_NAME $YA_SCRIPT $CONFIG_FILE $RELEASE_ID $RELEASE_BODY # publish_image $BUILD_DIR $IMAGE_NAME $YA_SCRIPT $CONFIG_FILE $RELEASE_ID $RELEASE_BODY
publish_image $2 $3 $4 $5 $6 "$7";; publish_image $2 $3 $4 $5 $6 "$7";;
execute) execute)
# execute $IMAGE $MOUNT_POINT $EXECUTE_FILE ... # execute $IMAGE $EXECUTE_FILE ...
execute $2 $3 $4 ${@:5};; execute $2 $3 ${@:4};;
copy_to_chroot)
# copy_to_chroot $IMAGE $MOVE_FILE $MOVE_TO
copy_to_chroot $2 $3 $4;;
*) *)
echo "Enter one of: mount_system, get_image, resize_fs, publish_image, execute";; echo "Enter one of: mount_system, get_image, resize_fs, publish_image, execute";;

View File

@@ -0,0 +1,680 @@
- tar:
local-name: catkin
uri: https://github.com/ros-gbp/catkin-release/archive/release/kinetic/catkin/0.7.11-0.tar.gz
version: catkin-release-release-kinetic-catkin-0.7.11-0
- tar:
local-name: cmake_modules
uri: https://github.com/ros-gbp/cmake_modules-release/archive/release/kinetic/cmake_modules/0.4.1-0.tar.gz
version: cmake_modules-release-release-kinetic-cmake_modules-0.4.1-0
- tar:
local-name: gencpp
uri: https://github.com/ros-gbp/gencpp-release/archive/release/kinetic/gencpp/0.6.0-0.tar.gz
version: gencpp-release-release-kinetic-gencpp-0.6.0-0
- tar:
local-name: geneus
uri: https://github.com/tork-a/geneus-release/archive/release/kinetic/geneus/2.2.6-0.tar.gz
version: geneus-release-release-kinetic-geneus-2.2.6-0
- tar:
local-name: genlisp
uri: https://github.com/ros-gbp/genlisp-release/archive/release/kinetic/genlisp/0.4.16-0.tar.gz
version: genlisp-release-release-kinetic-genlisp-0.4.16-0
- tar:
local-name: genmsg
uri: https://github.com/ros-gbp/genmsg-release/archive/release/kinetic/genmsg/0.5.10-0.tar.gz
version: genmsg-release-release-kinetic-genmsg-0.5.10-0
- tar:
local-name: gennodejs
uri: https://github.com/RethinkRobotics-release/gennodejs-release/archive/release/kinetic/gennodejs/2.0.1-0.tar.gz
version: gennodejs-release-release-kinetic-gennodejs-2.0.1-0
- tar:
local-name: genpy
uri: https://github.com/ros-gbp/genpy-release/archive/release/kinetic/genpy/0.6.7-0.tar.gz
version: genpy-release-release-kinetic-genpy-0.6.7-0
- tar:
local-name: message_generation
uri: https://github.com/ros-gbp/message_generation-release/archive/release/kinetic/message_generation/0.4.0-0.tar.gz
version: message_generation-release-release-kinetic-message_generation-0.4.0-0
- tar:
local-name: message_runtime
uri: https://github.com/ros-gbp/message_runtime-release/archive/release/kinetic/message_runtime/0.4.12-0.tar.gz
version: message_runtime-release-release-kinetic-message_runtime-0.4.12-0
- tar:
local-name: ros/mk
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/mk/1.14.3-0.tar.gz
version: ros-release-release-kinetic-mk-1.14.3-0
- tar:
local-name: ros/ros
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/ros/1.14.3-0.tar.gz
version: ros-release-release-kinetic-ros-1.14.3-0
- tar:
local-name: ros/rosbash
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/rosbash/1.14.3-0.tar.gz
version: ros-release-release-kinetic-rosbash-1.14.3-0
- tar:
local-name: ros/rosboost_cfg
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/rosboost_cfg/1.14.3-0.tar.gz
version: ros-release-release-kinetic-rosboost_cfg-1.14.3-0
- tar:
local-name: ros/rosbuild
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/rosbuild/1.14.3-0.tar.gz
version: ros-release-release-kinetic-rosbuild-1.14.3-0
- tar:
local-name: ros/rosclean
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/rosclean/1.14.3-0.tar.gz
version: ros-release-release-kinetic-rosclean-1.14.3-0
- tar:
local-name: ros/roscreate
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/roscreate/1.14.3-0.tar.gz
version: ros-release-release-kinetic-roscreate-1.14.3-0
- tar:
local-name: ros/roslang
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/roslang/1.14.3-0.tar.gz
version: ros-release-release-kinetic-roslang-1.14.3-0
- tar:
local-name: ros/roslib
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/roslib/1.14.3-0.tar.gz
version: ros-release-release-kinetic-roslib-1.14.3-0
- tar:
local-name: ros/rosmake
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/rosmake/1.14.3-0.tar.gz
version: ros-release-release-kinetic-rosmake-1.14.3-0
- tar:
local-name: ros/rosunit
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/rosunit/1.14.3-0.tar.gz
version: ros-release-release-kinetic-rosunit-1.14.3-0
- tar:
local-name: ros_comm/message_filters
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/message_filters/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-message_filters-1.12.13-0
- tar:
local-name: ros_comm/ros_comm
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/ros_comm/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-ros_comm-1.12.13-0
- tar:
local-name: ros_comm/rosbag
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosbag/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosbag-1.12.13-0
- tar:
local-name: ros_comm/rosbag_storage
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosbag_storage/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosbag_storage-1.12.13-0
- tar:
local-name: ros_comm/rosconsole
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosconsole/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosconsole-1.12.13-0
- tar:
local-name: ros_comm/roscpp
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/roscpp/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-roscpp-1.12.13-0
- tar:
local-name: ros_comm/rosgraph
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosgraph/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosgraph-1.12.13-0
- tar:
local-name: ros_comm/roslaunch
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/roslaunch/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-roslaunch-1.12.13-0
- tar:
local-name: ros_comm/roslz4
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/roslz4/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-roslz4-1.12.13-0
- tar:
local-name: ros_comm/rosmaster
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosmaster/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosmaster-1.12.13-0
- tar:
local-name: ros_comm/rosmsg
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosmsg/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosmsg-1.12.13-0
- tar:
local-name: ros_comm/rosnode
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosnode/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosnode-1.12.13-0
- tar:
local-name: ros_comm/rosout
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosout/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosout-1.12.13-0
- tar:
local-name: ros_comm/rosparam
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosparam/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosparam-1.12.13-0
- tar:
local-name: ros_comm/rospy
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rospy/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rospy-1.12.13-0
- tar:
local-name: ros_comm/rosservice
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosservice/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosservice-1.12.13-0
- tar:
local-name: ros_comm/rostest
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rostest/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rostest-1.12.13-0
- tar:
local-name: ros_comm/rostopic
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rostopic/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rostopic-1.12.13-0
- tar:
local-name: ros_comm/roswtf
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/roswtf/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-roswtf-1.12.13-0
- tar:
local-name: ros_comm/topic_tools
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/topic_tools/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-topic_tools-1.12.13-0
- tar:
local-name: ros_comm/xmlrpcpp
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/xmlrpcpp/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-xmlrpcpp-1.12.13-0
- tar:
local-name: ros_comm_msgs/rosgraph_msgs
uri: https://github.com/ros-gbp/ros_comm_msgs-release/archive/release/kinetic/rosgraph_msgs/1.11.2-0.tar.gz
version: ros_comm_msgs-release-release-kinetic-rosgraph_msgs-1.11.2-0
- tar:
local-name: ros_comm_msgs/std_srvs
uri: https://github.com/ros-gbp/ros_comm_msgs-release/archive/release/kinetic/std_srvs/1.11.2-0.tar.gz
version: ros_comm_msgs-release-release-kinetic-std_srvs-1.11.2-0
- tar:
local-name: ros_environment
uri: https://github.com/ros-gbp/ros_environment-release/archive/release/kinetic/ros_environment/1.0.0-0.tar.gz
version: ros_environment-release-release-kinetic-ros_environment-1.0.0-0
- tar:
local-name: roscpp_core/cpp_common
uri: https://github.com/ros-gbp/roscpp_core-release/archive/release/kinetic/cpp_common/0.6.9-0.tar.gz
version: roscpp_core-release-release-kinetic-cpp_common-0.6.9-0
- tar:
local-name: roscpp_core/roscpp_serialization
uri: https://github.com/ros-gbp/roscpp_core-release/archive/release/kinetic/roscpp_serialization/0.6.9-0.tar.gz
version: roscpp_core-release-release-kinetic-roscpp_serialization-0.6.9-0
- tar:
local-name: roscpp_core/roscpp_traits
uri: https://github.com/ros-gbp/roscpp_core-release/archive/release/kinetic/roscpp_traits/0.6.9-0.tar.gz
version: roscpp_core-release-release-kinetic-roscpp_traits-0.6.9-0
- tar:
local-name: roscpp_core/rostime
uri: https://github.com/ros-gbp/roscpp_core-release/archive/release/kinetic/rostime/0.6.9-0.tar.gz
version: roscpp_core-release-release-kinetic-rostime-0.6.9-0
- tar:
local-name: roslisp
uri: https://github.com/ros-gbp/roslisp-release/archive/release/kinetic/roslisp/1.9.21-0.tar.gz
version: roslisp-release-release-kinetic-roslisp-1.9.21-0
- tar:
local-name: rospack
uri: https://github.com/ros-gbp/rospack-release/archive/release/kinetic/rospack/2.4.4-0.tar.gz
version: rospack-release-release-kinetic-rospack-2.4.4-0
- tar:
local-name: std_msgs
uri: https://github.com/ros-gbp/std_msgs-release/archive/release/kinetic/std_msgs/0.5.11-0.tar.gz
version: std_msgs-release-release-kinetic-std_msgs-0.5.11-0
- tar:
local-name: actionlib
uri: https://github.com/ros-gbp/actionlib-release/archive/release/kinetic/actionlib/1.11.13-0.tar.gz
version: actionlib-release-release-kinetic-actionlib-1.11.13-0
- tar:
local-name: angles
uri: https://github.com/ros-gbp/geometry_angles_utils-release/archive/release/kinetic/angles/1.9.11-0.tar.gz
version: geometry_angles_utils-release-release-kinetic-angles-1.9.11-0
- tar:
local-name: async_web_server_cpp
uri: https://github.com/gt-rail-release/async_web_server_cpp-release/archive/release/kinetic/async_web_server_cpp/0.0.3-0.tar.gz
version: async_web_server_cpp-release-release-kinetic-async_web_server_cpp-0.0.3-0
- tar:
local-name: bond_core/bond
uri: https://github.com/ros-gbp/bond_core-release/archive/release/kinetic/bond/1.8.1-0.tar.gz
version: bond_core-release-release-kinetic-bond-1.8.1-0
- tar:
local-name: bond_core/bond_core
uri: https://github.com/ros-gbp/bond_core-release/archive/release/kinetic/bond_core/1.8.1-0.tar.gz
version: bond_core-release-release-kinetic-bond_core-1.8.1-0
- tar:
local-name: bond_core/bondcpp
uri: https://github.com/ros-gbp/bond_core-release/archive/release/kinetic/bondcpp/1.8.1-0.tar.gz
version: bond_core-release-release-kinetic-bondcpp-1.8.1-0
- tar:
local-name: bond_core/bondpy
uri: https://github.com/ros-gbp/bond_core-release/archive/release/kinetic/bondpy/1.8.1-0.tar.gz
version: bond_core-release-release-kinetic-bondpy-1.8.1-0
- tar:
local-name: bond_core/smclib
uri: https://github.com/ros-gbp/bond_core-release/archive/release/kinetic/smclib/1.8.1-0.tar.gz
version: bond_core-release-release-kinetic-smclib-1.8.1-0
- tar:
local-name: catkin
uri: https://github.com/ros-gbp/catkin-release/archive/release/kinetic/catkin/0.7.11-0.tar.gz
version: catkin-release-release-kinetic-catkin-0.7.11-0
- tar:
local-name: class_loader
uri: https://github.com/ros-gbp/class_loader-release/archive/release/kinetic/class_loader/0.3.9-0.tar.gz
version: class_loader-release-release-kinetic-class_loader-0.3.9-0
- tar:
local-name: cmake_modules
uri: https://github.com/ros-gbp/cmake_modules-release/archive/release/kinetic/cmake_modules/0.4.1-0.tar.gz
version: cmake_modules-release-release-kinetic-cmake_modules-0.4.1-0
- tar:
local-name: common_msgs/actionlib_msgs
uri: https://github.com/ros-gbp/common_msgs-release/archive/release/kinetic/actionlib_msgs/1.12.6-0.tar.gz
version: common_msgs-release-release-kinetic-actionlib_msgs-1.12.6-0
- tar:
local-name: common_msgs/diagnostic_msgs
uri: https://github.com/ros-gbp/common_msgs-release/archive/release/kinetic/diagnostic_msgs/1.12.6-0.tar.gz
version: common_msgs-release-release-kinetic-diagnostic_msgs-1.12.6-0
- tar:
local-name: common_msgs/geometry_msgs
uri: https://github.com/ros-gbp/common_msgs-release/archive/release/kinetic/geometry_msgs/1.12.6-0.tar.gz
version: common_msgs-release-release-kinetic-geometry_msgs-1.12.6-0
- tar:
local-name: common_msgs/nav_msgs
uri: https://github.com/ros-gbp/common_msgs-release/archive/release/kinetic/nav_msgs/1.12.6-0.tar.gz
version: common_msgs-release-release-kinetic-nav_msgs-1.12.6-0
- tar:
local-name: common_msgs/sensor_msgs
uri: https://github.com/ros-gbp/common_msgs-release/archive/release/kinetic/sensor_msgs/1.12.6-0.tar.gz
version: common_msgs-release-release-kinetic-sensor_msgs-1.12.6-0
- tar:
local-name: common_msgs/stereo_msgs
uri: https://github.com/ros-gbp/common_msgs-release/archive/release/kinetic/stereo_msgs/1.12.6-0.tar.gz
version: common_msgs-release-release-kinetic-stereo_msgs-1.12.6-0
- tar:
local-name: common_msgs/trajectory_msgs
uri: https://github.com/ros-gbp/common_msgs-release/archive/release/kinetic/trajectory_msgs/1.12.6-0.tar.gz
version: common_msgs-release-release-kinetic-trajectory_msgs-1.12.6-0
- tar:
local-name: common_msgs/visualization_msgs
uri: https://github.com/ros-gbp/common_msgs-release/archive/release/kinetic/visualization_msgs/1.12.6-0.tar.gz
version: common_msgs-release-release-kinetic-visualization_msgs-1.12.6-0
- tar:
local-name: cv_camera
uri: https://github.com/OTL/cv_camera-release/archive/release/kinetic/cv_camera/0.3.0-0.tar.gz
version: cv_camera-release-release-kinetic-cv_camera-0.3.0-0
- tar:
local-name: diagnostics/diagnostic_updater
uri: https://github.com/ros-gbp/diagnostics-release/archive/release/kinetic/diagnostic_updater/1.9.3-0.tar.gz
version: diagnostics-release-release-kinetic-diagnostic_updater-1.9.3-0
- tar:
local-name: dynamic_reconfigure
uri: https://github.com/ros-gbp/dynamic_reconfigure-release/archive/release/kinetic/dynamic_reconfigure/1.5.49-0.tar.gz
version: dynamic_reconfigure-release-release-kinetic-dynamic_reconfigure-1.5.49-0
- tar:
local-name: gencpp
uri: https://github.com/ros-gbp/gencpp-release/archive/release/kinetic/gencpp/0.6.0-0.tar.gz
version: gencpp-release-release-kinetic-gencpp-0.6.0-0
- tar:
local-name: geneus
uri: https://github.com/tork-a/geneus-release/archive/release/kinetic/geneus/2.2.6-0.tar.gz
version: geneus-release-release-kinetic-geneus-2.2.6-0
- tar:
local-name: genlisp
uri: https://github.com/ros-gbp/genlisp-release/archive/release/kinetic/genlisp/0.4.16-0.tar.gz
version: genlisp-release-release-kinetic-genlisp-0.4.16-0
- tar:
local-name: genmsg
uri: https://github.com/ros-gbp/genmsg-release/archive/release/kinetic/genmsg/0.5.10-0.tar.gz
version: genmsg-release-release-kinetic-genmsg-0.5.10-0
- tar:
local-name: gennodejs
uri: https://github.com/RethinkRobotics-release/gennodejs-release/archive/release/kinetic/gennodejs/2.0.1-0.tar.gz
version: gennodejs-release-release-kinetic-gennodejs-2.0.1-0
- tar:
local-name: genpy
uri: https://github.com/ros-gbp/genpy-release/archive/release/kinetic/genpy/0.6.7-0.tar.gz
version: genpy-release-release-kinetic-genpy-0.6.7-0
- tar:
local-name: geographic_info/geographic_msgs
uri: https://github.com/ros-geographic-info/geographic_info-release/archive/release/kinetic/geographic_msgs/0.5.2-0.tar.gz
version: geographic_info-release-release-kinetic-geographic_msgs-0.5.2-0
- tar:
local-name: geometry/eigen_conversions
uri: https://github.com/ros-gbp/geometry-release/archive/release/kinetic/eigen_conversions/1.11.9-0.tar.gz
version: geometry-release-release-kinetic-eigen_conversions-1.11.9-0
- tar:
local-name: geometry/tf
uri: https://github.com/ros-gbp/geometry-release/archive/release/kinetic/tf/1.11.9-0.tar.gz
version: geometry-release-release-kinetic-tf-1.11.9-0
- tar:
local-name: geometry2/geometry2
uri: https://github.com/ros-gbp/geometry2-release/archive/release/kinetic/geometry2/0.5.17-0.tar.gz
version: geometry2-release-release-kinetic-geometry2-0.5.17-0
- tar:
local-name: geometry2/tf2
uri: https://github.com/ros-gbp/geometry2-release/archive/release/kinetic/tf2/0.5.17-0.tar.gz
version: geometry2-release-release-kinetic-tf2-0.5.17-0
- tar:
local-name: geometry2/tf2_bullet
uri: https://github.com/ros-gbp/geometry2-release/archive/release/kinetic/tf2_bullet/0.5.17-0.tar.gz
version: geometry2-release-release-kinetic-tf2_bullet-0.5.17-0
- tar:
local-name: geometry2/tf2_eigen
uri: https://github.com/ros-gbp/geometry2-release/archive/release/kinetic/tf2_eigen/0.5.17-0.tar.gz
version: geometry2-release-release-kinetic-tf2_eigen-0.5.17-0
- tar:
local-name: geometry2/tf2_geometry_msgs
uri: https://github.com/ros-gbp/geometry2-release/archive/release/kinetic/tf2_geometry_msgs/0.5.17-0.tar.gz
version: geometry2-release-release-kinetic-tf2_geometry_msgs-0.5.17-0
- tar:
local-name: geometry2/tf2_kdl
uri: https://github.com/ros-gbp/geometry2-release/archive/release/kinetic/tf2_kdl/0.5.17-0.tar.gz
version: geometry2-release-release-kinetic-tf2_kdl-0.5.17-0
- tar:
local-name: geometry2/tf2_msgs
uri: https://github.com/ros-gbp/geometry2-release/archive/release/kinetic/tf2_msgs/0.5.17-0.tar.gz
version: geometry2-release-release-kinetic-tf2_msgs-0.5.17-0
- tar:
local-name: geometry2/tf2_py
uri: https://github.com/ros-gbp/geometry2-release/archive/release/kinetic/tf2_py/0.5.17-0.tar.gz
version: geometry2-release-release-kinetic-tf2_py-0.5.17-0
- tar:
local-name: geometry2/tf2_ros
uri: https://github.com/ros-gbp/geometry2-release/archive/release/kinetic/tf2_ros/0.5.17-0.tar.gz
version: geometry2-release-release-kinetic-tf2_ros-0.5.17-0
- tar:
local-name: geometry2/tf2_sensor_msgs
uri: https://github.com/ros-gbp/geometry2-release/archive/release/kinetic/tf2_sensor_msgs/0.5.17-0.tar.gz
version: geometry2-release-release-kinetic-tf2_sensor_msgs-0.5.17-0
- tar:
local-name: geometry2/tf2_tools
uri: https://github.com/ros-gbp/geometry2-release/archive/release/kinetic/tf2_tools/0.5.17-0.tar.gz
version: geometry2-release-release-kinetic-tf2_tools-0.5.17-0
- tar:
local-name: image_common/camera_calibration_parsers
uri: https://github.com/ros-gbp/image_common-release/archive/release/kinetic/camera_calibration_parsers/1.11.13-0.tar.gz
version: image_common-release-release-kinetic-camera_calibration_parsers-1.11.13-0
- tar:
local-name: image_common/camera_info_manager
uri: https://github.com/ros-gbp/image_common-release/archive/release/kinetic/camera_info_manager/1.11.13-0.tar.gz
version: image_common-release-release-kinetic-camera_info_manager-1.11.13-0
- tar:
local-name: image_common/image_transport
uri: https://github.com/ros-gbp/image_common-release/archive/release/kinetic/image_transport/1.11.13-0.tar.gz
version: image_common-release-release-kinetic-image_transport-1.11.13-0
- tar:
local-name: mavlink
uri: https://github.com/mavlink/mavlink-gbp-release/archive/release/kinetic/mavlink/2018.6.6-0.tar.gz
version: mavlink-gbp-release-release-kinetic-mavlink-2018.6.6-0
- tar:
local-name: mavros/libmavconn
uri: https://github.com/mavlink/mavros-release/archive/release/kinetic/libmavconn/0.26.0-0.tar.gz
version: mavros-release-release-kinetic-libmavconn-0.26.0-0
- tar:
local-name: mavros/mavros
uri: https://github.com/mavlink/mavros-release/archive/release/kinetic/mavros/0.26.0-0.tar.gz
version: mavros-release-release-kinetic-mavros-0.26.0-0
- tar:
local-name: mavros/mavros_extras
uri: https://github.com/mavlink/mavros-release/archive/release/kinetic/mavros_extras/0.26.0-0.tar.gz
version: mavros-release-release-kinetic-mavros_extras-0.26.0-0
- tar:
local-name: mavros/mavros_msgs
uri: https://github.com/mavlink/mavros-release/archive/release/kinetic/mavros_msgs/0.26.0-0.tar.gz
version: mavros-release-release-kinetic-mavros_msgs-0.26.0-0
- tar:
local-name: message_generation
uri: https://github.com/ros-gbp/message_generation-release/archive/release/kinetic/message_generation/0.4.0-0.tar.gz
version: message_generation-release-release-kinetic-message_generation-0.4.0-0
- tar:
local-name: message_runtime
uri: https://github.com/ros-gbp/message_runtime-release/archive/release/kinetic/message_runtime/0.4.12-0.tar.gz
version: message_runtime-release-release-kinetic-message_runtime-0.4.12-0
- tar:
local-name: nodelet_core/nodelet
uri: https://github.com/ros-gbp/nodelet_core-release/archive/release/kinetic/nodelet/1.9.14-0.tar.gz
version: nodelet_core-release-release-kinetic-nodelet-1.9.14-0
- tar:
local-name: opencv3
uri: https://github.com/ros-gbp/opencv3-release/archive/release/kinetic/opencv3/3.3.1-5.tar.gz
version: opencv3-release-release-kinetic-opencv3-3.3.1-5
- tar:
local-name: orocos_kinematics_dynamics/orocos_kdl
uri: https://github.com/smits/orocos-kdl-release/archive/release/kinetic/orocos_kdl/1.3.1-0.tar.gz
version: orocos-kdl-release-release-kinetic-orocos_kdl-1.3.1-0
- tar:
local-name: orocos_kinematics_dynamics/python_orocos_kdl
uri: https://github.com/smits/orocos-kdl-release/archive/release/kinetic/python_orocos_kdl/1.3.1-0.tar.gz
version: orocos-kdl-release-release-kinetic-python_orocos_kdl-1.3.1-0
- tar:
local-name: pluginlib
uri: https://github.com/ros-gbp/pluginlib-release/archive/release/kinetic/pluginlib/1.11.3-0.tar.gz
version: pluginlib-release-release-kinetic-pluginlib-1.11.3-0
- tar:
local-name: ros/mk
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/mk/1.14.3-0.tar.gz
version: ros-release-release-kinetic-mk-1.14.3-0
- tar:
local-name: ros/ros
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/ros/1.14.3-0.tar.gz
version: ros-release-release-kinetic-ros-1.14.3-0
- tar:
local-name: ros/rosbash
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/rosbash/1.14.3-0.tar.gz
version: ros-release-release-kinetic-rosbash-1.14.3-0
- tar:
local-name: ros/rosboost_cfg
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/rosboost_cfg/1.14.3-0.tar.gz
version: ros-release-release-kinetic-rosboost_cfg-1.14.3-0
- tar:
local-name: ros/rosbuild
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/rosbuild/1.14.3-0.tar.gz
version: ros-release-release-kinetic-rosbuild-1.14.3-0
- tar:
local-name: ros/rosclean
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/rosclean/1.14.3-0.tar.gz
version: ros-release-release-kinetic-rosclean-1.14.3-0
- tar:
local-name: ros/roscreate
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/roscreate/1.14.3-0.tar.gz
version: ros-release-release-kinetic-roscreate-1.14.3-0
- tar:
local-name: ros/roslang
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/roslang/1.14.3-0.tar.gz
version: ros-release-release-kinetic-roslang-1.14.3-0
- tar:
local-name: ros/roslib
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/roslib/1.14.3-0.tar.gz
version: ros-release-release-kinetic-roslib-1.14.3-0
- tar:
local-name: ros/rosmake
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/rosmake/1.14.3-0.tar.gz
version: ros-release-release-kinetic-rosmake-1.14.3-0
- tar:
local-name: ros/rosunit
uri: https://github.com/ros-gbp/ros-release/archive/release/kinetic/rosunit/1.14.3-0.tar.gz
version: ros-release-release-kinetic-rosunit-1.14.3-0
- tar:
local-name: ros_comm/message_filters
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/message_filters/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-message_filters-1.12.13-0
- tar:
local-name: ros_comm/ros_comm
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/ros_comm/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-ros_comm-1.12.13-0
- tar:
local-name: ros_comm/rosbag
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosbag/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosbag-1.12.13-0
- tar:
local-name: ros_comm/rosbag_storage
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosbag_storage/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosbag_storage-1.12.13-0
- tar:
local-name: ros_comm/rosconsole
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosconsole/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosconsole-1.12.13-0
- tar:
local-name: ros_comm/roscpp
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/roscpp/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-roscpp-1.12.13-0
- tar:
local-name: ros_comm/rosgraph
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosgraph/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosgraph-1.12.13-0
- tar:
local-name: ros_comm/roslaunch
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/roslaunch/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-roslaunch-1.12.13-0
- tar:
local-name: ros_comm/roslz4
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/roslz4/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-roslz4-1.12.13-0
- tar:
local-name: ros_comm/rosmaster
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosmaster/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosmaster-1.12.13-0
- tar:
local-name: ros_comm/rosmsg
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosmsg/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosmsg-1.12.13-0
- tar:
local-name: ros_comm/rosnode
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosnode/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosnode-1.12.13-0
- tar:
local-name: ros_comm/rosout
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosout/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosout-1.12.13-0
- tar:
local-name: ros_comm/rosparam
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosparam/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosparam-1.12.13-0
- tar:
local-name: ros_comm/rospy
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rospy/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rospy-1.12.13-0
- tar:
local-name: ros_comm/rosservice
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rosservice/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rosservice-1.12.13-0
- tar:
local-name: ros_comm/rostest
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rostest/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rostest-1.12.13-0
- tar:
local-name: ros_comm/rostopic
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/rostopic/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-rostopic-1.12.13-0
- tar:
local-name: ros_comm/roswtf
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/roswtf/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-roswtf-1.12.13-0
- tar:
local-name: ros_comm/topic_tools
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/topic_tools/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-topic_tools-1.12.13-0
- tar:
local-name: ros_comm/xmlrpcpp
uri: https://github.com/ros-gbp/ros_comm-release/archive/release/kinetic/xmlrpcpp/1.12.13-0.tar.gz
version: ros_comm-release-release-kinetic-xmlrpcpp-1.12.13-0
- tar:
local-name: ros_comm_msgs/rosgraph_msgs
uri: https://github.com/ros-gbp/ros_comm_msgs-release/archive/release/kinetic/rosgraph_msgs/1.11.2-0.tar.gz
version: ros_comm_msgs-release-release-kinetic-rosgraph_msgs-1.11.2-0
- tar:
local-name: ros_comm_msgs/std_srvs
uri: https://github.com/ros-gbp/ros_comm_msgs-release/archive/release/kinetic/std_srvs/1.11.2-0.tar.gz
version: ros_comm_msgs-release-release-kinetic-std_srvs-1.11.2-0
- tar:
local-name: ros_environment
uri: https://github.com/ros-gbp/ros_environment-release/archive/release/kinetic/ros_environment/1.0.0-0.tar.gz
version: ros_environment-release-release-kinetic-ros_environment-1.0.0-0
- tar:
local-name: ros_tutorials/rospy_tutorials
uri: https://github.com/ros-gbp/ros_tutorials-release/archive/release/kinetic/rospy_tutorials/0.7.1-0.tar.gz
version: ros_tutorials-release-release-kinetic-rospy_tutorials-0.7.1-0
- tar:
local-name: rosauth
uri: https://github.com/gt-rail-release/rosauth-release/archive/release/kinetic/rosauth/0.1.7-0.tar.gz
version: rosauth-release-release-kinetic-rosauth-0.1.7-0
- tar:
local-name: rosbag_migration_rule
uri: https://github.com/ros-gbp/rosbag_migration_rule-release/archive/release/kinetic/rosbag_migration_rule/1.0.0-0.tar.gz
version: rosbag_migration_rule-release-release-kinetic-rosbag_migration_rule-1.0.0-0
- tar:
local-name: rosbridge_suite/rosapi
uri: https://github.com/RobotWebTools-release/rosbridge_suite-release/archive/release/kinetic/rosapi/0.9.0-0.tar.gz
version: rosbridge_suite-release-release-kinetic-rosapi-0.9.0-0
- tar:
local-name: rosbridge_suite/rosbridge_library
uri: https://github.com/RobotWebTools-release/rosbridge_suite-release/archive/release/kinetic/rosbridge_library/0.9.0-0.tar.gz
version: rosbridge_suite-release-release-kinetic-rosbridge_library-0.9.0-0
- tar:
local-name: rosbridge_suite/rosbridge_server
uri: https://github.com/RobotWebTools-release/rosbridge_suite-release/archive/release/kinetic/rosbridge_server/0.9.0-0.tar.gz
version: rosbridge_suite-release-release-kinetic-rosbridge_server-0.9.0-0
- tar:
local-name: rosbridge_suite/rosbridge_suite
uri: https://github.com/RobotWebTools-release/rosbridge_suite-release/archive/release/kinetic/rosbridge_suite/0.9.0-0.tar.gz
version: rosbridge_suite-release-release-kinetic-rosbridge_suite-0.9.0-0
- tar:
local-name: rosconsole_bridge
uri: https://github.com/ros-gbp/rosconsole_bridge-release/archive/release/kinetic/rosconsole_bridge/0.5.1-0.tar.gz
version: rosconsole_bridge-release-release-kinetic-rosconsole_bridge-0.5.1-0
- tar:
local-name: roscpp_core/cpp_common
uri: https://github.com/ros-gbp/roscpp_core-release/archive/release/kinetic/cpp_common/0.6.9-0.tar.gz
version: roscpp_core-release-release-kinetic-cpp_common-0.6.9-0
- tar:
local-name: roscpp_core/roscpp_serialization
uri: https://github.com/ros-gbp/roscpp_core-release/archive/release/kinetic/roscpp_serialization/0.6.9-0.tar.gz
version: roscpp_core-release-release-kinetic-roscpp_serialization-0.6.9-0
- tar:
local-name: roscpp_core/roscpp_traits
uri: https://github.com/ros-gbp/roscpp_core-release/archive/release/kinetic/roscpp_traits/0.6.9-0.tar.gz
version: roscpp_core-release-release-kinetic-roscpp_traits-0.6.9-0
- tar:
local-name: roscpp_core/rostime
uri: https://github.com/ros-gbp/roscpp_core-release/archive/release/kinetic/rostime/0.6.9-0.tar.gz
version: roscpp_core-release-release-kinetic-rostime-0.6.9-0
- tar:
local-name: roslint
uri: https://github.com/ros-gbp/roslint-release/archive/release/kinetic/roslint/0.11.0-0.tar.gz
version: roslint-release-release-kinetic-roslint-0.11.0-0
- tar:
local-name: roslisp
uri: https://github.com/ros-gbp/roslisp-release/archive/release/kinetic/roslisp/1.9.21-0.tar.gz
version: roslisp-release-release-kinetic-roslisp-1.9.21-0
- tar:
local-name: rospack
uri: https://github.com/ros-gbp/rospack-release/archive/release/kinetic/rospack/2.4.4-0.tar.gz
version: rospack-release-release-kinetic-rospack-2.4.4-0
- tar:
local-name: rosserial/rosserial
uri: https://github.com/ros-gbp/rosserial-release/archive/release/kinetic/rosserial/0.7.7-0.tar.gz
version: rosserial-release-release-kinetic-rosserial-0.7.7-0
- tar:
local-name: rosserial/rosserial_client
uri: https://github.com/ros-gbp/rosserial-release/archive/release/kinetic/rosserial_client/0.7.7-0.tar.gz
version: rosserial-release-release-kinetic-rosserial_client-0.7.7-0
- tar:
local-name: rosserial/rosserial_msgs
uri: https://github.com/ros-gbp/rosserial-release/archive/release/kinetic/rosserial_msgs/0.7.7-0.tar.gz
version: rosserial-release-release-kinetic-rosserial_msgs-0.7.7-0
- tar:
local-name: rosserial/rosserial_python
uri: https://github.com/ros-gbp/rosserial-release/archive/release/kinetic/rosserial_python/0.7.7-0.tar.gz
version: rosserial-release-release-kinetic-rosserial_python-0.7.7-0
- tar:
local-name: std_msgs
uri: https://github.com/ros-gbp/std_msgs-release/archive/release/kinetic/std_msgs/0.5.11-0.tar.gz
version: std_msgs-release-release-kinetic-std_msgs-0.5.11-0
- tar:
local-name: unique_identifier/uuid_msgs
uri: https://github.com/ros-geographic-info/unique_identifier-release/archive/release/kinetic/uuid_msgs/1.0.5-0.tar.gz
version: unique_identifier-release-release-kinetic-uuid_msgs-1.0.5-0
- tar:
local-name: urdf/urdf
uri: https://github.com/ros-gbp/urdf-release/archive/release/kinetic/urdf/1.12.12-0.tar.gz
version: urdf-release-release-kinetic-urdf-1.12.12-0
- tar:
local-name: urdf/urdf_parser_plugin
uri: https://github.com/ros-gbp/urdf-release/archive/release/kinetic/urdf_parser_plugin/1.12.12-0.tar.gz
version: urdf-release-release-kinetic-urdf_parser_plugin-1.12.12-0
- tar:
local-name: usb_cam
uri: https://github.com/ros-gbp/usb_cam-release/archive/release/kinetic/usb_cam/0.3.5-0.tar.gz
version: usb_cam-release-release-kinetic-usb_cam-0.3.5-0
- tar:
local-name: vision_opencv/cv_bridge
uri: https://github.com/ros-gbp/vision_opencv-release/archive/release/kinetic/cv_bridge/1.12.8-0.tar.gz
version: vision_opencv-release-release-kinetic-cv_bridge-1.12.8-0
- tar:
local-name: web_video_server
uri: https://github.com/RobotWebTools-release/web_video_server-release/archive/release/kinetic/web_video_server/0.0.7-0.tar.gz
version: web_video_server-release-release-kinetic-web_video_server-0.0.7-0

View File

@@ -0,0 +1,11 @@
#!/bin/bash
set -e
echo -e "\033[0;31m\033[1m$(date) | #1 Change boot partition\033[0m\033[0m"
sed -i 's/root=[^ ]*/root=\/dev\/mmcblk0p2/' /boot/cmdline.txt
sed -i 's/.* \/boot vfat defaults 0 2$/\/dev\/mmcblk0p1 \/boot vfat defaults 0 2/' /etc/fstab
sed -i 's/.* \/ ext4 defaults,noatime 0 1$/\/dev\/mmcblk0p2 \/ ext4 defaults,noatime 0 1/' /etc/fstab
echo -e "\033[0;31m\033[1m$(date) | End of change boot partition\033[0m\033[0m"

View File

@@ -38,6 +38,7 @@ echo -e "\033[0;31m\033[1m$(date) | #6 Turn on UART\033[0m\033[0m"
# https://github.com/RPi-Distro/raspi-config/pull/75 # https://github.com/RPi-Distro/raspi-config/pull/75
/usr/bin/raspi-config nonint do_serial 1 /usr/bin/raspi-config nonint do_serial 1
/usr/bin/raspi-config nonint set_config_var enable_uart 1 /boot/config.txt /usr/bin/raspi-config nonint set_config_var enable_uart 1 /boot/config.txt
/usr/bin/raspi-config nonint set_config_var dtoverlay pi3-miniuart-bt /boot/config.txt
# After adding to Raspbian OS # After adding to Raspbian OS
# https://github.com/RPi-Distro/raspi-config/commit/d6d9ecc0d9cbe4aaa9744ae733b9cb239e79c116 # https://github.com/RPi-Distro/raspi-config/commit/d6d9ecc0d9cbe4aaa9744ae733b9cb239e79c116

View File

@@ -8,10 +8,13 @@ echo -e "\033[0;31m\033[1m$(date) | #1 Write to /etc/wpa_supplicant/wpa_supplica
echo " echo "
network={ network={
ssid=\"CLEVER\" ssid=\"CLEVER\"
mode=2
key_mgmt=WPA-PSK
psk=\"cleverwifi\" psk=\"cleverwifi\"
frequency=2437 mode=2
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP
group=CCMP
auth_alg=OPEN
}" >> /etc/wpa_supplicant/wpa_supplicant.conf }" >> /etc/wpa_supplicant/wpa_supplicant.conf
echo -e "\033[0;31m\033[1m$(date) | #2 Write STATIC to /etc/dhcpcd.conf\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | #2 Write STATIC to /etc/dhcpcd.conf\033[0m\033[0m"
@@ -20,36 +23,23 @@ echo "
interface wlan0 interface wlan0
static ip_address=192.168.11.1/24" >> /etc/dhcpcd.conf static ip_address=192.168.11.1/24" >> /etc/dhcpcd.conf
echo -e "\033[0;31m\033[1m$(date) | #3 Write iface to /etc/default/isc-dhcp-server\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | #3 Write dhcp-config to /etc/dnsmasq.conf\033[0m\033[0m"
# https://www.shellhacks.com/ru/sed-find-replace-string-in-file/ echo "
sed -i 's/INTERFACESv4=\"\"/INTERFACESv4=\"wlan0\"/' /etc/default/isc-dhcp-server interface=wlan0
address=/clever/coex/192.168.11.1
dhcp-range=192.168.11.100,192.168.11.200,12h
no-hosts
filterwin2k
bogus-priv
domain-needed
quiet-dhcp6
" >> /etc/dnsmasq.conf
echo -e "\033[0;31m\033[1m$(date) | #4 Write dhcp declaration subnet to /etc/dhcp/dhcpd.conf\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | #4 Write magic script for rename SSID to /etc/rc.local\033[0m\033[0m"
echo "subnet 192.168.11.0 netmask 255.255.255.0 {
range 192.168.11.11 192.168.11.254;
#option domain-name-servers 8.8.8.8;
#option domain-name "rpi.local";
option routers 192.168.11.1;
option broadcast-address 192.168.11.255;
default-lease-time 600;
max-lease-time 7200;
}" >> /etc/dhcp/dhcpd.conf
echo -e "\033[0;31m\033[1m$(date) | #5 Write start script for dhcpd to /etc/network/if-up.d/isc-dhcp-server\033[0m\033[0m"
echo "#!/bin/sh
if [ \"\$IFACE\" = \"--all\" ];
then sleep 10 && systemctl start isc-dhcp-server.service &
fi
" > /etc/network/if-up.d/isc-dhcp-server \
&& chmod +x /etc/network/if-up.d/isc-dhcp-server
echo -e "\033[0;31m\033[1m$(date) | #6 Write magic script for rename SSID to /etc/rc.local\033[0m\033[0m"
RENAME_SSID="sudo sed -i.OLD \"s/CLEVER/CLEVER-\$(head -c 100 /dev/urandom | xxd -ps -c 100 | sed -e 's/[^0-9]//g' | cut -c 1-4)/g\" /etc/wpa_supplicant/wpa_supplicant.conf && sudo sed -i '/sudo sed/d' /etc/rc.local && sudo reboot" RENAME_SSID="sudo sed -i.OLD \"s/CLEVER/CLEVER-\$(head -c 100 /dev/urandom | xxd -ps -c 100 | sed -e 's/[^0-9]//g' | cut -c 1-4)/g\" /etc/wpa_supplicant/wpa_supplicant.conf && sudo sed -i '/sudo sed/d' /etc/rc.local && sudo reboot"
sed -i "19a$RENAME_SSID" /etc/rc.local sed -i "19a$RENAME_SSID" /etc/rc.local
echo -e "\033[0;31m\033[1m$(date) | #7 End of network installation\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | #5 End of network installation\033[0m\033[0m"

View File

@@ -7,15 +7,14 @@ set -e
################################################################################################################################## ##################################################################################################################################
# ros http://wiki.ros.org/action/fullsearch/ROSberryPi/Installing%20ROS%20Kinetic%20on%20the%20Raspberry%20Pi # ros http://wiki.ros.org/action/fullsearch/ROSberryPi/Installing%20ROS%20Kinetic%20on%20the%20Raspberry%20Pi
# maintainer @urpylka
echo -e "\033[0;31m\033[1m$(date) | #0 Installing ROS\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | Installing ROS\033[0m\033[0m"
echo -e "\033[0;31m\033[1m$(date) | #1 Installing dirmngr & add key to apt-key\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | #1 Installing dirmngr & add key to apt-key\033[0m\033[0m"
# Install a tool that apt-key uses to add ROS repository key # Install a tool that apt-key uses to add ROS repository key
# http://wpblogger.su/tags/apt/ # http://wpblogger.su/tags/apt/
apt-get install dirmngr apt-get install --no-install-recommends -y dirmngr=2.1.18-8~deb9u2
# setup keys # setup keys
apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116 apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116
@@ -31,36 +30,41 @@ apt-get update
echo -e "\033[0;31m\033[1m$(date) | #3 Installing wget, unzip, python-rosdep, python-rosinstall-generator, python-wstool, python-rosinstall, build-essential, cmake\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | #3 Installing wget, unzip, python-rosdep, python-rosinstall-generator, python-wstool, python-rosinstall, build-essential, cmake\033[0m\033[0m"
apt-get install --no-install-recommends -y \ apt-get install --no-install-recommends -y \
wget \ python-rosdep=0.12.2-1 \
unzip \ python-rosinstall-generator=0.1.14-1 \
python-rosdep \ python-wstool=0.1.17-1 \
python-rosinstall-generator \ python-rosinstall=0.7.8-1 \
python-wstool \ build-essential=12.3
python-rosinstall \
build-essential \
cmake \
libjpeg8-dev
echo -e "\033[0;31m\033[1m$(date) | #4 rosdep init && rosdep update\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | #4 rosdep init && rosdep update\033[0m\033[0m"
# bootstrap rosdep # bootstrap rosdep
rosdep init && rosdep update rosdep init && rosdep update
echo -e "\033[0;31m\033[1m$(date) | #5 Preparing ros_comm packages to kinetic-ros_comm-wet.rosinstall\033[0m\033[0m" # If $3 = false, then discover packages
if [ "$3" = "false" ];
then
echo -e "\033[0;31m\033[1m$(date) | #5 Preparing ros_comm packages to kinetic-ros_comm-wet.rosinstall\033[0m\033[0m"
# create catkin workspace # create ros catkin workspace
mkdir -p /home/pi/ros_catkin_ws && cd /home/pi/ros_catkin_ws \ mkdir -p /home/pi/ros_catkin_ws && cd /home/pi/ros_catkin_ws \
&& rosinstall_generator ros_comm --rosdistro kinetic --deps --wet-only --tar > kinetic-ros_comm-wet.rosinstall \ && rosinstall_generator ros_comm --rosdistro kinetic --deps --wet-only --tar > kinetic-ros_comm-wet.rosinstall \
&& wstool init src kinetic-ros_comm-wet.rosinstall && wstool init src kinetic-ros_comm-wet.rosinstall
echo -e "\033[0;31m\033[1m$(date) | #6 Preparing other ROS-packages to kinetic-custom_ros.rosinstall\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | #6 Preparing other ROS-packages to kinetic-custom_ros.rosinstall\033[0m\033[0m"
cd /home/pi/ros_catkin_ws \ cd /home/pi/ros_catkin_ws \
&& rosinstall_generator \ && rosinstall_generator \
actionlib actionlib_msgs angles async_web_server_cpp bond bond_core bondcpp bondpy camera_calibration_parsers camera_info_manager catkin class_loader cmake_modules cpp_common cv_bridge cv_camera diagnostic_msgs diagnostic_updater dynamic_reconfigure eigen_conversions gencpp geneus genlisp genmsg gennodejs genpy geographic_msgs geometry_msgs geometry2 image_transport libmavconn mavlink mavros_msgs message_filters message_generation message_runtime mk nav_msgs nodelet orocos_kdl pluginlib python_orocos_kdl ros ros_comm rosapi rosauth rosbag rosbag_migration_rule rosbag_storage rosbash rosboost_cfg rosbridge_library rosbridge_server rosbridge_suite rosbuild rosclean rosconsole rosconsole_bridge roscpp roscpp_serialization roscpp_traits roscreate rosgraph rosgraph_msgs roslang roslaunch roslib roslint roslisp roslz4 rosmake rosmaster rosmsg rosnode rosout rospack rosparam rospy rospy_tutorials rosserial rosserial_client rosserial_msgs rosserial_python rosservice rostest rostime rostopic rosunit roswtf sensor_msgs smclib std_msgs std_srvs stereo_msgs tf tf2 tf2_bullet tf2_eigen tf2_geometry_msgs tf2_kdl tf2_msgs tf2_py tf2_ros tf2_sensor_msgs tf2_tools topic_tools trajectory_msgs urdf urdf_parser_plugin usb_cam uuid_msgs visualization_msgs web_video_server xmlrpcpp mavros opencv3 mavros_extras \ actionlib actionlib_msgs angles async_web_server_cpp bond bond_core bondcpp bondpy camera_calibration_parsers camera_info_manager catkin class_loader cmake_modules cpp_common cv_bridge cv_camera diagnostic_msgs diagnostic_updater dynamic_reconfigure eigen_conversions gencpp geneus genlisp genmsg gennodejs genpy geographic_msgs geometry_msgs geometry2 image_transport libmavconn mavlink mavros_msgs message_filters message_generation message_runtime mk nav_msgs nodelet orocos_kdl pluginlib python_orocos_kdl ros ros_comm rosapi rosauth rosbag rosbag_migration_rule rosbag_storage rosbash rosboost_cfg rosbridge_library rosbridge_server rosbridge_suite rosbuild rosclean rosconsole rosconsole_bridge roscpp roscpp_serialization roscpp_traits roscreate rosgraph rosgraph_msgs roslang roslaunch roslib roslint roslisp roslz4 rosmake rosmaster rosmsg rosnode rosout rospack rosparam rospy rospy_tutorials rosserial rosserial_client rosserial_msgs rosserial_python rosservice rostest rostime rostopic rosunit roswtf sensor_msgs smclib std_msgs std_srvs stereo_msgs tf tf2 tf2_bullet tf2_eigen tf2_geometry_msgs tf2_kdl tf2_msgs tf2_py tf2_ros tf2_sensor_msgs tf2_tools topic_tools trajectory_msgs urdf urdf_parser_plugin usb_cam uuid_msgs visualization_msgs web_video_server xmlrpcpp mavros opencv3 mavros_extras \
--rosdistro kinetic --deps --wet-only --tar > kinetic-custom_ros.rosinstall \ --rosdistro kinetic --deps --wet-only --tar > kinetic-custom_ros.rosinstall \
&& wstool merge -t src kinetic-custom_ros.rosinstall \ && wstool merge -t src kinetic-custom_ros.rosinstall \
&& wstool update -t src && wstool update -t src
else
echo -e "\033[0;31m\033[1m$(date) | #5 Creating manual ros_catkin_ws\033[0m\033[0m"
mkdir -p /home/pi/ros_catkin_ws && cd /home/pi/ros_catkin_ws \
&& wstool init src kinetic-ros-coex.rosinstall
fi
echo -e "\033[0;31m\033[1m$(date) | #7 Installing dependencies apps with rosdep\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | #7 Installing dependencies apps with rosdep\033[0m\033[0m"
cd /home/pi/ros_catkin_ws cd /home/pi/ros_catkin_ws
@@ -92,7 +96,6 @@ set -e
[[ "$install_ok" == true ]] [[ "$install_ok" == true ]]
echo -e "\033[0;31m\033[1m$(date) | End of rosdep install\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | End of rosdep install\033[0m\033[0m"
echo -e "\033[0;31m\033[1m$(date) | #8 Refactoring usb_cam in SRC\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | #8 Refactoring usb_cam in SRC\033[0m\033[0m"
sed -i '/#define __STDC_CONSTANT_MACROS/a\#define PIX_FMT_RGB24 AV_PIX_FMT_RGB24\n#define PIX_FMT_YUV422P AV_PIX_FMT_YUV422P' /home/pi/ros_catkin_ws/src/usb_cam/src/usb_cam.cpp sed -i '/#define __STDC_CONSTANT_MACROS/a\#define PIX_FMT_RGB24 AV_PIX_FMT_RGB24\n#define PIX_FMT_YUV422P AV_PIX_FMT_YUV422P' /home/pi/ros_catkin_ws/src/usb_cam/src/usb_cam.cpp
@@ -119,50 +122,42 @@ echo -e "\033[0;31m\033[1m$(date) | #10 Building packages on 1 thread\033[0m\033
# TODO: Can we increase threads number with HDD swap? # TODO: Can we increase threads number with HDD swap?
cd /home/pi/ros_catkin_ws && ./src/catkin/bin/catkin_make_isolated --install -j1 -DCMAKE_BUILD_TYPE=Release --install-space /opt/ros/kinetic cd /home/pi/ros_catkin_ws && ./src/catkin/bin/catkin_make_isolated --install -j1 -DCMAKE_BUILD_TYPE=Release --install-space /opt/ros/kinetic
echo -e "\033[0;31m\033[1m$(date) | #12 Creating catkin_ws\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | #11 Remove build_isolated & devel_isolated from ros_catkin_ws\033[0m\033[0m"
mkdir -p /home/pi/catkin_ws/src \ rm -rf /home/pi/ros_catkin_ws/build_isolated /home/pi/ros_catkin_ws/devel_isolated
&& cd /home/pi/catkin_ws \ chown -Rf pi:pi /home/pi/ros_catkin_ws
&& . /opt/ros/kinetic/setup.sh \
&& catkin init \
&& wstool init /home/pi/catkin_ws/src
echo -e "\033[0;31m\033[1m$(date) | #13 Installing CLEVER-BUNDLE\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | #12 Creating catkin_ws & Installing CLEVER-BUNDLE\033[0m\033[0m"
cd /home/pi/catkin_ws/src \ git clone $1 /home/pi/catkin_ws/src/clever \
&& git clone https://github.com/CopterExpress/clever.git clever \ && cd /home/pi/catkin_ws/src/clever \
&& git checkout $2 \
&& pip install wheel \ && pip install wheel \
&& pip install -r /home/pi/catkin_ws/src/clever/clever/requirements.txt \ && pip install -r /home/pi/catkin_ws/src/clever/clever/requirements.txt \
&& cd /home/pi/catkin_ws \ && cd /home/pi/catkin_ws \
&& . /opt/ros/kinetic/setup.sh \ && . /opt/ros/kinetic/setup.sh \
&& catkin_make -j1 \ && catkin_make -j1 -DCMAKE_BUILD_TYPE=Release \
&& systemctl enable /home/pi/catkin_ws/src/clever/deploy/roscore.service \ && ln -s /home/pi/catkin_ws/src/clever/deploy/roscore.service /lib/systemd/system/roscore.service \
&& systemctl enable /home/pi/catkin_ws/src/clever/deploy/clever.service && ln -s /home/pi/catkin_ws/src/clever/deploy/clever.service /lib/systemd/system/clever.service \
&& systemctl enable roscore \
&& systemctl enable clever
echo -e "\033[0;31m\033[1m$(date) | #14 Adding mjpg-streamer at /home/pi\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | #13 Change permissions for catkin_ws\033[0m\033[0m"
# https://github.com/jacksonliam/mjpg-streamer chown -Rf pi:pi /home/pi/catkin_ws
cd /home/pi \ echo -e "\033[0;31m\033[1m$(date) | #14 Setup ROS environment\033[0m\033[0m"
&& git clone https://github.com/jacksonliam/mjpg-streamer.git \
&& cd /home/pi/mjpg-streamer/mjpg-streamer-experimental \
&& make \
&& make install
echo -e "\033[0;31m\033[1m$(date) | #15 Adding ENV vars\033[0m\033[0m" cat <<EOF | tee -a /home/pi/.bashrc > /dev/null
LANG=C.UTF-8
LC_ALL=C.UTF-8
ROS_DISTRO=kinetic
export ROS_IP=192.168.11.1
source /opt/ros/kinetic/setup.bash
source /home/pi/catkin_ws/devel/setup.bash
EOF
# setup environment #echo -e "\033[0;31m\033[1m$(date) | #14 Removing local apt mirror\033[0m\033[0m"
echo "LANG=C.UTF-8" >> /home/pi/.bashrc
echo "LC_ALL=C.UTF-8" >> /home/pi/.bashrc
echo "ROS_DISTRO=kinetic" >> /home/pi/.bashrc
echo "export ROS_IP=192.168.11.1" >> /home/pi/.bashrc
echo "source /opt/ros/kinetic/setup.bash" >> /home/pi/.bashrc \
&& echo "source /home/pi/catkin_ws/devel/setup.bash" >> /home/pi/.bashrc
chown -Rf pi:pi /home/pi
#echo -e "\033[0;31m\033[1m$(date) | #16 Removing local apt mirror\033[0m\033[0m"
# Restore original sources.list # Restore original sources.list
#mv /var/sources.list.bak /etc/apt/sources.list #mv /var/sources.list.bak /etc/apt/sources.list
# Clean apt cache # Clean apt cache
@@ -170,4 +165,4 @@ apt-get clean
# Remove local mirror repository key # Remove local mirror repository key
#apt-key del COEX-MIRROR #apt-key del COEX-MIRROR
echo -e "\033[0;31m\033[1m$(date) | #16 END of ROS INSTALLATION\033[0m\033[0m" echo -e "\033[0;31m\033[1m$(date) | END of ROS INSTALLATION\033[0m\033[0m"

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