简介:VTOL-AirLib是一份面向垂直起降(VTOL)飞机仿真与控制的AirLib增强版源码资源,基于C++实现,专为需要研究倾转旋翼机、eVTOL等新型飞行器的开发者、科研人员及AirSim二次开发用户准备。资源共224个文件,以205个hpp头文件和13个cpp源文件为主,辅以工程配置、说明文档与辅助脚本,压缩包仅486KB,结构紧凑且便于直接嵌入现有Unreal Engine仿真流程。包内针对倾转旋翼机提供了专用实现,覆盖飞行控制逻辑、RPC通信与安全评估等关键环节,可显著降低VTOL飞行模型搭建与验证门槛;同时提供清晰的目录与注释,帮助开发者快速定位和修改底层代码;借助AirSim生态,可模拟多种飞行环境与气象条件,为真实飞行前的设计验证提供支撑。目前已有265人学习下载,适合希望深入挖掘AirLib底层能力、开展VTOL控制算法与安全性测试的开发者参考。
1. 项目到底解决了什么问题
先说个背景。用过AirSim做无人机仿真的人应该都有这种感觉:四旋翼体验非常好,官方文档齐全、代码路径清晰,但一旦你把项目切换到固定翼或者VTOL(垂直起降),整个流程就变得别扭起来。AirSim的气动模型对多旋翼做了深度优化,旋翼的推力、扭矩、电机响应都建得很细,但机翼升力、攻角、失速这些固定翼的基本要素,在很长一段时间里都没有被原生支持。
vtol-AirLib这个项目,说白了就是把AirSim底层的AirLib仓库fork了一份,然后在上面打了一套针对VTOL飞机的补丁。AirLib是AirSim的仿真核心库,飞机动力学、传感器模型、控制器都在这层实现;AirSim本身只是一个薄薄的包装壳,负责渲染、物理引擎的耦合以及各种开发接口的暴露。所以对动力学建模有重度需求的人,通常不会去动AirSim的UE4工程,而是直接在AirLib里改C++代码,跑起来更快,测试也更干净。
这个fork解决了什么具体痛点呢?我在实际开发里碰到的最大问题,就是AirSim默认的物理模型根本没法把“旋翼推力”和“机翼气动力”同时算对。VTOL飞机在垂直起降阶段要考旋翼的推力与力矩,在平飞阶段又要考虑机翼的升力和阻力,整个过渡过程里推力矢量方向和气流攻角都在大范围变化。官方AirLib里没有一套统一的模型能处理这种混合动力布局,于是大家要么自己魔改Pawn参数,拼凑一个凑合能飞的状态,要么干脆在外部用PX4的软件在环做半实物仿真,绕开AirSim的动力学。vtol-AirLib就是冲着这个空档去的。
还有个容易被忽略的细节:AirSim原版的VehicleController对固定翼的控制量定义极其简单,基本上就是油门、升降舵、副翼、方向舵四个值,而且用的还是PWM风格的比例映射,跟真实飞控的混控逻辑差得很远。这个fork在控制器层面补上了针对VTOL的混控模块,算是把整个链路从气动到舵面到控制器打通了。
2. VTOL额外加了哪些核心能力
2.1 气动模型的扩展:从“会转”到“会飞”
AirLib原本的多旋翼动力学是这么建模的:每个电机输出一个向上的力,同时附带一个反扭矩,通过简单的力和力矩叠加得到机体的合力和合力矩。这套模型对旋翼机够用,但完全不区分升力面,说白了它不具备“机翼”的概念。
vtol-AirLib里最重要的改动,是在AirLib的dynamics模块里加入了固定翼气动力的求解逻辑。具体来说增加了机翼升力系数、阻力系数、侧力系数这几个关键气动参数,并且把它们设计成迎角(攻角)和侧滑角的函数。这样在仿真里,当VTOL飞机从垂飞状态慢慢前倾过渡到平飞状态时,机翼的攻角由大变小,升力依据攻角曲线逐步建立,最后完全承担飞机的重量,两个倾转旋翼则把推力方向从前向过渡到水平。这套逻辑在实现上不是一个简单的查表,而是用插值的方式把气动系数曲线写入到代码里,支持分段线性拟合,所以你可以根据自己飞机的翼型数据来校准。
实际用下来有个经验:气动参数里最影响手感的是升力系数的斜率(升力线斜率,通常用每弧度升力系数的变化量来衡量),这个值如果拍脑袋填得太大会导致飞控发散,填得太小飞机就成了“天上下坠的砖头”。我一般是用XFoil或者AVL先算出无人机小迎角范围内的升力线斜率,再折减掉一些工程余量,然后再搬进代码里。
2.2 倾转机构和过渡走廊的建模
VTOL和固定翼、多旋翼最大的区别就是“过渡”——飞机要在几十秒内从悬停状态平滑变成前飞状态,这个过程的物理建模是整个仿真里最麻烦的部分。
vtol-AirLib的处理思路是把倾转角作为一个额外的状态量加入动力学方程中。也就是说机体的状态不再只是位置、姿态、速度、角速度这12维,还多了一个倾转角相关的状态(如果是倾转旋翼,通常左右两侧各有一个倾转角,但很多仿真模型为了方便会先假定同步倾转)。旋翼的推力和扭矩向量要按照倾转角做一次旋转,之后才能叠加到机体合力上。
同时,这套仿真方案在代码里加了一个“过渡速度”的判定逻辑:当空速低于某个阈值时,控制逻辑以多旋翼模式为主,倾转角维持在垂直方向;当空速超过阈值并且机翼已经产生了足够升力,控制逻辑自动切到固定翼模式,倾转角逐步向水平方向偏转。这个阈值在配置里是可以调的,我调试时习惯把它设置成一个区间而不是一个点,比如速度在18到25米每秒之间做线性过渡,避免控制逻辑在阈值附近震荡。
有些更进阶的fork版本还会在这个过渡逻辑里加入“过渡走廊”(transition corridor)的约束——就是根据当前推力余量、电机饱和状态和迎角限制,实时判断飞机是否处于安全过渡包线内。vtol-AirLib最初的版本只做了比较朴素的模式切换,如果你的项目里对安全性要求高,后面可以按这个思路继续扩展。
3. 拿到这个仓库之后怎么用起来
3.1 fork之后如何跟上游保持同步
这个要专门说一下,因为很多人在GitHub上点了fork之后,就再也没同步过上游。GitHub本身就提供了比较方便的方式,但你需要在本地配合操作。
先加远端地址:
git remote add upstream https://github.com/microsoft/AirSim.git git fetch upstream以后想从上游拉新代码:
git checkout master git merge upstream/master这里提示一下,因为vtol-AirLib对AirLib的改动集中在几个核心文件里,经常会在merge时出现冲突,尤其是AirLib/include/vehicles/multirotor/api/MultirotorCommon.hpp这种文件。我的做法是把上游的改动挑着 cherry-pick,而不是无脑merge,保持master分支尽量和上游一致,自己所有的VTOL改动都放到独立的feature分支上。这样做的好处是后续上游修复了某个bug,你能快速同步过来,而自己的功能代码不会受到影响。
3.2 编译和运行的基本流程
这个项目本质上还是一个标准的AirSim扩展,所以编译流程和你熟悉的构建方式基本一致。在Windows环境下,进入SDK目录后执行:
python setup.py build如果你是从源码编译整个AirSim UE4插件,要先把vk等依赖装好,然后在AirSim仓库根目录运行:
./build.sh或者在Windows的developer command prompt里运行build.cmd。需要留意的是,这个fork的代码是基于特定版本AirLib的,直接用它去对接最新版AirSim的UE4插件,可能出现头文件路径或者接口签名对不上的情况。我建议是把AirSim整体checkout到vtol-AirLib README里指定的那个基线上,不然就是我们自己来解迁移工作。
3.3 写一个VTOL车型的settings.json
AirSim的车型配置全部集中在settings.json里。下面这个是我在用的一个倾转旋翼VTOL的最小化配置结构,你可以参照着调整:
{ "Vehicles": { "VTOL": { "VehicleType": "CustomVTOL", "UseSerial": false, "PawnPath": "", "Parameters": { "Mass": 12.5, "WingArea": 0.85, "WingAspectRatio": 9.2, "CLSlope": 5.1, "CD0": 0.028, "TiltMaxSpeed": 22.0 }, "InitialLocation": { "X": 0.0, "Y": 0.0, "Z": -30.0 }, "InitialRotation": { "Pitch": 90.0, "Roll": 0.0, "Yaw": 0.0 } } }, "PhysicsEngine": { "EngineType": "FastPhysics" }, "ClockSpeed": 1.0 }初始俯仰角设置成90度,是为了让飞机从“机头朝上的悬停姿态”(tail sitter式)或者让倾转旋翼机的初始状态符合垂直起飞的要求。VTOL的真实起点姿态取决于你的机型,如果是倾转旋翼,通常初始姿态就是水平的,旋翼倾转角从90度开始往下走;如果是尾座式,飞机整体就是竖着的。
另外提一句,WingArea单位是平方米,CLSlope是每弧度的升力系数斜率,注意不是每度,我见过有人在这里填错之后飞机怎么调都别扭。
4. 我实际调试中踩过的坑
4.1 物理发散:症状非常像“炸机”
第一次跑通VTOL动力学的时候,我遇到过几次典型的数值发散问题:屏幕上飞机起飞不到两秒就开始疯狂翻滚,姿态角发散,最后直接坠地。很多人第一反应是PID参数不对,但实际原因是代码里的气动力模型在迎角比较大的时候没有做限幅处理,升力系数随攻角线性增长到很大后,产生的力矩会把数值积分瞬间击穿。
解决办法是在气动参数计算里加入失速修正,迎角超过失速角后升力系数要回落到一个较低的值,同时加大阻力系数。简单说就是给攻角一个合理的区间限制。你在vtol-AirLib的代码里能找到处理角度限制的函数,确认一下自己的机型参数有没有让它跑到极端状态。
4.2 PID参数的合理初始值
VTOL的PID参数不能直接照搬四旋翼的。原因很直观:四旋翼的大部分控制力矩来自于旋翼拉力的差动,而VTOL在平飞阶段主要靠舵面。舵面控制的响应带宽比旋翼低得多,所以如果你直接把多旋翼的姿态增益搬到固定翼模式上,飞机会出现轻微的持续震荡——看着像“呼吸效应”,飞控一直在修正,但永远修不平。
我的经验是,固定翼通道的P值要比多旋翼通道低40%到50%,D值适当提高一点来补偿舵面响应的延迟。更直观的做法是先在垂飞模式下用多旋翼PID把高度和姿态稳住,然后切换到平飞模式时,再单独调升降舵和副翼的PID。
另外,倾转过渡走廊那段区间内,控制器的参考模型变化非常快。建议把过渡状态的姿态指令变化率限制在每秒30度以内,否则飞控追指令都追不过来,更不要说稳定飞行了。
4.3 代码合并且改动冲突怎么办
我用的是把改动放feature分支的做法,但自己也踩过“深度merge冲突”的坑。vtol-AirLib改的地方通常是AirLib/source/vehicles/multirotor/MultirotorController.cpp和AirLib/include/vehicles/multirotor/api/MultirotorControllerBase.hpp这两个大文件。而这些文件在上游同样频繁变动,每次merge都要手动解决大段的冲突。
后来我学乖了,把跟VTOL相关的代码尽量集中封装成独立的文件,比如新的TiltWingModel.hpp、VtolAerodynamics.cpp,在原有调用点只留一个统一的接口。这样上游的改动集中在小范围内的声明上,冲突就好了很多。这也是我在团队里推荐别人做fork开发时一定会强调的一点:尽量增量式地新增文件,而不是在原有函数里到处插代码。
4.4 一个容易被忽略的坑:坐标系和符号约定
AirSim使用NED坐标系(北东地),也就是X轴指向北、Z轴向下。气动计算里攻角、侧滑角的定义以及升力、阻力方向的符号,在不同仿真软件里可能完全不同。我在一开始按照NASA的body坐标系手写气动力代码时,把升力向量的符号算反了,结果飞机一离地就被“吸”向地面——这种问题时有时无,非常考验人。
建议如果你以后要往这个fork里加气动模块,先用一个简单的case做校验:把飞机固定在一个迎角下,看升力和重力方向是否一致,再确认一下力矩方向与机头抬升方向是否匹配。花一个下午做好这个校核,能省掉后面好几天的排查时间。
5. 把它接到PX4和ROS2里跑
单纯用AirSim自带的遥控器或者API控制VTOL,对真实项目来说往往不够,因为它缺乏实际飞控的低层航向、高度、速度的完整控制逻辑。我自己习惯把这个fork编出来的AirLib跟PX4的软件在环仿真接起来跑。
做法不复杂:AirLib这边提供MAVLink消息的收口,PX4的SITL模式把mavlink package发到UDP端口,AirSim作为HITL/SITL的仿真节点接收控制指令并回传状态。vtol-AirLib在PX4的VTOL机型支持方面,主要是保证了仿真模型的方向与PX4的VTOL状态机(包括MC_MODE、FW_MODE、TRANSITION这几个状态)能对得上,这样PX4里的混控输出才能正确映射到仿真模型的舵面和倾转机构上。
ROS2这边主要是用AirSim-Rover/PX4这类适配包,把AirSim的计算结果转换为geometry_msgs/PoseStamped和nav_msgs/Odometry发布出来。需要注意的是一旦启用了额外的气动,仿真输出的加速度和真实飞控解算出来的加速度会有微小偏差,这是正常的,不要过度怀疑模型。
如果你不跑PX4,直接用AirSim自带的C++或Python API也能控制VTOL。初始化VehicleClient之后,可以用setAngleRates和moveByAngleThrottle把倾转角和油门指令发过去。但说实话这种场景更适合做控制器验证,不适合做整机飞行任务的仿真。
6. 我个人的经验总结
跟着vtol-AirLib把VTOL仿真跑通之后,我最大的感受是,这套东西的价值不在于它帮你省了多少建模工作量,而在于它把“旋翼”和“固定翼”两套物理模型在同一个仿真框架里统一了起来,并且给出了一个可以改、可以extend的控制与配置接口。你在它上面的所有工作,无论是调气动参数、写新的混控算法,还是做过渡走廊的优化,最后都能被PX4等真实飞控的仿真循环复用。
有一个经验值得反复说:任何VTOL仿真项目,先花时间把“过渡段”的定义自己想清楚,远比急着去调PID参数重要。所谓过渡段,就是飞机从旋翼主导变成机翼主导的这个速度区间。这个区间定的宽窄直接影响你的飞控切换时机感。区间太窄,飞控频繁切换,对模型误差很敏感;区间太宽,过渡过程漫长,垂推效率降低,电机会提前过热。我最终用的参数是把过渡起始速度设在悬停失速速度高30%的位置,把结束速度设在平飞巡航速度低20%的位置,整个过渡持续8到10秒。这个区间对于大多数小尺寸VTOL都算是一个合理的起点。
最后再分享一个小技巧:在AirSim的FastPhysics模式下调试VTOL动力学的时候,可以先用ClockSpeed调慢仿真时钟,比如设成0.5,让飞机飞得慢一些,方便你逐帧观察旋翼倾转和机翼升力建立的过程。等逻辑稳定之后再把ClockSpeed恢复成1,跑实时。这个方法反复验证下来非常高效,尤其适合看过渡段的气动变化。
本文还有配套的精品资源,点击获取