# 无人机自动驾驶软件系列 E01：OFFBOARD控制以及Gazebo仿真

这里是视频教程：<https://www.bilibili.com/video/av44348419>

我们建议开发者使用镜像来安装 GAAS，这样可以节省很多的时间和精力：

{% content-ref url="../handy-tools/gaas-v0.7-release-jing-xiang-x86" %}
[gaas-v0.7-release-jing-xiang-x86](https://gaas.gitbook.io/guide/handy-tools/gaas-v0.7-release-jing-xiang-x86)
{% endcontent-ref %}

无人机可以使用机载电脑，通过OFFBOARD模式进行控制飞行。控制过程主要通过一连串的MAVROS命令来实现，而MAVROS是MAVLink的一层高级封装，从而免去了我们通过MAVLink控制无人机的繁琐。通过MAVROS，我们可以轻松实现很多功能，例如：起飞，降落，指点飞行，朝向控制等等。

本课中，我们会讲解一下如何通过机载电脑，在模拟器中控制你的无人机飞行。首先，我们先从配置环境开始讲起。

{% hint style="info" %}
本课在 Ubuntu 16.04 LTS 以及ROS-Kinetic环境下测试通过，我们建议优先选择Ubuntu 16.04 LTS环境，但是如有需要也可以在Ubuntu 18.04 LTS和ROS-Melodic下工作。

在虚拟机环境下（VMWare，VirtualBox等）可能会出现问题，不建议使用虚拟机。
{% endhint %}

以下是测试版 GAAS 镜像的下载链接，包含了第一课和 SLAM 所需要的配置，以及 GAAS 的软件（以防万一，请使用前更新到最新版）。

因为是测试版，所以可能还会有一些问题，如遇困难欢迎在 GAAS 讨论群联系我们。

![](https://1955112758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYUhlGdK9Y1iLhupMFC%2F-Lft7Sfumj6Uiy3PcOyh%2F-Lft7rzZoKXO2TCpd_il%2Fgaasqrcode.png?alt=media\&token=3b670200-8300-4423-9986-65a66d93c471)

## Environment Setup 环境配置

我们提供两种方式配置环境，你可以选择逐个安装依赖包，也可以直接使用Docker。

### 1. 源码编译

{% hint style="info" %}
若选择使用此种安装方式，请确保网络连接 “稳定”。
{% endhint %}

#### 基本依赖项

为了使用所有脚本的功能，请先按照如下安装依赖项:

```
sudo apt install -y \
	ninja-build \
	exiftool \
	python-argparse \
	python-empy \
	python-toml \
	python-numpy \
	python-yaml \
	python-dev \
	python-pip \
	ninja-build \
	protobuf-compiler \
	libeigen3-dev \
	genromfs 
```

```
pip install \
	pandas \
	jinja2 \
	pyserial \
	cerberus \
	pyulog \
	numpy \
	toml \
	pyquaternion
```

#### ROS的安装

ROS (Robot Operating System)  是一个在机器人领域应用非常广泛的框架，它包含了很多有用的库以及工具，我们在本课以及接下来的所有课程中都会使用ROS Kinetic，首先，让我们安装ROS Kinetic。

若您在Ubuntu 18.04下安装，则可以使用ROS Melodic版本，只要将以下命令中的所有`ros-kinetic`更改为`ros-melodic`即可，例如对于：

`sudo apt-get install ros-kinetic-desktop-full`

可以将其改为：

`sudo apt-get install ros-melodic-desktop-full`

安装 ROS Kinetic，请按照如下步骤：

```
sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list'
#此处使用国内的ROS镜像源
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
sudo apt-get update
sudo apt-get install ros-kinetic-desktop-full
sudo rosdep init
rosdep update
echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc
source ~/.bashrc
sudo apt install python-rosinstall python-catkin-tools python-rosinstall-generator python-wstool build-essential

# install ros-gazebo plugins
sudo apt install ros-kinetic-gazebo-*
```

{% hint style="info" %}
浏览 <http://wiki.ros.org/kinetic/Installation/Ubuntu> 以便了解更多信息
{% endhint %}

完成上列步骤后，你可以通过下面的命令来测试是否成功安装:

```
roscore
```

如果 ROS 安装成功，你可以看到下列结果:

```
... logging to /home/.ros/log/6a1b2330-2eb3-11e9-a39c-9cb6d0e498fb/roslaunch-gishr-XPS-15-9560-4452.log
Checking log directory for disk usage. This may take awhile.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://XPS-15:44361/
ros_comm version 1.12.14


SUMMARY
========

PARAMETERS
 * /rosdistro: kinetic
 * /rosversion: 1.12.14

NODES

auto-starting new master
process[master]: started with pid [4463]
ROS_MASTER_URI=http://XPS-15:11311/

setting /run_id to 6a1b2330-2eb3-11e9-a39c-*********
process[rosout-1]: started with pid [4476]
started core service [/rosout
```

接下来，需要生成catkin工作空间，你所有的基于ROS的库都可以存放在此。

```
mkdir -p ~/catkin_ws/src
```

#### MAVROS

如之前所说，MAVROS是一层MAVLink与ROS通信的封装，旨在方便无人机与机载电脑通信。若要安装，你可以选择通过apt安装，或者从源码编译。请参考如下步骤:

```
# 你可以使用下列任何一种方法

# 方法 1
sudo apt-get install ros-kinetic-mavros ros-kinetic-mavros-extras

# 安装geographic lib :
wget https://raw.githubusercontent.com/mavlink/mavros/master/mavros/scripts/install_geographiclib_datasets.sh
sudo chmod a+x install_geographiclib_datasets.sh
./install_geographiclib_datasets.sh


# 方法 2
cd ~/catkin_ws
catkin init && wstool init src
rosinstall_generator --rosdistro kinetic mavlink | tee /tmp/mavros.rosinstall
rosinstall_generator --upstream mavros | tee -a /tmp/mavros.rosinstall
wstool merge -t src /tmp/mavros.rosinstall
wstool update -t src -j4
rosdep install --from-paths src --ignore-src -y

# 安装geographic lib :
sudo ./src/mavros/mavros/scripts/install_geographiclib_datasets.sh
sudo apt install ros-kinetic-catkin python-catkin-tools
catkin build
```

{% hint style="info" %}

```
若要了解更多关于Mavros信息，请参考如下网址:
https://github.com/mavlink/mavros/blob/master/mavros/README.md#installation
```

{% endhint %}

#### PX4 Firmware

我们会在此课以及接下来的课程中使用 PX4 v1.8.0固件。

```
cd ~/catkin_ws/src

# 请保证网络连接正常，此步骤耗时较长
git clone https://github.com/PX4/Firmware.git
cd Firmware
git checkout v1.8.0
make posix_sitl_default gazebo
```

若以上步骤通过，此时会弹出Gazebo模拟器窗口，你会看到一架无人机出现在环境中，现在将窗口关闭即可。

修改环境变量，这样每次打开新的终端都可以保持环境变量一致:

```
# Use your favorite editor, we will be using gedit
# NOTE: you will need to use ROOT to edit bashrc
sudo gedit ~/.bashrc

# 在bashrc中，拷贝以下内容到bashrc尾端
source ~/catkin_ws/devel/setup.bash # 如果通过第一种方式安装了MAVROS，忽略此步。
source ~/catkin_ws/src/Firmware/Tools/setup_gazebo.bash ~/catkin_ws/src/Firmware/ ~/catkin_ws/src/Firmware/build/posix_sitl_default
export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:~/catkin_ws/src/Firmware
export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:~/catkin_ws/src/Firmware/Tools/sitl_gazebo
```

打开一个新终端，输入:

```
roslaunch px4 posix_sitl.launch
```

在另一个终端，输入:

```
roslaunch mavros px4.launch fcu_url:="udp://:14540@127.0.0.1:14557"
```

或者你可以直接输入:

```
roslaunch px4 mavros_posix_sitl.launch
```

一个如下图所示的窗口会弹出:

![Figure 1, Gazebo and PX4 simulation in empty world](https://1955112758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYUhlGdK9Y1iLhupMFC%2F-LYyS2gb0WTxMoFG2A4I%2F-LYyS9hf9gZcetNvLRR6%2Ft1-f1-mavros-sim.png?alt=media\&token=21d3f7f2-0a4a-4383-85cd-28bec74e0315)

在一个新终端，输入

```
rostopic echo /mavros/state
```

你可以看到:

```
header: 
  seq: 1
  stamp: 
    secs: 730
    nsecs: 280000000
  frame_id: ''
connected: True
armed: False
guided: False
mode: "MANUAL"
system_status: 3
---
```

如果你看到上面的connected为True，那就代表你的Gazebo仿真环境配置成功，同时你的MAVROS通信也成功设置。

![](https://1955112758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYUhlGdK9Y1iLhupMFC%2F-LgaYGT7xNerBUpDSdtg%2F-LgaYY-BOQcIXA0TxxjC%2FWechatIMG16845.jpeg?alt=media\&token=2238e2ed-e58a-4eb0-be59-2bd7c6428806)

{% hint style="info" %}
运行 Gazebo 时，如果一切正常但出现以上报错信息，该报错信息并不会影响 Gazebo 运行，可以继续进行到下一步。

如果您知道如何解决以上报错，欢迎在 GAAS GitHub 页面提交 PR，帮助我们减少不必要的报错信息。
{% endhint %}

### 2. 使用Docker

如果你想直接跳过上面的步骤，可以使用Docker来运行仿真。Docker的使用较为简单，但是需要的资源较多，所以使用Docker的话GUI程序帧率以及分辨率会较低。我们使用VNC作为GUI交互，它的使用很广泛，可以用在包括Macos， Windows以及Android的多种平台上。

{% hint style="info" %}
建议通过第一种方式配置环境以便获得最优效果。
{% endhint %}

#### 使用VNC并获取Docker镜像

为了在Docker环境下使用GUI程序，需要在本地环境中安装VNC-viewer。你可以访问下面的网站了解更多信息:

```
https://www.realvnc.com/en/connect/download/viewer/
```

对于Linux系统来说，你可以直接下载下面的二进制文件:

```
wget https://www.realvnc.com/download/file/viewer.files/VNC-Viewer-6.19.107-Linux-x64
```

之后:

```
# NOTE the exact file name might differ
# 注意文件名可能会不一样
chmod +x VNC-Viewer-6.19.107-Linux-x64 
./VNC-Viewer-6.19.107-Linux-x64
```

其他平台的安装很简单，我们在此跳过。VNC-viewer安装后，需要获取Docker镜像到你的本地环境下:

```
docker pull gaas/mavros-gazebo7-px4
```

若要使用Docker，打开一个终端并输入:

```
# 取决于硬件配置，此过程可能需要3-5分钟
docker run -p 6080:80 -p 5900:5900 gaas/mavros-gazebo7-px4:latest
```

{% hint style="info" %}
在使用Docker过程中，视需求需要使用ROOT权限。
{% endhint %}

在另一个终端:

```
# 文件名或者文件路径可能会不一样
./VNC-Viewer-6.19.107-Linux-x64
```

你可以看到一个如下窗口弹出:

![Figure 2, VNC viewer window](https://1955112758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYUhlGdK9Y1iLhupMFC%2F-LYyVauFQTpyZSqliHIf%2F-LYyXItuendtTszr-N4N%2Ft1-f3-vnc.png?alt=media\&token=575d8ecd-8df0-4ab0-b328-ec4e1821bd0c)

输入如下地址:

```
# 你可以更改使用的端口，在Docker运行时修改对应参数即可
127.0.0.1:5900
```

回车后，你可以看到一个LXDE桌面的Ubuntu系统窗口:

![Figure 3, Docker Container](https://1955112758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYUhlGdK9Y1iLhupMFC%2F-LZ3rrePNREORc-n9pLB%2F-LZ3tdbPZfffy4JPCH2Y%2Ft1-3-vnc.png?alt=media\&token=d34852ac-f3b2-4f28-a5f0-dd3e017e2f69)

本课所需要的所有资料都可以在如下文件夹内找到:

```
/root/gi/GAAS/demo/tutorial_1
```

最后，每次打开Docker后，使用仿真前，你都需要手动执行下列命令:

```
cd /root/gi/px4/Firmware && make posix_sitl_default gazebo
```

仿真环境窗口弹出后，让我们暂时将它关闭。

现在，你可以直接跳到最后的 “控制无人机” 部分了！

## OFFBOARD 控制

{% hint style="info" %}
如果你使用Docker的话，可以直接跳到 “控制无人机” 部分。
{% endhint %}

首先，将仿真需要的文件获取到本地环境，文件包括无人机模型，世界模型以及其他一些你会用到的内容。此课程中我们将只关注基于python的MAVROS例子，如果你感兴趣的话可以试试GAAS提供的其他功能。

```
git clone git@github.com:generalized-intelligence/GAAS.git
```

你可以看到四个文件夹:

* demo: 本课用到的所有内容都可以在此文件夹内找到;
* hardware: 制作无人机所需的硬件资料可以在此文件夹找到;
* simulator: 包含仿真用到的模型等;
* software: 包含了例如ObstacleMap, SLAM，Local 以及Global path planner等内容。

你可以在各个文件夹内的README.md 中了解更多信息。

现在，将模型文件所在地址更新到环境变量中:

```
echo "export GAZEBO_MODEL_PATH=${GAZEBO_MODEL_PATH}:(GAAS_PATH)/simulator/models" >> ~/.bashrc
```

将模型以及配置文件拷贝到对应文件夹中:

```
cp -r (GAAS_PATH)/simulator/models/* ~/catkin_ws/src/Firmware/Tools/sitl_gazebo/models/
cp -r (GAAS_PATH)/simulator/worlds/* ~/catkin_ws/src/Firmware/Tools/sitl_gazebo/worlds/
cp -r (GAAS_PATH)/simulator/posix-config/* ~/catkin_ws/src/Firmware/posix-configs/SITL/init/ekf2/
```

### 控制无人机

如果你使用的是Docker，执行:

```
cd /root/gi/px4/Firmware && make posix_sitl_default gazebo
```

若make成功，Gazebo仿真窗口成功弹出，无人机出现在环境中，此时可以暂时将弹出的Gazebo窗口关闭。

接下来，无论你通过哪种方式配置的环境，都需要用同样的命令启动仿真环境，打开一个终端，输入:

```
roslaunch px4 mavros_posix_sitl.launch 
```

同时，不要忘记检查MAVROS连接情况:

```
# 请确保 connected 结果为 True
rostopic echo /mavros/state
```

如果Gazebo仿真环境成功启动且MAVROS连接成功，在一个新的终端，改变路径到GAAS下的DEMO文件夹，执行python脚本:

```
# 如果你使用的是Docker
cd /root/gi/GAAS/demo/tutorial_1/1_px4_mavros_offboard_controller
python px4_mavros_run.py

# 如果你使用第一种安装方法
cd (GAAS_PATH)/demo/tutorial_1/1_px4_mavros_offboard_controller
python px4_mavros_run.py
```

你可以看到一个无人机逐渐起飞到3米高并悬停在此。在另外一个终端中:

```
python commander.py
```

你可以看到无人机按照下面的顺序飞行:

1. 向右飞一米;
2. 逆时针旋转90度;
3. 降落。

或者你可以打开一个新的终端，使用提供的API来控制无人机:

```
# in folder '1_px4_mavros_offboard_controller'
python

# import packages
from commander import Commander
import time

# create Commander instance
con = Commander()

# control the drone to move 1 meter to the right
con.move(1,0,0)
# wait for 2 seconds 
time.sleep(2)

# control the drone to move 1 meter to the front
con.move(0,1,0)
# wait for 2 seconds
time.sleep(2)

# control the drone to move 1 meter to the left
con.move(-1,0,0)
# wait for 2 seconds
time.sleep(2)

# control the drone to move 1 meter to the back
con.move(0,-1,0)
# wait for 2 seconds
time.sleep(2)

# control the drone to move 1 meter above
con.move(0,0,1)
# wait for 2 seconds

# land
con.land()
```

你可以看到无人机按照正方形运行，升高之后降落。你可能已经发现无人机运动时总是按照”当前“位置作为坐标系，此时运动的参考系为BODY\_OFFSET\_ENU 或 FLU（Forward，Left，Up），每次运动命令总会控制无人机按照机身坐标系进行运动。move 方法中的第一个参数控制无人机向前飞行（注意，向前飞行不等于向北飞行），第二个参数控制无人机向左飞行，第三个参数向上飞行。飞机飞行的默认参考系为BODY\_OFFSET\_ENU。如果你想使用LOCAL\_ENU坐标系，此时运动按照的参考系是对于“起飞”时的位置，你可以在move方法中添加第四个参数，如下:

```
con = Commander()

# for BODY_OFF_SET_ENU or FLU frame
con.move(x,y,z)

# for LOCAL_ENU frame
con.move(x,y,z,BODY_OFF_SET_ENU=False)
```

![Figure 4, FLU body frame](https://1955112758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYUhlGdK9Y1iLhupMFC%2F-LdC8TetVpgx5kZGIssv%2F-LdC8hJHO9cb1pFmse22%2Ft1-body-frame.jpeg?alt=media\&token=75e6c466-0fb5-4f98-8bcd-eb4822f9dbc8)

接下来，你可以在模拟器中试试其他提供的API。

下一课，我们会讲解一下如果在模拟器环境中通过OFFBOARD模式制作一个3D模型。

## 阅读资料

若有兴趣，请阅读如下资料：

1. General ROS introduction: <http://wiki.ros.org/>
2. MAVROS: <http://wiki.ros.org/mavros>
3. MAVLINK: [https://mavlink.io/](https://mavlink.io/en/messages/common.html)
4. Gazebo: <http://gazebosim.org/>
5. rep-105: <https://www.ros.org/reps/rep-0105.html>
6. <https://github.com/PX4/Devguide/blob/master/en/ros/external_position_estimation.md>
