Merge branch 'master' into master

This commit is contained in:
sfalexrog
2019-02-08 14:30:00 +03:00
committed by GitHub
160 changed files with 66919 additions and 904 deletions

BIN
docs/assets/Mikhail.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

BIN
docs/assets/Timofey.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

BIN
docs/assets/calibration.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

BIN
docs/assets/calibresult.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 419 KiB

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 423 KiB

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 379 KiB

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 378 KiB

After

Width:  |  Height:  |  Size: 152 KiB

BIN
docs/assets/chessboard.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

BIN
docs/assets/google_play.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
docs/assets/img1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
docs/assets/img2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
docs/assets/misha_calib.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

BIN
docs/assets/pty1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

BIN
docs/assets/pty2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

BIN
docs/assets/pty3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

BIN
docs/assets/screen.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
docs/assets/tim_calib.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

BIN
docs/assets/wcp1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

BIN
docs/assets/wcp2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

View File

@@ -6,7 +6,7 @@ Appropriate phase wires and their control signal (Fig. 1b) are marked with the s
For example, orange color -> bottom-right motor -> S1 - orange wire.
## PixRacer flight controller pin-out
## Pixracer flight controller pin-out
Fig. 2a shows the pin-out of the terminal strip:
@@ -15,7 +15,7 @@ Fig. 2a shows the pin-out of the terminal strip:
* 1, 2, 3, 4 are ports for connecting ESCs.
* 1, 2 are ports for expanding the output PWM signal (can be setup in QGroundControl, can also can be used to control the hexacopter).
Fig. 2b shows motor numbering of the PixRacer flight controller.
Fig. 2b shows motor numbering of the Pixracer flight controller.
* The arrow is the flight controller orientation.
* Black M3, M4 are the motors that rotate clockwise.
@@ -23,8 +23,8 @@ Fig. 2a shows the pin-out of the terminal strip:
## Picture of the connection, based on the current orientation of the 4 in 1 ESC board
Using Fig. 1a, 1b, 2a, 2b, map its own control signal to each motor, and connect in accordance with the PixRacer motor numbering order.
Using Fig. 1a, 1b, 2a, 2b, map its own control signal to each motor, and connect in accordance with the Pixracer motor numbering order.
For example, motor M3 that rotates counter-clockwise (top left corner) is controlled by signal S4 (green wire). It is connected to port 3.
![Connecting 4 in 1 ESCs](../assets/cl3_connectionESC4in1.jpg)
![Connecting 4 in 1 ESCs](../assets/cl3_connectionESC4in1.jpg)

View File

