官方api
https://microsoft.github.io/AirSim/api_docs/html/
https://zhuanlan.zhihu.com/p/307956920?utm_source=wechat_session
设置摄像机参数和图像参数
修改UE4仿真环境的参数,同样是修改settings.json
文件,可以修改AirSim摄像机保存图像的尺寸等参数。示例如下:
{ "SettingsVersion": 1.2, "CameraDefaults": { "CaptureSettings": [ { "ImageType": 0, "Width": 1920, "Height": 1080, "FOV_Degrees": 90, "AutoExposureSpeed": 100, "MotionBlurAmount": 0 } ] }, "SimMode": "ComputerVision" }
只是个参考
基本api代码整理
官方自带的测试程序
自己整理的测试python
1 基本控制移动,两种控制模式
1-1依靠速度控制.
1-2依靠坐标位置控制
备注说明,例如一边拍照一边控制移动,的开个多线程专门处理移动不能影响彩图卡顿。去掉jion函数不会等待动作执行完毕才去执行拍照,就可以做到一边移动一边拍照。
2获取集本数据 gps position
3获取图像,转化成opencv可以操作的数据
3-1修改相机编号 下视还是前视,默认下视
3-2修改画面数据,彩色还是深度图,默认彩色图
# In settings.json first activate computer vision mode: # https://github.com/Microsoft/AirSim/blob/master/docs/image_apis.md#computer-vision-mode #基本集成了飞机所有的控制,图像转换到opencv #import setup_path #导入自己的airsim编译路径 import sys sys.path.append("/home/dongdong/3Code/Airsim/AirSim/PythonClient") import airsim import cv2 import time import sys import pprint import numpy as np import os import tempfile #选择要采集的图像类型 cameraType = "scene" #正常画面 12fps 1920*1080 cameraTypeMap = { "depth": airsim.ImageType.DepthVis,#黑白景深图像 "segmentation": airsim.ImageType.Segmentation,#彩色目标分割图像 "seg": airsim.ImageType.Segmentation,#彩色目标分割图像 "scene": airsim.ImageType.Scene,#正常图像 "disparity": airsim.ImageType.DisparityNormalized, "normals": airsim.ImageType.SurfaceNormals } #选择摄像头 ''' ---camera_name_val: airsim自带的simple flight,每个无人机自带5个相机,其ID 与相机分别对应如下: 0 = front_center 1 = front_right 2 = front_left 3 = bottom_center #下视画面 4 = back_center ''' cameraUse="3" # 连接到Airsim仿真器 #client = airsim.MultirotorClient()#默认本机 client = airsim.MultirotorClient("192.168.0.1")#局域网主机IP # 每1秒检查一次连接状态,并在控制台中报告,以便用户可以查看连接的进度(应该是开启了个线程,因为只是调用了一次) client.confirmConnection() #开启api控制,默认是false,有的设备不允许用API控制,所以用isApiControlEnabled可以查看是否可以用API控制 client.enableApiControl(True) #获取无人飞机的所有数据 Flystate = client.getMultirotorState() #s = pprint.pformat(state) #print("state: %s" % s) #从所有数据扣出 position坐标 北偏地坐标系 position1=Flystate.kinematics_estimated.position #print(position1) print("position位置") print(position1.x_val) print(position1.y_val) print(position1.z_val) #负为上升,北偏地坐标系 #从所有数据扣出 gps_data数据 经纬度 gps_data=Flystate.gps_location #print(gps_data) print("GPS数据") print(gps_data.altitude) print(gps_data.latitude) print(gps_data.longitude) #单独获取当前位置GPS数据的api #gps_data = client.getGpsData() #s = pprint.pformat(gps_data) #print("gps_data: %s" % s) #按键等待 airsim.wait_key('安任何按键,开始采集起飞') #起飞 landed = client.getMultirotorState().landed_state if landed == airsim.LandedState.Landed: print("taking off...") client.takeoffAsync().join() else: print("already flying...") client.hoverAsync().join() #悬停 client.hoverAsync().join() #飞行代码测试 有两种模式 定点飞和恒定速度飞 注销开启测试 ''' ----------------------------飞行控制模式1---------------------------------- (1)坐标点控制 初始化原点,化点为x,y,z是全局坐标位置,velocity是速度。 实现的效果是以 1m/s 的速度飞到 (5, 0) 点,3m 高的位置。 .join() 后缀的意思是程序在这里等待直到任务完成,也就是四旋翼到达目标位置点,同时到达设置的高度。 如果不加 .join() 后缀,则不用等待任务是否完成,函数直接返回,程序继续往下执行。 ''' ''' airsim.wait_key('Press any key to fly1') client.moveToZAsync(-3, 1).join() # 上升到3m高度 client.moveToPositionAsync(5, 0, -3, 1).join() # 飞到(5,0)点坐标 高度3米 速度1m/s client.moveToPositionAsync(5, 5, -3, 1).join() # 飞到(5,5)点坐标 高度3米 速度1m/s ''' ''' ----------------------------飞行控制模式2---------------------------------- (2) 速度运动控制模式 #全局坐标系是北东地坐标系 vx:全局坐标系下x轴方向上的速度 vy:全局坐标系下y轴方向上的速度 z:全局坐标系下的高度 duration:持续的时间,单位:秒 ''' ''' airsim.wait_key('Press any key to fly2') client.moveToZAsync(-6, 1).join() # 上升到6m高度 client.moveByVelocityZAsync(1, 0, -6, 3).join() # 第三阶段:以1m/s速度向x前飞3秒钟 -6米高度 client.moveByVelocityZAsync(0, 1, -6, 3).join() # 第三阶段:以1m/s速度向y前飞3秒钟 -6米高度 ''' #按键等待 airsim.wait_key('按任何按键,开始采集图像,记得修改相机编号和图像类型') client.moveToZAsync(-10, 10).join() #飞到10米高 10米速度 #client.moveByVelocityZAsync(0, 1, -10, 9) # 以y轴1m/s速度向y前飞9秒钟 10米高度 为了移动采集画面,不用等待join() 结束 client.moveByVelocityZAsync(100, 0, -10, 2) #2米/妙速度 10米高度 飞到 (100 ,0)位置 #---------------------画图输出帧率字体格式------------------ fontFace = cv2.FONT_HERSHEY_SIMPLEX fontScale = 0.5 thickness = 2 textSize, baseline = cv2.getTextSize("FPS", fontFace, fontScale, thickness) print (textSize) textOrg = (10, 10 + textSize[1]) frameCount = 0 startTime=time.clock() fps = 0 #---------------------画图输出帧率字体格式------------------ cv2.namedWindow("Airsim", cv2.WINDOW_NORMAL) while True: # because this method returns std::vector<uint8>, msgpack decides to encode it as a string unfortunately. rawImage = client.simGetImage(cameraUse, cameraTypeMap[cameraType])#获取airsim原始格式视频数据 if (rawImage == None): print("图像为空") #sys.exit(0) continue else: png = cv2.imdecode(airsim.string_to_uint8_array(rawImage), cv2.IMREAD_UNCHANGED)#AIRSIM转换数据OPENCV cv2.putText(png,'FPS ' + str(fps),textOrg, fontFace, fontScale,(255,0,255),thickness) cv2.imshow("Airsim", png) frameCount = frameCount + 1 endTime=time.clock() diff = endTime - startTime if (diff > 1): fps = frameCount frameCount = 0 startTime = endTime key = cv2.waitKey(1) & 0xFF; if (key == 27 or key == ord('q') or key == ord('Q')): break; cv2.destroyAllWindows() #降落 landed = client.getMultirotorState().landed_state if landed == airsim.LandedState.Landed: print("already landed...") else: print("landing...") client.landAsync().join() # 上锁 client.armDisarm(False) client.reset() #关闭控制 client.enableApiControl(False)
四旋翼飞行控制 API 讲解
AirSim 坐标系定义总结
水平位置控制函数
函数定义:
def moveToPositionAsync( self, x, # 位置坐标(北东地坐标系) y, z, velocity, # 速度 timeout_sec=3e38, drivetrain=DrivetrainType.MaxDegreeOfFreedom, yaw_mode=YawMode(), lookahead=-1, adaptive_lookahead=1, vehicle_name="", )
输入参数包括:
x,y,z:位置坐标(全局坐标系 - 北东地) velocity: 飞行速度(m/s) timeout_sec: 如果没有响应,超时时间 drivetrain,yaw_mode: 设置飞行朝向模式和yaw角控制模式 lookahead, adaptive_lookahead: 设置路径飞行的时候的yaw角控制模式 vehicle_name: 控制的四旋翼名字
x, y, z, velocity 这四个参数是必须要设置的量,指示四旋翼以多大的速度飞往哪个坐标点。后面的几个参数都有其默认值,不用设置也可以。
lookahead 和 adaptive_lookahead 这两个参数是设置当四旋翼飞轨迹的时候的朝向,目前还用不到。
vehicle_name 是将指令发送给哪个四旋翼,当做多个四旋翼协同飞行控制的时候,这个参数就派上用场了,后面会有多机协同编队的教程。
drivetrain 和 yaw_mode 这两个参数的组合可以设置四旋翼的偏航角控制模式,下面详细介绍。
2.3 偏航角控制模式详解
drivetrain 参数可以设置为两个量:
airsim.DrivetrainType.ForwardOnly
: 始终朝向速度方向airsim.DrivetrainType.MaxDegreeOfFreedom
:手动设置yaw角度
yaw_mode 必须设置为 YawMode() 类型的变量,这个结构体类型包含两个属性:
- YawMode().is_rate:True - 设置角速度;False - 设置角度
- YawMode().yaw_or_rate:可以是任意浮点数
AirSim 坐标系定义总结
Unreal 引擎中的坐标系与 AirSim 定义的坐标系是不同的,甚至长度单位都不同。Unreal的长度单位是厘米,而AirSim的长度单位是米。不过不用担心,AirSim已经非常好的处理了这个问题,你不用管Unreal的坐标系是什么,只需要按照AirSim的坐标系设置即可,AirSim会帮你自动转换的。
本文先说明两个坐标系的定义: 全局坐标系、机体坐标系。
全局坐标系是固连到大地的,x,y,z三个坐标轴的指向分别是北,东,地,也就是朝北是x轴的正方向,朝南就是x轴的负方向。全局坐标系的原点位置是大地的某一点(可以在settings文件中设置)。
机体坐标系是固连到四旋翼机身的,x,y,z三个坐标轴的指向分别是前,右,下,也就是飞机的前方是x轴的正方向,飞机后方是x轴的负方向。机体坐标系的原点位置是机体的重心位置。
如果按照1.2节的设置,将 playerStart的旋转都设为0,那么仿真刚开始的时候,四旋翼的机体坐标系与全局坐标系是重合的。
暂停和继续的API
可以使用pause(True)
实现暂停。可能会遇到这样的情况,特别是在使用强化学习时,会在指定的时间内运行模拟,然后自动暂停。当模拟暂停时,可以执行一些昂贵的计算,发送一个新命令,然后在指定的时间内再次运行模拟。这个也可以使用continueForTime(seconds)
实现(非常重要,太关键了),执行一段时间然后暂停。这个例子的使用,可以参考 pause_continue_car.py 和 pause_continue_drone.py.