快乐人L 发表于 2021-1-23 16:44

airsim系列(五) - 控制四旋翼的飞行(core api)

本节继续介绍 AirSim 的 core api,如何控制四旋翼的飞行。
本文的主要内容有:让四旋翼飞一个正方形、详细介绍四旋翼位置控制API、AirSim坐标系定义。
1. 四旋翼飞正方形代码

1.1 完整代码

"""
square flight
"""
import airsim
import time

# connect to the AirSim simulator
client = airsim.MultirotorClient()

client.enableApiControl(True)   # get control
client.armDisarm(True)          # unlock
client.takeoffAsync().join()    # takeoff

# square flight
client.moveoZAsync(-3, 1).join()               # 上升到3m高度
client.moveToPositionAsync(5, 0, -3, 1).join()# 飞到(5,0)点坐标
client.moveToPositionAsync(5, 5, -3, 1).join()# 飞到(5,5)点坐标
client.moveToPositionAsync(0, 5, -3, 1).join()# 飞到(0,5)点坐标
client.moveToPositionAsync(0, 0, -3, 1).join()# 回到(0,0)点坐标

client.landAsync().join()       # land
client.armDisarm(False)         # lock
client.enableApiControl(False)# release control
此代码能够实现的效果是:
第一阶段:起飞第二阶段:上升到3米高度第三阶段:飞正方形
向前飞 5 米向右飞 5 米向后飞 5 米向左飞 5 米,回到起飞点
第四阶段:降落
1.2 飞行效果



注意,如果你的仿真在刚开始的时候,四旋翼并不是正对前方(下图是正对前方的效果)。
说明 player start 的位置是有角度的,将其改成 0 即可。
1.3 代码讲解

client = airsim.MultirotorClient()# connect to the AirSim simulator

client.enableApiControl(True)   # get control
client.enableApiControl(False)# release control

client.armDisarm(True)          # unlock
client.armDisarm(False)         # lock

client.takeoffAsync().join()    # takeoff
client.landAsync().join()       # land以上是之前学习过的,如果有不懂的可以看上一篇文章。


client.moveToZAsync(-3, 1).join()   # 高度控制moveToZAsync(z, velocity) 是高度控制 API,第一个参数是高度,第二个参数是速度。实现的效果是以 1m/s 的速度飞到 3 米高。.join() 后缀的意思是程序在这里等待直到任务完成,也就是四旋翼达到 3 米的高度。如果不加.join()后缀,则不用等待任务是否完成,函数直接返回,程序继续往下执行。


client.moveToPositionAsync(5, 0, -3, 1).join()# 飞到(5,0)点坐标
client.moveToPositionAsync(5, 5, -3, 1).join()# 飞到(5,5)点坐标
client.moveToPositionAsync(0, 5, -3, 1).join()# 飞到(0,5)点坐标
client.moveToPositionAsync(0, 0, -3, 1).join()# 回到(0,0)点坐标moveToPositionAsync(x, y, z, velocity) 是水平位置控制 API,x,y,z是全局坐标位置,velocity是速度。实现的效果是以 1m/s 的速度飞到 (5, 0) 点,3m 高的位置。.join() 后缀的意思是程序在这里等待直到任务完成,也就是四旋翼到达目标位置点,同时到达设置的高度。如果不加 .join() 后缀,则不用等待任务是否完成,函数直接返回,程序继续往下执行。


2. 四旋翼飞行控制 API 讲解

2.1 四旋翼底层飞控通道简介

关于四旋翼的非线性建模和底层控制器设计,在后面的文章中详细讲解,目前先简单介绍一下四旋翼的底层飞控可以控制什么量。当四旋翼低速飞行时,其底层飞控可以解耦为3个通道:
水平通道高度通道偏航通道
这3个通道可以分别控制,可以理解为通道之间相互不会影响。水平通道可以控制四旋翼的水平位置、水平速度、水平姿态角;高度通道可以控制垂直高度、垂直速度、垂直加速度;偏航通道可以控制偏航角度、偏航角速度、偏航角加速度。
本文例子程序中的 x,y 是水平通道的指令,控制四旋翼水平方向的飞行;z 是高度通道指令,控制四旋翼的高度。本文例子程序中没有偏航通道指令,默认的偏航是 0,也就是四旋翼自身不会水平旋转,其朝向始终朝向前方。


