AirSim是微软一款开源三维仿真器。说是仿真器,其实更准确地说,AirSim是一套可以应用于三维引擎Unreal Engine和Unity的插件,用来采集仿真环境中多旋翼无人机和车辆的传感器信息,并控制其运动,可通过在setttings中设置SimMode参数来在无人机和车辆间切换。
AirSim可以用来对无人机、自动驾驶等方面的算法进行仿真测试。本文涉及的项目就是围绕着车辆模型下(即在setting文件中选择SimMode: Car)视觉slam算法的仿真测试展开的。
本文介绍的内容解决了如下几个问题:
Unreal Engine这种三维仿真引擎是非常消耗资源的,因此仿真环境的规模稍微大一点,AirSim通过ROS接口能够获得的图像流频率就会很低。如我的一台计算机配置是:i7-8700 @ 3.20GHz × 12,56G内存,GeForce GTX 1070 8G显存,在我的测试环境下(ubuntu16.04,ros-kinetic,UE 4.24),ROS接口输出的640*480双目图像的频率只能在5Hz以下。过低的图像频率会显著影响很多vslam算法的效果。
一个显而易见的解决办法是:降低仿真速度,这样在AirSim获取单帧图片的实际时间不变的情况下,我们就能获得仿真时间上更加“稠密”的图像了。这是一种“以时间换数据”的思路。
AirSim的setting中已经提供了ClockSpeed参数,按照官网说明,ClockSpeed参数大于1.0,仿真将以比现实时间快的速度运行,小于1.0时则反之。因此我们可以使用小于1.0的ClockSpeed运行仿真,以获取频率更高的图像数据。
然而问题是,ClockSpeed这个参数在无人机(Multirotor)的SimMode下是有效的,如果换成Car SimMode,无论怎样改变ClockSpeed,仿真都以现实速率运行,相关issue参见:
ClockSpeed相关issue
从代码上来看,车辆SimMode和无人机SimMode使用的物理引擎是不一样的,车辆使用的物理引擎好像不能像无人机使用的那样可以设置可变的时间步长。虽然不知道AirSim为什么要进行这样的设计,但我尝试着让车辆SimMode模式也使用无人机SimMode使用的物理引擎,修改后的仓库储存在:
GimpelZhang/AirSim
欢迎尝试使用!主要的改动集中在SimModeCar.cpp & SimModeCar.h两个文件,setting文件中需要进行如下设置(pr的简要描述):
“PhysicsEngineName”: “FastPhysicsEngine”, “ClockType”:
“SteppableClock”,
截止本文写作之时,AirSim官方仍然没有尝试解决或者回答这个问题,所以我这只是个vslam仿真测试应用下暂时的解决方案。
在我开始着手解决上面的ClockSpeed问题时,AirSim官方提供的ROS接口还只有无人机的,所以我仿照无人机的ROS wrapper写了一版车辆的,但在今年8月份,AirSim对ROS接口做了一次大的更新,包括兼容了车辆模式Car SimMode,增加了更多的传感器接口等。因此我在自己的仓库GimpelZhang/airsim_ros里只保留了官方提供的ROS接口,并在此基础上解决了下节所述的问题。
原版的AirSim的ROS接口,没有针对双目相机做特殊处理,只是将双目相机当做两个单独的相机获取图像。这样一来,双目间的时间差基本就是AirSim插件获取单帧图片的时间了。这样一来,左右目间的图像的时间差过大,对基于双目的视觉slam算法影响很大。根据以下链接的原创工作:
xuhao1/airsim_ros_pkgs
我修改了AirSim在8月更新后的ROS接口,解决了兼容无人机模式和车辆模式的ROS接口的双目图像时间戳同步问题。修改后的接口在我的一台机器上(ubuntu 16.04, i7-8700 CPU @ 3.20GHz × 12 ,32G, ros-kinetic, UE 4.24, no GPU)测试,双目输出的左右目时间戳的差别最大为0.0003秒,而如VINS双目算法左右目时间戳能允许的最大差别为0.003秒,所以修改后的ROS接口能够满足双目视觉slam的测试要求。
这部分工作的代码储存在仓库:
GimpelZhang/airsim_ros
欢迎尝试使用!主要的改动集中在airsim_ros_wrapper.cpp等文件中。
为了方便进行仿真测试,我还在GimpelZhang/airsim_ros里提供了一些其他工具,包括:
roslaunch airsim_car_teleop airsim_car_teleop_joy.launch
###可以选择在运行仿真和ROS接口的同时打开以下节点实时记录位姿:
roslaunch simu_tools car_pose_recorder output_filename rostopic_name
###或者选择在仿真时将位姿真值也记录到rosbag中,在仿真结束后用以下/simu_tools/scripts/groundtruth_extractor.py脚本提取真值保存为文件:
./groundtruth_extractor.py
an opencv Exception “Image is wrongly formed: height * step != size or 0 * 0 != 1” raised
目前还不清楚是否是因为我在第4节的修改产生了偶尔的空白帧。但是可以在运行vslam算法之前使用我的images_remove.py脚本对rosbag文件进行预处理,剔除上述空白帧。
关于如何在自己搭建的Unreal仿真环境中使用AirSim,我后续会单开一帖做简要介绍。
最后附上两张我使用此仿真环境结合ROS接口进行vslam算法测试的截图:
楼主初学乍练,欢迎感兴趣的朋友沟通交流!Discussions
【转载请注明出处,附上所有链接,谢谢合作!】