大模型驱动的智能无人机应用开发2:无人机基本控制

AirSim 中无人机控制主要分为 手动控制编程(API)控制 两大类。手动控制依赖于 RC 遥控器、键盘或游戏手柄等外部输入设备;而编程控制则通过 AirSim 各语言客户端提供的 RPC 接口,按需调用相应命令,实现无人机的自动化飞行。

1. 手动控制

1.1 RC 遥控器控制

  • AirSim 支持硬件在环(HIL),可以将真实的飞控(如 PX4)和 RC 遥控器信号桥接到模拟环境中进行测试。通过在 settings.json 中配置相应端口和设备,即可在模拟器中使用手柄或遥杆直接操控无人机 。

1.2 键盘 / 控制台控制

  • 借助第三方脚本(例如 Zartris/Airsim-terminal-drone-control),可以在终端通过命令或键盘按键(W/A/S/D 控制平移,E/Q 控制偏航,Z/X 控制上下,T 退出模式)实时操控无人机 。

2. 编程(API)控制

2.1 通用控制接口

所有客户端(C++/Python/…)都提供下列通用接口:

  • reset():重置无人机到初始状态。

  • confirmConnection():检查并确认与模拟器的连接状态。

  • enableApiControl(bool) / isApiControlEnabled():开启/查询 API 控制授权,若未授权则后续命令被忽略 。

  • armDisarm(bool):解锁(上锁)电机,必须在起飞前调用以启动飞控 。

  • ping()simPrintLogMessage() 等调试与仿真专用接口。

2.2 多旋翼专用控制接口

AirSim 对多旋翼(Multirotor)提供了一系列分层次的控制 API,从最高层的 路径点控制 到最低层的 电机 PWM 直写

2.2.1 起飞/降落/返航

  • takeoffAsync(timeout_sec):异步起飞到离地 3 m 高度,返回 Future,可通过 .join() 等待完成。

  • landAsync(timeout_sec):异步降落,返回 Future

  • goHomeAsync():返航至起始点并悬停,与 takeoffAsynclandAsync 参数相同。

  • hoverAsync():在当前位置悬停。

2.2.2 位置(Position)控制

  • moveToPositionAsync(x, y, z, velocity, max_wait_sec):以给定速度将无人机移动到指定 NED 坐标点。

  • moveOnPathAsync(path_points, velocity, drivetrain, yaw_mode, lookahead, adaptive_lookahead):按路径点序列跟踪飞行,内部使用“胡萝卜跟踪(carrot following)”算法。

  • moveToZAsync(z, velocity, max_wait_sec):保持 X/Y 不变,移动至指定 Z 轴高度 。

2.2.3 速度(Velocity)控制

  • moveByVelocityAsync(vx, vy, vz, duration, drivetrain, yaw_mode):在持续时间内以指定 NED 速度分量飞行。

  • moveByVelocityZAsync(vx, vy, z, duration, drivetrain, yaw_mode):指定水平速度与目标高度同时控制。

2.2.4 姿态/角度(Attitude/Angle)控制

  • moveByRollPitchYawThrottleAsync(roll, pitch, yaw, throttle, duration):按给定姿态角(弧度)和推力比控制飞行 。

  • moveByRollPitchYawZAsync(roll, pitch, yaw, z, duration):姿态角与高度混合控制 。

2.2.5 角速度(Angular Rate)控制

  • moveByAngleRatesThrottleAsync(roll_rate, pitch_rate, yaw_rate, throttle, duration):指定三轴角速度和推力比。

  • moveByAngleRatesZAsync(roll_rate, pitch_rate, yaw_rate, z, duration):角速度与高度混合控制 。

2.2.6 电机 PWM 直接控制

  • moveByMotorPWMsAsync(motor1, motor2, motor3, motor4, duration):直接对四个电机的 PWM 值进行设置,最低层控制 。

2.2.7 RC/手动模式模拟

  • moveByRC(rc_data):模拟 RC 遥控器输入,适用于需要在仿真中测试手动飞控逻辑的场景 。

  • moveByManualAsync(vx_max, vy_max, z_min, duration, drivetrain, yaw_mode):读取实时 RC 状态并根据设定约束进行限制飞行。

2.3 参数设置与控制器调优

  • DrivetrainForwardOnly(机头始终指向速度方向)或 MaxDegreeOfFreedom(机体可横向移动,如螃蟹行走)。

  • YawMode:由 yaw_or_rate(角度或角速度)和 is_rate(布尔)共同决定偏航角度设定的含义 。

  • lookahead/adaptive_lookahead:路径跟踪时“胡萝卜跟踪”算法的前视距离与自适应控制 。

  • PID 增益:可通过 setAngleLevelControllerGains()setVelocityControllerGains()setPositionControllerGains() 等接口调整底层控制器增益

