本文总结一下AirSim中无人机相关常用的最基本的API函数接口。
1. 无人机起飞降落
建立通信
client = airsim.MultirotorClient()
获得API控制权
client.enableApiControl(True)
释放API控制权
client.enableApiControl(False)
解锁旋翼
client.armDisarm(True)
关闭旋翼
client.armDisarm(False)
起飞
client.takeoffAsync(timeout_sec = 20, vehicle_name = '')
降落
client.landAsync(timeout_sec = 60, vehicle_name = '')
回到起始位置
client.goHomeAsync(timeout_sec = 3e+38, vehicle_name = '')
这里的返回起始位置是指从终点沿直线返回终点
悬停
client.hoverAsync(vehicle_name = '')
通常配合time.sleep(timesec)
使用,来表示悬停多少秒
2. 获取无人机状态
2.1 获取估计状态
- 这个状态是由传感器估计的状态,并不是无人机状态的真值。
- AirSim默认的无人机底层飞控 simple_flight 并不支持状态估计,所以如果是simple_flight 飞控,此函数得到的状态与真值相同。
- 使用PX4 飞控可以获取估计的状态
state = client.getMultirotorState(vehicle_name = '')
其中无人机的状态变量 state
包含如下:
class MultirotorState(MsgpackMixin):
collision = CollisionInfo() # 碰撞信息
kinematics_estimated = KinematicsState() # 动力学状态信息
gps_location = GeoPoint() # GPS信息
timestamp = np.uint64(0) # 时间戳,从仿真开始到当前时刻的时间间隔
landed_state = LandedState.Landed # 是否是降落状态
rc_data = RCData() # 遥控器数据
ready = False # 无人机是否准备好飞行
ready_message = "" # 无人机是否准备就绪的附加信息
can_arm = False # 无人机是否可以解锁
碰撞信息的定义:
class CollisionInfo(MsgpackMixin):
has_collided = False # 是否发生碰撞
normal = Vector3r() # 碰撞发生时的法线向量,这个向量通常垂直于碰撞表面
impact_point = Vector3r() # 碰撞点的位置,碰撞发生时物体接触的具体点
position = Vector3r() # 发生碰撞时物体的位置
penetration_depth = 0.0 # 碰撞导致的穿透深度(严重程度)
time_stamp = 0.0 # 碰撞发生的时间戳
object_name = "" # 发生碰撞的对象的名称
object_id = -1 # 发生碰撞的对象的唯一标识符
动力学状态信息的定义:
class KinematicsState(MsgpackMixin):
position = Vector3r() # 物体在空间中的位置
orientation = Quaternionr() # 姿态角,在空间中的方向和旋转,用四元数表示
linear_velocity = Vector3r() # 线性速度
angular_velocity = Vector3r() # 机体角速度
linear_acceleration = Vector3r() # 线性加速度
angular_acceleration = Vector3r() # 机体角加速度
GPS 信息包含:
class GeoPoint(MsgpackMixin):
latitude = 0.0 # 维度
longitude = 0.0 # 经度
altitude = 0.0 # 海拔
在起飞时获取的估计状态参数值如下
<MultirotorState> {
'collision': <CollisionInfo> # 碰撞信息
{
'has_collided': False, # 是否发生碰撞
'impact_point': <Vector3r> # 碰撞点的位置,碰撞发生时物体接触的具体点
{
'x_val': 0.0,
'y_val': 0.0,
'z_val': 0.0
},
'normal': <Vector3r> # 碰撞发生时的法线向量,这个向量通常垂直于碰撞表面
{
'x_val': 0.0,
'y_val': 0.0,
'z_val': 0.0
},
'object_id': -1, # 发生碰撞的对象的唯一标识符
'object_name': '', # 发生碰撞的对象的名称
'penetration_depth': 0.0, # 碰撞导致的穿透深度(严重程度)
'position': <Vector3r> # 发生碰撞时物体的位置
{
'x_val': 0.0,
'y_val': 0.0,
'z_val': 0.0
},
'time_stamp': 0 # 碰撞发生的时间戳
},
'gps_location': <GeoPoint> # GPS信息
{
'altitude': 121.37482452392578,
'latitude': 47.641468012630014,
'longitude': -122.1401651312439
},
'kinematics_estimated': <KinematicsState> # 动力学状态信息
{
'angular_acceleration': <Vector3r> # 机体角加速度
{
'x_val': 0.0,
'y_val': 0.0,
'z_val': 0.0
},
'angular_velocity': <Vector3r> # 机体角速度
{
'x_val': 0.0,
'y_val': 0.0,
'z_val': 0.0
},
'linear_acceleration': <Vector3r> # 线性加速度
{
'x_val': 0.0,
'y_val': 0.0,
'z_val': 0.0
},
'linear_velocity': <Vector3r> # 线性速度
{
'x_val': 0.0,
'y_val': 0.0,
'z_val': 0.0
},
'orientation': <Quaternionr> # 姿态角,在空间中的方向和旋转,用四元数表示
{
'w_val': 1.0,
'x_val': 0.0,
'y_val': 0.0,
'z_val': 0.0
},
'position': <Vector3r> # 物体在空间中的位置
{
'x_val': 0.0,
'y_val': 0.0,
'z_val': 0.628971517086029
}
},
'landed_state': 0, # 是否是降落状态
'rc_data': <RCData> # 遥控器数据
{
'is_initialized': False,
'is_valid': False,
'left_z': 0.0,
'pitch': 0.0,
'right_z': 0.0,
'roll': 0.0,
'switches': 0,
'throttle': 0.0,
'timestamp': 0,
'vendor_id': '',
'yaw': 0.0
},
'timestamp': 1706536051897009408 # 时间戳
}
2.2 获取状态真值
kinematics_state = client.simGetGroundTruthKinematics(vehicle_name = '')
在起飞时获取的状态真值参数值如下
<KinematicsState>
{
'angular_acceleration': <Vector3r> # 机体角加速度
{
'x_val': 0.0,
'y_val': 0.0,
'z_val': 0.0
},
'angular_velocity': <Vector3r> # 机体角速度
{
'x_val': 0.0,
'y_val': 0.0,
'z_val': 0.0
},
'linear_acceleration': <Vector3r> # 线性加速度
{
'x_val': 0.0,
'y_val': 0.0,
'z_val': 0.0
},
'linear_velocity': <Vector3r> # 线性速度
{
'x_val': 0.0,
'y_val': 0.0,
'z_val': 0.0
},
'orientation': <Quaternionr> # 姿态角,在空间中的方向和旋转,用四元数表示
{
'w_val': 1.0,
'x_val': 0.0,
'y_val': 0.0,
'z_val': 0.0
},
'position': <Vector3r> # 物体在空间中的位置
{
'x_val': 0.0,
'y_val': 0.0,
'z_val': 0.6289318799972534
}
}
3. 无人机控制
3.1 位置控制
x,y,z是全局坐标系下的三维位置坐标指令。用于将无人机移动到指定的三维坐标位置。
client.moveToPositionAsync( # 将无人机移动到指定的三维坐标位置
x,
y,
z, # 目标位置的 x, y, z 坐标
velocity, # 移动到目标位置的速度
timeout_sec = 3e+38, # 操作的超时时间
drivetrain = DrivetrainType.MaxDegreeOfFreedom, # 驱动类型,可在所有方向上移动
yaw_mode = YawMode(), # 控制无人机偏航(旋转)的模式
lookahead = -1, # 预先查看的距离,用于路径规划
adaptive_lookahead = 1, # 是否使用自适应预先查看
vehicle_name = ''
)
在该指令中,速度velocity
指的是无人机移动到目标位置时的合速度(速率)。这个速度值是一个标量,表示无人机在向目标位置移动时的速度大小,而不是一个向量,它不直接指定方向。
client.moveToPositionAsync(5, 4, -6, 1).join()
当参数值如上时,运行轨迹如下所示:
3.2 速度控制
vx,vy,vz是全局坐标系(NED)下的速度指令。用于按指定的速度向量控制无人机移动。
client.moveByVelocityAsync(
vx,
vy,
vz, # 三维速度矢量
duration, # 移动时间
drivetrain = DrivetrainType.MaxDegreeOfFreedom, # 驱动类型,可在所有方向上移动
yaw_mode = YawMode(), # # 控制无人机偏航(旋转)的模式
vehicle_name = ''
)
client.moveByVelocityAsync(1, 2, -1, 8).join()
client.landAsync().join()
在速度控制飞行一段距离后,会有一个减速的阶段,这个时候下降会出现抛物线轨迹
client.moveByVelocityAsync(1, 2, -1, 8).join()
client.hoverAsync().join() # 加入悬停
time.sleep(2)
client.landAsync().join()
当飞行结束后,会控制无人机悬停一段时间来保持飞行姿态,机身稳定后再着陆。
在下图中会出现无人机悬停时,由于惯性向前飞一段距离,然后通过无人机自身定位微调位置来定位着陆点。
3.3 水平速度控制(指定高度)
vx,vy是全局坐标系(NED)下的速度指令,z是全局高度指令。控制无人机以特定的水平速度移动,同时保持在特定的高度。
client.moveByVelocityZAsync(
vx,
vy, # 二维水平速度矢量
z, # 保持飞行的高度
duration,
drivetrain = DrivetrainType.MaxDegreeOfFreedom,
yaw_mode = YawMode(),
vehicle_name = ''
)
通常在moveToZAsync()
后使用,来维持在一定高度
3.4 水平姿态角控制(指定高度)
pitch, roll是水平姿态角指令,z 是全局高度指令,yaw是偏航角指令。控制无人机的姿态角,同时保持在特定的高度。
client.moveByRollPitchYawZAsync(
roll, # 无人机的滚转角
pitch, # 无人机的俯仰角
yaw, # 无人机的偏航角
z, # 保持飞行的高度
duration,
vehicle_name = ''
)
3.5 水平姿态角控制(高度油门控制)
pitch, roll是水平姿态角指令,throttle 是油门量指令,yaw_rate是偏航角速率指令。通过控制无人机的姿态角和油门来控制其运动。
moveByAngleThrottleAsync(
pitch, # 无人机的俯仰角
roll, # 无人机的滚转角
throttle, # 油门值,控制上升或下降的力度
yaw_rate, # 偏航速率
duration,
vehicle_name = ''
)
3.6 高度控制
z 是全局高度指令,velocity是垂直速度。用于控制无人机到达指定的高度。
(注意是往下为z轴正方形)
client.moveToZAsync(
z, # 目标高度
velocity, # 移动到目标高度的速度
timeout_sec = 3e+38,
yaw_mode = YawMode(), # 控制无人机偏航(旋转)的模式
lookahead = -1, # 预先查看的距离,用于路径规划
adaptive_lookahead = 1, # 是否使用自适应预先查看
vehicle_name = ''
)
3.7 偏航角控制
用于控制无人机旋转到特定的偏航角。(水平面内旋转,+alpha角就是顺时针旋转)
client.rotateToYawAsync(
yaw, # 目标偏航角度
timeout_sec = 3e+38,
margin = 5, # 达到目标偏航角的允许误差范围
vehicle_name = ''
)
3.8 偏航角速率控制
用于按指定的速率旋转无人机的偏航角。
client.rotateByYawRateAsync(
yaw_rate, # 偏航角速率(每秒旋转的度数)
duration,
vehicle_name = ''
)
3.9 沿路径飞行
用于沿预定路径飞行。
client.moveOnPathAsync(
path, # 一系列点的列表,定义了无人机应该沿着飞行的路径
velocity, # 沿路径飞行的速度
timeout_sec = 3e+38,
drivetrain = DrivetrainType.MaxDegreeOfFreedom,
yaw_mode = YawMode(),
lookahead = -1,
adaptive_lookahead = 1,
vehicle_name = ''
)
3.10 遥控器控制
由遥控器信号控制,vx_max, vy_max是速度限制,z_min 是最低高度限制。
client.moveByManualAsync(
vx_max,
vy_max,
z_min,
duration,
drivetrain = DrivetrainType.MaxDegreeOfFreedom,
yaw_mode = YawMode(),
vehicle_name = ''
)
3.11 遥控器控制(程序定义遥控器信号量)
client.moveByRC(rcdata = RCData(), vehicle_name = '')
rcdata
包括:
- timestamp
- pitch
- roll
- throttle
- yaw
- switch1
- switch2
- switch3
- switch4
- switch5
- switch6
- switch7
- switch8
- is_initialized
- is_valid
4. 无人机底层飞控
(看不懂,忽略了)
4.1 直接控制四个电机
client.moveByMotorPWMsAsync(
front_right_pwm,
rear_left_pwm,
front_left_pwm,
rear_right_pwm,
duration,
vehicle_name = ''
)
4.2 姿态角控制、指定高度控制
roll, pitch, yaw 姿态角指令,z 高度指令
client.moveByRollPitchYawZAsync(
roll,
pitch,
yaw,
z,
duration,
vehicle_name = ''
)
4.3 姿态角控制、高度油门控制
client.moveByRollPitchYawThrottleAsync(
roll,
pitch,
yaw,
throttle,
duration,
vehicle_name = ''
)
4.4 俯仰翻滚姿态角、偏航角速率、高度油门控制
client.moveByRollPitchYawrateThrottleAsync(
roll,
pitch,
yaw_rate,
throttle,
duration,
vehicle_name = ''
)
4.5 俯仰翻滚姿态角、偏航角速率、指定高度控制
client.moveByRollPitchYawrateZAsync(
roll,
pitch,
yaw_rate,
z,
duration,
vehicle_name = ''
)
4.6 姿态角速率、指定高度
client.moveByAngleRatesZAsync(
roll_rate,
pitch_rate,
yaw_rate,
z,
duration,
vehicle_name = ''
)
4.7 姿态角速率、高度油门控制
client.moveByAngleRatesThrottleAsync(
roll_rate,
pitch_rate,
yaw_rate,
throttle,
duration,
vehicle_name = ''
)
4.8 更改角速度环控制器参数
client.setAngleRateControllerGains(
angle_rate_gains=AngleRateControllerGains(),
vehicle_name = ''
)
4.9 更改角度环控制器参数
client.setAngleLevelControllerGains(
angle_level_gains=AngleLevelControllerGains(),
vehicle_name = ''
)
4.10 更改速度环控制器参数
client.setVelocityControllerGains(
velocity_gains=VelocityControllerGains(),
vehicle_name = ''
)
4.11 更改位置环控制器参数
client.setPositionControllerGains(
position_gains=PositionControllerGains(),
vehicle_name = ''
)
5. Async
这里面的很多控制函数都有 dutation
或者 timeout_sec
,而且函数有 Async
后缀。这些方法的调用会立即返回,即使其所指定的任务还没有完成,这样程序可以继续往下执行,而不用在这里等待仿真中的无人机把任务执行完。如果想要程序在这里等待任务执行完,则需要在方法后面加上 .join()
。例如,让四旋翼起飞,如果想要程序一直在这里等待四旋翼起飞完成,然后再执行后面的语句,则可以用client.takeoffAsync().join()
6. 任务覆盖
在代码执行时,如果使用的都是立即返回,那么很有可能在仿真中,无人机的上一个任务还没有执行完,新的任务就又到来了,此时旧的任务会被取消,新的任务会覆盖掉旧的任务,无人机会立即执行最新的任务。
7. 偏航角控制
drivetrain 和 yaw_mode 这两个参数的组合可以设置四旋翼的偏航角控制模式。
drivetrain 参数可以设置为两个量:
airsim.DrivetrainType.ForwardOnly
: 始终朝向速度方向airsim.DrivetrainType.MaxDegreeOfFreedom
:手动设置yaw角度
yaw_mode 必须设置为 YawMode() 类型的变量,这个结构体类型包含两个属性:
- YawMode().is_rate:True - 设置角速度;False - 设置角度
- YawMode().yaw_or_rate:可以是任意浮点数
下面总结一下这两个参数的设置对效果的影响:
ForwardOnly | MaxDegreeOfFreedom | |
---|---|---|
is_rate=True | 不允许 | yaw角以yaw_or_rate度/秒旋转 |
is_rate=False | yaw角相对于速度方向偏差yaw_or_rate度 | yaw角相对正北方向偏差yaw_or_rate度 |