AirSim笔记5:在AirSim中控制无人机平台并采集数据

Dec 3,2021   3747 words   14 min

Tags: SLAM

在之前这篇这篇这篇博客中,我们使用汽车作为采集平台进行了数据采集。但前面我们也说过,AirSim还支持无人机的仿真。所以这篇博客主要介绍如何使用无人机作为平台来采集数据。而且这也是十分有必要的。因为有些仿真场景真的不适合用车来开啊,比如LandscapeMountains、或者Zhangjiajie场景,汽车在里面基本动不了,如下图所示。 汽车会卡在山上动不了,无法顺利探索。

1.无人机控制

AirSim切换成无人机模式十分简单,只需要在配置文件settings.json中将SimMode属性设为Multirotor即可。但问题在于无人机的控制。因为AirSim默认是通过外部的手柄操控无人机,而非普通键盘,所以直接用键盘是操作不了无人机的。但我们手边又没有可以控制的手柄,所以必须要先研究如何利用键盘操控无人机。

怎么解决这个办法呢?答案是可以通过AirSim提供的API来操控无人机。通过编写脚本监听键盘事件,根据不同的按键对应不同的API,即可实现对于无人机的操控。网上也有现成的代码,下面的代码主要参考了这个网页。关于AirSim的可编程API,我们会在之后的笔记中再介绍。这里就先“无脑”使用即可。

# coding=utf-8
import keyboard
import airsim


def callBackFunc(x):
    w = keyboard.KeyboardEvent('down', 28, 'w')             # 前进
    s = keyboard.KeyboardEvent('down', 28, 's')             # 后退
    a = keyboard.KeyboardEvent('down', 28, 'a')             # 左移
    d = keyboard.KeyboardEvent('down', 28, 'd')             # 右移
    up = keyboard.KeyboardEvent('down', 28, 'up')           # 上升
    down = keyboard.KeyboardEvent('down', 28, 'down')       # 下降
    left = keyboard.KeyboardEvent('down', 28, 'left')       # 左转
    right = keyboard.KeyboardEvent('down', 28, 'right')     # 右转
    k = keyboard.KeyboardEvent('down', 28, 'k')             # 获取控制
    l = keyboard.KeyboardEvent('down', 28, 'l')             # 释放控制

    if x.event_type == 'down' and x.name == w.name:
        # 前进
        client.moveByVelocityBodyFrameAsync(3, 0, 0, 0.5)
        print("前进")
    elif x.event_type == 'down' and x.name == s.name:
        # 后退
        client.moveByVelocityBodyFrameAsync(-3, 0, 0, 0.5)
        print("后退")
    elif x.event_type == 'down' and x.name == a.name:
        # 左移
        client.moveByVelocityBodyFrameAsync(0, -2, 0, 0.5)
        print("左移")
    elif x.event_type == 'down' and x.name == d.name:
        # 右移
        client.moveByVelocityBodyFrameAsync(0, 2, 0, 0.5)
        print("右移")
    elif x.event_type == 'down' and x.name == up.name:
        # 上升
        client.moveByVelocityBodyFrameAsync(0, 0, -0.5, 0.5)
        print("上升")
    elif x.event_type == 'down' and x.name == down.name:
        # 下降
        client.moveByVelocityBodyFrameAsync(0, 0, 0.5, 0.5)
        print("下降")
    elif x.event_type == 'down' and x.name == left.name:
        # 左转
        client.rotateByYawRateAsync(-20, 0.5)
        print("左转")
    elif x.event_type == 'down' and x.name == right.name:
        # 右转
        client.rotateByYawRateAsync(20, 0.5)
        print("右转")
    elif x.event_type == 'down' and x.name == k.name:
        # 无人机起飞
        # get control
        client.enableApiControl(True)
        print("get control")
        # unlock
        client.armDisarm(True)
        print("unlock")
        # Async methods returns Future. Call join() to wait for task to complete.
        client.takeoffAsync().join()
        print("takeoff")
    elif x.event_type == 'down' and x.name == l.name:
        # 无人机降落
        client.landAsync().join()
        print("land")
        # lock
        client.armDisarm(False)
        print("lock")
        # release control
        client.enableApiControl(False)
        print("release control")
    else:
        # 没有按下按键
        client.moveByVelocityBodyFrameAsync(0, 0, 0, 0.5).join()
        client.hoverAsync().join()  # 第四阶段:悬停6秒钟
        print("悬停")


if __name__ == '__main__':
    # 建立脚本与AirSim环境的连接
    client = airsim.MultirotorClient()
    client.confirmConnection()

    # 监听键盘事件,执行回调函数
    keyboard.hook(callBackFunc)
    keyboard.wait()

使用脚本前需要确保有keyboardairsim两个包,如果没有pip install一下。启动脚本后,按k键获取控制,按l键释放控制。W、S、A、D键用于控制前进后退、左右平移,方向键控制上升下降以及左转右转。这个脚本也放到了Github项目中,叫AirSimDroneKeyboardController.py点击查看源文件。

2.数据录制

在可以完整控制无人机以后,后面的操作就和用汽车采集数据一样了。比如,这里给出一个利用无人机录制双目影像的配置文件。

{
  "SeeDocsAt": "https://github.com/Microsoft/AirSim/blob/master/docs/settings.md",
  "SettingsVersion": 1.2,
  "SimMode": "Multirotor",
  "Recording": {
    "RecordInterval": 0.05,
    "Cameras": [
        { "CameraName": "front_left", "ImageType": 0, "PixelsAsFloat": false, "Compress": true },
        { "CameraName": "front_right", "ImageType": 0, "PixelsAsFloat": false, "Compress": true }
    ]
  },
  "CameraDefaults": {
    "CaptureSettings": [
      {
        "ImageType": 0,
        "Width": 600,
        "Height": 400,
        "FOV_Degrees": 90
      }
    ]
  }
}

然后我们启动AirSim,进入Zhangjiajie环境,如下图所示。 然后,我们开启一个终端,运行脚本,然后按k键即可获取控制,如下所示。 然后就可以移动了。最后,在仿真环境中按下R键开始录制,再切回终端一边移动一边录制,结束时再切回仿真环境按R键结束录制即可,如下图所示。 就会得到和之前一样的采集好的数据了。我们当然可以进一步用之前写好的脚本进行处理,然后跑SLAM。

3.跑ORB-SLAM

这一部分其实是和这篇博客说的内容是一样的,可以参考。为了完整性,这里再简单列一下。

3.1 数据处理

之前的博客中也提到了,AirSim直接保存的影像由于格式的问题,不能直接拿来跑ORB-SLAM。因此,需要对数据进行一些预处理。预处理可以使用之前已经写好的脚本,这里就不再赘述了。

3.2 ORB-SLAM运行

数据准备好以后,就可以跑ORB-SLAM了。配置好相关文件,运行即可。利用无人机采集数据,并跑SLAM的效果如下动图所示。 可视化的轨迹以及和真值的比较如下所示。

4.参考资料

  • [1] https://blog.csdn.net/weixin_44691296/article/details/119605213

本文作者原创,未经许可不得转载,谢谢配合

返回顶部