!pip install numpy
import sys
sys.path.append('../external-libraries')
import airsim
import math
import numpy as np

# connect to the AirSim simulator
#client = airsim.MultirotorClient(ip="192.168.31.194") #ip不写就是本地,写了就是跑airsim的机器
client = airsim.MultirotorClient() #ip不写就是本地,写了就是跑airsim的机器
client.confirmConnection()

# get control,允许api控制,默认是不允许的
client.enableApiControl(True)

# unlock,解锁,流程和真实飞行器一样
client.armDisarm(True)

# takeoff,起飞,很多无人机或者汽车控制的函数都有 Async/异步作为后缀,执行的时候会立即返回,不阻塞
# 但命令本身还是顺序执行的,所以需要join等待命令执行完毕,上一个命令执行完成,才会执行下一个命令
# 也可以不join,直接执行下一个命令,但是这样的话,就不知道上一个命令是否执行完成了,需要自己控制
client.takeoffAsync().join()
print("起飞-------------------------")

#降落
client.landAsync().join()
print("降落-------------------------")



# lock
client.armDisarm(False)

# release control
client.enableApiControl(False)

定点飞行-offboard

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

# get control,允许api控制,默认是不允许的
client.enableApiControl(True)

# unlock,解锁,流程和真实飞行器一样
client.armDisarm(True)


# takeoff,起飞,很多无人机或者汽车控制的函数都有 Async/异步作为后缀,执行的时候会立即返回,不阻塞
# 但命令本身还是顺序执行的,所以需要join等待命令执行完毕,上一个命令执行完成,才会执行下一个命令
# 也可以不join,直接执行下一个命令,但是这样的话,就不知道上一个命令是否执行完成了,需要自己控制
client.takeoffAsync().join()
print("起飞--------------------------------")


#moveToZAsync,坐标系是NED,所以正数是向上,负数是向下
client.moveToZAsync(-3, 1).join()   # 上升到3米高度,1是速度

# 初始化4个点的坐标,并在视口中标识出来
points = [airsim.Vector3r(5, 0, -3),
          airsim.Vector3r(5, 5, -3),
          airsim.Vector3r(0, 5, -3),
          airsim.Vector3r(0, 0, -3)]
client.simPlotPoints(points, color_rgba=[0, 1, 0, 1], size=30, is_persistent=True)

# 方法1:按照逐个点飞,形成正方形
client.moveToPositionAsync(5, 0, -3, 1).join()  # 移动到(5,0,-3)的位置,1是速度x, y, z
client.moveToPositionAsync(5, 5, -3, 1).join()
client.moveToPositionAsync(0, 5, -3, 1).join()
client.moveToPositionAsync(0, 0, -3, 1).join()

# 方法2:直接按照航路点飞正方形轨迹
client.moveOnPathAsync(points, 1)

#降落
client.landAsync().join()
print("降落----------------------------------------------")


# lock
client.armDisarm(False)

# release control
client.enableApiControl(False)

最终效果如下:

无人机的状态

在AirSim中,simGetGroundTruthKinematics 和 simGetVehiclePose 都是获取无人机状态的接口,但返回数据的精度、用途和底层含义有本质区别。以下是两者的详细对比:


1. simGetVehiclePose()

  • 功能:获取无人机的位姿(Pose),即位置和姿态。
  • 返回数据
    Pose(
        position=Vector3r(x, y, z),  # 位置(NED坐标系,单位:米)
        orientation=Quaternionr(w, x, y, z)  # 四元数姿态(相对世界坐标系)
    )
    
  • 特点
    • 数据来源于仿真的传感器模型(如GPS、IMU),可能包含噪声。
    • 模拟真实无人机传感器输出的结果,适合测试SLAM、导航等算法。
    • 如果AirSim设置中启用了传感器噪声(默认关闭),返回的坐标会有扰动。

2. simGetGroundTruthKinematics()

  • 功能:获取无人机的真实运动学状态(Ground Truth)。
  • 返回数据
    KinematicsState(
        position=Vector3r(x, y, z),  # 位置(绝对精确,NED坐标系)
        orientation=Quaternionr(w, x, y, z),  # 姿态(绝对精确)
        linear_velocity=Vector3r(vx, vy, vz),  # 线速度(米/秒)
        angular_velocity=Vector3r(wx, wy, wz),  # 角速度(弧度/秒)
        linear_acceleration=Vector3r(ax, ay, az),  # 线加速度(米/秒²)
        angular_acceleration=Vector3r(αx, αy, αz)  # 角加速度(弧度/秒²)
    )
    
  • 特点
    • 数据来源于仿真的物理引擎,是绝对精确的“上帝视角”数据,无任何噪声。
    • 适合用于算法验证(如对比传感器数据与真实值的误差)或控制算法设计(如直接获取速度反馈)。

