# 无人机自动驾驶软件系列 E06： 简单全局目标追踪

我们建议开发者使用镜像来安装 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 %}

前几讲中，我们讲述了如何设置仿真环境，如何通过 python 控制无人机，如何使用双目进行深度估计。本讲中，我会简要介绍如何通过 [GAAS-Object-Tracking ](https://github.com/generalized-intelligence/GAAS-Object-Tracking.git) 模块进行全局目标跟踪。注意，此实现比较简单，实际情况下需要使用更为复杂的方法。

为了方便维护，我们将跟踪算法放入了另一个 [repo](https://github.com/generalized-intelligence/GAAS-Object-Tracking.git)，你可以通过如下命令克隆跟踪模块到本地环境：

```bash
git clone https://github.com/generalized-intelligence/GAAS-Object-Tracking.git
```

GAAS 的全局跟踪模块包含四个算法，分别是[TLD](https://ieeexplore.ieee.org/abstract/document/6104061)， [KCF](https://ieeexplore.ieee.org/abstract/document/6870486)，[GOTURN](https://arxiv.org/pdf/1604.01802.pdf)， 以及基于 [pysot](https://github.com/STVIR/pysot.git) 的 SiamRPN等算法。其中后两种为神经网络算法，前两种为传统算法。在本教程，我们使用 KCF 算法作为程序的追踪算法。

请注意，该全局跟踪是 GAAS：<https://github.com/generalized-intelligence/GAAS> 的一个模块，无法独立使用。请熟悉 GAAS 后再进行本教程。

## 更新环境

首先请更新 GAAS:

```bash
git pull origin master
```

接下来，将 Gazebo 仿真所用的文件拷贝到 PX4 文件所在的目录中：

```bash
cp -r (GAAS_PATH)/simulator/launch/* ~/catkin_ws/src/Firmware/launch/
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/
cp -r (GAAS_PATH)/simulator/urdf ~/catkin_ws/src/Firmware/Tools/sitl_gazebo/
```

接下来进入下一步

## 启动仿真

本教程的要达到的效果是在仿真环境下，无人机追踪一个可以移动的小车。首先启动仿真：

```bash
roslaunch px4 car_tracking.launch
```

上述命令会启动仿真，生成一个可移动的小车，以及无人机。

![仿真环境下的无人机和小车](https://1955112758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYUhlGdK9Y1iLhupMFC%2F-LjLB7gFPhmNsOiuCaKy%2F-LjLBSAgKzaUYcdww7RE%2F1.png?alt=media\&token=5401aa2e-5243-4f55-907b-d4e7be52fe41)

这个小车将会是你追踪的目标。小车订阅了 `/cmd_vel` 的 topic 所以我们可以通过代码（这里不详述了），或者使用插件：

```bash
sudo apt install ros-kinetic-teleop-twist-keyboard
```

安装好插件后，使用：

```bash
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
```

运行插件。使用方法如下图，在启动插件后会自动打印说明，只需在启动插件的终端按相应的按键，即可控制小车移动。

![teleop\_twist 使用说明](https://1955112758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYUhlGdK9Y1iLhupMFC%2F-LjLB7gFPhmNsOiuCaKy%2F-LjLBdEUU4ZfEaQrpmTS%2F2.png?alt=media\&token=410d68e0-839c-4726-9d15-66a71bafa2ec)

> 本教程所用的小车是一个非常简单的小车模型，如果你需要一个更加精美的小车模型，可以选择使用 [husky\_gazebo](https://github.com/TaarLab/husky_joy.git) 模型。控制都是通过 `/cmd_vel` 进行。

## 编译跟踪模块

本教程使用跟踪模块的 KCF 方法，此方法使用 c++ 实现，所以需要编译：

```bash
cd (GAAS-Object-Tracking_PATH)/KCF
mkdir build
cd build
cmake ..
make -j6
```

> 如果遇到 "fatal error: ros\_kcf/InitRect.h: No such file or directory..." 的问题，调大编译所用线程的数量即可。比如从 `make -j1` 到 `make -j6` 。

## 测试

### 1. 初始化仿真环境

首先打开仿真环境：

```bash
roslaunch px4 car_tracking.launch
```

让飞机起飞并悬停，此时悬停的高度为 3 米：

```bash
cd (GAAS_PATH)/demo/tutorial_6/6_object_tracking/
python python px4_mavros_run.py
```

打开另一个终端控制飞机飞到小车上方：

```bash
python init_drone.py
```

![飞机在小车上方悬停](https://1955112758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYUhlGdK9Y1iLhupMFC%2F-LjLB7gFPhmNsOiuCaKy%2F-LjLBzCdUtFhFnX3H8C3%2F3.png?alt=media\&token=7d339033-5039-46bd-b7fa-dfb63bfd89ea)

或者参考 [第一课](https://gaas.gitbook.io/guide/software-realization-build-your-own-autonomous-drone/build-your-own-autonomous-drone-e01-offboard-control-and-gazebo-simulation) 的方法自行编辑指令控制飞机飞到小车上方。打开 `rviz` 确认小车出现在摄像机的视野。

![摄像机视角](https://1955112758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYUhlGdK9Y1iLhupMFC%2F-LjLB7gFPhmNsOiuCaKy%2F-LjLC4PBXuSPw8cOVm4L%2F4.png?alt=media\&token=45cab40f-5ea1-4d02-8e63-548d6841ad43)

### 2. 开启全局追踪算法

打开新的终端，开启全局追踪算法：

```bash
cd (GAAS-Object-Tracking_PATH)/KCF
./bin/startRosService
```

注：此时是没有任何输出的，算法正在等待通过 ROS Service 给算法设置起始位置。

GAAS 提供了一个小的 GUI 程序来快速设置初始坐标点。使用如下命令即可运行：

```bash
cd (GAAS_PATH)/demo/tutorial_6/6_object_tracking/
python set_init.py
```

为了不使我们的环境变量太过冗余，我们人工修改下 `set_init.py` 将 Service 的依赖加入到程序的系统变量。首先用编辑器打开 `set_init.py` ：

```bash
gedit (GAAS_PATH)/demo/tutorial_6/6_object_tracking/set_init.py
```

将 ROS Service 依赖加载到运行时的变量：

```python
import rospy
import cv2
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError
import numpy as np 

import sys 
sys.path.append('(GAAS-Object-Tracking_PATH)/KCF/build/devel/lib/python2.7/dist-packages')  #
from ros_kcf.srv import InitRect    #Import this ROS Service dependency
from std_msgs.msg import Int32MultiArray
```

设置以后保存，关闭 gedit ，运行 `set_init.py` ，在弹出的界面中画一个矩形框住目标，然后在键盘上点击 `s` 将目标初始位置通过 ROS Service 传递给全局追踪算法。

![设置小车初始位置](https://1955112758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYUhlGdK9Y1iLhupMFC%2F-LjLB7gFPhmNsOiuCaKy%2F-LjLCJkuV9X4m3lrE1Bo%2FScreen%20Shot%202019-07-09%20at%206.08.55%20PM.png?alt=media\&token=597716f9-e58c-4321-ac08-4347fd46c5cb)

此时在算法运行的终端界面中，可以看到终端在打印检测到的每帧的结果，此时可以按 `ctrl + c` 关闭程序。

![实时追踪结果](https://1955112758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYUhlGdK9Y1iLhupMFC%2F-LjLB7gFPhmNsOiuCaKy%2F-LjLC_dn73Pr8DxDu8bM%2F6.png?alt=media\&token=31458375-830f-4375-9756-cdcf9d0445c6)

追踪算法默认订阅 `/gi/simulation/left/image_raw` topic，如果您想修改，请修改配置文件：

```bash
gedit (GAAS-Object-Tracking_PATH)/KCF/config.yaml
```

> 此 GUI 小程序是一个非常简单的程序，我们未来会推出功能更全面的 GUI 程序，也欢迎你为 GAAS 做贡献提供代码。

### 3. 开始全局追踪

首先设置参数，你可以设置飞机在一个固定的高度，也可以根据双目摄像头的景深估计来使飞机与小车保持固定高度距离。目前软件支持使用 StereoBM 算法计算视差图，你可以使用 [这个程序](https://github.com/generalized-intelligence/GAAS-Opencv-Disparity-Map-Tuner-with-ROS.git) 进行调参。为了方便使用，本教程默认使用设置固定高度的方法来做。在这种方法下，如果你想控制飞机飞得更高，请修改相应参数。

然后启动算法：

```bash
python track_and_move.py
```

启动小车控制插件：

```bash
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
```

控制小车即可。

![飞机跟随小车走](https://1955112758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYUhlGdK9Y1iLhupMFC%2F-LjLB7gFPhmNsOiuCaKy%2F-LjLCfHIN-CnXk7N11dQ%2F7.png?alt=media\&token=19342f0d-d9d5-44b7-a32f-ec1a0b34bf17)

> 在追踪过程中，请勿关闭追踪算法。如果你觉得需要重新追踪物体，请重启追踪算法，并运行 `set_init.py` 重新设置物体起始坐标。

在本教程中飞机和小车的朝向是 X 轴正方向，如果你需要修改初始朝向，请修改代码。如果你想使用世界坐标系，请参考 [课程一](https://gaas.gitbook.io/guide/software-realization-build-your-own-autonomous-drone/build-your-own-autonomous-drone-e01-offboard-control-and-gazebo-simulation) 的代码。我们也会不断完善目标追踪的功能，加入精度更高的双目测距，以及加入追迹算法。本教程旨在提供一个简单算法实现基本的追踪小车。如果你发现任何问题，或有不明白的地方，欢迎提 issue 或者加入我们的微信群聊。
