Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8dc4e6e0b9 | ||
|
|
360ce5c77b | ||
|
|
4b6d630f5c | ||
|
|
47d4b3d8a8 | ||
|
|
162d9d05cc | ||
|
|
4f114184bf | ||
|
|
810e44563c | ||
|
|
704aaf163c | ||
|
|
55988650a6 | ||
|
|
eb499512ee | ||
|
|
794310550c | ||
|
|
280db083b4 | ||
|
|
d5353a5bef | ||
|
|
fc428d45b9 | ||
|
|
19181facdb | ||
|
|
8813fce63f | ||
|
|
ac8090ae8b | ||
|
|
53e644a5f7 | ||
|
|
a325156e71 | ||
|
|
05e1875eec | ||
|
|
98d1ad8494 | ||
|
|
ef6b8727b9 | ||
|
|
d7ced0f9c4 | ||
|
|
d76ef207fe | ||
|
|
fdf6eadfcd | ||
|
|
4e4f02404f | ||
|
|
42c942514f | ||
|
|
a6b0ac43e9 | ||
|
|
0893eb85bc | ||
|
|
e817e3c7a5 | ||
|
|
32f98fa70e | ||
|
|
66bdffc747 | ||
|
|
5d353125d2 | ||
|
|
7f2d4344e3 | ||
|
|
4736871524 | ||
|
|
bcd88d6d4d | ||
|
|
8ffe74b772 | ||
|
|
57ae4c304f | ||
|
|
8be77ab7d9 | ||
|
|
8c193b913f | ||
|
|
4fac517a1e | ||
|
|
4f7061351f | ||
|
|
decc5ecae6 | ||
|
|
f06fae6885 | ||
|
|
8d46f51c66 | ||
|
|
601ef0848d | ||
|
|
3b0dd46ca6 | ||
|
|
16b2e1903a | ||
|
|
36d7a95d34 | ||
|
|
1d82e195ec | ||
|
|
78cae0c69a | ||
|
|
2b46ee27f2 | ||
|
|
de44400749 | ||
|
|
55e40bd6c3 | ||
|
|
124950d7e4 | ||
|
|
199104ca83 | ||
|
|
e5552e0a4b | ||
|
|
bfb0aa7961 | ||
|
|
44d83bdcf8 | ||
|
|
d960e57cf9 | ||
|
|
30ec03ef4d | ||
|
|
c2c27b1577 | ||
|
|
c0449ccf59 | ||
|
|
ea933ce3d1 | ||
|
|
327666385b | ||
|
|
8ea511b293 | ||
|
|
c510fe5cf0 | ||
|
|
dab70937f5 | ||
|
|
204dd97b00 | ||
|
|
27bfecc737 |
22
.markdownlint.json
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,8 @@ Use it to learn how to assemble, configure, pilot and program autonomous CLEVER
|
||||
|
||||
**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).**
|
||||
|
||||
[](http://builder.coex.space/job/CopterExpress---clever/)
|
||||
|
||||
Image includes:
|
||||
|
||||
* Raspbian Stretch
|
||||
|
||||
@@ -9,6 +9,5 @@ target 'cleverrc' do
|
||||
|
||||
# Pods for cleverrc
|
||||
pod 'SwiftSocket', '~> 2.0'
|
||||
pod 'NotificationBannerSwift'
|
||||
|
||||
end
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>3</string>
|
||||
<string>5</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
|
||||
@@ -62,15 +62,7 @@ class ViewController: UIViewController, WKScriptMessageHandler {
|
||||
} else if (message.name == "notification") {
|
||||
// Got notification message
|
||||
print(message)
|
||||
let m = message.body as! NSDictionary;
|
||||
let level = m["level"] as! Int
|
||||
if level == 4 {
|
||||
let banner = NotificationBanner(title: m["msg"] as! String, style: .warning)
|
||||
banner.show()
|
||||
} else {
|
||||
let banner = NotificationBanner(title: m["msg"] as! String, style: .danger)
|
||||
banner.show()
|
||||
}
|
||||
tapticNotify()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,84 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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"
|
||||
viewBox="0 0 52.5 52.5" enable-background="new 0 0 52.5 52.5" xml:space="preserve">
|
||||
<g>
|
||||
<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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
C35.1,17.7,35.4,17.5,35.7,17.2z"/>
|
||||
<g>
|
||||
<polygon points="41.6,29.7 41.6,29.7 41.6,29.6 41.6,29.6 "/>
|
||||
<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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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"/>
|
||||
<polygon points="22.3,34.9 22.3,34.9 22.3,34.9 22.3,34.9 "/>
|
||||
</g>
|
||||
<g>
|
||||
<polygon points="40.7,30.2 40.7,30.2 40.7,30.2 "/>
|
||||
<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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 69.988266 69.987198"
|
||||
height="69.987198"
|
||||
width="69.988266"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
version="1.1"><metadata
|
||||
id="metadata8"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs6"><clipPath
|
||||
id="clipPath18"
|
||||
clipPathUnits="userSpaceOnUse"><path
|
||||
id="path16"
|
||||
d="M 0,52.49 H 52.491 V 0 H 0 Z" /></clipPath></defs><g
|
||||
transform="matrix(1.3333333,0,0,-1.3333333,0,69.9872)"
|
||||
id="g10"><g
|
||||
id="g12"><g
|
||||
clip-path="url(#clipPath18)"
|
||||
id="g14"><g
|
||||
transform="translate(35.6531,35.3361)"
|
||||
id="g20"><path
|
||||
id="path22"
|
||||
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 C 0.279,0.322 0.5,0.686 0.657,1.081 0.827,1.513 0.914,1.968 0.917,2.434 0.92,2.924 0.829,3.403 0.647,3.857 0.458,4.329 0.165,4.77 -0.2,5.13 -0.587,5.512 -1.061,5.812 -1.571,5.995 -2.138,6.198 -2.756,6.262 -3.358,6.18 -3.821,6.115 -4.263,5.967 -4.671,5.739 -4.886,5.618 -5.094,5.472 -5.291,5.305 L -5.467,5.151 C -5.527,5.099 -5.587,5.049 -5.649,5.003 -5.775,4.909 -5.906,4.827 -6.04,4.759 -6.173,4.691 -6.314,4.633 -6.458,4.586 -6.575,4.549 -6.696,4.519 -6.819,4.496 -6.917,4.478 -7.017,4.465 -7.115,4.457 c -0.623,-0.052 -1.281,0.082 -1.9,0.385 -0.224,0.111 -0.439,0.241 -0.64,0.387 -0.042,0.03 -0.084,0.063 -0.127,0.095 -0.039,0.031 -0.069,0.054 -0.102,0.09 -0.023,0.025 -0.043,0.05 -0.061,0.077 -0.056,0.082 -0.093,0.176 -0.107,0.271 -0.004,0.022 -0.005,0.044 -0.006,0.066 l -0.002,6.486 c -0.534,0.589 -1.115,1.136 -1.728,1.626 -0.913,0.73 -1.913,1.352 -2.971,1.845 -0.867,0.405 -1.779,0.725 -2.711,0.952 -0.851,0.208 -1.731,0.34 -2.617,0.391 -0.912,0.053 -1.834,0.023 -2.741,-0.092 -0.741,-0.094 -1.479,-0.246 -2.194,-0.453 -1.274,-0.365 -2.494,-0.905 -3.628,-1.604 -0.824,-0.507 -1.603,-1.101 -2.316,-1.764 -0.687,-0.64 -1.317,-1.35 -1.871,-2.109 -0.505,-0.692 -0.951,-1.432 -1.327,-2.2 -0.375,-0.764 -0.684,-1.566 -0.919,-2.383 -0.201,-0.7 -0.351,-1.423 -0.446,-2.147 -0.12,-0.919 -0.153,-1.858 -0.099,-2.79 0.05,-0.838 0.171,-1.673 0.359,-2.482 0.201,-0.856 0.481,-1.7 0.833,-2.507 0.546,-1.253 1.265,-2.423 2.136,-3.479 0.317,-0.384 0.654,-0.753 1.002,-1.098 0.158,-0.157 0.32,-0.31 0.485,-0.459 h 6.121 c 0.051,0.08 0.099,0.161 0.143,0.245 0.037,0.071 0.072,0.144 0.104,0.218 0.026,0.062 0.05,0.128 0.073,0.193 0.132,0.394 0.159,0.784 0.077,1.127 -0.013,0.052 -0.028,0.105 -0.046,0.157 -0.024,0.068 -0.053,0.136 -0.087,0.201 -0.048,0.09 -0.105,0.174 -0.169,0.249 -0.035,0.041 -0.07,0.079 -0.107,0.116 l -0.024,0.026 c -0.025,0.029 -0.046,0.053 -0.066,0.079 -0.014,0.02 -0.02,0.029 -0.027,0.038 l -0.079,0.096 c -0.109,0.134 -0.212,0.277 -0.304,0.42 -0.207,0.318 -0.378,0.659 -0.506,1.013 -0.118,0.32 -0.202,0.651 -0.252,0.985 -0.085,0.571 -0.073,1.146 0.035,1.71 0.098,0.509 0.273,0.999 0.521,1.454 0.258,0.475 0.588,0.903 0.98,1.272 0.419,0.394 0.895,0.711 1.415,0.942 0.557,0.249 1.15,0.393 1.762,0.428 0.659,0.035 1.298,-0.05 1.914,-0.258 0.653,-0.221 1.268,-0.585 1.78,-1.05 0.541,-0.492 0.977,-1.106 1.261,-1.776 0.151,-0.357 0.26,-0.729 0.324,-1.106 0.072,-0.415 0.092,-0.843 0.058,-1.272 -0.031,-0.388 -0.108,-0.773 -0.227,-1.144 -0.11,-0.341 -0.257,-0.673 -0.441,-0.988 -0.103,-0.177 -0.216,-0.347 -0.335,-0.503 -0.037,-0.051 -0.077,-0.1 -0.117,-0.151 l -0.033,-0.04 -0.005,0.002 -0.049,-0.07 c -0.022,-0.028 -0.043,-0.054 -0.066,-0.08 l -0.076,-0.08 c -0.028,-0.03 -0.055,-0.062 -0.081,-0.094 -0.05,-0.063 -0.095,-0.131 -0.134,-0.202 -0.035,-0.064 -0.066,-0.131 -0.09,-0.199 -0.019,-0.053 -0.035,-0.105 -0.049,-0.158 -0.085,-0.34 -0.062,-0.729 0.066,-1.123 0.021,-0.066 0.045,-0.13 0.071,-0.193 0.03,-0.073 0.063,-0.145 0.1,-0.215 0.045,-0.088 0.096,-0.176 0.156,-0.269 h 7.162 l 0.002,7.527 c 10e-4,0.022 0.002,0.043 0.006,0.065 0.008,0.061 0.027,0.124 0.057,0.187 0.03,0.06 0.067,0.114 0.111,0.161 0.034,0.037 0.065,0.062 0.102,0.09 l 0.062,0.048 c 0.087,0.065 0.173,0.126 0.262,0.183 0.487,0.316 1.027,0.526 1.563,0.608 0.154,0.024 0.312,0.037 0.482,0.04 0.037,0.001 0.076,0 0.113,-0.001 0.062,-0.002 0.124,-0.005 0.186,-0.01 0.123,-0.011 0.247,-0.029 0.367,-0.053 0.338,-0.071 0.654,-0.2 0.939,-0.383 0.11,-0.07 0.214,-0.149 0.31,-0.231 0.031,-0.026 0.061,-0.053 0.09,-0.081 l 0.029,-0.028 -0.07,-0.106 c 0.003,-0.003 0.007,-0.007 0.01,-0.01 l 0.071,0.101 0.215,-0.169 c 0.13,-0.101 0.243,-0.179 0.358,-0.25 0.24,-0.146 0.497,-0.266 0.763,-0.355 0.656,-0.219 1.363,-0.253 2.04,-0.097 0.374,0.086 0.731,0.229 1.059,0.424 C -0.581,-0.571 -0.268,-0.309 0,0" /></g><g
|
||||
transform="translate(41.5882,22.8337)"
|
||||
id="g24"><path
|
||||
id="path26"
|
||||
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 V 0 L 0.053,0.044 0.013,0.018 Z" /></g><g
|
||||
transform="translate(28.5515,3.2736)"
|
||||
id="g28"><path
|
||||
id="path30"
|
||||
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 0.934,-0.757 1.959,-1.398 3.045,-1.906 0.84,-0.39 1.72,-0.702 2.615,-0.927 0.883,-0.222 1.796,-0.362 2.714,-0.416 0.944,-0.054 1.897,-0.019 2.832,0.106 0.707,0.094 1.414,0.242 2.102,0.439 1.276,0.368 2.496,0.908 3.628,1.605 0.798,0.492 1.556,1.065 2.251,1.704 0.724,0.666 1.384,1.408 1.962,2.205 0.468,0.646 0.886,1.334 1.242,2.044 0.409,0.815 0.742,1.672 0.99,2.547 0.179,0.628 0.316,1.274 0.409,1.921 0.14,0.979 0.182,1.98 0.123,2.973 -0.048,0.819 -0.165,1.638 -0.348,2.433 -0.2,0.872 -0.484,1.732 -0.843,2.556 -0.538,1.234 -1.247,2.392 -2.106,3.442 -0.313,0.381 -0.648,0.752 -0.998,1.1 l -0.52,0.493 H 12.982 L 12.831,22.068 C 12.797,22.003 12.763,21.931 12.732,21.857 12.705,21.794 12.681,21.73 12.659,21.665 12.527,21.268 12.5,20.878 12.582,20.536 c 0.012,-0.053 0.027,-0.105 0.045,-0.156 0.024,-0.069 0.054,-0.137 0.088,-0.202 0.046,-0.086 0.103,-0.171 0.169,-0.251 0.027,-0.032 0.056,-0.062 0.086,-0.093 l 0.045,-0.048 c 0.023,-0.025 0.044,-0.051 0.065,-0.078 l -0.046,-0.082 0.061,0.057 0.003,-0.002 0.022,-0.028 -10e-4,-10e-4 0.01,-0.015 0.004,0.003 0.05,-0.062 c 0.171,-0.212 0.322,-0.433 0.451,-0.659 0.275,-0.478 0.469,-0.996 0.575,-1.538 0.141,-0.718 0.124,-1.472 -0.05,-2.181 -0.152,-0.623 -0.431,-1.228 -0.807,-1.751 -0.303,-0.42 -0.667,-0.79 -1.082,-1.1 C 11.868,12.048 11.425,11.81 10.954,11.64 10.456,11.461 9.935,11.362 9.406,11.345 8.955,11.331 8.505,11.376 8.07,11.48 c -0.494,0.118 -0.965,0.308 -1.399,0.565 -0.509,0.301 -0.958,0.685 -1.333,1.14 -0.393,0.477 -0.692,1.014 -0.89,1.596 -0.218,0.645 -0.305,1.348 -0.25,2.031 0.029,0.355 0.095,0.704 0.194,1.037 0.114,0.383 0.273,0.751 0.474,1.095 0.095,0.164 0.207,0.334 0.334,0.503 0.038,0.051 0.078,0.102 0.118,0.151 L 5.45,19.56 v 0 l -0.101,0.074 0.055,0.073 c 0.023,0.028 0.045,0.054 0.066,0.078 l 0.076,0.08 c 0.03,0.031 0.057,0.062 0.082,0.095 0.05,0.063 0.095,0.131 0.135,0.203 0.034,0.063 0.065,0.13 0.09,0.199 0.019,0.052 0.034,0.103 0.047,0.156 0.086,0.341 0.063,0.73 -0.065,1.124 -0.021,0.065 -0.044,0.129 -0.071,0.193 -0.033,0.082 -0.071,0.162 -0.113,0.24 -0.044,0.084 -0.092,0.165 -0.143,0.244 h -7.162 l -0.002,-7.532 c -0.001,-0.02 -0.003,-0.041 -0.006,-0.06 -0.015,-0.099 -0.052,-0.192 -0.107,-0.272 -0.018,-0.027 -0.039,-0.052 -0.061,-0.076 -0.035,-0.037 -0.064,-0.061 -0.102,-0.09 -0.02,-0.016 -0.042,-0.033 -0.065,-0.05 -0.122,-0.091 -0.254,-0.181 -0.393,-0.264 -0.619,-0.37 -1.29,-0.565 -1.942,-0.565 -0.093,-0.003 -0.179,0.003 -0.268,0.011 -0.11,0.01 -0.221,0.025 -0.33,0.046 -0.36,0.071 -0.709,0.213 -1.008,0.411 -0.109,0.072 -0.213,0.152 -0.309,0.237 -0.029,0.026 -0.058,0.052 -0.085,0.079 h -0.026 l -0.022,0.042 -0.036,0.027 c -0.035,0.03 -0.061,0.051 -0.087,0.072 l -0.073,0.059 c -0.212,0.162 -0.427,0.296 -0.648,0.404 -0.416,0.204 -0.861,0.328 -1.324,0.367 -0.345,0.028 -0.695,0.012 -1.037,-0.053 -0.259,-0.05 -0.511,-0.126 -0.75,-0.228 -0.498,-0.211 -0.954,-0.534 -1.32,-0.936 -0.345,-0.381 -0.614,-0.838 -0.779,-1.322 -0.154,-0.455 -0.218,-0.933 -0.191,-1.421 0.026,-0.462 0.136,-0.909 0.326,-1.327 0.175,-0.386 0.412,-0.738 0.706,-1.047 0.283,-0.296 0.609,-0.543 0.97,-0.734 0.319,-0.168 0.661,-0.289 1.015,-0.36 0.449,-0.089 0.906,-0.095 1.357,-0.021 0.246,0.041 0.49,0.108 0.725,0.198 0.254,0.098 0.499,0.225 0.727,0.377 0.113,0.075 0.229,0.161 0.343,0.257 l 0.068,0.054 0.016,0.046 0.041,0.002 c 0.012,0.013 0.02,0.02 0.029,0.028 l 0.055,0.052 c 0.051,0.043 0.1,0.084 0.151,0.124 0.104,0.08 0.212,0.151 0.322,0.213 0.28,0.159 0.589,0.268 0.917,0.324 0.152,0.026 0.31,0.04 0.48,0.043 h 0.109 C -4.1,9.429 -3.938,9.414 -3.782,9.389 -3.261,9.303 -2.734,9.095 -2.256,8.787 -2.167,8.73 -2.08,8.668 -1.996,8.604 l 0.053,-0.04 c 0.048,-0.037 0.077,-0.061 0.111,-0.097 0.047,-0.05 0.084,-0.104 0.113,-0.162 0.029,-0.062 0.048,-0.125 0.057,-0.187 0.003,-0.02 0.005,-0.04 0.006,-0.06 L -1.654,8.021 V 1.566 C -1.142,1.001 -0.585,0.474 0,0" /></g><g
|
||||
transform="translate(22.2707,17.571)"
|
||||
id="g32"><path
|
||||
id="path34"
|
||||
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 v -0.008 l 0.011,0.019 v 0 z" /></g><g
|
||||
transform="translate(40.657,22.3049)"
|
||||
id="g36"><path
|
||||
id="path38"
|
||||
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 Z" /></g><g
|
||||
transform="translate(49.1867,28.5134)"
|
||||
id="g40"><path
|
||||
id="path42"
|
||||
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 0.721,0.884 1.337,1.848 1.832,2.865 0.359,0.739 0.659,1.516 0.89,2.311 0.244,0.839 0.413,1.706 0.503,2.579 0.173,1.678 0.063,3.352 -0.329,4.976 -0.323,1.339 -0.834,2.625 -1.518,3.823 -0.416,0.728 -0.898,1.425 -1.432,2.072 -0.597,0.724 -1.268,1.394 -1.993,1.994 -0.636,0.525 -1.32,0.999 -2.034,1.409 -0.75,0.431 -1.539,0.796 -2.345,1.086 -1,0.359 -2.041,0.609 -3.095,0.743 -0.401,0.051 -0.808,0.086 -1.209,0.104 -0.205,0.009 -0.41,0.014 -0.615,0.015 h -0.098 c -0.479,-0.003 -0.943,-0.026 -1.379,-0.069 -0.825,-0.08 -1.65,-0.231 -2.451,-0.45 -0.861,-0.235 -1.705,-0.551 -2.509,-0.941 -0.765,-0.371 -1.502,-0.811 -2.191,-1.308 -0.571,-0.411 -1.115,-0.866 -1.618,-1.352 -0.236,-0.227 -0.471,-0.469 -0.698,-0.72 v -6.121 c 0.079,-0.052 0.161,-0.1 0.245,-0.144 0.07,-0.037 0.143,-0.071 0.216,-0.102 0.064,-0.027 0.13,-0.051 0.195,-0.074 0.394,-0.132 0.784,-0.158 1.127,-0.077 0.053,0.012 0.105,0.027 0.156,0.045 0.069,0.024 0.136,0.054 0.201,0.088 0.088,0.047 0.173,0.104 0.251,0.169 0.04,0.034 0.078,0.071 0.116,0.107 l 0.029,0.028 c 0.035,0.029 0.055,0.046 0.077,0.063 l 0.107,0.085 c 0.164,0.132 0.314,0.24 0.466,0.338 0.319,0.205 0.662,0.373 1.018,0.502 0.317,0.115 0.649,0.198 0.987,0.245 0.56,0.082 1.126,0.068 1.681,-0.038 0.51,-0.098 1,-0.273 1.455,-0.521 0.473,-0.257 0.901,-0.587 1.272,-0.981 0.394,-0.418 0.711,-0.894 0.942,-1.414 0.248,-0.558 0.392,-1.151 0.427,-1.762 0.037,-0.645 -0.052,-1.307 -0.258,-1.914 -0.22,-0.652 -0.583,-1.267 -1.049,-1.781 -0.491,-0.54 -1.105,-0.976 -1.776,-1.26 -0.352,-0.149 -0.724,-0.259 -1.106,-0.325 -0.421,-0.072 -0.849,-0.091 -1.272,-0.057 -0.371,0.03 -0.739,0.1 -1.09,0.21 -0.365,0.113 -0.716,0.267 -1.042,0.458 -0.167,0.096 -0.336,0.209 -0.503,0.334 -0.051,0.039 -0.102,0.078 -0.151,0.118 l -0.108,0.086 c -0.028,0.022 -0.053,0.043 -0.079,0.065 -0.03,0.028 -0.056,0.054 -0.082,0.079 -0.029,0.026 -0.061,0.054 -0.094,0.081 -0.064,0.05 -0.132,0.095 -0.201,0.133 -0.064,0.035 -0.132,0.065 -0.201,0.091 -0.051,0.018 -0.101,0.034 -0.154,0.046 C -20.829,6.024 -21.219,6 -21.613,5.873 -21.677,5.852 -21.742,5.828 -21.806,5.802 -21.887,5.768 -21.967,5.73 -22.045,5.689 -22.129,5.645 -22.21,5.598 -22.289,5.546 v -7.162 l 7.532,-0.003 c 0.02,-0.001 0.04,-0.002 0.06,-0.005 0.098,-0.015 0.192,-0.052 0.272,-0.107 0.026,-0.018 0.053,-0.039 0.076,-0.062 0.035,-0.033 0.058,-0.061 0.085,-0.096 l 0.053,-0.068 c 0.094,-0.125 0.184,-0.257 0.267,-0.395 0.362,-0.608 0.557,-1.269 0.563,-1.912 0.002,-0.099 -0.002,-0.198 -0.01,-0.298 -0.009,-0.11 -0.025,-0.221 -0.046,-0.33 -0.072,-0.362 -0.213,-0.711 -0.41,-1.008 -0.074,-0.11 -0.153,-0.214 -0.238,-0.309 -0.026,-0.029 -0.053,-0.057 -0.08,-0.086 l -0.025,-0.026 v 10e-4 l -0.18,-0.227 c -0.083,-0.106 -0.161,-0.219 -0.23,-0.334 -0.143,-0.233 -0.26,-0.483 -0.349,-0.744 -0.223,-0.654 -0.261,-1.359 -0.109,-2.037 0.084,-0.378 0.229,-0.742 0.429,-1.083 0.208,-0.351 0.47,-0.665 0.779,-0.932 0.323,-0.28 0.687,-0.5 1.081,-0.656 0.429,-0.17 0.884,-0.257 1.352,-0.26 h 0.026 c 0.482,0 0.951,0.09 1.397,0.269 0.473,0.19 0.913,0.483 1.274,0.848 0.383,0.388 0.682,0.862 0.865,1.371 0.203,0.566 0.267,1.184 0.184,1.786 -0.066,0.477 -0.221,0.931 -0.461,1.349 -0.117,0.204 -0.256,0.4 -0.413,0.584 l -0.073,0.089 0.005,0.01 -0.002,0.006 0.007,0.002 0.017,0.033 0.035,0.065 -0.091,-0.085 -0.053,0.057 c -0.051,0.06 -0.101,0.12 -0.148,0.182 -0.091,0.121 -0.173,0.253 -0.243,0.391 -0.067,0.13 -0.125,0.27 -0.172,0.417 -0.038,0.116 -0.068,0.239 -0.091,0.363 -0.018,0.097 -0.031,0.196 -0.039,0.294 -0.052,0.624 0.082,1.281 0.385,1.901 0.109,0.221 0.239,0.436 0.386,0.639 0.031,0.043 0.064,0.085 0.096,0.127 0.032,0.041 0.055,0.069 0.09,0.102 0.025,0.023 0.051,0.045 0.078,0.063 0.079,0.054 0.172,0.091 0.27,0.106 0.02,0.003 0.04,0.004 0.06,0.005 l 0.038,0.003 h 6.454 C -0.981,-1.113 -0.465,-0.57 0,0" /></g>
|
||||
</g></g></g></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 13 KiB |
@@ -17,6 +17,7 @@
|
||||
<div class="stick-pointer"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notifications"></div>
|
||||
<script src="main.js" type="text/javascript"></script>
|
||||
<script src="telemetry.js" type="text/javascript"></script>
|
||||
</body>
|
||||
|
||||
@@ -8,7 +8,7 @@ html, body {
|
||||
}
|
||||
|
||||
* {
|
||||
user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.stick {
|
||||
@@ -76,7 +76,8 @@ body.armed .telemetry .mode {
|
||||
|
||||
body.low-battery .battery {
|
||||
color: #ff554b;
|
||||
animation: scale 0.3s 1 ease-in-out}
|
||||
animation: scale 0.3s 1 ease-in-out
|
||||
}
|
||||
|
||||
.logo {
|
||||
position: absolute;
|
||||
@@ -93,3 +94,32 @@ body.low-battery .battery {
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.notifications {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.notifications.hidden {
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
.notifications.anim {
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.notifications .item {
|
||||
font-size: 4mm;
|
||||
-webkit-text-size-adjust: none;
|
||||
background: #fca83a;
|
||||
padding: 3mm;
|
||||
padding-bottom: 1.5mm;
|
||||
}
|
||||
|
||||
.notifications .item:last-child {
|
||||
padding-bottom: 3mm;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
var url = 'ws://192.168.11.1:9090';
|
||||
var modeEl = document.querySelector('.telemetry .mode');
|
||||
var batteryEl = document.querySelector('.battery');
|
||||
var notificationsEl = document.querySelector('.notifications');
|
||||
|
||||
var ros = new ROSLIB.Ros({ url: url });
|
||||
|
||||
@@ -35,10 +36,14 @@ new ROSLIB.Topic({
|
||||
});
|
||||
|
||||
function notifyLowBattery() {
|
||||
console.log('low battery');
|
||||
callNativeApp('lowBattery');
|
||||
body.classList.remove('low-battery');
|
||||
void body.offsetWidth; // trick for repeating animation
|
||||
body.classList.add('low-battery');
|
||||
}
|
||||
|
||||
notifyLowBatteryThrottled = throttle(notifyLowBattery, 10000);
|
||||
notifyLowBatteryThrottled = throttle(notifyLowBattery, 15000);
|
||||
|
||||
new ROSLIB.Topic({
|
||||
ros: ros,
|
||||
@@ -50,29 +55,50 @@ new ROSLIB.Topic({
|
||||
batteryEl.innerHTML = (message.cell_voltage[0].toFixed(2) + ' V') || '';
|
||||
|
||||
if (message.cell_voltage[0] < LOW_BATTERY) {
|
||||
console.log('low battery');
|
||||
callNativeApp('lowBattery');
|
||||
body.classList.remove('low-battery');
|
||||
void body.offsetWidth; // trick for repeating animation
|
||||
body.classList.add('low-battery');
|
||||
notifyLowBatteryThrottled();
|
||||
} else {
|
||||
body.classList.remove('low-battery');
|
||||
}
|
||||
});
|
||||
|
||||
var notificationHideTimer;
|
||||
|
||||
function notify(text, severity) {
|
||||
var item = document.createElement('div');
|
||||
item.innerHTML = text;
|
||||
item.classList.add('item');
|
||||
notificationsEl.prepend(item);
|
||||
var itemHeight = item.offsetHeight;
|
||||
notificationsEl.classList.remove('anim');
|
||||
notificationsEl.style.transform = 'translateY(' + -itemHeight + 'px)';
|
||||
setTimeout(function() {
|
||||
notificationsEl.classList.add('anim');
|
||||
notificationsEl.style.transform = 'translateY(0)';
|
||||
}, 0);
|
||||
clearTimeout(notificationHideTimer);
|
||||
notificationHideTimer = setTimeout(function() {
|
||||
notificationsEl.style.transform = '';
|
||||
notificationsEl.classList.add('hidden');
|
||||
setTimeout(function() {
|
||||
notificationsEl.innerHTML = '';
|
||||
}, 210);
|
||||
}, 4000);
|
||||
}
|
||||
|
||||
new ROSLIB.Topic({
|
||||
ros: ros,
|
||||
name: '/rosout_agg',
|
||||
messageType: 'rosgraph_msgs/Log'
|
||||
name: '/mavros/statustext/recv',
|
||||
messageType: 'mavros_msgs/StatusText'
|
||||
}).subscribe(function(message) {
|
||||
var BLACKLIST = ['CMD: ', 'PR: ', 'DROPPED', 'Clock skew detected', 'MANUAL CONTROL LOST'];
|
||||
if (message.level >= 4) {
|
||||
if (message.severity <= 4) {
|
||||
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;
|
||||
}
|
||||
notify(message.text, message.severity);
|
||||
callNativeApp('notification', message);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -15,5 +15,8 @@
|
||||
"yametrika": {
|
||||
"id": 49359238
|
||||
}
|
||||
},
|
||||
"structure": {
|
||||
"glossary": "_GLOSSARY.md"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
<!-- gcs bridge -->
|
||||
<param name="gcs_url" value="tcp-l://0.0.0.0:5760" if="$(eval gcs_bridge == 'tcp')"/>
|
||||
<param name="gcs_url" value="udp://0.0.0.0:14550@14550" if="$(eval gcs_bridge == 'udp')"/>
|
||||
<param name="gcs_url" value="udp-b://0.0.0.0:14550@14550" if="$(eval gcs_bridge == 'udp-b')"/>
|
||||
<param name="gcs_url" value="udp-pb://0.0.0.0:14550@14550" if="$(eval gcs_bridge == 'udp-pb')"/>
|
||||
<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_quiet_mode" value="true"/>
|
||||
<param name="conn/timeout" value="10"/>
|
||||
<param name="conn/timeout" value="8"/>
|
||||
|
||||
<!-- default px4 params -->
|
||||
<rosparam command="load" file="$(find mavros)/launch/px4_config.yaml"/>
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
flask==0.12.2
|
||||
geopy==1.11.0
|
||||
pymavlink==2.2.10
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "std_msgs/String.h"
|
||||
#include "mavros_msgs/State.h"
|
||||
#include "mavros_msgs/ManualControl.h"
|
||||
#include "mavros_msgs/Mavlink.h"
|
||||
|
||||
struct ControlMessage
|
||||
{
|
||||
@@ -27,6 +28,9 @@ public:
|
||||
std::thread t(&RC::socketThread, this);
|
||||
t.detach();
|
||||
|
||||
std::thread gcst(&RC::fakeGCSThread, this);
|
||||
gcst.detach();
|
||||
|
||||
initLatchedState();
|
||||
}
|
||||
|
||||
@@ -35,6 +39,7 @@ private:
|
||||
ros::Subscriber state_sub;
|
||||
ros::Publisher state_pub;
|
||||
ros::Timer state_timeout_timer;
|
||||
ros::Time last_manual_control{0};
|
||||
mavros_msgs::StateConstPtr state_msg;
|
||||
|
||||
void handleState(const mavros_msgs::StateConstPtr& state)
|
||||
@@ -70,6 +75,37 @@ private:
|
||||
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 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
@@ -123,6 +159,8 @@ private:
|
||||
manual_control_msg.z = msg->z;
|
||||
manual_control_msg.r = msg->r;
|
||||
manual_control_pub.publish(manual_control_msg);
|
||||
|
||||
last_manual_control = ros::Time::now();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
109
clever/src/selfcheck.py
Executable 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()
|
||||
@@ -1,4 +1,6 @@
|
||||
Использование внешнего 3G-модема
|
||||
===
|
||||
|
||||
Использование внешнего 3G-модема на Raspberry возможно с помощью пакета `sakis3g`.
|
||||
|
||||
TODO
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
|
||||
Для того, чтобы научиться собирать, настраивать, пилотировать и программировать автономный дрон «Клевер», воспользуйтесь этим учебником.
|
||||
|
||||
Если вы детально изучили наш gitbook, но так и не нашли ответа на свой вопрос, напишите в чат техподдержки и наши специалисты вам с радостью ответят: https://t.me/COEXHelpdesk.
|
||||
|
||||
Также у нас есть чат для программистов, которые разрабатывают под PX4, автономную навигацию в помещениях и рои дронов https://t.me/DroneCode.
|
||||
|
||||
Образ для Raspberry Pi
|
||||
----------------------
|
||||
|
||||
@@ -20,7 +24,7 @@
|
||||
|
||||
* Raspbian Stretch
|
||||
* ROS Kinetic
|
||||
* Настроенную работу с сетью
|
||||
* Настроенную [работу с сетью](network.md)
|
||||
* OpenCV
|
||||
* mavros
|
||||
* Набор ПО для работы с Клевером
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Summary
|
||||
|
||||
* [Введение](README.md)
|
||||
* [Глоссарий](glossary.md)
|
||||
* [Сборка](assemble.md)
|
||||
* [Первоначальная настройка](setup.md)
|
||||
* [Полетные режимы](modes.md)
|
||||
@@ -9,6 +10,8 @@
|
||||
* [Подключение Raspberry Pi к PixHawk](connection.md)
|
||||
* [Подключение по Wi-Fi](wifi.md)
|
||||
* [Работа с QGroundControl через Wi-Fi](gcs_bridge.md)
|
||||
* [Прошивка PixHawk/PixRacer](firmware.md)
|
||||
* [Пилотирование со смартфона](rc.md)
|
||||
* [SSH-доступ](ssh.md)
|
||||
* [Неисправности радиоаппаратуры](radioerrors.md)
|
||||
* [Безопасность](safety.md)
|
||||
@@ -30,6 +33,10 @@
|
||||
* [Использование 3G-модема](3g.md)
|
||||
* [Устройство сети RPi](network.md)
|
||||
* [Работа с логами PX4](flight_logs.md)
|
||||
* [Протокол MAVLink](mavlink.md)
|
||||
* [Типы силовых разъемов](connectortypes.md)
|
||||
* [Ошибки радиоаппаратуры](radioerrors1.md)
|
||||
* [Настройка PID](calibratePID.md)
|
||||
* Учебник
|
||||
* [Теория и видеоуроки](lessons.md)
|
||||
* [Учебно-методическое пособие](metod.md)
|
||||
@@ -38,4 +45,5 @@
|
||||
* [CopterHack-2017](copterhack2017.md)
|
||||
* [Прошивка ESC контроллеров с помощью Arduino](esc_firmware.md)
|
||||
* [Работа со светодиодной лентой](leds.md)
|
||||
* [Проекты на базе коптера "Клевер"](projects.md)
|
||||
* [Полезные ссылки](links.md)
|
||||
|
||||
@@ -122,7 +122,7 @@ _Примечание_: указанное выше определение пр
|
||||
* `LNDMC_THR_RANGE` = 0.5
|
||||
* `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.
|
||||
|
||||

|
||||
|
||||
|
||||
BIN
docs/assets/3dmodel.png
Normal file
|
After Width: | Height: | Size: 99 KiB |
46
docs/assets/appstore.svg
Executable 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="<Group>">
|
||||
<g id="_Group_2" data-name="<Group>">
|
||||
<g id="_Group_3" data-name="<Group>">
|
||||
<path id="_Path_" data-name="<Path>" 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="<Path>" 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="<Group>">
|
||||
<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
|
After Width: | Height: | Size: 166 KiB |
BIN
docs/assets/calculation.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
docs/assets/detal.png
Normal file
|
After Width: | Height: | Size: 391 KiB |
BIN
docs/assets/detal1.png
Normal file
|
After Width: | Height: | Size: 632 KiB |
BIN
docs/assets/detal2.png
Normal file
|
After Width: | Height: | Size: 598 KiB |
BIN
docs/assets/elements.png
Normal file
|
After Width: | Height: | Size: 223 KiB |
BIN
docs/assets/elements1.png
Normal file
|
After Width: | Height: | Size: 248 KiB |
BIN
docs/assets/finalball.png
Normal file
|
After Width: | Height: | Size: 593 KiB |
BIN
docs/assets/safetyball.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
docs/assets/stmrev.jpg
Normal file
|
After Width: | Height: | Size: 131 KiB |
BIN
docs/assets/table.png
Normal file
|
After Width: | Height: | Size: 78 KiB |
@@ -26,6 +26,6 @@
|
||||
|
||||
* ОС [Raspbian Jessie](https://www.raspberrypi.org/downloads/raspbian/)
|
||||
* Фреймворк [ROS](ros.md)
|
||||
* Пакет [MAVROS](mavros.md) для связи с PixHawk по MAVLINK
|
||||
* Пакет [MAVROS](mavros.md) для связи с PixHawk по [MAVLink](mavlink.md)
|
||||
* Дополнительные пакеты ROS: web_video_server, usb_cam, rosbridge_suite и другие
|
||||
* Пакет программ clever_bundle
|
||||
|
||||
@@ -13,9 +13,10 @@
|
||||
```
|
||||
|
||||
Фрейм камеры задается таким образом, что:
|
||||
* x указывает направо на изображении;
|
||||
* y указывает вниз на изображении;
|
||||
* z указывает от плоскости матрицы камеры.
|
||||
|
||||
* **<font color=red>x</font>** указывает направо на изображении;
|
||||
* **<font color=green>y</font>** указывает вниз на изображении;
|
||||
* **<font color=blue>z</font>** указывает от плоскости матрицы камеры.
|
||||
|
||||
Сдвиги задаются в метрах, углы задаются в радианах. Корректность установленной трансформации может быть проверена с использованием [rviz](rviz.md).
|
||||
|
||||
|
||||
@@ -5,13 +5,12 @@
|
||||
|
||||
Убедиться в работоспособности подключения, выполнив на Raspberry Pi:
|
||||
|
||||
```
|
||||
```bash
|
||||
rostopic echo /mavros/state
|
||||
```
|
||||
|
||||
Поле `connected` должно содержать значение `True`.
|
||||
|
||||
|
||||
Подключение по USB
|
||||
---
|
||||
|
||||
|
||||
@@ -2,40 +2,40 @@
|
||||
|
||||
Хорошая статья, которая объясняет принцип работы ESC \(Electric speed controller\) регуляторов: [http://www.avmodels.ru/engines/electric/esc.html](http://www.avmodels.ru/engines/electric/esc.html)
|
||||
|
||||
#### Зачем перепрошивать?
|
||||
## Зачем перепрошивать?
|
||||
|
||||
Иногда требуется поменять один из параметров регулятора, например направление вращения мотора, минимальная и максимальная скважности PPM сигнала на входе контроллера, уровень громкости звуковых сигналов, издаваемых мотором или время, через которое регулятор начинает напоминать, что он включён.
|
||||
|
||||
#### Программа для прошивки регуляторов
|
||||
## Программа для прошивки регуляторов
|
||||
|
||||
Для прошивки самых разнообразных ESC регуляторов существует программа [BLHeliSuite](https://github.com/4712/BLHeliSuite) \(для Windows\).
|
||||
|
||||
Для запуска программы \(BLHeliSuite.exe\) необходимо распаковать архивы BLHeliAtmelHEX.zip и BLHeliSilabsHEX.zip в папку с программой.
|
||||
|
||||
#### Программатор для прошивки регуляторов.
|
||||
## Программатор для прошивки регуляторов
|
||||
|
||||
Чтобы прошить регулятор, необходим программатор, который умеет общаться с контроллером регулятора по 1-wire протоколу. Один из способов добыть программатор - взять подвернувшуюся под руку ардуинку и прошить её специальной прошивкой. В BLHeliSuite есть инструмент для создания интерфейсов программаторов.
|
||||
|
||||
Создание программатора на примере Arduino Mega.
|
||||
|
||||
1. Запустите программу BLHeliSuite и выберите вкладку Make interfaces.
|
||||
1. Запустите программу BLHeliSuite и выберите вкладку Make interfaces.
|
||||
|
||||

|
||||
|
||||
2. Подключите Arduino к компьютеру, при необходимости посмотрите в диспетчере устройств номер COM порта, к которому подключена плата.
|
||||
|
||||
3. Нажмите Arduino 4way-interface в разделе Make Arduino Interface Boards и выберите файл прошивки. После выбора файла начнётся прошивка контроллера.
|
||||
3. Нажмите Arduino 4way-interface в разделе Make Arduino Interface Boards и выберите файл прошивки. После выбора файла начнётся прошивка контроллера.
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
4. После прошивки Arduino вернитесь на вкладку Silabs ESC Setup и подключитесь к Arduino, предварительно выбрав интерфейс программатора 4way-if и COM порт Arduino.
|
||||
|
||||
|
||||

|
||||

|
||||
|
||||
#### Подключение ESC регуляторов к Arduino.
|
||||
## Подключение ESC регуляторов к Arduino
|
||||
|
||||
Для прошивки или изменения настроек регуляторов необходимо подключить сигнальные порты (обычно белого цвета) ESC регуляторов к портам Arduino, предварительно посмотрев в мануале (см. рисунок ниже), какие порты используются для соединения с регуляторами. Так же нужно соединить GND Arduino с землёй одного из регуляторов (обычно черного цвета). Регуляторы должны быть подключены к питанию, а если к регуляторам подключены моторы, **на них не должно быть винтов**.
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
В случае с Arduino Mega, сигнальные порты регуляторов подключаются к портам D43-D49 и D51.
|
||||
|
||||
#### Изменение настроек ESC регуляторов.
|
||||
## Изменение настроек ESC регуляторов
|
||||
|
||||
Для загрузки информации о версии прошивки и настроек регуляторов нужно нажать на кнопку Check.
|
||||
|
||||
@@ -64,15 +64,15 @@
|
||||
|
||||
Для отображения настроек со всех регуляторов одновременно можно воспользоваться вкладкой ESC Overview.
|
||||
|
||||
#### Прошивка ESC регуляторов.
|
||||
## Прошивка ESC регуляторов
|
||||
|
||||
Файлы с прошивками регуляторов находятся [здесь](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).
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||
> **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
|
||||
```
|
||||
|
||||
@@ -18,6 +18,7 @@ TCP-бридж
|
||||
---
|
||||
|
||||
Изменить параметр `gcs_bridge` в launch-файле:
|
||||
|
||||
```xml
|
||||
<arg name="gcs_bridge" default="tcp"/>
|
||||
```
|
||||
@@ -32,6 +33,7 @@ UDP бридж (с автоматическим подключением)
|
||||
---
|
||||
|
||||
Изменить параметр gcs_bridge в launch-файле:
|
||||
|
||||
```xml
|
||||
<arg name="gcs_bridge" default="udp-b"/>
|
||||
```
|
||||
|
||||
66
docs/glossary.md
Normal 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.
|
||||
49
docs/leds.md
@@ -1,6 +1,6 @@
|
||||
## Работа со светодиодной лентой на Raspberry 3
|
||||
# Работа со светодиодной лентой на Raspberry 3
|
||||
|
||||
#### Подключение и определение типа ленты
|
||||
## Подключение и определение типа ленты
|
||||
|
||||
Есть два основных типа адресуемых светодиодов: 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\).
|
||||
|
||||
#### Установка библиотеки для работы со светодиодной лентой
|
||||
## Установка библиотеки для работы со светодиодной лентой
|
||||
|
||||
Определите папку, в которой будут находиться файлы библиотеки, и открыть путь к этой папке в терминале. По-умолчанию можно использовать домашнюю папку, для перехода в неё нужно выполнить команду
|
||||
|
||||
@@ -51,7 +51,7 @@ sudo python ./setup.py build
|
||||
sudo python ./setup.py install
|
||||
```
|
||||
|
||||
#### Пример программы для светодиодной ленты на RPI3
|
||||
## Пример программы для светодиодной ленты на RPI3
|
||||
|
||||
Откройте в текстовом редакторе файл strandtest.py из папки python/examples \(находится в папке с библиотекой\)
|
||||
|
||||
@@ -96,7 +96,7 @@ sudo python strandtest.py
|
||||
|
||||
Права администратора необходимы для выполнения скрипта, т.к. без них нет доступа к функциям прерывания, которые использует библиотека для работы с лентой.
|
||||
|
||||
#### Совместимость с ROS и python
|
||||
## Совместимость с ROS и python
|
||||
|
||||
При запуске программы с помощью sudo пользовательское окружение изменяется и появляются ошибки импорта библиотек, т.к. в окружении отсутствуют необходимые пути. Чтобы добавить в окружение пути к библиотекам python и пакетам ROS, необходимо добавить в файл /etc/sudoers следующие строки:
|
||||
|
||||
@@ -107,7 +107,7 @@ Defaults env_keep += "ROS_ROOT"
|
||||
Defaults env_keep += "ROS_MASTER_URI"
|
||||
```
|
||||
|
||||
#### Функции для работы со светодиодной лентой
|
||||
## Функции для работы со светодиодной лентой
|
||||
|
||||
Для подключения библиотеки и её корректной работы требуется подключить следующие модули: neopixels - для работы ленты, time - для управления задержками, sys и signal для прерываний и формирования управляющего сигнала.
|
||||
|
||||
@@ -144,23 +144,23 @@ pydoc neopixel
|
||||
|
||||
```(bash)
|
||||
Help on module neopixel:
|
||||
|
||||
|
||||
NAME
|
||||
neopixel
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
# Adafruit NeoPixel library port to the rpi_ws281x library.
|
||||
# Author: Tony DiCola (tony@tonydicola.com)
|
||||
|
||||
|
||||
CLASSES
|
||||
__builtin__.object
|
||||
Adafruit_NeoPixel
|
||||
|
||||
|
||||
class Adafruit_NeoPixel(__builtin__.object)
|
||||
| Methods defined here:
|
||||
|
|
||||
|
|
||||
| __del__(self)
|
||||
|
|
||||
|
|
||||
| __init__(self, num, pin, freq_hz=800000, dma=5, invert=False)
|
||||
| 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
|
||||
@@ -168,38 +168,38 @@ pydoc neopixel
|
||||
| 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
|
||||
| specifying if the signal line should be inverted (default False).
|
||||
|
|
||||
|
|
||||
| begin(self)
|
||||
| Initialize library, must be called once before other functions are
|
||||
| called.
|
||||
|
|
||||
|
|
||||
| getPixelColor(self, n)
|
||||
| Get the 24-bit RGB color value for the LED at position n.
|
||||
|
|
||||
|
|
||||
| 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.
|
||||
|
|
||||
|
|
||||
| numPixels(self)
|
||||
| Return the number of pixels in the display.
|
||||
|
|
||||
|
|
||||
| setBrightness(self, 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
|
||||
| quantization issues (i.e. blowing out to white or black) if used repeatedly!
|
||||
|
|
||||
|
|
||||
| setPixelColor(self, n, color)
|
||||
| Set LED at position n to the provided 24-bit color value (in RGB order).
|
||||
|
|
||||
|
|
||||
| setPixelColorRGB(self, n, red, green, blue)
|
||||
| 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
|
||||
| lowest intensity and 255 is the highest intensity).
|
||||
|
|
||||
|
|
||||
| show(self)
|
||||
| Update the display with the data from the LED buffer.
|
||||
|
|
||||
|
||||
|
|
||||
|
||||
FUNCTIONS
|
||||
Color(red, green, blue)
|
||||
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.
|
||||
```
|
||||
|
||||
#### Почему именно так и можно ли по-другому?
|
||||
## Почему именно так и можно ли по-другому?
|
||||
|
||||
Основные типы лент, которые используются для Clever3, это WS2812, WS2812B и SK6812 \(аналог WS2812B\). Они управляются по одному и тому же принципу: для массива светодиодов в ленте отправляется пакет данных по 24 бита на светодиод; каждый светодиод считывает первые 24 бита из пришедших к нему данных и устанавливает соответствующий цвет, остальные данные он отправляет следующему светодиоду в ленте. Нули и единицы задаются разными сочетаниями длительностей высокого и низкого уровня в импульсе.
|
||||
|
||||
@@ -227,4 +227,3 @@ pydoc neopixel
|
||||
3. Если нам важна и работа аудио, и подключение к SPI устройств кроме лед ленты, то можно управлять лентой по каналу PCM \(GPIO 21 или 31\). При этом никаких дополнительных манипуляций с распберри не требуется.
|
||||
|
||||
Исходя из вышеперечисленных способов управления лентой, наилучшим вариантом, позволяющим управлять лентой, сохранить работоспособность встроенной аудиосистемы и возможность подключения всяческих устройств и датчиков по SPI, является управление по каналу PCM \(GPIO 21\) с использованием 10 канала DMA.
|
||||
|
||||
|
||||
179
docs/mavlink.md
Normal 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> цветом выделены поля данных (полезной нагрузки). Для каждого типа сообщения существует свой набор таких полей.
|
||||
@@ -1,12 +1,14 @@
|
||||
# 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 автоматически запускается в 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/local_position/pose` — локальная позиция коптера в системе координат ENU.
|
||||
`/mavros/local_position/pose` — локальная позиция коптера в системе координат ENU и его ориентация.
|
||||
|
||||
`/mavros/local_position/velocity` — текущая скорость в локальных координатах. Угловые скорости.
|
||||
|
||||
@@ -28,6 +30,8 @@ MAVROS подписывается определенные ROS-топики в
|
||||
|
||||
`/mavros/global_position/rel_alt` — относительная высота \(относительно высоты включения моторов\).
|
||||
|
||||
Просмотр сообщений, публикуемых в топики возможен с помощью утилиты `rostopic`, например `rostopic echo /mavros/state`. Подробнее см. [работа с ROS](ros.md).
|
||||
|
||||
## Основные топики для публикации
|
||||
|
||||
`/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/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).
|
||||
|
||||
|
||||
@@ -7,47 +7,47 @@
|
||||
Учебно-методическое пособие
|
||||
---------------------------
|
||||
|
||||
[Урок 1. «Знакомство. Принципы проектирования и строение мультикоптеров»](https://github.com/CopterExpress/clever/blob/master/docs/ https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 1. «Знакомство. Принципы проектирования и строение мультикоптеров»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 2. «Основы электричества»](https://github.com/CopterExpress/clever/blob/master/docs/ https://github.com/CopterExpress/clever/blob/master/docs/ https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 2. «Основы электричества»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 3. «Теория пайки»]( https://github.com/CopterExpress/clever/blob/master/docs/ https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 3. «Теория пайки»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 4. «Аэродинамика полета. Пропеллер»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 4. «Аэродинамика полета. Пропеллер»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 5. «Основы электромагнетизма. Типы двигателей»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 5. «Основы электромагнетизма. Типы двигателей»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 6. «Бесколлекторные двигатели и регуляторы их хода»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 6. «Бесколлекторные двигатели и регуляторы их хода»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 7. «Принцип работы, типы и устройство аккумуляторов»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 7. «Принцип работы, типы и устройство аккумуляторов»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 8. «Управление полётом мультикоптера. Принцип функционирования полетного контроллера. ПИД регуляторы»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 8. «Управление полётом мультикоптера. Принцип функционирования полетного контроллера. ПИД регуляторы»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 9. «Основы радиосвязи. Принцип работы радиоаппаратуры управления»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 9. «Основы радиосвязи. Принцип работы радиоаппаратуры управления»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 10. «Аналоговая и цифровая видеотрансляция. Применяемые камеры, радиопередатчики и приёмники»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 10. «Аналоговая и цифровая видеотрансляция. Применяемые камеры, радиопередатчики и приёмники»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 11. «Техника безопасности при сборке и настройке коптеров, при подготовке к вылету. Техника безопасности при работе с аккумуляторами»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 11. «Техника безопасности при сборке и настройке коптеров, при подготовке к вылету. Техника безопасности при работе с аккумуляторами»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 12. «Теория ручного визуального пилотирования»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 12. «Теория ручного визуального пилотирования»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 13. «Техника безопасности при летной эксплуатации коптера»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 13. «Техника безопасности при летной эксплуатации коптера»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 14. «Обучение лётному мастерству»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 14. «Обучение лётному мастерству»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 15. «Основы радиоэлектроники, схемотехники и макетирования электрических схем»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 15. «Основы радиоэлектроники, схемотехники и макетирования электрических схем»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 16. «Основы работы с аналоговым и цифровым сигналом»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 16. «Основы работы с аналоговым и цифровым сигналом»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 17. «Основы работы с лабораторным оборудованием»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 17. «Основы работы с лабораторным оборудованием»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 18. «Теория FPV полетов»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 18. «Теория FPV полетов»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 19. «История автономных полетов. Развитие автопилотов в авиации»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 19. «История автономных полетов. Развитие автопилотов в авиации»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 20. «Основы программирование на языке Python»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 20. «Основы программирование на языке Python»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 21. «Знакомство с компьютером Raspberry Pi»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 21. «Знакомство с компьютером Raspberry Pi»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
[Урок 22. «Управление автономным дроном: теория»]( https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
[Урок 22. «Управление автономным дроном: теория»](https://github.com/CopterExpress/clever/blob/master/docs/metodmaterials.md)
|
||||
|
||||
|
||||
@@ -13,3 +13,11 @@
|
||||
Для установки образа воспользуйтесь утилитой [Etcher](https://etcher.io).
|
||||
|
||||
[](https://etcher.io)
|
||||
|
||||
## Версия образа
|
||||
|
||||
Версию установленного образа можно узнать в файле `/etc/clever_version`:
|
||||
|
||||
```bash
|
||||
cat /etc/clever_version
|
||||
```
|
||||
|
||||
@@ -31,7 +31,7 @@ PX4
|
||||
|
||||
В режиме автоматического полета квадрокоптер игнорирует сигналы с пульта.
|
||||
|
||||
* **AUTO.MISSION** – PX4 выполняет заранее загруженную в квадрокоптер миссию (миссия загружается с помощью QGroundControl, или по MAVLINK используя MAVROS).
|
||||
* **AUTO.MISSION** – PX4 выполняет заранее загруженную в квадрокоптер миссию (миссия загружается с помощью QGroundControl, или по [MAVLink](mavlink.md) используя [MAVROS](mavros.md).
|
||||
* **AUTO.RTL** – коптер автоматически вовращается в точку взлета.
|
||||
* **AUTO.LAND** – коптер выполняет посадку.
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# Настройка Wi-Fi
|
||||
|
||||
Wi-Fi адаптер на Raspberry Pi имеет два основных режима работы:
|
||||
|
||||
1. **Режим клиента** – RPi подключается к существующей Wi-Fi сети.
|
||||
2. **Режим точки доступа** – RPi создает Wi-Fi сеть, к которой вы можете подключиться.
|
||||
|
||||
При использовании [образа для RPi](microsd_images.md) по умолчанию Wi-Fi адаптер работает в режиме точки доступа.
|
||||
При использовании [образа для RPi](microsd_images.md) по умолчанию Wi-Fi адаптер работает в [режиме точки доступа](wifi.md).
|
||||
|
||||
## Инструкция для переключения адаптера в режим клиента
|
||||
|
||||
@@ -116,7 +117,9 @@ ___
|
||||
Ниже вы можете узнать больше о том, как устроена работа с сетью на RPi.
|
||||
|
||||
# Устройство сети RPi
|
||||
|
||||
Работа сети на образе **2017-11-29-raspbian-stretch-lite** поддерживается двумя предустановленными службами:
|
||||
|
||||
* **networking** — служба включает все сетевые интерфейсы в момент запуска [5].
|
||||
* **dhcpcd** — служба обеспечивает настройку адресации и маршрутризации на интерфейсах, полученных динамически или указаных в файле настроек статически.
|
||||
|
||||
@@ -188,9 +191,11 @@ network={
|
||||
```bash
|
||||
sudo systemctl restart dhcpcd
|
||||
```
|
||||
|
||||
## DHCP сервер
|
||||
|
||||
### dnsmasq-base
|
||||
|
||||
`dnsmasq-base` – консольная утилита, не являющаяся службой, для использования dnsmasq как службы надо установить пакет `dnsmasq`.
|
||||
|
||||
```bash
|
||||
@@ -264,7 +269,6 @@ fi
|
||||
EOF
|
||||
```
|
||||
|
||||
|
||||
## Ссылки
|
||||
|
||||
1. [habr.com: Linux WiFi из командной строки с wpa_supplicant](https://habr.com/post/315960/)
|
||||
|
||||
94
docs/projects.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Шаровая защита коптера
|
||||
|
||||
|
||||
1. Введение
|
||||
|
||||
Наверное, летать в помещениях приходилось каждому, кто брал в руки коптер. Подобные полеты сопряжены с немалым риском повредить коптер о стены и различные предметы. Даже полеты на относительно больших пространствах связаны с рисками удариться о препятствие: на пути коптера может встать ствол дерева или здание — что уж говорить о полетах в замкнутых пространствах. Подобные «краш-тесты» не очень приятный момент, который может оказаться в лучшем случае причиной потери внушительной суммы денег на ремонт, а в худшем — и вовсе утраты коптера. Тем более неприятны такие ситуации для новичка, который не может своевременно увернуться от препятствия и только учится летать.
|
||||
|
||||
Это все подвигло нас к поиску решений. К сожалению, перерыв весь интернет, мы не нашли достаточно легкого и простого в изготовлении решения для простых пользователей, а главное — такого, которое будет всем по карману. Например, защита по контуру пропеллеров неплохо предохраняет сами пропеллеры, но при малейшем касании о препятствие коптер переворачивается и падает. В общем, защита либо не оберегала коптер полностью, либо выглядела несуразно и была слишком узко доступна.
|
||||
|
||||

|
||||
|
||||
Нами было принято сложное решение: придется делать ее полностью самим и почти с нуля, а также поставлена цель сделать ее простой в изготовлении и максимально легкой.
|
||||
|
||||
2. Разработка
|
||||
|
||||
В результате поиска решения, удовлетворяющего всем нашим требованиям, мы остановились на нескольких схожих вариантах. Было решено сделать защиту в форме полуправильного многогранника (примерами могут служить фуллерен, молекула углерода, или фигура пентакисдодекаэдр) — его мы и выбрали как самый приятный глазу. Кроме того, такая защита легко масштабируема под нужный размер.
|
||||
|
||||
При создании такой фигуры используются два вида ребер (далее — лучей): короткие и длинные, их длины рассчитываются исходя из нужного диаметра вписанной в многогранник сферы. Для лучшего понимания я вставлю все необходимые формулы ниже из «Википедии».
|
||||
|
||||

|
||||
|
||||
С угловыми соединениями (фитингами), тоже не все просто: их также два вида — с пятью гранями при вершине (пять лучей исходят из вершины) и с шестью гранями (шесть лучей исходят из вершины).
|
||||
|
||||
3. Первые модели
|
||||
|
||||
Была составлена спецификация для удобства контроля процесса изготовления, и мы приступили к моделированию.
|
||||
|
||||
Сделав несложные расчеты под нужные размеры, мы построили модели в Inventor CAD.
|
||||
|
||||
В ходе проектирования мы столкнулись с проблемами в моделировании угловых соединений, но они были решены упрощением конструкции, а разность углов компенсируется гибкостью материалов. Таким образом, все соединения сидят в небольшом натяге.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
(Элементы крепления защиты к корпусу)
|
||||
|
||||

|
||||
|
||||
4. Материалы
|
||||
|
||||
В ходе проектирования встал вопрос, из чего же все-таки сделать такую защиту, чтобы получилось легко и прочно. Ответ пришел, как всегда, совершенно неожиданно. На глаза попались шпажки из бамбука: они достаточно тонкие, чтобы не повлиять на аэродинамику, имеют достаточную гибкость и при этом достаточно прочные. Далее возник вопрос, из чего и как делать фитинги. Конечно же, 3D-печать! 3D-принтер — это вообще незаменимая вещь, тем более для тех, кто любит что-то делать сам. К тому же они из-за не самой высокой цены получили достаточно широкое распространение. На таком принтере можно делать изделия почти любой сложности. То, что надо!
|
||||
|
||||
Готовые модели переводим в .stl, закидываем в слайсер (в нашем случае — Cura), вводим настройки под конкретный принтер и пластик и ставим на печать.
|
||||
|
||||
Для уменьшения веса был выбран ABC-пластик как один из самых легких и доступных.
|
||||
|
||||

|
||||
|
||||
Шпажки были порезаны на расчетные длины и подготовлены к последующей работе.
|
||||
|
||||
5. Сборка и установка
|
||||
|
||||
После того как все было напечатано и порезано, настало время собирать защиту.
|
||||
|
||||

|
||||
|
||||
Сборка здесь самый ответственный момент, так как требует специального алгоритма.
|
||||
|
||||
Из пятилучевого фитинга выходят только короткие лучи, в то время как из шестилучевого — только каждая вторая длинная.
|
||||
|
||||
Сборка:
|
||||
|
||||
1. Вначале собираем все пятилучевые вершины.
|
||||
2. На каждый луч, исходящий из пятилучевой вершины, надеваем шестилучевую.
|
||||
3. Соединяем между собой шестилучевые фитинги длинными шпажками.
|
||||
4. Присоединяем уже собранные пятилучевые вершины к шестилучевым, учитывая, что в шестилучевом фитинге короткие и длинные лучи чередуются.
|
||||
5. Повторяем процесс для каждой пятилучевой вершины, пока шар не соберется.
|
||||
|
||||
После сборки разделяем шар на две полусферы, устанавливаем крепления на коптер, смотрим, что все подходит.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
(Пример установки креплений)
|
||||
|
||||
Теперь полусферы можно проклеивать. Между собой полусферы не склеиваются — это нужно для установки коптера внутрь. Мы в качестве клея использовали растворитель для пластиков «Дихлорэтан», но с тем же успехом можно использовать и любой быстросохнущий клей для полимеров.
|
||||
|
||||
После высыхания защита готова к установке и первым пробным полетам!
|
||||
|
||||

|
||||
|
||||
(Пока еще без креплений)
|
||||
|
||||

|
||||
|
||||
6. Первые полеты
|
||||
|
||||
Мы делали защиту под коптер «Клевер 2», являющийся обучающим пособием по сборке и настройке квадрокоптеров, и на него она устанавливается без доработок. Защита весит на 70 г больше (139 грамм), чем стандартная, и на управляемость и время полета почти не влияет.
|
||||
|
||||
Отдельно стоит сказать, что излишние вибрации, если таковые имеются, можно убрать путем более жесткого крепления защиты к коптеру.
|
||||
|
||||
В итоге получилась необычная защита для коптера с небольшим весом и интересным дизайном, открывающая новые горизонты для полетов в тех местах, где летать для коптера раньше было опасно.
|
||||
@@ -9,13 +9,14 @@ Raspberry Pi означает «малиновый пирог». Этот сво
|
||||
* оперативная память – 512 Мб;
|
||||
* есть USB -разъемы (один или два в зависимости от модели); м
|
||||
* наиболее применяемая модель мини-компьютера Raspberry Pi – модель В - это модель В на с поддержкой Ethernet.
|
||||
|
||||
|
||||
Сферы применения компьютера Raspberry Pi достаточно широки, ведь это всё-таки вполне полноценный компьютер. Если вам нужна машина для решения несложных задач, которые не требуют применения мощных ресурсов в плане вычисления, то вы смело можете подключать к устройству Raspberry Pi стандартные элементы компьютера: монитор; мышь; клавиатуру;
|
||||
|
||||
Вообще, Raspberry Pi – очень популярная платформа, на которой можно реализовать множество проектов, таких как
|
||||
|
||||
* сервер домашней автоматизации (или система «умный дом»)
|
||||
* сервер хранения данных (NAS)
|
||||
* домашний медиа-сервер
|
||||
* «мозговой центр» для автоматизированных станков или роботов
|
||||
|
||||
Собственно, в последнем качестве мы и будем его использовать, благодаря возможности подключения его к автопилоту Pixhawk.
|
||||
|
||||
Собственно, в последнем качестве мы и будем его использовать, благодаря возможности подключения его к автопилоту PixHawk.
|
||||
|
||||
10
docs/rc.md
@@ -1,20 +1,22 @@
|
||||
Управление Клевером со смартфона
|
||||
===
|
||||
|
||||
Для управления Клевером со смартфона через Wi-Fi необходимо установить приложение – [iOS](), Android (в разработке).
|
||||
<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*).
|
||||
|
||||

|
||||
|
||||
> **Warning** Мобильный пульт предназначен в первую очередь для полетов в помещении на дальность не более 10-15 м. Большое количество Wi-Fi сетей также может ухудшить отзывчивость и дальность пульта.
|
||||
|
||||
> **Info** Также управление со смартфона [доступно в мобильной версия приложения](https://docs.qgroundcontrol.com/en/SettingsView/VirtualJoystick.html) QGroundControl.
|
||||
Также управление со смартфона [доступно в мобильной версия приложения](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`):
|
||||
Установите [образ Clever на RPi](microsd_images.md). Для работы приложения параметры `rosbridge` и `rc` в launch-файле (`~/catkin_ws/src/clever/clever/launch/clever.launch`) должны быть включены:
|
||||
|
||||
```xml
|
||||
<arg name="rosbridge" default="true"/>
|
||||
@@ -32,7 +34,7 @@ sudo systemctl restart clever
|
||||
|
||||
Также необходимо убедиться, что PX4-параметр `COM_RC_IN_MODE` установлен в значение `0` (RC Transmitter).
|
||||
|
||||
Дополнительные параметры:
|
||||
Дополнительные параметры PX4:
|
||||
|
||||
* `COM_RC_LOSS_T` – таймаут для определения потери сигнала пульта (мобильного или физического). Рекомендуется увеличение таймаута до нескольких секунд.
|
||||
* `NAV_RCL_ACT` – действие при потере сигнала пульта.
|
||||
|
||||
85
docs/ros.md
@@ -1,15 +1,19 @@
|
||||
ROS: основные концепции
|
||||
====
|
||||
ROS
|
||||
===
|
||||
|
||||
Основная статья: http://wiki.ros.org
|
||||
|
||||
TODO
|
||||
ROS – это широко используемый фреймворк для создания сложных и распределенных роботехнических систем.
|
||||
|
||||
Установка
|
||||
---
|
||||
|
||||
Основная статья: 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
|
||||
|
||||
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
|
||||
|
||||
Топик – это именованная шина данных, по которой ноды обмениваются сообщениями. Любая нода может *опубликовать* сообщение в произвольный топик, а также *подписаться* на произвольный топик.
|
||||
|
||||
Пример публикации сообщения типа [`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
|
||||
|
||||
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, подключенном к полетому контроллеру и т. д.
|
||||
|
||||
Для запуска ноды
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
Simple offboard
|
||||
===
|
||||
|
||||
> **Warning** Это описание API версии 0.5. См. [описание API предыдущих версий](https://github.com/CopterExpress/clever/blob/67051b21a05b12e2e9e519cb640565bccb80fbe3/docs/simple_offboard.md).
|
||||
|
||||
Модуль `simple_offboard` пакета `clever` предназначен для упрощенного программирования автономного дрона (режим `OFFBOARD`). Он позволяет устанавливать желаемые полетные задачи и автоматически трансформирует [систему координат](frames.md).
|
||||
Модуль `simple_offboard` пакета `clever` предназначен для упрощенного программирования автономного дрона ([режим](modes.md) `OFFBOARD`). Он позволяет устанавливать желаемые полетные задачи и автоматически трансформирует [систему координат](frames.md).
|
||||
|
||||
`simple_offboard` является высокоуровневым способом взаимодействия с полетным контроллером. Для более низкоуровневой работы см. [mavros](mavros.md).
|
||||
|
||||
|
||||
@@ -75,6 +75,8 @@ while True:
|
||||
|
||||
Рассчет общего угла коптера к горизонту:
|
||||
|
||||
TODO: fix
|
||||
|
||||
```python
|
||||
telem = get_telemetry()
|
||||
|
||||
@@ -105,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)):
|
||||
|
||||
```python
|
||||
|
||||
@@ -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.
|
||||
|
||||
TODO: иллюстрации.
|
||||
|
||||
|
||||
2
image_builder/Jenkinsfile
vendored
@@ -4,7 +4,7 @@ pipeline {
|
||||
string(name: 'GWBT_REF', defaultValue: "master")
|
||||
string(name: 'GWBT_URL', defaultValue: "https://github.com/CopterExpress/clever.git")
|
||||
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')
|
||||
booleanParam(name: 'ONLY_PUBLISH', defaultValue: false, description: 'ONLY PUBLISH')
|
||||
string(name: 'BUILD_DIR', defaultValue: '/mnt/hdd_builder/workspace', description: 'Build workspace')
|
||||
|
||||
@@ -44,7 +44,7 @@ sudo systemctl disable dphys-swapfile
|
||||
"password":"PASS",
|
||||
"url":"https://api.github.com/repos/CopterExpress/clever/releases/"
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
6. Add webhook to release on your github project
|
||||
> TODO
|
||||
@@ -79,3 +79,11 @@ sudo systemctl start jenkins
|
||||
## Requirements
|
||||
|
||||
* Jenkins (BlueOcean plugin, optional)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If JDK not installed:
|
||||
|
||||
```bash
|
||||
sudo apt-get install default-jdk
|
||||
```
|
||||
|
||||
@@ -96,3 +96,8 @@ 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 "================================================================================"
|
||||
|
||||
@@ -6,7 +6,6 @@ pipeline {
|
||||
string(name: 'IMAGE_VERSION', defaultValue: 'no_version', description: 'Image version')
|
||||
|
||||
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')
|
||||
// TODO: Add mirrorparameters
|
||||
@@ -42,7 +41,7 @@ pipeline {
|
||||
}
|
||||
// TODO: Transfer apps.sh initialisation code here
|
||||
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') {
|
||||
@@ -50,7 +49,7 @@ pipeline {
|
||||
EXECUTE_FILE = 'image_builder/scripts/hardware_setup.sh'
|
||||
}
|
||||
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') {
|
||||
@@ -58,7 +57,7 @@ pipeline {
|
||||
EXECUTE_FILE = 'image_builder/scripts/software_install.sh'
|
||||
}
|
||||
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') {
|
||||
@@ -66,17 +65,18 @@ pipeline {
|
||||
EXECUTE_FILE = 'image_builder/scripts/network_setup.sh'
|
||||
}
|
||||
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') {
|
||||
environment {
|
||||
EXECUTE_FILE = 'image_builder/scripts/ros_install.sh'
|
||||
MOVE_FILE = 'image_builder/kinetic-ros-coex.rosinstall'
|
||||
MOVE_TO = '/home/pi/ros_catkin_ws'
|
||||
}
|
||||
steps {
|
||||
sh "if ! ${params.DISCOVER_ROS_PACKAGES}; then $WORKSPACE/image_builder/image_config.sh copy_to_chroot ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$MOVE_FILE; fi"
|
||||
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE ${params.GWBT_URL} ${params.DISCOVER_ROS_PACKAGES}"
|
||||
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
|
||||
@@ -87,7 +87,7 @@ pipeline {
|
||||
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} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE"
|
||||
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} $WORKSPACE/$EXECUTE_FILE"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,17 +15,17 @@ get_image() {
|
||||
# TEMPLATE: get_image $BUILD_DIR $RPI_DONWLOAD_URL $IMAGE_NAME
|
||||
|
||||
local RPI_ZIP_NAME=$(basename $2)
|
||||
if [ ! -e "$1/$RPI_ZIP_NAME" ];
|
||||
if [ ! -e "$1/${RPI_ZIP_NAME}" ];
|
||||
then
|
||||
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"
|
||||
else
|
||||
echo "$(date) | 1. Linux distribution already donwloaded"
|
||||
fi
|
||||
echo "$(date) | 2. Unzipping Linux distribution image"
|
||||
local RPI_IMAGE_NAME=$(echo $RPI_ZIP_NAME | sed 's/zip/img/')
|
||||
unzip -p $1/$RPI_ZIP_NAME $RPI_IMAGE_NAME > $1/$3
|
||||
local RPI_IMAGE_NAME=$(echo ${RPI_ZIP_NAME} | sed 's/zip/img/')
|
||||
unzip -p $1/${RPI_ZIP_NAME} ${RPI_IMAGE_NAME} > $1/$3
|
||||
echo "$(date) | Unzipping complete"
|
||||
}
|
||||
|
||||
@@ -63,9 +63,9 @@ resize_fs() {
|
||||
&& local DEV_IMAGE=$(losetup -Pf $1 --show) \
|
||||
&& sleep 0.5 \
|
||||
&& echo -e "\033[0;31m\033[1mMount loop-image: $1\033[0m\033[0m" \
|
||||
&& echo ", +" | sfdisk -N ${ROOT_PARTITION} $DEV_IMAGE \
|
||||
&& echo ", +" | sfdisk -N ${ROOT_PARTITION} ${DEV_IMAGE} \
|
||||
&& sleep 0.5 \
|
||||
&& losetup -d $DEV_IMAGE \
|
||||
&& losetup -d ${DEV_IMAGE} \
|
||||
&& sleep 0.5 \
|
||||
&& local DEV_IMAGE=$(losetup -Pf $1 --show) \
|
||||
&& sleep 0.5 \
|
||||
@@ -74,7 +74,7 @@ resize_fs() {
|
||||
&& echo -e "\033[0;31m\033[1mExpand filesystem\033[0m\033[0m" \
|
||||
&& resize2fs "${DEV_IMAGE}p${ROOT_PARTITION}" \
|
||||
&& echo -e "\033[0;31m\033[1mUmount loop-image\033[0m\033[0m" \
|
||||
&& losetup -d $DEV_IMAGE
|
||||
&& losetup -d ${DEV_IMAGE}
|
||||
|
||||
set -e
|
||||
}
|
||||
@@ -82,7 +82,7 @@ resize_fs() {
|
||||
mount_system() {
|
||||
|
||||
# STATIC FUNCTION
|
||||
# TEMPLATE: mount_system $IMAGE $MOUNT_POINT
|
||||
# TEMPLATE: mount_system $IMAGE
|
||||
|
||||
# Partitions numbers
|
||||
local BOOT_PARTITION=1
|
||||
@@ -98,48 +98,49 @@ mount_system() {
|
||||
local DEV_IMAGE=$(losetup -Pf $1 --show)
|
||||
sleep 0.5
|
||||
|
||||
echo -e "\033[0;31m\033[1mMount dirs $2 & $2/boot\033[0m\033[0m"
|
||||
#mount $3 $2
|
||||
#mount $4 $2/boot
|
||||
mount "${DEV_IMAGE}p${ROOT_PARTITION}" $2
|
||||
mount "${DEV_IMAGE}p${BOOT_PARTITION}" $2/boot
|
||||
# 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[1mBind system dirs\033[0m\033[0m"
|
||||
# https://github.com/debian-pi/raspbian-ua-netinst/issues/314
|
||||
echo "Mounting /proc in chroot... "
|
||||
if [ ! -d $2/proc ] ; then
|
||||
mkdir -p $2/proc \
|
||||
&& echo "Created $2/proc"
|
||||
if [ ! -d ${MOUNT_POINT}/proc ] ; then
|
||||
mkdir -p ${MOUNT_POINT}/proc \
|
||||
&& echo "Created ${MOUNT_POINT}/proc"
|
||||
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 "Mounting /sys in chroot... "
|
||||
if [ ! -d $2/sys ] ; then
|
||||
mkdir -p $2/sys \
|
||||
&& echo "Created $2/sys"
|
||||
if [ ! -d ${MOUNT_POINT}/sys ] ; then
|
||||
mkdir -p ${MOUNT_POINT}/sys \
|
||||
&& echo "Created ${MOUNT_POINT}/sys"
|
||||
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 "Mounting /dev/ and /dev/pts in chroot... " \
|
||||
&& mkdir -p -m 755 $2/dev/pts \
|
||||
&& mount -t devtmpfs -o mode=0755,nosuid devtmpfs $2/dev \
|
||||
&& mount -t devpts -o gid=5,mode=620 devpts $2/dev/pts \
|
||||
&& mkdir -p -m 755 ${MOUNT_POINT}/dev/pts \
|
||||
&& mount -t devtmpfs -o mode=0755,nosuid devtmpfs ${MOUNT_POINT}/dev \
|
||||
&& mount -t devpts -o gid=5,mode=620 devpts ${MOUNT_POINT}/dev/pts \
|
||||
&& echo "OK"
|
||||
# mount -t devpts none "$2/dev/pts" -o ptmxmode=0666,newinstance
|
||||
# ln -fs "pts/ptmx" "$2/dev/ptmx"
|
||||
# mount -t devpts none "${MOUNT_POINT}/dev/pts" -o ptmxmode=0666,newinstance
|
||||
# ln -fs "pts/ptmx" "${MOUNT_POINT}/dev/ptmx"
|
||||
|
||||
# mount -o bind /dev $2/dev
|
||||
# mount -t proc proc $2/proc
|
||||
# mount -t devpts devpts $2/dev/pts
|
||||
# mount -o bind /dev ${MOUNT_POINT}/dev
|
||||
# mount -t proc proc ${MOUNT_POINT}/proc
|
||||
# mount -t devpts devpts ${MOUNT_POINT}/dev/pts
|
||||
|
||||
# mount -t proc proc $2/proc
|
||||
# mount -t sysfs sys $2/sys
|
||||
# mount --bind /dev $2/dev
|
||||
# mount -t proc proc ${MOUNT_POINT}/proc
|
||||
# mount -t sysfs sys ${MOUNT_POINT}/sys
|
||||
# mount --bind /dev ${MOUNT_POINT}/dev
|
||||
|
||||
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)
|
||||
# http://www.unix-lab.org/posts/chroot/
|
||||
@@ -148,15 +149,15 @@ mount_system() {
|
||||
# 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
|
||||
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() {
|
||||
|
||||
# STATIC FUNCTION
|
||||
# TEMPLATE: execute $IMAGE $MOUNT_POINT $EXECUTE_FILE ...
|
||||
# TEMPLATE: execute $IMAGE $EXECUTE_FILE ...
|
||||
|
||||
# Partitions numbers
|
||||
local BOOT_PARTITION=1
|
||||
@@ -166,56 +167,59 @@ execute() {
|
||||
local DEV_IMAGE=$(losetup -Pf $1 --show)
|
||||
sleep 0.5
|
||||
|
||||
echo -e "\033[0;31m\033[1mMount dirs $2 & $2/boot\033[0m\033[0m"
|
||||
mount "${DEV_IMAGE}p${ROOT_PARTITION}" $2
|
||||
mount "${DEV_IMAGE}p${BOOT_PARTITION}" $2/boot
|
||||
# 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[1mBind system dirs\033[0m\033[0m"
|
||||
echo "Mounting /proc in chroot... "
|
||||
if [ ! -d $2/proc ] ; then
|
||||
mkdir -p $2/proc
|
||||
echo "Created $2/proc"
|
||||
if [ ! -d ${MOUNT_POINT}/proc ] ; then
|
||||
mkdir -p ${MOUNT_POINT}/proc
|
||||
echo "Created ${MOUNT_POINT}/proc"
|
||||
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 "Mounting /sys in chroot... "
|
||||
if [ ! -d $2/sys ] ; then
|
||||
mkdir -p $2/sys
|
||||
echo "Created $2/sys"
|
||||
if [ ! -d ${MOUNT_POINT}/sys ] ; then
|
||||
mkdir -p ${MOUNT_POINT}/sys
|
||||
echo "Created ${MOUNT_POINT}/sys"
|
||||
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 "Mounting /dev/ and /dev/pts in chroot... " \
|
||||
&& mkdir -p -m 755 $2/dev/pts \
|
||||
&& mount -t devtmpfs -o mode=0755,nosuid devtmpfs $2/dev \
|
||||
&& mount -t devpts -o gid=5,mode=620 devpts $2/dev/pts \
|
||||
&& mkdir -p -m 755 ${MOUNT_POINT}/dev/pts \
|
||||
&& mount -t devtmpfs -o mode=0755,nosuid devtmpfs ${MOUNT_POINT}/dev \
|
||||
&& mount -t devpts -o gid=5,mode=620 devpts ${MOUNT_POINT}/dev/pts \
|
||||
&& echo "OK"
|
||||
|
||||
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"
|
||||
script_name=$(basename $3)
|
||||
script_path_root="$2/root/$script_name"
|
||||
local script_name=$(basename $2)
|
||||
local script_path_root="${MOUNT_POINT}/root/${script_name}"
|
||||
# Copy script into chroot fs
|
||||
# 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)
|
||||
script_args="${@:4}"
|
||||
script_args="${@:3}"
|
||||
# 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
|
||||
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 $MOUNT_POINT $MOVE_FILE
|
||||
# TEMPLATE: copy_to_chroot $IMAGE $MOVE_FILE $MOVE_TO
|
||||
|
||||
# Partitions numbers
|
||||
local BOOT_PARTITION=1
|
||||
@@ -225,44 +229,25 @@ copy_to_chroot() {
|
||||
local DEV_IMAGE=$(losetup -Pf $1 --show)
|
||||
sleep 0.5
|
||||
|
||||
echo -e "\033[0;31m\033[1mMount dirs $2 & $2/boot\033[0m\033[0m"
|
||||
mount "${DEV_IMAGE}p${ROOT_PARTITION}" $2
|
||||
mount "${DEV_IMAGE}p${BOOT_PARTITION}" $2/boot
|
||||
# Get temp directory to mount image
|
||||
local MOUNT_POINT=$(mktemp -d)
|
||||
|
||||
echo -e "\033[0;31m\033[1mBind system dirs\033[0m\033[0m"
|
||||
echo "Mounting /proc in chroot... "
|
||||
if [ ! -d $2/proc ] ; then
|
||||
mkdir -p $2/proc
|
||||
echo "Created $2/proc"
|
||||
fi
|
||||
mount -t proc -o nosuid,noexec,nodev proc $2/proc \
|
||||
&& echo "OK"
|
||||
|
||||
echo "Mounting /sys in chroot... "
|
||||
if [ ! -d $2/sys ] ; then
|
||||
mkdir -p $2/sys
|
||||
echo "Created $2/sys"
|
||||
fi
|
||||
mount -t sysfs -o nosuid,noexec,nodev sysfs $2/sys \
|
||||
&& echo "OK"
|
||||
|
||||
echo "Mounting /dev/ and /dev/pts in chroot... " \
|
||||
&& mkdir -p -m 755 $2/dev/pts \
|
||||
&& mount -t devtmpfs -o mode=0755,nosuid devtmpfs $2/dev \
|
||||
&& mount -t devpts -o gid=5,mode=620 devpts $2/dev/pts \
|
||||
&& echo "OK"
|
||||
|
||||
echo -e "\033[0;31m\033[1mCopy DNS records\033[0m\033[0m" \
|
||||
&& cp -L /etc/resolv.conf $2/etc/resolv.conf
|
||||
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"
|
||||
script_name=$(basename $3)
|
||||
script_path_root="$2/root/$script_name"
|
||||
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
|
||||
cp "$3" "$script_path_root"
|
||||
if [ ! -d ${file_path_root} ] ; then
|
||||
mkdir -p ${file_path_root} \
|
||||
&& echo "Created ${file_path_root}"
|
||||
fi
|
||||
cp "$2" "${file_path_root}"
|
||||
|
||||
umount_system $2 $DEV_IMAGE
|
||||
umount_system ${MOUNT_POINT} ${DEV_IMAGE}
|
||||
}
|
||||
|
||||
umount_system() {
|
||||
@@ -317,6 +302,8 @@ publish_image() {
|
||||
echo -e "\033[0;31m\033[1m$(date) | Zipping complete!\033[0m\033[0m"
|
||||
else
|
||||
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
|
||||
|
||||
echo -e "\033[0;31m\033[1m$(date) | Upload image\033[0m\033[0m"
|
||||
@@ -370,8 +357,8 @@ echo "\$7: $7"
|
||||
|
||||
case "$1" in
|
||||
mount_system)
|
||||
# mount_system $IMAGE $MOUNT_POINT
|
||||
mount_system $2 $3;;
|
||||
# mount_system $IMAGE
|
||||
mount_system $2;;
|
||||
|
||||
get_image)
|
||||
# get_image $BUILD_DIR $RPI_DONWLOAD_URL $IMAGE_NAME
|
||||
@@ -386,11 +373,11 @@ case "$1" in
|
||||
publish_image $2 $3 $4 $5 $6 "$7";;
|
||||
|
||||
execute)
|
||||
# execute $IMAGE $MOUNT_POINT $EXECUTE_FILE ...
|
||||
execute $2 $3 $4 ${@:5};;
|
||||
# execute $IMAGE $EXECUTE_FILE ...
|
||||
execute $2 $3 ${@:4};;
|
||||
|
||||
copy_to_chroot)
|
||||
# copy_to_chroot $IMAGE $MOUNT_POINT $MOVE_FILE
|
||||
# copy_to_chroot $IMAGE $MOVE_FILE $MOVE_TO
|
||||
copy_to_chroot $2 $3 $4;;
|
||||
|
||||
*)
|
||||
|
||||
@@ -7,7 +7,6 @@ set -e
|
||||
##################################################################################################################################
|
||||
|
||||
# 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) | Installing ROS\033[0m\033[0m"
|
||||
|
||||
@@ -42,8 +41,8 @@ echo -e "\033[0;31m\033[1m$(date) | #4 rosdep init && rosdep update\033[0m\033[0
|
||||
# bootstrap rosdep
|
||||
rosdep init && rosdep update
|
||||
|
||||
# If $2 = false, then discover packages
|
||||
if [ "$2" = "false" ];
|
||||
# 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"
|
||||
|
||||
@@ -64,7 +63,6 @@ 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 \
|
||||
&& mv /root/kinetic-ros-coex.rosinstall kinetic-ros-coex.rosinstall \
|
||||
&& wstool init src kinetic-ros-coex.rosinstall
|
||||
fi
|
||||
|
||||
@@ -132,17 +130,20 @@ chown -Rf pi:pi /home/pi/ros_catkin_ws
|
||||
echo -e "\033[0;31m\033[1m$(date) | #12 Creating catkin_ws & Installing CLEVER-BUNDLE\033[0m\033[0m"
|
||||
|
||||
git clone $1 /home/pi/catkin_ws/src/clever \
|
||||
&& cd /home/pi/catkin_ws/src/clever \
|
||||
&& git checkout $2 \
|
||||
&& pip install wheel \
|
||||
&& pip install -r /home/pi/catkin_ws/src/clever/clever/requirements.txt \
|
||||
&& cd /home/pi/catkin_ws \
|
||||
&& . /opt/ros/kinetic/setup.sh \
|
||||
&& catkin_make -j1 \
|
||||
&& systemctl enable /home/pi/catkin_ws/src/clever/deploy/roscore.service \
|
||||
&& systemctl enable /home/pi/catkin_ws/src/clever/deploy/clever.service
|
||||
&& catkin_make -j1 -DCMAKE_BUILD_TYPE=Release \
|
||||
&& ln -s /home/pi/catkin_ws/src/clever/deploy/roscore.service /lib/systemd/system/roscore.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) | #13 Remove build dir from catkin_ws\033[0m\033[0m"
|
||||
echo -e "\033[0;31m\033[1m$(date) | #13 Change permissions for catkin_ws\033[0m\033[0m"
|
||||
|
||||
rm -rf /home/pi/catkin_ws/build
|
||||
chown -Rf pi:pi /home/pi/catkin_ws
|
||||
|
||||
echo -e "\033[0;31m\033[1m$(date) | #14 Setup ROS environment\033[0m\033[0m"
|
||||
|
||||