3. 关键区别总结

特性 simGetVehiclePose() simGetGroundTruthKinematics()
数据来源 传感器模型(可能含噪声) 物理引擎(绝对精确)
数据维度 仅位置和姿态 位置、姿态、速度、加速度
用途 模拟真实传感器输出 算法验证、控制闭环设计
计算开销 低(仅读取传感器数据) 高(需从物理引擎获取完整状态)

4. 使用场景建议

  • 需要传感器级数据(如测试SLAM、避障):
    使用 simGetVehiclePose(),并启用传感器噪声(通过AirSim的设置文件配置)。

  • 需要真实状态验证(如控制器调试、轨迹跟踪):
    使用 simGetGroundTruthKinematics().position 或 linear_velocity

  • 需要动力学参数(如速度反馈、加速度前馈):
    直接读取 linear_velocity 和 linear_acceleration

import time
import airsim

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

# get control,允许api控制,默认是不允许的
client.enableApiControl(True)

# unlock,解锁,流程和真实飞行器一样
client.armDisarm(True)


# takeoff,起飞,很多无人机或者汽车控制的函数都有 Async/异步作为后缀,执行的时候会立即返回,不阻塞
# 但命令本身还是顺序执行的,所以需要join等待命令执行完毕,上一个命令执行完成,才会执行下一个命令
# 也可以不join,直接执行下一个命令,但是这样的话,就不知道上一个命令是否执行完成了,需要自己控制
client.takeoffAsync().join()
print("起飞--------------------------------")

#moveToZAsync,坐标系是NED,所以正数是向上,负数是向下
client.moveToZAsync(-3, 1).join()   # 上升到3米高度,1是速度

for i in range(2):
    kinematic_state_groundtruth = client.simGetGroundTruthKinematics(vehicle_name='')
    #print("kinematic_state_groundtruth: ", kinematic_state_groundtruth)

    # state_groundtruth 的6个属性
    print(
    "position", kinematic_state_groundtruth.position,  # 位置信息
    "\n\n linear_velocity", kinematic_state_groundtruth.linear_velocity,  # 速度信息
    "\n\n linear_acceleration", kinematic_state_groundtruth.linear_acceleration , # 加速度信息
    "\n\n orientation", kinematic_state_groundtruth.orientation,  # 姿态信息
    "\n\n angular_velocity", kinematic_state_groundtruth.angular_velocity,  # 姿态角速率信息
    "\n\n angular_acceleration", kinematic_state_groundtruth.angular_acceleration,  # 姿态角加速度信息
    )

    # 无人机全局位置坐标真值
    x = kinematic_state_groundtruth.position.x_val  # 全局坐标系下,x轴方向的坐标
    y = kinematic_state_groundtruth.position.y_val  # 全局坐标系下,y轴方向的坐标
    z = kinematic_state_groundtruth.position.z_val  # 全局坐标系下,z轴方向的坐标
    print("x: ", x, "y: ", y, "z: ", z)

    time.sleep(1)
    print("-----------------------------------------------------------------------------------")

 输出结果为:

position  {   'x_val': 0.024876724928617477,
    'y_val': -0.03703678771853447,
    'z_val': -2.6352598667144775} 

 linear_velocity  {   'x_val': 0.0,
    'y_val': 0.0,
    'z_val': 0.04969768971204758} 

 linear_acceleration  {   'x_val': 0.0,
    'y_val': 0.0,
    'z_val': 1.3143653869628906} 

 orientation  {   'w_val': 0.9999985098838806,
    'x_val': 0.0,
    'y_val': 0.0,
    'z_val': -0.0016540370415896177} 

 angular_velocity  {   'x_val': 0.0,
    'y_val': 0.0,
    'z_val': 0.0} 

 angular_acceleration  {   'x_val': 0.0,
    'y_val': 0.0,
    'z_val': 0.0}
x:  0.024876724928617477 y:  -0.03703678771853447 z:  -2.6352598667144775

3.项目资源

项目github:GitHub - maris205/airsim_agent

项目huggingface:dnagpt/airsim_agent · Hugging Face

网易云课堂:大模型驱动的智能无人机应用开发 - 网易云课堂

你可能感兴趣的:(无人机大模型,无人机,python,nlp,transformer,chatgpt,大模型,深度学习)