@@ -24,11 +24,11 @@ The image includes:
* Raspbian Stretch
* ROS Kinetic
* Configured [networking] (network.md)
* Configured [networking](network.md)
* OpenCV
* mavros
* A software set for working with Clever
[API description](simple_offboard.md) for autonomous flights.
The source code of the collector of the image and only can be found at [GitHub](https://github.com/CopterExpress/clever).
The source code of the collector of the image and only can be found at [GitHub](https://github.com/CopterExpress/clever).

View File

@@ -26,7 +26,7 @@ Clever 2 construction kit assembly instruction
* EFEST Luc V4 Li-lon Charger ×1.
* Regulators protective case ×4.
* Legs attachment ×8.
* PixHawk flight controller ×1.
* Pixhawk flight controller ×1.
* FlySky i6 radio receiver×1.
* FlySky i6 radio transmitter ×1.
* EFEST LUC V4 Charger ×1.
@@ -292,7 +292,7 @@ IMPORTANT NOTE about polarity
![Connecting the radio receiver power](../assets/connectingRadio.jpg)
[Radio equipment troubleshooting manual ](radioerrors.md)
[Radio equipment troubleshooting manual](radioerrors.md)
### Checking the motors rotation direction
@@ -322,13 +322,13 @@ IMPORTANT NOTE about polarity
![Turn the assembly upside down](../assets/topPreview.png)
#### Installation of the PixHawk flight controller
#### Installation of the Pixhawk flight controller
1. Stick the two-sided adhesive tape in the corners of the flight controller. ![Flight controller](../assets/pixhawk.png)
> **IMPORTANT** When the motors rotate, vibrations occur, which affect sensors of the PixHawk flight controller. To avoid this effect, the number of double-sided tape layers
> **IMPORTANT** When the motors rotate, vibrations occur, which affect sensors of the Pixhawk flight controller. To avoid this effect, the number of double-sided tape layers
should be increased up to 4 5.
2. Install the flight controller in the center of the frame. ![Flight controller](../assets/topviewpixhawk.jpg)
> **IMPORTANT** The arrows on the frame and PixHawk should point in the same direction
> **IMPORTANT** The arrows on the frame and Pixhawk should point in the same direction
#### Connecting the flight controller according to the circuit diagram
@@ -385,4 +385,4 @@ The copter is ready for configuration!
2. When connecting (disconnecting) batteries, hold only the connectors, never pull or tug the wires.
3. If you see open connectors, violation of insulation or battery compartment integrity, do not touch it, and immediately inform the instructor.
See article [safety precautions when soldering and during copter flight operation](safety.md)
See article [safety precautions when soldering and during copter flight operation](safety.md)

View File

@@ -95,7 +95,7 @@ TODO
![Installation of the BEC voltage Converter](../assets/cl3_mountBEC.JPG)
## Installation of the 4 in 1 ESC board and the PDB power-board
## Installation of the 4 in 1 ESC board and the PDB power-board
1. Install the 4 in 1 ESC circuit-board as shown in the picture.
@@ -188,7 +188,7 @@ article [remote faults](radioerrors.md).
![Installation of Raspberry Pi Model B](../assets/cl3_mountRaspberryPi.JPG)
## Installation of Arduino and the FlySky radio receiver
## Installation of Arduino and the FlySky radio receiver
1. Mount the pins of the Arduino Nano micro-controller using soldering.
2. Install the micro-controller into a special mount, and attach to the lower deck using М3х16 screws (4 pcs).

View File

@@ -25,4 +25,4 @@ This connector may be used together with a buzzer (beeper) for monitoring batter
There is a great variety of Gold bullet pin connectors. Connectors of this type may have different diameters and size. The most widespread connectors are those with the diameter of 2 mm, 3 mm, and 4 mm.
They are often used for solderless connections on PDB and motors.
<img src="../assets/Banana.jpg" alt="Banana" width=200>
<img src="../assets/Banana.jpg" alt="Banana" width=200>

View File

@@ -19,13 +19,13 @@ Pixhawk, Ardupilot, Naze32, CC3D.
An electric motor that rotates propellers of the multicopter. Usually, brushless motors are used. These motors are connected to ESC.
## ESC / motor controller / "regul"
## ESC / motor controller
An Electronic Speed Controller. A specialized circuit-board that controls the speed of the brushless motor. It is controlled by a flight controller using pulse width modulation (PWM).
ESC has the firmware that determines the characteristics of its operation.
## Remote control / radio control equipment/ "appa"
## Remote control / radio control equipment
A radio-operated quadcopter remote control. Operation of the remote control requires connecting a receiver to the flight controller.
@@ -67,4 +67,4 @@ A library that is a link between the aircraft operating using the MAVLink protoc
## UART
A serial asynchronous data transfer interface used in many devices. For example, GPS antennas, Wi-Fi routers, or Pixhawk.
A serial asynchronous data transfer interface used in many devices. For example, GPS antennas, Wi-Fi routers, or Pixhawk.

View File

@@ -2,7 +2,7 @@
Main documentation: [http://wiki.ros.org/mavros](http://wiki.ros.org/mavros)
MAVROS \(MAVLink + ROS\) is a package for ROS that provides the possibility of controlling drones via the [MAVLink] protocol (mavlink.md). MAVROS supports flight stacks PX4 and APM. Communication is established via UART, USB, TCP or UDP.
MAVROS \(MAVLink + ROS\) is a package for ROS that provides the possibility of controlling drones via the [MAVLink](mavlink.md) protocol. MAVROS supports flight stacks PX4 and APM. Communication is established via UART, USB, TCP or UDP.
MAVROS subscribes to certain ROS topics while waiting for commands, publishes telemetry to other topics, and provides services.

View File

@@ -30,7 +30,7 @@ In manual mode, the pilot controls the drone directly. GPS, computer vision data
In the automatic flight mode, the quadcopter ignores the control signals from the transmitter.
* **AUTO.MISSION** PX4 completes the mission pre-loaded into the drone (the mission is downloaded using the QGroundControl, or from [MAVLink] (mavlink.md) using [MAVROS](mavros.md).
* **AUTO.MISSION** PX4 completes the mission pre-loaded into the drone (the mission is downloaded using the QGroundControl, or from [MAVLink](mavlink.md) using [MAVROS](mavros.md).
* **AUTO.RTL** the copter automatically returns to the takeoff point.
* **AUTO.LAND** the copter lands automatically.
@@ -44,4 +44,4 @@ The main used MAVLink packages are:
* [SET_POSITION_TARGET_LOCAL_NED](https://mavlink.io/en/messages/common.html#SET_POSITION_TARGET_LOCAL_NED)
* [SET_ATTITUDE_TARGET](https://mavlink.io/en/messages/common.html#SET_ATTITUDE_TARGET)
See: [autonomous flying the quadcopter in the OFFBOARD mode](simple_offboard.md).
See: [autonomous flying the quadcopter in the OFFBOARD mode](simple_offboard.md).

View File

@@ -2,7 +2,9 @@
The Raspberry Pi Wi-Fi adapter of has two main operating modes:
1. **Client mode** RPi connects to an existing Wi-Fi network.
1. **Client mode** RPi connects to an existing Wi-Fi network.
2. **Access point mode** RPi creates a Wi-Fi network that you can connect to.
When using [the RPi image](microsd_images.md), the Wi-Fi adapter works in the [access point mode] by default (Wi-Fi.md).

View File

@@ -35,7 +35,7 @@ If anyone says the opposite don't believe him, he is trying to misguide you:
Flying
------
### Safety during preparation to flying
### Safety during pre-flight preparations
* Make sure that the Li-ion batteries are charged.
* Make sure the batteries in the control equipment are charged.
@@ -88,4 +88,4 @@ After a scheduled landing, do the following:
1. Disarm (Move the left stick left-down for 3 seconds)
2. Disconnect the Li-ion battery on the copter.
3. Turn off the remote.
3. Turn off the remote.

View File

@@ -146,7 +146,6 @@ Start the calibration procedure
![Gyroscope calibration](../assets/calibrategyro.jpg)
> *Warning* During calibration, the drone should remain in position, be stable, etc.
## Flight modes

View File

@@ -269,7 +269,6 @@ set_velocity(vx=0.4, vy=0.0, vz=0, yaw=float('nan'), yaw_rate=0.4, frame_id='bod
Setting pitch, roll, yaw and throttle level (approximate analogue to control in [the `STABILIZED` mode](modes.md)). This service may be used for lower level monitoring of the copter behavior or controlling the copter, if no reliable data about its position are available.
Parameters:
* `pitch`, `roll`, `yaw` required pitch, roll, and yaw angle *(radians)*;

View File

@@ -1,6 +1,6 @@
# Viewing images from cameras
To view images from cameras (or other Ros topics), you can use [rviz](rviz.md), rqt, or watch them in a browser using web\_video\_server.
To view images from cameras (or other ROS topics), you can use [rviz](rviz.md), rqt, or watch them in a browser using web\_video\_server.
See read more about [using rqt](rviz.md).

View File

@@ -21,4 +21,4 @@ Blanching a wire means doing the following:
3. Apply flux to the twisted stripped wires
4. Apply a layer of solder.
![Blanching wires](../assets/zap.jpg)
![Blanching wires](../assets/zap.jpg)

View File

@@ -50,13 +50,16 @@
* [3G-модем](3g.md)
* Проекты на базе Клевера
* [Шаровая защита коптера](shield.md)
* [Распознавание лиц](face_recognition.md)
* [Пульт на Андроид](android.md)
* [CopterHack-2018](copterhack2018.md)
* [CopterHack-2017](copterhack2017.md)
* Дополнительные материалы
* [Вклад в Клевер](contributing.md)
* [Прошивка ESC контроллеров с помощью Arduino](esc_firmware.md)
* [Прошивка ESC контроллеров](esc_firmware.md)
* [Протокол MAVLink](mavlink.md)
* [Работа с логами PX4](flight_logs.md)
* [Калибровка камеры](calibration.md)
* Учебник
* [Теория и видеоуроки](lessons.md)
* [Учебно-методическое пособие](metod.md)

142
docs/ru/android.md Normal file
View File

@@ -0,0 +1,142 @@
# Пульт на Android
Все владельцы мобильных устройств фирмы *Apple* ещё морозным январем 2018го обзавелись приятным приложением под *iOS* для пилотирования квадрокоптеров с помощью **WiFi**. И вот, спустя год вышло такое же приложение но уже для другой операционной системы. Актуальную версию вы можете скачать [**тут**](https://vk.com/away.php?to=https%3A%2F%2Fplay.google.com%2Fstore%2Fapps%2Fdetails%3Fid%3Dexpress.copter.cleverrc&cc_key=) .
## Введение
В данной статье я расскажу вам о том, как можно написать свой или доработать уже имеющийся пульт для Андроид своими руками. Для работы будем использовать модный язык *Kotlin*, а в качестве среды разработки возьмем *Android Studio*. Для тех кто ни разу ей не пользовался рекомендую к ознакомлению следующие [*материалы*](https://www.google.com/search?ei=xQxDXMH0C8OOmgW4mYigDQ&q=%D0%A7%D1%82%D0%BE+%D0%B4%D0%B5%D0%BB%D0%B0%D1%82%D1%8C+%D0%B5%D1%81%D0%BB%D0%B8+%D1%8F+%D0%BD%D0%B5+%D1%83%D0%BC%D0%B5%D1%8E+%D0%BF%D0%B8%D1%81%D0%B0%D1%82%D1%8C+%D0%BF%D0%BE%D0%B4+%D0%B0%D0%BD%D0%B4%D1%80%D0%BE%D0%B8%D0%B4%3F&oq=%D0%A7%D1%82%D0%BE+%D0%B4%D0%B5%D0%BB%D0%B0%D1%82%D1%8C+%D0%B5%D1%81%D0%BB%D0%B8+%D1%8F+%D0%BD%D0%B5+%D1%83%D0%BC%D0%B5%D1%8E+%D0%BF%D0%B8%D1%81%D0%B0%D1%82%D1%8C+%D0%BF%D0%BE%D0%B4+%D0%B0%D0%BD%D0%B4%D1%80%D0%BE%D0%B8%D0%B4%3F&gs_l=psy-ab.3...4413.17423..17726...9.0..2.442.4577.45j5j1j0j1....2..0....1..gws-wiz.....6..0i71j35i39j0i131j0j0i67j0i131i67j0i22i30j33i22i29i30j33i21j33i160.0bZz-WGxoHY). Весь код приложения можно найти [**тут**](https://github.com/Tennessium/android). Если вы хотите сразу получить приложение с целью дальнейшей доработки, выполните следующую команду:
```Bash
git clone https://github.com/Tennessium/android
```
Однако чтобы вы смогли полностью понять устройство приложения, я расскажу вам о каждом этапе создания проекта, как если бы вы делали его с нуля.
## Обертка
Начнем с самого простого - внешнего вида нашего приложения. На [**гитхабе**](https://github.com/CopterExpress/clever/tree/master/apps/android/app/src/main/assets) вы можете найти *HTML*, *CSS* и *JavaScript* файлы, это и есть веб страница с которой будет происходить управление коптером. Чтобы эта страница отображалась у нас в приложении надо:
1. Создать папку **assets** в главной папке приложения **app**
2. Добавить в нее файлы все файлы [отсюда](https://github.com/CopterExpress/clever/tree/master/apps/android/app/src/main/assets)
Если вы дошли до этого этапа то у вас уже есть необходимая веб страница, поздравляю! Теперь нам надо её как-то отобразить в приложении. Для этого в классе вашего *activity* в методе **onCreate** необходимо написать следующий код:
```Kotlin
main_web.loadUrl("file:///android_asset/index.html")
```
Где *main_web* - id вашего *WebView*, который должен находится в *xml* файле выбранного вами *activity*.
К сожалению, пульт для управления коптером требует всего экрана устройства, а элементы интерфейса системы мешают полноценному использованию программы. Для этого надо в начале метода **onCreate** вызвать следующую функцию:
```Kotlin
private fun fullScreenCall() {
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
if (Build.VERSION.SDK_INT < 19) {
val v = this.window.decorView
v.systemUiVisibility = View.GONE
} else {
//for higher api versions.
val decorView = window.decorView
val uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
decorView.systemUiVisibility = uiOptions
}
}
```
Данная функция позволяет избавиться от элементов интерфейса системы. Идем дальше.
Вот так выглядит пульт на этом этапе:
<img src="../assets/IMG_4397.PNG" width="50%">
Если вы запустите приложение, то заметите что стики не работают. Это происходит по тому, что на нашей странице отключен *JavaScript*. чтобы его включить надо прописать следующее:
```Kotlin
main_web.settings.apply {
domStorageEnabled = true
javaScriptEnabled = true
loadWithOverviewMode = true
useWideViewPort = true
setSupportZoom(false)
}
```
Этим куском кода мы разрешаем странице использовать *JavaScript* и заодно готовимся к следующему этапу - **логике**.
## Прием данных с веб страницы
Чтобы телефон мог принимать данные с *HTML страницы*, надо создать класс для взаимодействия с веб интерфейсом
```Kotlin
class WebAppInterface(c: Context) {
@JavascriptInterface
public fun postMessage(message: String) {
val data = JSONObject(message)
send("255.255.255.255", 35602, pack(
data.getInt("x").toShort(),
data.getInt("y").toShort(),
data.getInt("z").toShort(),
data.getInt("r").toShort()))
}
}
```
Данный класс будет получать сообщение с веб страницы отправленное методом *postMessage*, где аргумент *message* - сообщение от страницы.
Теперь надо связать классы **WebAppInterface** и **MainActivity**. Для этого надо всего лишь добавить одну строку в метод **onCreate**:
```Kotlin
main_web.addJavascriptInterface(WebAppInterface(this), "appInterface")
```
## Отправка данных на коптер
**Важно!**
Для любой работы с интернетом на платформе *Android* в файле **AndroidManifest.xml** внутри тега *manifest* необходимо добавить такую строку:
```XML
<uses-permission android:name="android.permission.INTERNET"/>
```
Она дает вашему приложению доступ в интернет и возможность передавать данные по средствам **WiFi**. А как это делать, мы с вами сейчас и узнаем. Идём дальше!
Вы наверное заметили функцию *send* в классе **WebAppInterface**. Именно она отправляет данные на коптер. Давайте объявим ее **вне классов**:
```Kotlin
fun send(host: String, port: Int, data: ByteArray, senderPort: Int = 0): Boolean {
var ret = false
var socket: DatagramSocket? = null
try {
socket = DatagramSocket(senderPort)
val address = InetAddress.getByName(host)
val packet = DatagramPacket(data, data.size, address, port)
socket.send(packet)
ret = true
} catch (e: Exception) {
e.printStackTrace()
} finally {
socket?.close()
}
return ret
}
```
Данная функция отправляет данные при помощи [*протокола пользовательских датаграмм*](https://www.google.com/search?q=udp+%D0%BF%D1%80%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%BB&oq=udp+&aqs=chrome.0.69i59j69i57j35i39j0l3.1434j1j7&sourceid=chrome&ie=UTF-8) на коптер. Программа отправляет **байты**, поэтому неплохо бы было объявить функцию для создания массива **байтов** из четырех переменных:
```Kotlin
fun pack(x: Short, y: Short, z: Short, r: Short): ByteArray {
val pump_on_buf: ByteBuffer = ByteBuffer.allocate(8)
pump_on_buf.putShort(r)
pump_on_buf.putShort(z)
pump_on_buf.putShort(y)
pump_on_buf.putShort(x)
return pump_on_buf.array().reversedArray()
}
```
## Итог
Теперь ваше приложение имеет полный функционал аналога под **iOS**. Можете кастомизировать его как пожелаете. По любым вопросам о приложении можете обращаться в Телеграм @Tenessinum.

View File

@@ -110,7 +110,7 @@ void setup()
nav_req.x = 0;
nav_req.y = 0;
nav_req.z = 2;
nav_req.frame_id = "fcu_horiz";
nav_req.frame_id = "body";
nav_req.speed = 0.5;
navigate.call(nav_req, nav_res);
@@ -128,7 +128,7 @@ void setup()
nav_req.x = 3;
nav_req.y = 0;
nav_req.z = 0;
nav_req.frame_id = "fcu_horiz";
nav_req.frame_id = "body";
nav_req.speed = 0.8;
navigate.call(nav_req, nav_res);
@@ -145,7 +145,6 @@ void setup()
nav_req.y = 0;
nav_req.z = 2;
nav_req.frame_id = "aruco_map";
nav_req.update_frame = true;
nav_req.speed = 0.8;
navigate.call(nav_req, nav_res);

View File

@@ -1,5 +1,7 @@
# Навигация с использованием ArUco-маркеров
> **Note** Документация для версий [образа](microsd_images.md), начиная с **0.15**. Для более ранних версий см. [документацию для версии **0.14**](https://github.com/CopterExpress/clever/blob/v0.14/docs/ru/aruco.md).
[ArUco-маркеры](https://docs.opencv.org/3.2.0/d5/dae/tutorial_aruco_detection.html) — это популярная технология для позиционирования
роботехнических систем с использованием компьютерного зрения.
@@ -141,12 +143,12 @@ _Примечание_: указанное выше определение пр
```python
# Вначале необходимо взлететь, чтобы коптер увидел карту меток
# и появился фрейм aruco_map:
navigate(0, 0, 2, frame_id='fcu_horiz', speed=0.5, auto_arm=True) # взлет на 2 метра
navigate(0, 0, 2, frame_id='body', speed=0.5, auto_arm=True) # взлет на 2 метра
time.sleep(5)
# Полет в координату 2:2 маркерного поля, высота 2 метра
navigate(2, 2, 2, speed=1, frame_id='aruco_map', update_frame=True) # полет в координату 2:2, высота 3 метра
navigate(2, 2, 2, speed=1, frame_id='aruco_map') # полет в координату 2:2, высота 3 метра
```
См. [другие функции](simple_offboard.md) simple_offboard.
@@ -160,7 +162,7 @@ navigate(2, 2, 2, speed=1, frame_id='aruco_map', update_frame=True) # поле
Чтобы задавать карту маркеров в "перевернутой" системе координат, необходимо изменить параметр `aruco_orientation` в файле `~/catkin_ws/src/clever/clever/aruco.launch`:
```xml
<param name="aruco_orientation" value="local_origin_upside_down"/>
<param name="aruco_orientation" value="map_upside_down"/>
```
При задании вышеуказанного параметра фрейм aruco\_map также окажется "перевернутым". Таким образом, для полета на высоту 2 метра ниже потолка, аргумент `z` нужно устанавливать в 2:

227
docs/ru/calibration.md Normal file
View File

@@ -0,0 +1,227 @@
# Калибровка камеры
Компьютерное зрение получает все более широкое распространение. Зачастую, алгоритмы компьютерного зрения работают неточно, получая искаженное изображение с камеры, что особенно характерно для fisheye-камер.
![img](../assets/img1.jpg)
> Изображение "скруглено" ближе к краям.
Какой-либо алгоритм компьютерного зрения будет воспринимать информацию с этой картинки неправильно. Для устранения подобных искажений камера, получающая изображения, должна быть откалибрована в соответствии со своими особенностями.
## Установка скрипта
Для начала, необходимо установить необходимые библиотеки:
```
pip install numpy
pip install opencv-python
pip install glob
pip install pyyaml
pip install urllib.request
```
Затем скачиваем скрипт из репозитория:
```bash
git clone https://github.com/tinderad/clever_cam_calibration.git
```
Переходим в скачанную папку и устанавливаем скрипт:
```bash
cd clever_cam_calibration
sudo python setup.py build
sudo python setup.py install
```
Если вы используете Windows, тогда скачайте архив из [репозитория](https://github.com/tinderad/clever_cam_calibration/archive/master.zip), распакуйте его и установите:
```bash
cd path\to\archive\clever_cam_calibration\
python setup.py build
python setup.py install
```
> path\to\archive - путь до распакованного архива.
## Подготовка к калибровке
Вам необходимо подготовить калибровочную мишень. Она представляет собой «шахматную доску». Файл можно взять [отсюда](https://www.oreilly.com/library/view/learning-opencv-3/9781491937983/assets/lcv3_ac01.png).
Наклейте распечатанную мишень на любую твердую поверхность. Посчитайте количество пересечений в длину и в ширину доски, измерьте размер клетки (в мм).
![img](../assets/chessboard.jpg)
Включите Клевер и подключитесь к его Wifi.
> Перейдите на 192.168.11.1:8080 и проверьте, получает ли компьютер изображения из топика image_raw.
## Калибровка
Запустите скрипт **_calibrate_cam_**:
**Windows:**
```bash
>path\to\python\Scripts\calibrate_cam.exe
```
> path\to\Python - путь до директории Python
**Linux:**
```bash
>calibrate_cam
```
Задайте параметры доски:
```bash
>calibrate_cam
Chessboard width: # Перекрестий в ширину
Chessboard height: # Перекрестий в длину
Square size: # Длина ребра клетки (в мм)
Saving mode (YES - on): # Режим сохранения
```
> Режим сохранения: если включен, то все полученные фотографии будут сохраняться в нынешней директории.
Скрипт начнет свою работу:
...
Calibration started!
Commands:
help, catch (key: Enter), delete, restart, stop, finish
Чтобы откалибровать камеру, вам требуется сделать как минимум 25 фото шахматной доски с различных ракурсов.
![img](../assets/calibration.jpg)
Чтобы сделать фото, введите команду **_catch_**.
```bash
>catch
```
Программа будет информировать вас о состоянии калибровки.
```bash
...
Chessboard not found, now 0 (25 required)
> # Enter
---
Image added, now 1 (25 required)
```
> Вместо того, чтобы каждый раз вводить команду **_catch_**, Вы можете просто нажимать клавишу **_Enter_** (вводить пустую строку).
После того, как будет набрано достаточное количество изображений, введите команду **_finish_**.
```bash
...
>finish
Calibration successful!
```
**Калибровка по существующим изображениям:**
Если же у вас уже есть изображения, то вы можете откалибровать камеру по ним при помощи скрипта **_calibrate_cam_ex_**.
```bash
>calibrate_cam_ex
```
Указываем характеристики мишени, а так же путь до папки с изображениями:
```bash
>calibrate_cam_ex
Chessboard width: # Перекрестий в ширину
Chessboard height: # Перекрестий в длину
Square size: # Длина ребра клетки (в мм)
Path: # Путь до папки с изображениями
```
В остальном этот скрипт работает аналогично **_calibrate_cam_**.
Программа обработает все полученные фотографии, и создаст файл **_camera_info_****_._****_yaml_** в нынешней директории. При помощи этого файла можно будет выравнивать искажения на изображениях, полученных с этой камеры.
> Если вы поменяете разрешение получаемого изображения, вам нужно будет снова калибровать камеру.
## Исправление искажений
За получение исправленного изображения отвечает функция **_get_undistorted_image(cv2_image, camera_info)_**:
* **_cv2_image_**: Закодированное в массив cv2 изображение.
* **_camera_****_­__****_info_**: Путь до файла калибровки.
Функция возвращает массив cv2, в котором закодировано исправленное изображение.
> Если вы используете fisheye-камеру, поставляемую вместе с Клевером, то для обработки изображений разрешением 320x240 или 640x480 вы можете использовать уже существующие параметры калибровки. Для этого в качестве аргумента **_camera_info_** передайте параметры **_clever_cam_calibration.clevercamcalib.CLEVER_FISHEYE_CAM_320_** или **_clever_cam_calibration.clevercamcalib.CLEVER_FISHEYE_CAM_640_** соответственно.
## Примеры работы
Изначальные изображения:
![img](../assets/img1.jpg)
![img](../assets/img2.jpg)
Иcправленные изображения:
![img](../assets/calibresult.jpg)
![img](../assets/calibresult1.jpg)
## Пример использования
**Обработка потока изображений с камеры**.
Данная программа получает изображения с камеры Клевера и выводит их на экран в исправленном виде, используя существующий калибровочный файл.
```python
import clevercamcalib.clevercamcalib as ccc
import cv2
import urllib.request
import numpy as np
while True:
req = urllib.request.urlopen('http://192.168.11.1:8080/snapshot?topic=/main_camera/image_raw')
arr = np.asarray(bytearray(req.read()), dtype=np.uint8)
image = cv2.imdecode(arr, -1)
undistorted_img = ccc.get_undistorted_image(image, ccc.CLEVER_FISHEYE_CAM_640)
cv2.imshow("undistort", undistorted_img)
cv2.waitKey(33)
cv2.destroyAllWindows()
```
## Использование для ArUco
Чтобы применить параметры калибровки к системе ArUco-навигации, требуется перенести калибровочный .yaml файл на Raspberry Pi Клевера и инициализировать его.
> Не забудьте подключиться к WiFI Клевера.
Для передачи файла используется протокол SFTP. В данном примере используется программа WinSCP.
Подключимся к Raspberry Pi по SFTP:
> Пароль: _**raspberry**_
![img](../assets/wcp1.png)
Нажимаем “Войти”. Переходим в _**/home/pi/catkin_ws/src/clever/clever/camera_info/**_ и копируем туда калибровочный .yaml файл:
![img](../assets/wcp2.jpg)
Теперь мы должны выбрать этот файл в конфигурации ArUco. Для этого используется связь по протоколу SSH. В данном примере используется программа PuTTY.
Подключимся к Raspberry Pi по SSH:
![img](../assets/pty1.jpg)
Войдем под логином _**pi**_ и паролем _**raspberry**_, перейдем в директорию _**/home/pi/catkin_ws/src/clever/clever/launch**_ и начнем редактировать конфигурацию _**main_camera.launch**_:
![img](../assets/pty2.jpg)
В строке _**camera node**_ заменим параметр _**camera_info**_ на _**camera_info.yaml**_:
![img](../assets/pty3.jpg)
> Не забудьте изменить разрешение камеры.

View File

@@ -1,12 +1,14 @@
# Настройка расположения основной камеры
> **Note** Документация для версий [образа](microsd_images.md), начиная с **0.15**. Для более ранних версий см. [документацию для версии **0.14**](https://github.com/CopterExpress/clever/blob/v0.14/docs/ru/camera_frame.md).
Расположение и ориентация основной камеры задается в файле `~/catkin_ws/src/clever/clever/launch/main_camera.launch`:
```xml
<node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0 0 -0.07 -1.5707963 0 3.1415926 fcu main_camera_optical"/>
<node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0 0 -0.07 -1.5707963 0 3.1415926 base_link main_camera_optical"/>
```
Эта строка задает статическую трансформацию между фреймом `fcu` ([соответствует корпусу полетного контроллера](frames.md)) и камерой (`main_camera_optical`) в формате:
Эта строка задает статическую трансформацию между фреймом `base_link` ([соответствует корпусу полетного контроллера](frames.md)) и камерой (`main_camera_optical`) в формате:
```txt
сдвиг_x сдвиг_y сдвиг_z угол_рысканье угол_тангаж угол_крен
@@ -22,40 +24,40 @@
## Настройки для Клевера
> Первое изображение - как выглядит модель коптера в Rviz при указанных настройках, второе - как выглядит Клевер при тех же настройках.
Первое изображение как выглядит модель коптера в rviz при указанных настройках, второе как выглядит Клевер при тех же настройках.
### 1. Камера направлена вниз, шлейф назад
```xml
<node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 -0.07 -1.5707963 0 3.1415926 fcu main_camera_optical"/>
<node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 -0.07 -1.5707963 0 3.1415926 base_link main_camera_optical"/>
```
![](../assets/camera_option_1_rviz.png)
![](../assets/camera_option_1_clever.jpg)
<img src="../assets/camera_option_1_rviz.png" width=400>
<img src="../assets/camera_option_1_clever.jpg" width=400>
### 2. Камера направлена вниз, шлейф вперёд
```xml
<node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 -0.07 1.5707963 0 3.1415926 fcu main_camera_optical"/>
<node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 -0.07 1.5707963 0 3.1415926 base_link main_camera_optical"/>
```
![](../assets/camera_option_2_rviz.png)
![](../assets/camera_option_2_clever.jpg)
<img src="../assets/camera_option_2_rviz.png" width=400>
<img src="../assets/camera_option_2_clever.jpg" width=400>
### 3. Камера направлена вверх, шлейф назад
```xml
<node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 0.07 1.5707963 0 0 fcu main_camera_optical"/>
<node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 0.07 1.5707963 0 0 base_link main_camera_optical"/>
```
![](../assets/camera_option_3_rviz.png)
![](../assets/camera_option_3_clever.jpg)
<img src="../assets/camera_option_3_rviz.png" width=400>
<img src="../assets/camera_option_3_clever.jpg" width=400>
### 4. Камера направлена вверх, шлейф вперёд
```xml
<node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 0.07 -1.5707963 0 0 fcu main_camera_optical"/>
<node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 0.07 -1.5707963 0 0 base_link main_camera_optical"/>
```
![](../assets/camera_option_4_rviz.png)
![](../assets/camera_option_4_clever.jpg)
<img src="../assets/camera_option_4_rviz.png" width=400>
<img src="../assets/camera_option_4_clever.jpg" width=400>

View File

@@ -1,3 +1,5 @@
# Комплектация
В составе набора имеется 4 дополнительных рамы (поз. 2).
Они абсолютно одинаковые.
Поэтому для дальнейшего удобства понимания инструкции условно разделим их на верхнюю и нижнюю дополнительные рамы

163
docs/ru/face_recognition.md Normal file
View File

@@ -0,0 +1,163 @@
# Система распознавания лиц
## Введение
В последнее время системы распознавания лиц используются все шире, область применения этой технологии поистине огромна: от обычных селфи-дронов до дронов-полицейских. Ее интеграция в различные устройства проводится повсеместно. Сам процесс распознавания реально завораживает, и это сподвигло меня сделать проект связанный именно с этим. Целью моего стажерского проекта является создание простой open source-ной системы распознавания лиц с квадрокоптера Клевер. Данная программа берет изображения с камеры квадрокоптера, а его обработка происходит уже на компьютере. Поэтому все оставшиеся инструкции выполняются на ПК.
## Разработка
Первой задачей было найти алгоритм самого распознавания. В качестве пути решения проблемы было выбрано использовать [готовое API для Python](https://github.com/ageitgey/face_recognition). Данное API сочетает в себе ряд преимуществ: скорость и точность распознавания, а также простота использования.
## Установка
Для начала нужно установить все необходимые библиотеки:
```bash
pip install face_recognition
pip install opencv-python
```
Затем скачать сам скрипт из репозитория:
```bash
git clone https://github.com/mmkuznecov/face_recognition_from_clever.git
```
## Объяснение кода
Подключаем библиотеки:
```python
import face_recognition
import cv2
import os
import urllib.request
import numpy as np
```
***Данный кусок кода предназначен для Python 3. В Python 2.7 подключаем urllib2 вместо urllib:***
```python
import urllib2
```
Создаем список кодировок изображений и список имен:
```python
faces_images=[]
for i in os.listdir('faces/'):
faces_images.append(face_recognition.load_image_file('faces/'+i))
known_face_encodings=[]
for i in faces_images:
known_face_encodings.append(face_recognition.face_encodings(i)[0])
known_face_names=[]url
for i in os.listdir('faces/'):
i=i.split('.')[0]
known_face_names.append(i)
```
***Дополнение: все изображения хранятся в папке faces в формате name.jpg***
<img src="../assets/screen.jpg" width="50%">
<img src="../assets/Mikhail.jpg" width="30%">
<img src="../assets/Timofey.jpg" width="30%">
Инициализируем некоторые переменные:
```python
face_locations = []
face_encodings = []
face_names = []
process_this_frame = True
```
Берем изображение с сервера и преобразуем его в cv2 формат:
```python
req = urllib.request.urlopen('http://192.168.11.1:8080/snapshot?topic=/main_camera/image_raw')
arr = np.asarray(bytearray(req.read()), dtype=np.uint8)
frame = cv2.imdecode(arr, -1)
```
***Для Python 2.7:***
```python
req = urllib2.urlopen('http://192.168.11.1:8080/snapshot?topic=/main_camera/image_raw')
arr = np.asarray(bytearray(req.read()), dtype=np.uint8)
frame = cv2.imdecode(arr, -1)
```
Объяснение дальнейшего кода можно найти на githubе используемого API в комментариях к [следующему скрипту](https://github.com/ageitgey/face_recognition/blob/master/examples/facerec_from_webcam_faster.py)
## Использование
Достаточно подключиться к "Клеверу" через Wi-Fi и проверить, корректно ли работает видеострим с камеры.
Затем просто запускаем скрипт:
```bash
python recog.py
```
И на выходе:
<img src="../assets/Mikhail_output.jpg" width="50%">
<img src="../assets/Timofey_output.jpg" width="50%">
## Возможные трудности
При запуске скрипта может выскочить следующая ошибка:
```python
known_face_encodings.append(face_recognition.face_encodings(i)[0])
IndexError: list index out of range
```
В этом случае постарайтесь переделать изображения в папке faces, возможно из-за плохого качества программа не распознает лиц на изображениях.
## Использование калибровки
Для повышения точности распознавания можно использовать калибровку камеры. Модуль для калибровки можно установить, используя [специальный пакет](https://github.com/tinderad/clever_cam_calibration). Инструкцию по установке и использованию можно найти в файле calibration.md. Программа с использованием калибровочного пакета называется recog_undist.py
**Краткое пояснение кода:**
Подключаем установленный пакет:
```python
import clever_cam_calibration.clevercamcalib as ccc
```
Добавляем следующие строки:
```python
height_or, width_or, depth_or = frame.shape
```
Таким образом получаем информацию о размере изображения, где height_or-это высота оригинального изображения в пикселях, а width_or-ширина.
Затем исправляем искажения оригинального изображения и получаем уже его параметры:
```python
if height_or==240 and width_or==320:
frame=ccc.get_undistorted_image(frame,ccc.CLEVER_FISHEYE_CAM_320)
elif height_or==480 and width_or==640:
frame=ccc.get_undistorted_image(frame,ccc.CLEVER_FISHEYE_CAM_640)
else:
frame=ccc.get_undistorted_image(frame,input("Input your path to the .yaml file: "))
height_unz, width_unz, depth_unz = frame.shape
```
***В данном случае мы передаем аргумент ссс.CLEVER_FISHEYE_CAM_640, т.к. разрешение изображения в приведенном примере составляет 640x480, также можно использовать ссс.CLEVER_FISHEYE_CAM_320 для разрешения 320x240, в противном случае необходимо в качестве второго аргумента передать путь до калибровочного .yaml файла.***
И, наконец, возвращаем изображение к изначальному размеру:
```python
frame=cv2.resize(frame,(0,0), fx=(width_or/width_unz),fy=(height_or/height_unz))
```
Благодаря этому можно значительно повысить точность распознавания, т.к. обрабатываемое изображение будет уже не так сильно искажено.
<img src="../assets/misha_calib.jpg" width="50%">
<img src="../assets/tim_calib.jpg" width="50%">

View File

@@ -1,13 +1,15 @@
Системы координат (фреймы)
===
> **Note** Документация для версий [образа](microsd_images.md), начиная с **0.15**. Для более ранних версий см. [документацию для версии **0.14**](https://github.com/CopterExpress/clever/blob/v0.14/docs/ru/frames.md).
![Системы координаты Клевера (TF2)](../assets/frames.png)
Основные фреймы в пакете `clever`:
* `local_origin` — координаты относительно точки инициализации полетного контроллера: белая сетка на иллюстрации;
* `fcu` — координаты относительно квадрокоптера: схематичное изображение квадрокоптера на иллюстрации;
* `fcu_horiz` — координаты относительно квадрокоптера без учета наклонов по тангажу и крену: красная, синия и зеленая линии на иллюстрации.
* `map` — координаты относительно точки инициализации полетного контроллера: белая сетка на иллюстрации;
* `base_link` — координаты относительно квадрокоптера: схематичное изображение квадрокоптера на иллюстрации;
* `body` — координаты относительно квадрокоптера без учета наклонов по тангажу и крену: красная, синия и зеленая линии на иллюстрации.
> **Hint** В соответствии с [соглашением](http://www.ros.org/reps/rep-0103.html), для фреймов, связанных с коптером, ось X направлена вперед, Y налево и Z вверх.

View File

@@ -1,24 +1,24 @@
# Теория
[**Урок №1** «Знакомство. Принципы проектирования и строение мультикоптеров»](https://github.com/CopterExpress/clever/blob/master/docs/lesson1.md)
[**Урок №1** «Знакомство. Принципы проектирования и строение мультикоптеров»](https://github.com/CopterExpress/clever/blob/master/docs/ru/lesson1.md)
[**Урок №2** «Основы электричества»](https://github.com/CopterExpress/clever/blob/master/docs/lesson2.md)
[**Урок №2** «Основы электричества»](https://github.com/CopterExpress/clever/blob/master/docs/ru/lesson2.md)
[**Урок №3** «Теория пайки»](https://github.com/CopterExpress/clever/blob/master/docs/lesson3.md)
[**Урок №3** «Теория пайки»](https://github.com/CopterExpress/clever/blob/master/docs/ru/lesson3.md)
[**Урок №4** «Аэродинамика полета. Пропеллер»](https://github.com/CopterExpress/clever/blob/master/docs/lesson4.md)
[**Урок №4** «Аэродинамика полета. Пропеллер»](https://github.com/CopterExpress/clever/blob/master/docs/ru/lesson4.md)
[**Урок №5** «Бесколлекторные двигатели и регуляторы их хода»](https://github.com/CopterExpress/clever/blob/master/docs/lesson5.md)
[**Урок №5** «Бесколлекторные двигатели и регуляторы их хода»](https://github.com/CopterExpress/clever/blob/master/docs/ru/lesson5.md)
[**Урок №6** «Основы электромагнетизма. Типы двигателей»](https://github.com/CopterExpress/clever/blob/master/docs/lesson6.md)
[**Урок №6** «Основы электромагнетизма. Типы двигателей»](https://github.com/CopterExpress/clever/blob/master/docs/ru/lesson6.md)
[**Урок №7** «Принцип работы, типы и устройство аккумуляторов»](https://github.com/CopterExpress/clever/blob/master/docs/lesson7.md)
[**Урок №7** «Принцип работы, типы и устройство аккумуляторов»](https://github.com/CopterExpress/clever/blob/master/docs/ru/lesson7.md)
[**Урок №8** «Управление полётом мультикоптера. Принцип функционирования полётного контроллера. ПИД регуляторы»](https://github.com/CopterExpress/clever/blob/master/docs/lesson8.md)
[**Урок №8** «Управление полётом мультикоптера. Принцип функционирования полётного контроллера. ПИД регуляторы»](https://github.com/CopterExpress/clever/blob/master/docs/ru/lesson8.md)
[**Урок №9** «Основы радиосвязи. Принцип работы радиоаппаратуры управления»](https://github.com/CopterExpress/clever/blob/master/docs/lesson9.md)
[**Урок №9** «Основы радиосвязи. Принцип работы радиоаппаратуры управления»](https://github.com/CopterExpress/clever/blob/master/docs/ru/lesson9.md)
[**Урок №10** «Аналоговая и цифровая видеотрансляция. Применяемые камеры, радиопередатчики иприёмники»](https://github.com/CopterExpress/clever/blob/master/docs/lesson10.md)
[**Урок №10** «Аналоговая и цифровая видеотрансляция. Применяемые камеры, радиопередатчики иприёмники»](https://github.com/CopterExpress/clever/blob/master/docs/ru/lesson10.md)
## Видеоуроки

View File

@@ -18,6 +18,8 @@
[![Etcher](../assets/etcher.gif)](https://etcher.io)
После записи образа на SD-карту, вы можете подключаться к [Клеверу по Wi-Fi](wifi.md), получать [доступ по SSH](ssh.md) и использовать остальные функции.
## Версия образа
Версию установленного образа можно узнать в файле `/etc/clever_version`:

View File

@@ -1,9 +1,9 @@
Управление Клевером со смартфона
===
<a href="https://itunes.apple.com/ru/app/clever-rc/id1396166572?mt=8"><img src="../assets/appstore.svg"></a>
<a href="https://itunes.apple.com/ru/app/clever-rc/id1396166572?mt=8"><img src="../assets/appstore.svg"></a><a href="https://play.google.com/store/apps/details?id=express.copter.cleverrc"><img src="../assets/google_play.png" width="15%"></a>
Для управления Клевером со смартфона через Wi-Fi необходимо установить приложение  [iOS](https://itunes.apple.com/ru/app/clever-rc/id1396166572?mt=8), Android (*work-in-progress*).
Для управления Клевером со смартфона через Wi-Fi необходимо установить приложение [iOS](https://itunes.apple.com/ru/app/clever-rc/id1396166572?mt=8), [Android](https://play.google.com/store/apps/details?id=express.copter.cleverrc).
![CLEVER RC](../assets/IMG_4397.PNG)
@@ -46,7 +46,7 @@ sudo systemctl restart clever
Подключите смартфон к [Wi-Fi](wifi.md) сети Клевера (`CLEVER-xxxx`). Приложение должно подключиться с коптеру автоматически. При успешном подключении должны отобразиться текущий [режим](modes.md) и заряд батареи.
Стики на экране приложения работают так же, как и реальные стики. Для арма коптера подержите левый стик в правом нижнем углу на протяжении нескольких секунд. Для дизарма  в левом нижнем углу.
Стики на экране приложения работают так же, как и реальные стики. Для арма коптера подержите левый стик в правом нижнем углу на протяжении нескольких секунд. Для дизарма в левом нижнем углу.
Неисправности
---

View File

@@ -31,7 +31,7 @@ export ROS_IP=192.168.11.1
### Визуализация положения коптера
В качестве reference frame рекомендуется установить фрейм `local_origin`. Для визуализации коптера добавьте визуализационные маркеры из топика `/vehicle_markers`. Для визуализации камеры коптера добавьте визуализационные маркеры из топика `/main_camera/camera_markers`.
В качестве reference frame рекомендуется установить фрейм `map`. Для визуализации коптера добавьте визуализационные маркеры из топика `/vehicle_markers`. Для визуализации камеры коптера добавьте визуализационные маркеры из топика `/main_camera/camera_markers`.
Результат визуализации коптера и камеры представлен ниже:
@@ -43,6 +43,14 @@ export ROS_IP=192.168.11.1
Axis или Grid настроенный на фрейм `aruco_map` будут визуализировать расположение [карты ArUco-меток](aruco.md).
### jsk_rviz_plugins
Рекомендуется также установка набора дополнительных полезных плагинов для rviz [jsk_rviz_plugins](https://jsk-docs.readthedocs.io/en/latest/jsk_visualization/doc/jsk_rviz_plugins/index.html). Это набор позволяет визуализировать топики типа `TwistStamped` (скорость), `CameraInfo`, `PolygonArray` и многое другое. Для установки используйте команду:
```bash
sudo apt-get install ros-kinetic-jsk-visualization
```
Запуск инструментов rqt
---
@@ -60,11 +68,8 @@ ROS_MASTER_URI=http://192.168.11.1:11311 rqt
ROS_MASTER_URI=http://192.168.11.1:11311 rqt_image_view
```
jsk_rviz_plugins
---
Краткое описание полезных rqt-плагинов:
Рекомендуется также установка набора дополнительных полезных плагинов для rviz [jsk_rviz_plugins](https://jsk-docs.readthedocs.io/en/latest/jsk_visualization/doc/jsk_rviz_plugins/index.html). Это набор позволяет визуализировать топики типа `TwistStamped` (скорость), `CameraInfo`, `PolygonArray` и многое другое. Для установки используйте команду:
```bash
sudo apt-get install ros-kinetic-jsk-visualization
```
* `rqt_image_view` просмотр изображений из топиков типа `sensor_msgs/Image`;
* `rqt_multiplot` построение графиков по данным из произвольным топиков (установка: `sudo apt-get install ros-kinetic-rqt-multiplot`);
* Bag работа с [Bag-файлами](http://wiki.ros.org/rosbag).

View File

@@ -144,7 +144,7 @@
2. Устанавливаем БПЛА на ровную поверхность и кликаем OK.
3. Ждем окончания калибровки.
![Калибровка компаса](../assets/calibrategyro.jpg)
![Калибровка гироскопа](../assets/calibrategyro.jpg)
> *Warning* Во время калибровки БПЛА не должен менять своего положения, шататься и т.д.

View File

@@ -1,26 +1,14 @@
Simple offboard
===
> **Note** Документация для версий [образа](microsd_images.md), начиная с **0.15**. Для более ранних версий см. [документацию для версии **0.14**](https://github.com/CopterExpress/clever/blob/v0.14/docs/ru/simple_offboard.md).
Модуль `simple_offboard` пакета `clever` предназначен для упрощенного программирования автономного дрона ([режим](modes.md) `OFFBOARD`). Он позволяет устанавливать желаемые полетные задачи и автоматически трансформирует [систему координат](frames.md).
`simple_offboard` является высокоуровневым способом взаимодействия с полетным контроллером. Для более низкоуровневой работы см. [mavros](mavros.md).
Основные сервисы `get_telemetry` (получение всей телеметрии), `navigate` (полет в заданную точку по прямой), `navigate_global` (полет в глобальную точку по прямой), `land` (переход в режим посадки).
Общие для сервисов параметры:
* `auto_arm` = `true`/`false` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит**);
* `frame_id` — система координат в TF2, в которой заданы координаты и рысканье (yaw), [описание систем координат](frames.md);
* `update_frame` — считать ли систему координат изменяющейся (например, `false` для `local_origin`, `fcu`, `fcu_horiz`, `true` для `marker_map`);
* `x`, `y` горизонтальные координаты в системе координат `frame_id` *(м)*;
* `z` — высота в системе координат `frame_id` *(м)*;
* `lat`, `lon` широта и долгота *(градусы)*;
* `yaw` — рысканье в радианах в системе координат `frame_id` (0 коптер смотрит по оси X);
* `yaw_rate` — угловая скорость по рысканью в радианах в секунду (против часовой), `yaw` должен быть установлен в NaN;
* `thrust` — уровень газа от 0 (нет газа) до 1 (полный газ).
> **Warning** API модуля `simple_offboard` на данный момент нестабилен и может измениться.
Использование из языка Python
---
@@ -59,11 +47,11 @@ release = rospy.ServiceProxy('release', Trigger)
Параметры:
* `frame_id`  [фрейм](frames.md) для значений `x`, `y`, `z`, `vx`, `vy`, `vz`. Пример: `local_origin`, `fcu_horiz`, `aruco_map`.
* `frame_id`  [система координат](frames.md) для значений `x`, `y`, `z`, `vx`, `vy`, `vz`. Пример: `map`, `body`, `aruco_map`. Значение по умолчанию: `map`.
Формат ответа:
* `frame_id`  фрейм;
* `frame_id`  система координат;
* `connected` есть ли подключение к <abbr title="Flight Control Unit, полетный контроллер">FCU</abbr>;
* `armed` состояние `armed` винтов (винты включены, если true);
* `mode` текущий [полетный режим](modes.md);
@@ -73,7 +61,7 @@ release = rospy.ServiceProxy('release', Trigger)
* `vx, vy, vz` скорость коптера *(м/с)*;
* `pitch`  угол по тангажу *(радианы)*;
* `roll` угол по крену *(радианы)*;
* `yaw` – угол по рысканью в фрейме `frame_id`;
* `yaw` – угол по рысканью *(радианы)*;
* `pitch_rate` – угловая скорость по тангажу *(рад/с)*;
* `roll_rate` – угловая скорость по крену *(рад/с)*;
* `yaw_rate` – угловая скорость по рысканью *(рад/с)*;
@@ -118,19 +106,19 @@ rosservice call /get_telemetry "{frame_id: ''}"
Параметры:
* `x`, `y`, `z` координаты в системе `frame_id` *(м)*;
* `x`, `y`, `z` координаты *(м)*;
* `yaw` угол по рысканью *(радианы)*;
* `yaw_rate` угловая скорость по рысканью (применяется при установке yaw в `NaN`) *(рад/с)*;
* `speed` скорость полета (скорость движения setpoint) *(м/с)*;
* `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит**);
* `frame_id`, `update_frame`.
* `frame_id`  [система координат](frames.md), в которой заданы `x`, `y`, `z` и `yaw` (по умолчанию: `map`).
> **Note** Для полета без изменения угла по рыскаью достаточно установить `yaw` в `NaN` (значение угловой скорости по-умолчанию 0).
Взлет на высоту 1.5 м со скоростью взлета 0.5 м/с:
```python
navigate(x=0, y=0, z=1.5, speed=0.5, frame_id='fcu_horiz', auto_arm=True)
navigate(x=0, y=0, z=1.5, speed=0.5, frame_id='body', auto_arm=True)
```
Полет по прямой в точку 5:0 (высота 2) в локальной системе координат со скоростью 0.8 м/с (рысканье установится в 0):
@@ -148,37 +136,37 @@ navigate(x=5, y=0, z=3, speed=0.8, yaw=float('nan'))
Полет вправо относительно коптера на 3 м:
```python
navigate(x=0, y=-3, z=0, speed=1, frame_id='fcu_horiz')
navigate(x=0, y=-3, z=0, speed=1, frame_id='body')
```
Повернуться на 90 градусов против часовой:
```python
navigate(yaw=math.radians(-90), frame_id='fcu_horiz')
navigate(yaw=math.radians(-90), frame_id='body')
```
Полет в точку 3:2 (высота 2) в системе координат [маркерного поля](aruco.md) со скоростью 1 м/с:
```python
navigate(x=3, y=2, z=2, speed=1, frame_id='aruco_map', update_frame=True)
navigate(x=3, y=2, z=2, speed=1, frame_id='aruco_map')
```
Вращение на месте со скоростью 0.5 рад/c (против часовой):
```python
navigate(x=0, y=0, z=0, yaw=float('nan'), yaw_rate=0.5, frame_id='fcu_horiz')
navigate(x=0, y=0, z=0, yaw=float('nan'), yaw_rate=0.5, frame_id='body')
```
Полет вперед 3 метра со скоростью 0.5 м/с, вращаясь по рысканью со скоростью 0.2 рад/с:
```python
navigate(x=3, y=0, z=0, speed=0.5, yaw=float('nan'), yaw_rate=0.2, frame_id='fcu_horiz')
navigate(x=3, y=0, z=0, speed=0.5, yaw=float('nan'), yaw_rate=0.2, frame_id='body')
```
Взлет на высоту 2 м (командная строка):
```bash
rosservice call /navigate "{x: 0.0, y: 0.0, z: 2, yaw: 0.0, yaw_rate: 0.0, speed: 0.5, frame_id: 'fcu_horiz', update_frame: false, auto_arm: true}"
rosservice call /navigate "{x: 0.0, y: 0.0, z: 2, yaw: 0.0, yaw_rate: 0.0, speed: 0.5, frame_id: 'body', auto_arm: true}"
```
### navigate_global
@@ -188,31 +176,31 @@ rosservice call /navigate "{x: 0.0, y: 0.0, z: 2, yaw: 0.0, yaw_rate: 0.0, speed
Параметры:
* `lat`, `lon` широта и долгота *(градусы)*;
* `z` высота в системе координат `frame_id` *(м)*;
* `z` высота *(м)*;
* `yaw` угол по рысканью *(радианы)*;
* `yaw_rate` угловая скорость по рысканью (при установке yaw в `NaN`) *(рад/с)*;
* `speed` скорость полета (скорость движения setpoint) *(м/с)*;
* `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит**);
* `frame_id`, `update_frame`.
* `frame_id`  [система координат](frames.md), в которой заданы `z` и `yaw` (по умолчанию: `map`).
> **Note** Для полета без изменения угла по рыскаью достаточно установить `yaw` в `NaN` (значение угловой скорости по-умолчанию 0).
Полет в глобальную точку со скоростью 5 м/с, оставаясь на текущей высоте (`yaw` установится в 0, коптер сориентируется передом на восток):
```python
navigate_global(lat=55.707033, lon=37.725010, z=0, speed=5, frame_id='fcu_horiz')
navigate_global(lat=55.707033, lon=37.725010, z=0, speed=5, frame_id='body')
```
Полет в глобальную точку без изменения угла по рысканью (`yaw` = `NaN`, `yaw_rate` = 0):
```python
navigate_global(lat=55.707033, lon=37.725010, z=0, speed=5, yaw=float('nan'), frame_id='fcu_horiz')
navigate_global(lat=55.707033, lon=37.725010, z=0, speed=5, yaw=float('nan'), frame_id='body')
```
Полет в глобальную точку (командная строка):
```bash
rosservice call /navigate_global "{lat: 55.707033, lon: 37.725010, z: 0.0, yaw: 0.0, yaw_rate: 0.0, speed: 5.0, frame_id: 'fcu_horiz', update_frame: false, auto_arm: false}"
rosservice call /navigate_global "{lat: 55.707033, lon: 37.725010, z: 0.0, yaw: 0.0, yaw_rate: 0.0, speed: 5.0, frame_id: 'body', auto_arm: false}"
```
### set_position
@@ -223,34 +211,34 @@ rosservice call /navigate_global "{lat: 55.707033, lon: 37.725010, z: 0.0, yaw:
Параметры:
* `x`, `y`, `z` координаты точки в системе координат `frame_id` *(м)*;
* `x`, `y`, `z` координаты точки *(м)*;
* `yaw` угол по рысканью *(радианы)*;
* `yaw_rate` угловая скорость по рысканью (при установке yaw в NaN) *(рад/с)*;
* `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит**);
* `frame_id`, `update_frame`.
* `frame_id`  [система координат](frames.md), в которой заданы `x`, `y`, `z` и `yaw` (по умолчанию: `map`).
Зависнуть на месте:
```python
set_position(frame_id='fcu_horiz')
set_position(frame_id='body')
```
Назначить целевую точку на 3 м выше текущей позиции:
```python
set_position(x=0, y=0, z=3, frame_id='fcu_horiz')
set_position(x=0, y=0, z=3, frame_id='body')
```
Назначить целевую точку на 1 м впереди текущей позиции:
```python
set_position(x=1, y=0, z=0, frame_id='fcu_horiz')
set_position(x=1, y=0, z=0, frame_id='body')
```
Вращение на месте со скоростью 0.5 рад/c:
```python
set_position(x=0, y=0, z=0, frame_id='fcu_horiz', yaw=float('nan'), yaw_rate=0.5)
set_position(x=0, y=0, z=0, frame_id='body', yaw=float('nan'), yaw_rate=0.5)
```
### set_velocity
@@ -261,34 +249,32 @@ set_position(x=0, y=0, z=0, frame_id='fcu_horiz', yaw=float('nan'), yaw_rate=0.5
* `yaw` угол по рысканью *(радианы)*;
* `yaw_rate` угловая скорость по рысканью (при установке yaw в NaN) *(рад/с)*;
* `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит**);
* `frame_id`, `update_frame`.
* `frame_id`  [система координат](frames.md), в которой заданы `vx`, `vy`, `vz` и `yaw` (по умолчанию: `map`).
> **Note** Параметр `frame_id` определяет только ориентацию результирующего вектора скорости, но не его длину.
Полет вперед (относительно коптера) со скоростью 1 м/с:
```python
set_velocity(vx=1, vy=0.0, vz=0, frame_id='fcu_horiz')
set_velocity(vx=1, vy=0.0, vz=0, frame_id='body')
```
Один из вариантов полета по кругу:
```python
set_velocity(vx=0.4, vy=0.0, vz=0, yaw=float('nan'), yaw_rate=0.4, frame_id='fcu_horiz', update_frame=True)
set_velocity(vx=0.4, vy=0.0, vz=0, yaw=float('nan'), yaw_rate=0.4, frame_id='body')
```
### set_attitude
Установить тангаж, крен, рысканье и уровень газа (примерный аналог управления в [режиме `STABILIZED`](modes.md)). Данный сервис может быть использован для более низкоуровнего контроля поведения коптера либо для управления коптером при отсутствии источника достоверных данных о его позиции.
> **Note** Параметр `frame_id` определяет только систему координат, в которой задается рысканье (`yaw`).
Параметры:
* `pitch`, `roll`, `yaw` – необходимый угол по тангажу, крену и рысканью *(радианы)*;
* `thrust` – уровень газа от 0 (нет газа) до 1 (полный газ);
* `thrust` – уровень газа от 0 (нет газа, пропеллеры остановлены) до 1 (полный газ);
* `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит**);
* `frame_id`, `update_frame`.
* `frame_id`  [система координат](frames.md), в которой задан `yaw` (по умолчанию: `map`).
### set_rates
@@ -297,14 +283,14 @@ set_velocity(vx=0.4, vy=0.0, vz=0, yaw=float('nan'), yaw_rate=0.4, frame_id='fcu
Параметры:
* `pitch_rate`, `roll_rate`, `yaw_rate` – угловая скорость по танажу, крену и рыканью *(рад/с)*;
* `thrust` уровень газа от 0 (нет газа) до 1 (полный газ).
* `thrust` уровень газа от 0 (нет газа, пропеллеры остановлены) до 1 (полный газ).
* `auto_arm` перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит**);
### land
Перевести коптер в [режим](modes.md) посадки (`AUTO.LAND` или аналогичный).
> **Note** Для автоматического отключения винтов после посадки PX4-параметр `COM_DISARM_LAND` должен быть установлен в значение > 0.
> **Note** Для автоматического отключения винтов после посадки [параметр PX4](px4_parameters.md) `COM_DISARM_LAND` должен быть установлен в значение > 0.
Посадка коптера:
@@ -321,9 +307,11 @@ if res.success:
rosservice call /land "{}"
```
<!--
### release
Перестать публиковать setpoint'ы коптеру (отпустить управление). Необходим для продолжения контроля средствами [MAVROS](mavros.md).
-->
Дополнительные материалы
------------------------

View File

@@ -39,7 +39,7 @@ tolerance = 0.2 # точность проверки высоты (м)
start = get_telemetry()
# Взлетаем на 2 м
print navigate(z=z, speed=0.5, frame_id='fcu_horiz', auto_arm=True)
print navigate(z=z, speed=0.5, frame_id='body', auto_arm=True)
# Ожидаем взлета
while True:
@@ -100,14 +100,14 @@ tf_listener = tf2_ros.TransformListener(tf_buffer)
# Создаем объект PoseStamped (либо получаем из топика):
pose = PoseStamped()
pose.header.frame_id = 'local_origin' # фрейм, в котором задана позиция
pose.header.frame_id = 'map' # фрейм, в котором задана позиция
pose.header.stamp = rospy.get_rostime() # момент времени, для которого задана позиция (текущее время)
pose.pose.position.x = 1
pose.pose.position.y = 2
pose.pose.position.z = 3
pose.pose.orientation.w = 1
frame_id = 'fcu' # целевой фрейм
frame_id = 'base_link' # целевой фрейм
transform_timeout = rospy.Duration(0.2) # таймаут ожидания транформации
# Преобразовываем позицию из старого фрейма в новый:
@@ -252,6 +252,22 @@ rospy.Subscriber('mavros/rc/in', RCIn, rc_callback)
rospy.spin()
```
### # {#set_mode}
Сменить [режим полета](modes.md) на произвольный:
```python
from mavros_msgs.srv import SetMode
# ...
set_mode = rospy.ServiceProxy('mavros/set_mode', SetMode)
# ...
set_mode(custom_mode='STABILIZED')
```
### # {#flip}
Флип:

View File

@@ -1,11 +1,15 @@
# Работа с ультразвуковым дальномером
Ультразвуковой дальномер (*«сонар»*) — это датчик расстояния, принцип действия которого основан на измерении времени распространения звуковой волны (с частотой около 40 Гц) до препятствия и обратно. Сонар может измерять расстояние до 1,53 м с точностью до нескольких сантиметров.
Ультразвуковой дальномер (*«сонар»*) — это датчик расстояния, принцип действия которого основан на измерении времени распространения звуковой волны (с частотой около 40 кГц) до препятствия и обратно. Сонар может измерять расстояние до 1,53 м с точностью до нескольких сантиметров.
## HC-SR04
## Дальномер HC-SR04
<img src="../assets/hc-sr04.jpg" alt="hc-sr04" width=200>
## Установка
Дальномер закрепляется к корпусу с помощью двухстороннего скотча. Для получения приемлемых результатов необходимо использование виброразвязки. В качестве виброразвязки можно использовать кусок поролона.
### Подключение
Подключите HC-SR04 к Raspberry Pi согласно схеме подключения. Используйте резисторы на 1,0 и 2,2 кОм и любые свободные GPIO-пины, например 23 и 24:
@@ -20,7 +24,7 @@
### Чтение данных
Чтобы считать данных с дальномера HC-SR04 используется библиотека для работы с <abbr title="General-Purpose Input/Output – пины ввода/вывода общего назначения">GPIO</abbr>  [`pigpio`](http://abyz.me.uk/rpi/pigpio/index.html). Эта библиотека предустановлена на [образе Клевера](microsd_images.md), начиная с версии **v0.14**. Для более старых версий образа используйте [инструкцию по установке](http://abyz.me.uk/rpi/pigpio/download.html).
Чтобы считать данные с дальномера HC-SR04, используется библиотека для работы с <abbr title="General-Purpose Input/Output – пины ввода/вывода общего назначения">GPIO</abbr>  [`pigpio`](http://abyz.me.uk/rpi/pigpio/index.html). Эта библиотека предустановлена на [образе Клевера](microsd_images.md), начиная с версии **v0.14**. Для более старых версий образа используйте [инструкцию по установке](http://abyz.me.uk/rpi/pigpio/download.html).
Для работы с `pigpio` необходимо запустить соответствующий демон:
@@ -108,7 +112,7 @@ while True:
Исходный код ROS-ноды, использовавшейся для построения графика можно найти [на Gist](https://gist.github.com/okalachev/feb2d7235f5c9636802c3cda43add253).
## RCW-0001
## Дальномер RCW-0001
<img src="../assets/rcw-0001.jpg" width=200>
@@ -119,11 +123,11 @@ while True:
Пример полетной программы с использованием [simple_offboard](simple_offboard.md), которая заставляет коптер лететь вперед, пока подключенный ультразвуковой дальномер не задетектирует препятствие:
```python
set_velocity(x=0.5, frame_id='fcu_horiz', auto_arm=True) # полет вперед со скоростью 0.5 мс
set_velocity(x=0.5, frame_id='body', auto_arm=True) # полет вперед со скоростью 0.5 мс
while True:
if read_distance_filtered() < 1:
# если препятствие ближе, чем в 1 м, зависаем в точке
set_position(x=0, y=0, z=0, frame_id='fcu_horiz')
set_position(x=0, y=0, z=0, frame_id='body')
rospy.sleep(0.1)
```

View File

@@ -1,6 +1,6 @@
# Просмотр изображений с камер
Для просмотра изображений с камер можно воспользовться [rviz](rviz.md), rqt, или смотреть их через браузер, используя web\_video\_server.
Для просмотра изображений с камер (или других ROS-топиков) можно воспользовться [rviz](rviz.md), rqt, или смотреть их через браузер, используя web\_video\_server.
См. подробнее про [использование rqt](rviz.md).
@@ -22,7 +22,7 @@ sudo systemctl restart clever
### Просмотр
Для просмотра видеострима нужно [подключиться к Wi-Fi](wifi.md) Клевера \(`CLEVER-xxxx`\), перейти на страницу [http://192.168.11.1:8080/](http://192.168.11.1:8080/) и выбрать топик камеры.
Для просмотра видеострима нужно [подключиться к Wi-Fi](wifi.md) Клевера \(`CLEVER-xxxx`\), перейти на страницу [http://192.168.11.1:8080/](http://192.168.11.1:8080/) и выбрать топик.
![Просмотр web_video_server](../assets/web_video_server.png)
@@ -33,3 +33,25 @@ http://192.168.11.1:8080/stream_viewer?topic=/main_camera/image_raw&quality=1
По URL выше будет доступен стрим с основной камеры в минимальном возможном качестве.
Также доступны параметры `width`, `height` и другие. Подробнее о `web_video_server`: http://wiki.ros.org/web_video_server.
## Просмотр через rqt_image_view
Для просмотра изображений через инструменты rqt необходим компьютер с установленной Ubuntu 16.04 и [ROS Kinetic](http://wiki.ros.org/kinetic/Installation/Ubuntu).
[Подключитесь к Wi-Fi сети Клевера](wifi.md) и запустите `rqt_image_view` с указанием его IP-адреса:
```bash
ROS_MASTER_URI=http://192.168.11.1:11311 rqt_image_view
```
Выберите топик для просмотра, например `/main_camera/image_raw`:
![rqt_image_view](../assets/rqt_image_view.jpg)
Для снижения нагрузки на сеть и уменьшения задержки используйте сжатый вариант топика  `/main_camera/image_raw/compressed`.
Для изменения настроек сжатия используйте rqt-плагин Dynamic Reconfigure:
![rqt_image_view+rqt_dynamic_reconfigure](../assets/rqt_image_view_dyn_rec.jpg)
См. [подробнее об rviz и rqt](rviz.md).

View File

@@ -8,3 +8,9 @@
<img src="../assets/ssid.png" width="300px" alt="Wi-Fi SSID">
Для изменения настроек Wi-Fi или получения более детальной информации о устройстве сети на Raspberry Pi прочитайте эту [статью](network.md).
## Веб-интерфейс
После подключения к Клеверу по адресу http://192.168.11.1 будет доступен веб-интерфейс. В нем доступны основные веб-инструменты Клевера: просмотр топиков с изображениями, веб-терминал (Butterfly) а также полная копия данной документации.
![web interface](../assets/web_interface.png)