资讯动态

横列式双旋翼矢量飞行器Simulink建模与仿真要点

发布时间:2026/10/21 22:17:27 来源:尧图企业网站定制
前段时间我把一个横列式双旋翼矢量飞行器的仿真模型在Simulink里搭了一遍。原以为参照常规飞行器六自由度建模就够了结果发现只要涉及旋翼倾转坐标系、力臂、执行机构限幅全都要重新捋一遍甚至差点被一个单位换算坑到模型直接发散。趁周末把这次建模和调试的过程整理一下今天这篇主要写给想用Simulink做类似飞行器仿真的朋友也顺便记录一下我自己踩过的坑。这种构型名字有点长但不复杂两个旋翼在机身两侧横向排布每个旋翼可以绕横向轴倾转让拉力方向在竖直和水平之间变化。于是它既有垂直起降能力又有高速前飞潜力控制上又不像四旋翼那样有四个独立升力点而是需要在“拉力大小”和“倾转角度”之间做分配。Simulink仿真的意义就在这里先把动力学和控制的逻辑验证清楚避免一上来就做实物摔机。1. 为什么折腾这个构型横列式双旋翼到底香在哪1.1 从四旋翼和固定翼的痛点说起四旋翼飞控成熟、机械结构简单但平飞效率低所有升力都靠旋翼向下吹平飞时需要倾斜机身拉力既要克服重力又要分出一部分向前推整个能量都耗在旋翼尾流里。固定翼巡航效率高但垂直起降能力基本没有要么用跑道要么靠弹射或伞降回收。横列式双旋翼矢量飞行器走的是中间路线垂直起飞阶段旋翼拉力朝上像直升机一样起降进入巡航后旋翼倾转拉力水平向前从“升力发动机”切换成“推进发动机”如果能配上机翼提供巡航升力效率会非常接近固定翼。这里需要说明我不是做气动出身的所以这个项目的定位很明确不是验证真实气动性能而是先把飞行力学和控制律在Simulink里跑通为后续电路、机构和控制样机打底子。横列式布局在结构上比四旋翼更简单两个旋翼、两个倾转机构、一套飞控这个构型的结构简洁特性让它很适合作为矢量飞行器概念验证的起点。从结构对比角度看四旋翼需要四个电机四个螺旋桨任何一个失效就是灾难纵列式双旋翼需要处理前后旋翼的下洗干扰横列式双旋翼左右对称差动油门可以直接产生滚转力矩两个旋翼镜像反转后反扭矩天然抵消偏航也可以靠差动拉力实现。虽然气动干扰依然存在但整体结构比四旋翼更轻比纵列式更对称适合做小型化样机。1.2 矢量倾转让飞行模式从一个变成三个常规旋翼飞行器的拉力方向基本固定矢量倾转等于多了一个“控制维度”倾转角从0度到90度变化拉力方向从竖直指向水平。这样飞行器可以工作在三种模式下垂直模式倾转角接近0度、过渡模式倾转角介于两者之间、平飞模式倾转角接近90度由机翼承担大部分升力。这三种模式的动力学特征差异很大。垂直模式下旋翼拉力主要用于平衡重力机体像一个“胖直升机”控制目标是姿态和垂向速度平飞模式下旋翼拉力主要用来克服阻力控制目标变成空速和航迹过渡模式最麻烦拉力的水平分量和垂向分量同时存在机体姿态、速度、高度互相耦合往往还会伴随低头、掉高等现象。模式多了建模就麻烦但这也是最有探索价值的地方。若用Simulink先搭一个参数化模型就可以把这三个模式用一种统一的动力学方程表达靠切换控制器结构来覆盖不同模态不用每个模式单独写一套模型。我就把倾转角当成一个连续状态从0到90度都允许控制策略则在内外环结构上做调度而不是设成硬切换。我认为做仿真的最大收益就在这里先把各种逻辑和参数在虚拟环境里试错等模型行为符合预期了再迁移到代码生成和实物测试。后面讲到的模型结构就是围绕“统一方程模式切换”这个思路搭起来的。2. 先把方程写清楚建模前我做了哪些假设2.1 坐标系和角度定义以及最容易搞反的符号实际建模中坐标系定义往往是第一个绊脚石。我采用的是航空上常用的北东地惯性坐标系机体系则是x轴沿机头向前、y轴沿机体向右、z轴垂直向下。这样重力加速度在惯性系下是[0; 0; 9.81]机体系坐标变换时只要用常规的欧拉角旋转矩阵就能对应起来。倾转角我定义成一个绕机体y轴转动的角正方向为旋翼向前倾转。倾转角δ0代表拉力垂直向上沿机体z轴负方向δ90°代表拉力水平向前沿机体x轴正方向。这个定义的好处是悬停时倾转角小控制量接近零巡航时倾转角接近90度逻辑清楚。需要注意的是Simulink里很多模块用弧度而控制器和调试界面我习惯用角度。我在初始化脚本里专门做了一组转换常量后面所有模块的参数都用标准国际单位只在显示层做角度转换。最开始我吃过一次亏把角度直接当成弧度送进MATLAB Function结果悬停时倾转角差了一个数量级模型直接往一边冲。这个细节看起来小实际排查起来特别费时间。2.2 旋翼力与力矩拉力、反扭矩、倾转角的关系单个旋翼简化为一个能产生拉力大小T的推力源方向由倾转角决定作用点在旋翼安装位置。在机体坐标系下拉力矢量可以写成F_body T * [sin(δ); 0; -cos(δ)]这里z分量带负号是因为坐标z轴向下而悬停时拉力向上。旋翼在旋转时还会产生反扭矩方向与旋翼旋转方向相反。两个旋翼采用镜像反转正常状态下反扭矩互相抵消一旦两侧拉力不同反扭矩差就会形成偏航力矩。这个力矩在建模时不能丢掉否则偏航通道会完全失去控制依据。旋翼拉力的执行机构电机和电调不是瞬时响应的我给它加了一个一阶惯性环节T_dot (T_cmd - T) / τ。τ取0.08秒代表旋翼升力响应滞后。实际电机和桨的时间常数需要台架测试但仿真阶段可以先这样处理至少避免控制律把模型当成理想执行器。这里还要补充一个容易忽略的点旋翼拉力的作用点不一定在重心位置。我的安装点在机体坐标系的x方向偏心约0.1米所以水平拉力会对机体产生俯仰力矩。很多人建模时只关心拉力大小而忽略作用点到控制阶段就会发现实际力矩和预期完全对不上。我建议从一开始就把安装位置、重心位置全部纳入参数表不要图省事简化成“所有力都作用在重心”。2.3 机体动力学刚体运动和简化气动把两个旋翼的力和力矩叠加再加上重力、机身气动力得到机体坐标系下的合力和合力矩。刚体运动方程用牛顿-欧拉公式平动部分要记得机体系加速度与惯性系加速度之间的旋转矩阵变换转动部分则要考虑角速度叉乘惯性张量带来的非线性项m * a_b F_gravity_b F_rotor_b F_aero_b I * ω_dot ω × (I * ω) M_rotor_b M_aero_b气动部分我没有做CFD而是用一个简单阻力模型低速时只保留平动阻力阻力与速度平方成正比阻力系数按照飞行器的迎风面积粗略估计角速度阻尼也做了简化处理。这个量级对控制律验证足够但对气动设计不够后续会用更精细的查表模型替换。在仿真初始阶段我建议把气动阻力先关掉只保留重力、旋翼力和惯性力。这样可以单独验证控制律是否正确等姿态控制稳定后再逐步加入气动项。否则一上来模型就带全套气动出现问题很难定位到底是控制参数不对还是气动模型有误。3. 把这些方程塞进Simulink模型架构和关键模块3.1 顶层结构四个模块怎么分工Simulink模型我拆成了四块环境模块、旋翼/执行机构模块、六自由度运动模块、控制模块。环境模块放重力、大气密度和风场后续扩展用旋翼模块接收控制律给出的拉力指令和倾转角指令做一阶滞后后再算力与力矩六自由度模块是核心输入合力与合力矩输出位置、速度、姿态和角速度控制模块则根据状态反馈计算执行器指令。信号流从控制模块出发经过旋翼模块生成力与力矩再进入六自由度模块更新状态状态反馈回控制模块。环境模块是全局参数总线所有模块都可以从里面读取重力、密度等常量。这样的分层让每个模块都可以独立测试后续做硬件在环时也容易把某个模块替换成真实部件。我强烈建议在顶层模型里使用Simulink的Bus对象来梳理信号不要一条一条信号线满天飞。横列式双旋翼的状态量很多比如位置、速度、四元数、角速度、倾转角、执行器饱和标志如果用离散信号线连接模型看起来就像蜘蛛网调试时根本分不清谁是谁。Bus相当于把相关信号打包成“结构体”在MATLAB Function里也能直接按字段读写好看也好查错。3.2 力与力矩合成模块的MATLAB Function实现力与力矩合成我用一个MATLAB Function来实现输入是左侧拉力T_L、右侧拉力T_R、左右倾转角δ_L、δ_R、当前机体系角速度Ω输出是机体系合力F和合力矩M。核心代码只要十几行function [Ftotal, Mtotal] rotor_force_sum(T_L, T_R, delta_L, delta_R) % 左旋翼安装位置 [x; y; z]右旋翼关于xOz平面对称 rL [0.35; -0.6; 0.1]; rR [0.35; 0.6; 0.1]; dir_L [sin(delta_L); 0; -cos(delta_L)]; dir_R [sin(delta_R); 0; -cos(delta_R)]; FL T_L * dir_L; FR T_R * dir_R; Ftotal FL FR; % 反扭矩与拉力近似成正比左右旋翼方向相反 k_torque 0.02; Mtip_L [0; 0; -k_torque * T_L]; Mtip_R [0; 0; k_torque * T_R]; ML cross(rL, FL) Mtip_L; MR cross(rR, FR) Mtip_R; Mtotal ML MR; end注意这里的方向定义是我自己项目里的约定不一定适合所有布局但思路可以复用先定义清楚安装位置和拉力方向再用力臂叉乘得到力矩反扭矩单独叠加。这样以后改成不同臂展或不同重心位置只需要改rL、rR不需要动控制逻辑。如果每个旋翼不只是单轴倾转而是具备两个方向的矢量能力代码里的拉力方向向量就需要改成两个角度的组合。可以用旋转矩阵把拉力矢量从旋翼坐标系转到机体坐标系。矩阵连乘看起来复杂但逻辑比手写三角函数清晰很多后续也容易扩展。3.3 六自由度运动模块与初始化脚本六自由度运动模块我用Simulink的经典结构由力矩方程解角加速度积分得到机体系角速度再用姿态运动学方程得到姿态。姿态参数我一开始用欧拉角后来发现大角度过渡飞行时会出现万向节锁问题于是换成了四元数控制回路里再转成欧拉角供调试观察。Simulink自带的姿态计算模块虽然有的版本不太稳定但至少比自己用欧拉角公式积分要可靠。仿真开始前需要有个初始化脚本把所有参数算好。我习惯把所有参数集中在一个结构体变量中比如param.mass、param.inertia、param.arm、param.rotor_tau脚本里再写好param到各模块的赋值。这样改参数不用一个个去点模块对话框而且可以一次性扫描不同参数组合跑批量仿真后期做参数优化很方便。% 初始化脚本示例 param.mass 8.5; % kg param.inertia diag([0.25; 0.32; 0.42]); % kg*m^2 param.gravity 9.81; param.rotor_tau 0.08; % 旋翼升力响应时间常数 param.k_torque 0.02; % 反扭矩系数 param.rL [0.35; -0.6; 0.1]; param.rR [0.35; 0.6; 0.1]; % 控制参数 param.kp_roll 45; param.kd_roll 8; param.kp_pitch 45; param.kd_pitch 8; param.kp_yaw 12; param.kd_yaw 3;所有模块对话框里的常量都直接用param.xxx的形式引用不单独在界面里填数值。这样仿真结果才能和参数一一对应而不是改了一大堆界面数字最后都不知道哪个参数生效。Simulink里可以用模型工作空间或数据字典管理这些参数我用的模型工作空间简单够用。4. 控制回路设计先跟姿态较劲再谈飞行4.1 内环姿态PID为什么横列式双旋翼缺了阻尼不行控制我采用内外环结构。内环是姿态控制外环是位置/速度控制。姿态环通常用三个通道独立PID滚转通过两侧拉力差控制俯仰通过两侧倾转角的同步变化控制偏航通过两侧反扭矩差控制。和四旋翼相比滚转通道的响应很快因为两侧拉力差直接产生滚转力矩俯仰通道则慢得多因为倾转机构有响应滞后而且倾转角变化还会扰动拉力方向。这里必须强调阻尼的重要性。横列式双旋翼如果没有角速度阻尼光靠比例控制是很难稳定的。倾转角稍微偏一点水平拉力就会带出俯仰力矩姿态越偏力矩越大最后发散。我在姿态环里把角速度反馈的微分增益加大相当于模拟一个阻尼器。角速度反馈不能直接从姿态微分拿最好用单独的陀螺仪信号在Simulink里就是直接接角速度状态不要等微分。悬停状态下我的初始增益大概是滚转和俯仰比例45微分8偏航比例12微分3。这只是个起点具体参数还要根据惯量、臂长来调。但经验是横列式双旋翼的比例增益不需要太大因为推力矢量产生的力矩往往已经很“直接”反而微分增益要给足才能压制倾转机构带来的相位延迟。4.2 控制分配四个“操作量”如何映射到六自由度假设需要期望力矩M_des和期望总升力F_z_des分配目标就是求解T_L、T_R、δ_L、δ_R。由于倾转角既影响力方向又影响力臂方程本质上是非线性的无法像多旋翼那样用一个常值矩阵直接反解。我采用的方法是在每个采样周期把当前倾转角作为工作点线性化得到雅可比矩阵然后用伪逆求解控制量增量。伪逆的好处是当系统有冗余执行器时会自动把控制量分散到各执行器上。比如某时刻需要的俯仰力矩较小伪逆可能会让左右倾转角各动一点而不是单边猛推。这种分配方式让控制更柔和但要注意限幅倾转角速度限制、拉力变化率限制都要在分配后再次检查否则控制器算出来的目标值执行机构根本跟不上反而激发高频振荡。我实际写分配器时先把四个输出量归一化拉力范围0到最大拉力倾转角范围0到90度然后再算伪逆。这样避免拉力数值太大时倾转角变化量被忽略。分配完成后再做限幅和反饱和处理把实际能执行的控制量反馈回去。这一步是后面调试稳定性的关键我调了整整两天才意识到问题出在这里。4.3 垂直转巡航的过渡状态怎么处理垂直起飞时目标点是0速度固定高度让倾转角保持在0附近。巡航状态则希望前向速度渐增高度不变随着速度增加机翼升力如果有逐渐参与旋翼倾转角慢慢增加。我在Simulink里把过渡过程做成一个由前向速度触发的状态机空速低于某阈值时用垂直控制器高于某阈值时切换到巡航控制器中间区域用一个线性插值系数混合两组指令。这个过渡逻辑看起来简单实际仿真里很容易出现一个问题如果切换条件只看速度而速度有波动控制器会在两个模式之间来回切换导致倾转角抖动。后来我给切换加了迟滞低速阈值设为6米每秒高速阈值设为8米每秒中间保留2米每秒的死区并且过渡期间不直接切姿态给定而是把给定值也做平滑滤波。过渡过程中高度保持也是个难点。倾转角增大后拉力垂直分量下降高度会掉如果高度控制器反应太快又会把拉力拉满产生过大的垂直加速度。我在过渡时把高度误差的积分项稍微降低让高度回路“慢半拍”优先保证速度建立等速度接近目标后再恢复高度权重。这样仿真出来的高度曲线会有一个小的下坠但总体可控。5. 仿真调试实录模型从发散到能飞的排查过程5.1 第一步就翻车求解器步长和离散模型的问题我把模型刚搭好跑了一个1秒钟的悬停仿真结果位置曲线直接飞到天上。第一反应是控制参数错了后来发现根本不是控制器问题我用了定步长求解器步长设置成0.1秒但姿态环需要的控制周期是0.01秒控制器采样周期跟不上模型动力学数值积分误差被积累放大。解决办法很简单把求解器步长改成0.001秒并把控制律模块做成离散状态更新采样时间设为0.01秒。这才让积分稳定下来。另外反馈信号的处理也要小心。姿态传感器模型如果直接输出连续信号控制率中的微分项会对噪声特别敏感。我加了一个截止频率5Hz的低通滤波器让角速度反馈平滑一点仿真结果接近真实机上传感器的表现。我后来用不同步长跑了一次对比步长0.01秒时姿态发散0.005秒时勉强稳定但有小幅振荡0.001秒时才完全平滑。这并不意味着所有模型都必须用0.001秒但至少说明在加入执行机构一阶滞后和控制器离散采样之后步长必须小于所有动态特征中最快的时间常数否则仿真结果没有参考意义。5.2 疑点重重的力臂一个y轴方向引起的深度排查有一次仿真里滚转通道突然发散我以为是增益太高做增益扫描后依然发散。后来我把左右旋翼安装位置打印出来才发现rL和rR的y方向符号搞反了。我的机体y轴向右左旋翼的y坐标应该是负的右旋翼是正的。但因为左右镜像安装要配合反扭矩方向代码里我把扭矩符号和坐标一起反了导致绕z轴的偏航力矩自相矛盾间接让滚转通道持续发散。这个问题的排查花了我一整个下午最后是逐个模块单测时发现的。建议大家在Simulink里做模块级测试单独给单位拉力、零倾转角看力与力矩是不是符合手算预期。比如左旋翼拉力10牛作用点x0.35、y-0.6、z0.1方向垂直向上那么对重心的力矩应该只有滚转方向绕x轴的项而俯仰和偏航方向应该为0。如果仿真结果不是这样那坐标系或力臂定义一定有问题。这类低级错误在纯代码工程里很容易通过单元测试暴露在Simulink图形界面下反而容易忽略。我后来专门建了一个“模块级测试”的测试模型每次改完参数就跑一遍,断言力和力矩的数值与手算一致。这几乎能排除一半以上的低级错误。5.3 执行机构限幅导致的高频振荡以及最终的稳定模型基本稳定后我开始给执行机构加限幅倾转角速度限制每秒60度拉力变化率限制对应脉冲信号。结果一加限幅悬停不到三秒就开始等幅振荡。原因分析下来是控制分配没有考虑限幅PID输出被截断后产生积分饱和控制器还在继续增大积分项等误差反向时输出又过大形成了一个极限环。这在真实无人机上非常常见也提醒我不要把控制律和限幅分开看待。解决方法是给PID加入积分限幅与抗积分饱和同时把限幅信息反馈给控制分配器让分配器知道哪些执行器已经饱和主动削减对应通道的权重。改完以后振荡明显减弱模型可以从任意初始姿态回稳。具体实现上我把四个执行器的饱和标志作为布尔量传到控制分配函数。如果某个执行器饱和分配矩阵就把它对应的列乘以一个很小的权重比如0.05让伪逆自动把控制量转移到其他未饱和执行器。这个思路类似于航空飞控里的“控制效能降级”虽然简单但在倾斜双旋翼这类强耦合系统里效果很明显。我整理了一个排查表方便后续遇到类似问题快速定位现象可能原因排查手段高频振荡微分增益过大或反馈噪声增大滤波器时间常数降低kd低频极限环执行机构饱和后控制积分继续增加加入抗积分饱和饱和信息反馈给分配器位置缓慢漂移坐标系或单位错误模块级单测检查重力分量符号过渡切换抖动状态机无迟滞增加切换死区对给定值做平滑6. 跑出来的数据与后续玩法6.1 一组典型的悬停到前飞过渡数据修改完限幅后我让模型从悬停开始给定2米每秒的前向速度指令观察倾转角、拉力、姿态角和高度的曲线。整个过程大概分成前3秒悬停稳定之后倾转角从0度逐渐增加到约18度两侧拉力总和先是接近总重随后因为拉力有水平分量垂向分量减小高度控制器会自动加大总拉力来维持高度。水平速度到达目标后倾转角回减配平到一个比较小的角度。这组数据直接验证了前面说的耦合倾转角一变高度和速度都在动。如果不把控制分配和过渡逻辑处理好单独只调高度环很难调稳。仿真结果也让我确定了后续实物测试哪些参数需要重点标定比如旋翼力臂、反扭矩系数和拉力响应时间常数。还有一个小发现两侧倾转角在过渡过程中并不完全同步。由于机体有滚转扰动控制分配器会给左右旋翼不同的倾转角修正量用来抑制滚转引起的耦合力矩。这说明如果我在物理样机上把两个倾转机构做成机械联动锁死控制性能会差不少。点开这个细节也是Simulink仿真比纯数学推导直观的地方。6.2 模型还能怎么扩展风场、弹性体、硬件在环这套Simulink模型目前是刚性机体简化气动但预留了扩展接口。下一步我打算加两个扩展一是风场模型在环境模块里加入平均风和紊流看看倾转飞行过程中侧风对偏航通道的扰动有多大二是把旋翼部分替换成更精细的动力模型包含电机电流、电调和电池电压变化为续航估算做支撑。如果后面要做实物Simulink模型还可以通过自动代码生成部署到飞控板上做硬件在环测试。这也是模型化设计的优势之前所有参数、调优、控制分配代码都能复用而不是每阶段都从头写一遍。我个人做下来的体会是横列式双旋翼矢量飞行器的仿真难点不在某一个单独的模块而在于各模块之间的耦合关系。Simulink的价值恰恰在于可以把这些耦合放到同一个时间域里去看哪个通道先发散、哪个通道饱和一目了然。如果你也准备在这个构型上做探索我建议先花时间把坐标系和分配矩阵搞对再来谈控制参数否则后面全是坑。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