# 无人机自动驾驶软件系列 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>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gaas.gitbook.io/guide/software-realization-build-your-own-autonomous-drone/wu-ren-ji-zi-dong-jia-shi-xi-lie-offboard-kong-zhi-yi-ji-gazebo-fang-zhen.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
