Merge branch 'master' into master

This commit is contained in:
Smirnov Artem
2018-06-21 23:43:35 +03:00
committed by GitHub
37 changed files with 190 additions and 45 deletions

13
.editorconfig Normal file
View File

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

View File

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

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 659 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 867 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 867 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 867 B

View File

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

View File

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

View File

@@ -7,6 +7,10 @@ html, body {
color: rgba(255, 255, 255, 0.9);
}
* {
user-select: none;
}
.stick {
border-radius: 50%;
width: 5cm;

View File

@@ -65,8 +65,8 @@ new ROSLIB.Topic({
name: '/rosout_agg',
messageType: 'rosgraph_msgs/Log'
}).subscribe(function(message) {
var BLACKLIST = ['CMD: ', 'PR: ', 'DROPPED'];
if(message.level >= 4) {
var BLACKLIST = ['CMD: ', 'PR: ', 'DROPPED', 'Clock skew detected', 'MANUAL CONTROL LOST'];
if (message.level >= 4) {
if (BLACKLIST.some(function(e) {
return message.msg.indexOf(e) != -1;
})) {

View File

@@ -18,8 +18,10 @@
<!-- 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://192.168.11.1:14550@" if="$(eval gcs_bridge == 'udp-b')"/>
<param name="gcs_url" value="udp-pb://192.168.11.1:14550@" if="$(eval gcs_bridge == 'udp-b')"/>
<param name="gcs_url" value="" if="$(eval not gcs_bridge)"/>
<param name="gcs_quiet_mode" value="true"/>
<param name="conn/timeout" value="10"/>
<!-- default px4 params -->
<rosparam command="load" file="$(find mavros)/launch/px4_config.yaml"/>

View File

@@ -28,6 +28,7 @@
* [Подключение GPS](gps.md)
* [Использование 3G-модема](3g.md)
* [Устройство сети RPi](network.md)
* [Работа с логами PX4](flight_logs.md)
* Учебник
* [Уроки](lessons.md)
* [Учебно-методическое пособие](metod.md)

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 KiB

BIN
docs/assets/flightplot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

BIN
docs/assets/listener.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 KiB

55
docs/flight_logs.md Normal file
View File

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

View File

@@ -4,7 +4,7 @@
Возможен контроль, управление и настройка полетного контроллера квадрокоптера с помощью программы QGroundControl по Wi-Fi.
Для этого необходимо подключиться к Wi-Fi сети `CLEVER-xxxx`.
После чего в launch-файле Клевера `/home/pi/catkin_ws/src/clever/clever/launch/clever.launch` выбрать один из преднастроенных режимов: TCP, UDP, UDP-B.
После чего в launch-файле Клевера `/home/pi/catkin_ws/src/clever/clever/launch/clever.launch` выбрать один из преднастроенных режимов: TCP, UDP, UDP broadcast.
После изменения launch-файла необходимо перезагрузить сервис clever:
@@ -51,9 +51,9 @@ UDP broadcast-бридж
<arg name="gcs_bridge" default="udp-b"/>
```
При использовании UDB broadcast-бриджа достаточно подключиться к Wi-Fi сети Клевера. QGroundControl должен подключиться к коптеру автоматически.
При использовании UDB broadcast-бриджа достаточно подключиться к Wi-Fi сети Клевера. QGroundControl должен подключиться к коптеру автоматически. Также при использовании UDP broadcast возможна работа с коптером одновременно с нескольких устройств (например, одновременно QGroundControl на ноутбуке и смартфоне).
> **Note** UDP broadcast-бридж работает быстрее, чем TCP-бридж, но связь в нем менее стабильная: иногда могут возникать проблемы при загрузке миссии на коптер, а также при калибровке сенсоров.
> **Note** UDP broadcast-бридж является наиболее быстрым соединением, но связь в нем менее стабильная: иногда могут возникать проблемы при загрузке миссии на коптер, а также при калибровке сенсоров.
___
После успешного подключения можно настраивать, калибровать и просматривать состояние квадкоптера без проводов.

View File

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

View File

@@ -36,4 +36,11 @@ git clone https://github.com/jacksonliam/mjpg-streamer.git /home/pi/mjpg-streame
&& make install \
&& chown -Rf pi:pi /home/pi/mjpg-streamer
echo -e "\033[0;31m\033[1m$(date) | End of software installation\033[0m\033[0m"
echo -e "\033[0;31m\033[1m$(date) | Add .vimrc\033[0m\033[0m"
# vim settings
echo "set mouse-=a
syntax on
" > /home/pi/.vimrc
echo -e "\033[0;31m\033[1m$(date) | End of network installation\033[0m\033[0m"