Files
clover/docs/en/simple_offboard.md
Oleg Kalachev f77843f4a5 Move ROS Noetic (#327)
* builder: Use 64-bit Raspberry Pi OS

* travis: Use 64-bit builder

* builder: Don't try to install Melodic packages on Noetic

* clover: Use package version 3, update dependencies

* travis: Enable Noetic build

* standalone_install: Auto-select Python, ROS distro

* builder: Use variable substitution for ROS_DISTRO

* builder: Add Noetic package definitions

* builder: Use variable substitution for validation

* aruco_pose, clover: Allow compiling against OpenCV 3 and 4

* builder: Add proper Noetic repository

* builder: Don't force Tornado version

Assume rosbridge_suite depends on the right one.

* builder: Install packages for Python 3

* builder/test: Use Python3 interpreter for ROS tests

TODO (?): add tests for Python2?

* builder: Use Python 3 syntax for Python 3 tests

* builder: Install rpi_ws281x for Python3

* standalone_install: Use proper Python for pytest

* builder: Install espeak for python3

* builder: Use proper path for roscore

* builder: Install rosdep, etc. for python3

* builder: Run Clever/Clover test with Python3

* builder: Use Python3 for Clever compat layer

* builder: Enable OpenCV 4.2 repository

* builder: Force versions for ROS packages that use OpenCV

Also, hold their versions so that they don't get updated for no reason.

* aruco_pose/draw: Replace OpenCV projection code with a rewrite

* builder: Don't try to install compressed_transport twice

* clover: Fix importing urllib for Python3

* aruco_pose, clover: Expose Python scripts through CMake

* clover/selfcheck: Be more python3-compatible

This is basically commit a01d199890 from buster-python3, not sure if it aged well.

* roswww_static: Add python script installation

* clover_blocks: Use Python3 syntax for exec

* aruco_pose: Remove unused code

* Melodic => Noetic in some docs

* docs: add 0.22 migration article

* docs: remove unneeded comment

* docs: python 3 updates

* docs: python 3 update in auto_setup article

* docs: add ROS Noetic transition note

* aruco.launch: add placement, length and map arguments

* genmap.py: add -o argument for output file name

* docs: use -o argument of genmap.py

* simple_offboard: correctly check manual control timeout, separate it from kill switch check

* blocks: force led_leds index to int

* docs: update and fix 0.22 migration articles

* blocks: fix set_leds with color-typed argument

* aruco_gen: Open file in binary mode for Python3 compatibility

* clover: Use proper variable in aruco.launch

* led: change default number of leds to 72

* aruco_pose: Make sure there are no undefined symbols

Also, compile in apriltag_quad_thresh.cpp - it contains some of the functions referenced
in aruco.cpp, which would otherwise be undefined.

* aruco_pose: Make vendored library compatible with older OpenCVs

* aruco_pose, clover: Reduce the amount of OpenCV libs requested

* aruco_pose, clover: Move subscriptions to the end of init

* aruco_pose: Don't expose vendored library symbols

* aruco_pose: Simplify dynamic parameter callback setting

* builder: Build with debug symbols

* clover: Attempt to respawn dying nodelets

* Change Raspberry Pi OS to latest armhf, use packages.coex.tech as a source

* Add CRYPTOGRAPHY_DONT_BUILD_RUST=1

* Fix Node.js installation

* image: use older CMake (3.13.4-1)
Fixing https://travis-ci.org/github/CopterExpress/clover/jobs/764367665#L6984

* image: update Raspberry Pi OS to 2021-03-04

* image: bring back moving ld.so.preload out of the way while building

* Fix pthreads ld error

* Try to fix pthreads ld error

* Another attempt to fix pthreads ld error

* Yet another attempt to fix pthreads ld error

* Try to fix

* Be verbose

* Temporarily disable rc and camera_markers building

* Fix standalone-install

* Revert "Temporarily disable rc and camera_markers building"

This reverts commit e119220e91.

* Try to fix

* Try to fix

* Revert "image: use older CMake (3.13.4-1)"

This reverts commit df28da0060.

* Revert "Revert "image: use older CMake (3.13.4-1)""

This reverts commit a28c774e8f.

* Verbosity

* Debugging

* More debugging

* Display all CMake variables

* Try to fix

* Another try to fix

* Revert "Another try to fix"

This reverts commit 5a4c3a0da7.

* Another try to fix

* And another

* And yet another

* Continue...

* Cleanup

* Sources lists cleanup

* More cleanup

* Restore .git directory in clover repo

* Fix building documentation

* Fix documentation building in image

* Trigger build to update ws281x package

* Test

* Disable unneeded hack

* Disable hack

* image: add cmake-modules package

* www: add viewing clover.err file from web interface

* Remove hacks

* Show nodelet version

* docs: add packages article

* image: add image-view package for recording video from topics

* Minor fix

* CI: add Docker authentication on image build

* CI: fix Bash syntax

* CI: fix authentication in Docker

* CI: move Melodic build and editorconfig-lint to GitHub Actions (#331)

* Create main.yml

* Update main.yml

* Disable native Melodic build in Travis

* Run editorconfig-lint in Actions

* Let wget be less verbose

* Test

* Test ok

* Disable editorconfig-lint in Travis

* docs: add links to hardware sources

* CI: move image building to GitHub actions (#335)

* Start working on building image in GitHub actions

* Trigger GitHub on push to any branch

* Fix TRAVIS_TAG

* Add compress image step

* Disable image build in Travis

* Add upload image step

* Fix compress image

* Fix

* Fix

* Minor fix

* Trigger build on tag

* Show images sizes not in human format

* Upload only built image

* Make prerelease

* Upload assets on release not on tags

* readme: change build badge to GitHub Actions

* readme: add support chat badge

* CI: move documentation building to GitHub Actions (#337)

* CI: change docs target branch to actions

* CI: change docs target branch to master

* CI: use gh-pages target branch for docs

* CI: split up to several workflows

* CI: remove .travis.yml

* CI: change apt to apt-get

* CI: push documentation site to the main repo

* builder: less verbosity

* CI: add new key for apt
Fixing https://github.com/CopterExpress/clover/runs/2700356960#step:3:74

* Add Noetic building to CI

* Add test for QR recognition

* Fix

* Move QR recognition test to a separate file

* Fix QR recognition code for Python 3

* Import SetLEDs, LEDStateArray, LEDState in tests

* Add more imports to tests
(from documentation)

* Fix permissions

* Fix standalone-install for Python 2

* Fix QR recognition test

* Don’t use ROS for QR recognition test

* docs: remove non-working example

* Make v4l2 device file an argument in main_camera.launch

* Wait for v4l2 device before launching the camera driver

* Use exec in waitfile

* Transfer main camera nodelet manager to main_camera.launch

* Update cv_camera version to 0.5.1

* docs: minor fix

* Revert cv_camera to 0.5.0

* Update Raspberry Pi OS to 2021-05-07

* docs: add link to the last ROS Melodic version.

Co-authored-by: Alexey Rogachevskiy <sfalexrog@gmail.com>
2021-06-08 20:13:46 +03:00

326 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Simple OFFBOARD
===
> **Note** In the image version **0.20** `clever` package was renamed to `clover`. See [previous version of the article](https://github.com/CopterExpress/clover/blob/v0.19/docs/en/simple_offboard.md) for older images.
<!-- -->
> **Hint** We recommend using our [custom PX4 firmware for Clover](firmware.md#modified-firmware-for-clover) for autonomous flights.
The `simple_offboard` module of the `clover` package is intended for simplified programming of the autonomous drone flight (`OFFBOARD` [flight mode](modes.md)). It allows setting the desired flight tasks, and automatically transforms [coordinates between frames](frames.md).
`simple_offboard` is a high level system for interacting with the flight controller. For a more low level system, see [mavros](mavros.md).
Main services are [`get_telemetry`](#gettelemetry) (receive telemetry data), [`navigate`](#navigate) (fly to a given point along a straight line), [`navigate_global`](#navigateglobal) (fly to a point specified as latitude and longitude along a straight line), [`land`](#land) (switch to landing mode).
Python examples
---
You need to create proxies for services before calling them. Use the following template for your programs:
```python
import rospy
from clover import srv
from std_srvs.srv import Trigger
rospy.init_node('flight') # 'flight' is name of your ROS node
get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry)
navigate = rospy.ServiceProxy('navigate', srv.Navigate)
navigate_global = rospy.ServiceProxy('navigate_global', srv.NavigateGlobal)
set_position = rospy.ServiceProxy('set_position', srv.SetPosition)
set_velocity = rospy.ServiceProxy('set_velocity', srv.SetVelocity)
set_attitude = rospy.ServiceProxy('set_attitude', srv.SetAttitude)
set_rates = rospy.ServiceProxy('set_rates', srv.SetRates)
land = rospy.ServiceProxy('land', Trigger)
```
Unused proxy functions may be removed from the code.
API description
---
> **Note** Omitted numeric parameters are set to 0.
### get_telemetry
Obtains complete telemetry of the drone.
Parameters:
* `frame_id` [frame](frames.md) for values `x`, `y`, `z`, `vx`, `vy`, `vz`. Example: `map`, `body`, `aruco_map`. Default value: `map`.
Response format:
* `frame_id` — frame;
* `connected` whether there is a connection to <abbr title="Flight Control Unit flight controller">FCU</abbr>;
* `armed` - drone arming state (armed if true);
* `mode` current [flight mode](modes.md);
* `x, y, z` — local position of the drone *(m)*;
* `lat, lon` drone latitude and longitude *(degrees)*, requires [GPS](gps.md) module;
* `alt` altitude in the global coordinate system (according to [WGS-84](https://ru.wikipedia.org/wiki/WGS_84) standard, not <abbr title="Above Mean Sea Level">AMSL</abbr>!), requires [GPS](gps.md) module;
* `vx, vy, vz` drone velocity *(m/s)*;
* `pitch` pitch angle *(radians)*;
* `roll` roll angle *(radians)*;
* `yaw` — yaw angle *(radians)*;
* `pitch_rate` — angular pitch velocity *(rad/s)*;
* `roll_rate` angular roll velocity *(rad/s)*;
* `yaw_rate` angular yaw velocity *(rad/s)*;
* `voltage` total battery voltage *(V)*;
* `cell_voltage` battery cell voltage *(V)*.
> **Note** Fields that are unavailable for any reason will contain the `NaN` value.
Displaying drone coordinates `x`, `y` and `z` in the local system of coordinates:
```python
telemetry = get_telemetry()
print(telemetry.x, telemetry.y, telemetry.z)
```
Displaying drone altitude relative to [the ArUco map](aruco.md):
```python
telemetry = get_telemetry(frame_id='aruco_map')
print(telemetry.z)
```
Checking global position availability:
```python
import math
if not math.isnan(get_telemetry().lat):
print('Global position is available')
else:
print('No global position')
```
Output of current telemetry (command line):
```bash
rosservice call /get_telemetry "{frame_id: ''}"
```
### navigate
Fly to the designated point in a straight line.
Parameters:
* `x`, `y`, `z` — coordinates *(m)*;
* `yaw` — yaw angle *(radians)*;
* `yaw_rate` angular yaw velocity (will be used if yaw is set to `NaN`) *(rad/s)*;
* `speed` flight speed (setpoint speed) *(m/s)*;
* `auto_arm` switch the drone to `OFFBOARD` mode and arm automatically (**the drone will take off**);
* `frame_id` [coordinate system](frames.md) for values `x`, `y`, `z`, `vx`, `vy`, `vz`. Example: `map`, `body`, `aruco_map`. Default value: `map`.
> **Note** If you don't want to change your current yaw set the `yaw` parameter to `NaN` (angular velocity by default is 0).
Ascending to the altitude of 1.5 m with the climb rate of 0.5 m/s:
```python
navigate(x=0, y=0, z=1.5, speed=0.5, frame_id='body', auto_arm=True)
```
Flying in a straight line to point 5:0 (altitude 2) in the local system of coordinates at the speed of 0.8 m/s (yaw is set to 0):
```python
navigate(x=5, y=0, z=3, speed=0.8)
```
Flying to point 5:0 without changing the yaw angle (`yaw` = `NaN`, `yaw_rate` = 0):
```python
navigate(x=5, y=0, z=3, speed=0.8, yaw=float('nan'))
```
Flying 3 m to the right from the drone:
```python
navigate(x=0, y=-3, z=0, speed=1, frame_id='body')
```
Flying 2 m to the left from the last navigation target:
```python
navigate(x=0, y=2, z=0, speed=1, frame_id='navigate_target')
```
Turn 90 degrees clockwise:
```python
navigate(yaw=math.radians(-90), frame_id='body')
```
Flying to point 3:2 (with the altitude of 2 m) in the [ArUco map](aruco.md) coordinate system with the speed of 1 m/s:
```python
navigate(x=3, y=2, z=2, speed=1, frame_id='aruco_map')
```
Rotating on the spot at the speed of 0.5 rad/s (counterclockwise):
```python
navigate(x=0, y=0, z=0, yaw=float('nan'), yaw_rate=0.5, frame_id='body')
```
Flying 3 meters forwards at the speed of 0.5 m/s, yaw-rotating at the speed of 0.2 rad/s:
```python
navigate(x=3, y=0, z=0, speed=0.5, yaw=float('nan'), yaw_rate=0.2, frame_id='body')
```
Ascending to the altitude of 2 m (command line):
```(bash)
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}"
```
> **Note** Consider using the `navigate_target` frame instead of `body` for missions that primarily use relative movements forward/back/left/right. This negates inaccuracies in relative point calculations.
### navigate_global
Flying in a straight line to a point in the global coordinate system (latitude/longitude).
Parameters:
* `lat`, `lon` — latitude and longitude *(degrees)*;
* `z` — altitude *(m)*;
* `yaw` — yaw angle *(radians)*;
* `yaw_rate` angular yaw velocity (used for setting the yaw to `NaN`) *(rad/s)*;
* `speed` flight speed (setpoint speed) *(m/s)*;
* `auto_arm` switch the drone to `OFFBOARD` and arm automatically (**the drone will take off**);
* `frame_id` [coordinate system](frames.md) for `z` and `yaw` (Default value: `map`).
> **Note** If you don't want to change your current yaw set the `yaw` parameter to `NaN` (angular velocity by default is 0).
Flying to a global point at the speed of 5 m/s, while maintaining current altitude (`yaw` will be set to 0, the drone will face East):
```python
navigate_global(lat=55.707033, lon=37.725010, z=0, speed=5, frame_id='body')
```
Flying to a global point without changing the yaw angle (`yaw` = `NaN`, `yaw_rate` = 0):
```python
navigate_global(lat=55.707033, lon=37.725010, z=0, speed=5, yaw=float('nan'), frame_id='body')
```
Flying to a global point (command line):
```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: 'body', auto_arm: false}"
```
### set_position
Set the setpoint for position and yaw. This service may be used to specify the continuous flow of target points, for example, for flying along complex trajectories (circular, arcuate, etc.).
> **Hint** Use the [`navigate`](#navigate) higher-level service to fly to a point in a straight line or to perform takeoff.
Parameters:
* `x`, `y`, `z` — point coordinates *(m)*;
* `yaw` — yaw angle *(radians)*;
* `yaw_rate` angular yaw velocity (used for setting the yaw to NaN) *(rad/s)*;
* `auto_arm` switch the drone to `OFFBOARD` and arm automatically (**the drone will take off**);
* `frame_id` [coordinate system](frames.md) for `x`, `y`, `z` and `yaw` parameters (Default value: `map`).
Hovering on the spot:
```python
set_position(frame_id='body')
```
Assigning the target point 3 m above the current position:
```python
set_position(x=0, y=0, z=3, frame_id='body')
```
Assigning the target point 1 m ahead of the current position:
```python
set_position(x=1, y=0, z=0, frame_id='body')
```
Rotating on the spot at the speed of 0.5 rad/s:
```python
set_position(x=0, y=0, z=0, frame_id='body', yaw=float('nan'), yaw_rate=0.5)
```
### set_velocity
Set speed and yaw setpoints.
* `vx`, `vy`, `vz` flight speed *(m/s)*;
* `yaw` — yaw angle *(radians)*;
* `yaw_rate` angular yaw velocity (used for setting the yaw to NaN) *(rad/s)*;
* `auto_arm` switch the drone to `OFFBOARD` and arm automatically (**the drone will take off**);
* `frame_id` [coordinate system](frames.md) for `vx`, `vy`, `vz` and `yaw` (Default value: `map`).
> **Note** Parameter `frame_id` specifies only the orientation of the resulting velocity vector, but not its length.
Flying forward (relative to the drone) at the speed of 1 m/s:
```python
set_velocity(vx=1, vy=0.0, vz=0, frame_id='body')
```
### set_attitude
Set pitch, roll, yaw and throttle level (similar to [the `STABILIZED` mode](modes.md)). This service may be used for lower level control of the drone behavior, or controlling the drone when no reliable data on its position is available.
Parameters:
* `pitch`, `roll`, `yaw` requested pitch, roll, and yaw angle *(radians)*;
* `thrust` — throttle level, ranges from 0 (no throttle, propellers are stopped) to 1 (full throttle).
* `auto_arm` switch the drone to `OFFBOARD` mode and arm automatically (**the drone will take off**);
* `frame_id` [coordinate system](frames.md) for `yaw` (Default value: `map`).
### set_rates
Set pitch, roll, and yaw rates and the throttle level (similar to [the `ACRO` mode](modes.md)). This is the lowest drone control level (excluding direct control of motor rotation speed). This service may be used to automatically perform aerobatic tricks (e.g., flips).
Parameters:
* `pitch_rate`, `roll_rate`, `yaw_rate` pitch, roll, and yaw rates *(rad/s)*;
* `thrust` — throttle level, ranges from 0 (no throttle, propellers are stopped) to 1 (full throttle).
* `auto_arm` switch the drone to `OFFBOARD` and arm automatically (**the drone will take off**);
The positive direction of `yaw_rate` rotation (when viewed from the top) is counterclockwise,`pitch_rate` rotation is forward, `roll_rate` rotation is to the left.
### land
Switch the drone to landing [mode](modes.md) (`AUTO.LAND` or similar).
> **Note** Set the `COM_DISARM_LAND` [PX4 parameter](px4_parameters.md) to a value greater than 0 to enable automatic disarm after landing.
Landing the drone:
```python
res = land()
if res.success:
print('drone is landing')
```
Landing the drone (command line):
```bash
rosservice call /land "{}"
```
<!--
### release
Stop publishing setpoints to the drone (release control). Required to continue monitoring by means of [MAVROS](mavros.md).
-->
Additional materials
------------------------
* [ArUco-based position estimation and navigation](aruco.md).
* [Program samples and snippets](snippets.md).