前言
基于uzh的论文和其代码做的一些相关的无人机竞速实验
一、无人机环境配置
主要在Linux系统下使用,其安装过程不在这里具体介绍,点击这里,下载代码
系统版本:Ubuntu16.04
仿真环境:Gazebo7.16
配置好环境后,要确保启动test_racing.launch不报错才行。
二、实验相关操作位置说明
2.1 训练数据收集测试
进入
sim2real_drone_racing/drone_racing/resources/scripts
目录下,运行collect_data.py
代码,首先验证下能否收集数据,运行不报错,且可以在相关文件夹下生成图像数据和label数据即可,然后停止运行该python代码
确保训练数据收集测试无误,再继续执行后面步骤
2.2 网络模型保存位置修改
train_model.sh
文件,在sim2real_drone_racing/learning/deep_drone_racing_learner/src/ddr_learner/
目录下主要通过修改其中的
checkpoint_dir
的值来更换神经网络模型的保存位置,默认是存放在/tmp/logs
文件夹下,因为该文件夹是Ubuntu系统的临时文件存放位置,因此可能在重启或其他的误操作后,该文件夹下的内容被清空,所以这里一定要进行修改
1 | #!/bin/bash |
模型保存位置修改后,运行train_model.sh
文件,测试能否成功训练,操作无误后,继续执行后面步骤
2.3 训练背景图修改
因为我们训练的背景是根据当前的研究目标而设定的,因此,需要在仿真环境中更改为实际场景背景,该背景图片可以用手机拍摄,也可以通过其他方式来获取,修改过后的训练场景图如图所示
2.3.1 图片尺寸大小更改
使用python代码,将图片大小全部修改为400*400像素
1 | import os |
更改过后的图片数据如下图:
2.3.2 训练背景替换
在uzh的代码中,主要通过读取特定文件夹下的图片来作为训练背景,因此,只需要找到其文件夹,并将其中的图片替换为自己的图片即可。
其训练背景图主要存放在sim2real_drone_racing/drone_racing/drone_racing/resources/race_track/iros_materials/materials/textures/train_bkgs
目录下,可以将整个train_bkgs
文件夹拷贝一份,并将复制的文件夹重名为train_bkgs_init
,保存其初始背景图,然后将train_bkgs
中的图片数据清空删除,并将上面的01-04.jpg
图片拷贝到train_bkgs
文件夹即可。
最后可以重新运行train_model.sh
文件,查看新收集的背景图是否修改来进行验证,也可以通过运行launch文件,并显示Gazebo界面来查看,如何显示Gazebo界面,会在后面进行介绍。
2.4 地面纹理图修改
原实验是使用的小草图片作为地面纹理,也可根据自己需要修改成其他图片
和2.3节一样,先运行python代码,将图片大小更改,然后进行数据替换。
将sim2real_drone_racing/drone_racing/drone_racing/resources/race_track/iros_materials/materials/textures
目录和sim2real_drone_racing/drone_racing/drone_racing/resources/race_track/iros_materials/materials/textures/test_floor_bkgs
目录下的asphalt.jpg
(小草图片)删除,然后将想要使用的地面纹理图,各拷贝一份到上面的两个目录下,重命名为asphalt.jpg
2.5 Gazebo界面显示
Gazebo界面默认是关闭的,但我们平常做一些相关的修改后,想要快速的查看效果,就可以用Gazebo进行界面显示了
在sim2real_drone_racing/drone_racing/drone_racing/launch
目录下,打开simulation_no_quad_gui.launch
文件,将其中第14行的value
属性值修改为true
,即如下代码所示:
1 | <arg name="gui" value="true"/> |
然后运行test_racing.launch
命令,就会显示Gazebo界面了
2.6 全局轨迹生成
全局轨迹对实验有着至关重要的作用,原代码默认有一个全局轨迹,但当我们修改了仿真平台中的某些数据后,也需要修改其轨迹。
仿真环境主要由4部分组成:背景图(4个方向上的墙壁)、地面纹理、门框、门框纹理。
其中,背景图和地面纹理的修改已在2.3、2.4节介绍。
该节主要介绍门框坐标位置的修改。(修改时,门框的朝向不变)
2.6.1 Gazebo环境中修改门框坐标
主要通过修改
world
文件来实现
race_track.world
文件,存放在sim2real_drone_racing/drone_racing/drone_racing/resources/worlds
目录下
总共有14个门框,每个门框都有其自定义的名称,通过修改其中的pose
属性值,上图中的18.2181,20.0025,2
表示门框的xyz坐标值,将上图中两处框出来的xyz坐标值都修改,最后的-0.874979
为门框朝向值,这里不做修改。
修改后,可以启动test_racing.launch
文件,在Gazebo界面中,查看门框的位置
2.6.2 RVIZ界面中门框坐标修改
在飞行过程中,是通过RVIZ显示无人机、门框以及全局路线的,因此,要在相应的文件中,将门框坐标值与world中的门框坐标值一一对应起来。
goals.yaml
文件,存放在sim2real_drone_racing/drone_racing/drone_racing/parameters
目录下
RVIZ界面显示如下:
goals.yaml
中的代码如下:
其中,goal_positions中
的xyz
坐标值表示RVIZ
界面中门框的xyz
坐标值
注意:
(1)xyz
坐标要与world
文件中的xyz
坐标一致
(2)修改时,要注意空格,也要注意数字为实数,不是整数
1 | goal_positions: |
2.6.3 全局轨迹生成
在
world
文件和yaml
文件中,修改了门框坐标后,就可以利用代码生成全局轨迹了可能有更好的方式生成,但我这里采用的是比较笨的方法
(1)global_trajectory.cpp
文件,存放在sim2real_drone_racing/drone_racing/drone_racing/src
目录下
全局轨迹生成主要是通过调用global_trajectory.cpp
文件中的generateGlobalTrajectory
函数来实现的。
主要代码贴出如下:
1 | double maximal_des_thrust = 18.0; |
主要是通过判断load_existing_trajectory_
值是否为真,来生成轨迹或加载轨迹,但在实验过程中,发现代码无法进入到if
函数体中,反而都是进入到else
函数体中了,因此,在if
上一行,手动添加了一个flag
标签,并且在需要生成轨迹的时候,使用if(flag)
进行判断,而不使用if (!load_existing_trajectory_)
来判断,当重新生成轨迹后,在使用 if (!load_existing_trajectory_)
来判断。
总结:在原代码基础上,添加两行代码
1 | bool flag = true; //添加的标签 |
(1)生成新全局轨迹,if(flag)
判断,注释if (!load_existing_trajectory_)
(2)加载全局轨迹,if (!load_existing_trajectory_)
判断,注释if(flag)
(2)编译
由于改动了
cpp
文件,因此要重新编译,否则改动无效每次改动
cpp
文件后,都必须要重新编译
在终端的drone_racing_ws/catkin_ddr
目录下,执行如下命令:
1 | catkin build |
(3)启动test_racing.launch
文件
修改完坐标值,启动launch文件,就可以重新生成轨迹了
启动launch
文件过程中,注意终端的输出,若终端有大量红色错误信息输出,可能需要重新启动文件测试
终端没有输出报错信息,则可以查看global_trajectory.txt
文件内容,该文件存放在
sim2real_drone_racing/drone_racing/drone_racing/resources/global_trajectories
目录下,并且该文件存储的是轨迹点上的值,或者在启动launch
文件之前,直接删除或拷贝一份global_trajectory.txt
文件,删除的话,则会重新生成一个txt
文件,若不做任何修改,还需要查看一下txt
中的值,来判断是否修改成功。
2.7 网络模型加载
训练了神经网络模型,我们则需要利用神经网络模型进行测试,或接着上次的模型继续训练,因此,需要对网络模型进行加载
在原代码中,通过使用tensorflow
的函数去调用最新训练的网络模型,但我对该函数用的比较少,因此将代码修改为指定的模型。
原代码:
1 | checkpoint = tf.train.latest_checkpoint(config.checkpoint_dir) |
将self.saver.restore(sess, checkpoint)
中的checkpoint
修改为指定模型路径就可以了。
2.7.1 接着上次的网络模型训练
base_learner.py
文件,存放在sim2real_drone_racing/learning/deep_drone_racing_learner/src/ddr_learner/models
目录下
在base_learner.py
的train
函数中,self.saver.restore()
方法则是接着之前的网络进行训练
1 | with sv.managed_session(config=gpu_config) as sess: |
2.7.2 使用训练过的神经网络模型测试
Networ.py
文件,存放在sim2real_drone_racing/learning/deep_drone_racing_learning_node/src/Network
目录下
在Networ.py
的callback_feedthrough
函数中,self.saver.restore()
方法则是使用神经网络进行测试
这里也没有使用tf.train.latest_checkpoint()
方法,而是指定神经网络模型路径
1 | def callback_feedthrough(self, data): |
2.8 神经网络模型结构
论文中的神经网络模型结构选用的是
DroNet
,也可以使用其他的网络模型结构。
nets.py
文件,存放在sim2real_drone_racing/learning/deep_drone_racing_learner/src/ddr_learner/models
目录下
代码如下所示,论文使用的是resnet函数中的网络结构,如果要使用其他网络结构,如Vgg16,可以重写一个函数,并将函数方法名修改为resnet即可。
1 | #Vgg16网络结构 |
2.9 动态门框设置
神经网络模型也在动态场景下进行了测试
main.yaml
文件,存放在sim2real_drone_racing/drone_racing/drone_racing/parameters
目录下
默认设置为false
,如果需要移动门框,则设置为true
,另外这里的gates_dyn_amplitude
属性我也没怎么搞懂
1 | # Moving the gates |
总结
整个代码真的太过复杂,到现在为止,对里面的很多细节还没弄清楚,如
(1)算法收集数据时,如何收集的,封装了topic,又是如何封装的?只知道执行py文件,就可以收集数据了
(2)控制到底是如何实现的?C++代码编写topic?我想要简单的控制无人机,如何给定合适的电机转速值?
(3)ROS与Gazebo的封装性太高了,确实只会用。
(4)除了sim2real_droneracing包,还有那么多的其他包都是干啥的?轨迹生成用到了其他包。
下面是对我用到过的文件写个简单的功能介绍:
launch文件,
sim2real_drone_racing/drone_racing/drone_racing/launch
目录simulation_no_quad_gui.launch
文件中,可以设置属性值,打开Gazebo界面或关闭Gazebo界面yaml文件,
sim2real_drone_racing/drone_racing/drone_racing/parameters
目录- goals.yaml文件,设置RVIZ界面中门框的坐标值,并图形显示
- main.yaml文件,设置门框是否移动,默认为false,不移动
resources目录下,完整目录为
sim2real_drone_racing/drone_racing/drone_racing/resources
- global_trajectories文件夹,存放的是全局最优轨迹的txt文件
- race_track文件夹:超级重要的文件夹,仿真环境的所有背景及纹理基本都在该文件夹下,需要多看看
- scripts文件夹,收集训练数据python代码
- worlds文件夹,Gazebo
中的模型坐标设置文件
ddr_learner目录下,完整目录为
sim2real_drone_racing/learning/deep_drone_racing_learner/src/ddr_learner
- train_model.sh文件:训练神经网络,并设置最大迭代次数,以及保存模型文件位置
- models目录下:
- base_learner.py:继续上次训练模型参数训练
- nets.py:可以自己设置神经网络模型结构
Network目录下,完整目录为
sim2real_drone_racing/learning/deep_drone_racing_learning_node/src/Network
- Network.py:使用神经网络进行测试,可以选择训练过的其他网络