2.2 水平位置控制函数

函数定义:
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:可以是任意浮点数
下面分几种情况讨论:
情况1 (不允许):
drivetrain = airsim.DrivetrainType.ForwardOnly
yaw_mode = airsim.YawMode(True, 0)
client.moveToPositionAsync(x, y, z, velocity, drivetrain=drivetrain, yaw_mode=yaw_mode).join()当drivetrain = airsim.DrivetrainType.ForwardOnly 时,四旋翼始终朝向其飞行的方向,这时 yaw_mode 不允许设置为 YawMode().is_rate = True。因为前面的参数要求四旋翼朝向运动方向,而 yaw_mode 要求四旋翼以一定的角速度旋转,这是矛盾的。
情况2:
drivetrain = airsim.DrivetrainType.ForwardOnly
yaw_mode = airsim.YawMode(False, 90)
client.moveToPositionAsync(x, y, z, velocity, drivetrain=drivetrain, yaw_mode=yaw_mode).join()这种情况下,四旋翼的朝向始终与前进方向相差90度,也就是四旋翼始终向左侧方向运动。例如:当四旋翼在绕着一个圆心转圈时,其朝向始终指向圆心(这种飞行状态的代码在下一篇文章中给出)。这里的90度可以任意设置。
情况3:
drivetrain = airsim.DrivetrainType.MaxDegreeOfFreedom
yaw_mode = airsim.YawMode(False, 0)
client.moveToPositionAsync(x, y, z, velocity, drivetrain=drivetrain, yaw_mode=yaw_mode).join()这种情况下,不管速度方向是什么,四旋翼的yaw角始终等于0, 也就是其朝向始终指向正北方向。如果是90度,则始终指向正东方向,而-90度,则始终指向正西方向。
情况4:
drivetrain = airsim.DrivetrainType.MaxDegreeOfFreedom
yaw_mode = airsim.YawMode(True, 10)
client.moveToPositionAsync(x, y, z, velocity, drivetrain=drivetrain, yaw_mode=yaw_mode).join()这种情况下,四旋翼不管速度方向是什么,yaw角以10度/秒的速度旋转。


下面总结一下这两个参数的设置对效果的影响:
ForwardOnlyMaxDegreeOfFreedomis_rate=True不允许yaw角以yaw_or_rate度/秒旋转is_rate=Falseyaw角相对于速度方向偏差yaw_or_rate度yaw角相对正北方向偏差yaw_or_rate度为什么0度是正北方向呢,这就涉及到坐标系的定义了,下面先简单介绍一下坐标系的定义。
3. AirSim 坐标系定义总结

Unreal 引擎中的坐标系与 AirSim 定义的坐标系是不同的,甚至长度单位都不同。Unreal的长度单位是厘米,而AirSim的长度单位是米。不过不用担心,AirSim已经非常好的处理了这个问题,你不用管Unreal的坐标系是什么,只需要按照AirSim的坐标系设置即可,AirSim会帮你自动转换的。


本文先说明两个坐标系的定义: 全局坐标系、机体坐标系。
全局坐标系是固连到大地的,x,y,z三个坐标轴的指向分别是北,东,地,也就是朝北是x轴的正方向,朝南就是x轴的负方向。全局坐标系的原点位置是大地的某一点(可以在settings文件中设置)。
机体坐标系是固连到四旋翼机身的,x,y,z三个坐标轴的指向分别是前,右,下,也就是飞机的前方是x轴的正方向,飞机后方是x轴的负方向。机体坐标系的原点位置是机体的重心位置。
如果按照1.2节的设置,将 playerStart的旋转都设为0,那么仿真刚开始的时候,四旋翼的机体坐标系与全局坐标系是重合的。
页: [1]
查看完整版本: airsim系列(五) - 控制四旋翼的飞行(core api)