1. 从一次炸机说起:飞控算法到底在管什么
很多人第一次接触无人机,注意力都在电机、桨叶、机架上,觉得这些看得见摸得着的东西才是核心。我当年也这么想,直到第一次试飞自组的四轴,起飞不到三秒就侧翻炸机,桨叶断了一地。那次之后我才真正意识到,让一架多旋翼能稳稳悬停在空中的,不是那几个转得飞快的电机,而是藏在飞控板里、每秒运算几百上千次的那套算法。
飞控算法,说白了就是无人机的大脑决策逻辑。它要干的事情可以拆成一条闭环链路:传感器告诉飞控“现在姿态是什么样”,飞控算法算出“离我想要的目标姿态差多少”,然后解算出每个电机该给多少油门,最后通过电调驱动电机。这条链路每秒要跑几百到几千轮,任何一环慢了或者算错了,飞机就会抖、会漂、会翻。
这篇文章我想把飞控算法这条链路从头到尾拆开讲清楚。适合两类人看:一类是刚上手 Pixhawk 这类开源飞控、想搞明白参数背后含义的飞友;另一类是自己写飞控、做硬件在环仿真或者路径规划,需要理解底层控制逻辑的开发者。我不会只丢公式,而是把每个环节“为什么这么设计”“实际调的时候会踩什么坑”讲透。看完你至少能明白:为什么你的飞机悬停会画圈、为什么定高会掉高、为什么自动航线会切弯切得离谱。
2. 姿态解算:飞控算法的第一道地基
2.1 传感器给的数据为什么不能直接用
飞控板上通常有加速度计和陀螺仪,高端点的还有磁力计和气压计。加速度计测的是比力,静止时能反映重力方向,从而知道“哪边是下”;陀螺仪测的是角速度,积分之后能得到角度变化。听起来两者都能算姿态,但单独用都不行。
加速度计的问题是对振动和线性加速度极其敏感。电机一转,机架高频振动直接混进加速度信号里,算出来的姿态全是噪声。而且飞机一旦加速往前飞,加速度计会把“向前加速”误判成“机身倾斜”,姿态就错了。陀螺仪的问题正好相反:它短期响应快、不受振动影响,但积分会累积漂移,时间一长角度就慢慢偏了,飞着飞着飞机就以为自己是斜的。
所以工程上的标准做法是互补滤波或者卡尔曼滤波,把两者的优点捏在一起。互补滤波的思路很直白:高频段信陀螺仪,低频段信加速度计。用一个简单的公式表达就是:
// 互补滤波伪代码 angle = 0.98 * (angle + gyro_rate * dt) + 0.02 * accel_angle;那个 0.98 和 0.02 就是权重系数,意思是“我更相信陀螺仪的短期变化,但长期慢慢往加速度计修正”。这个系数不是随便拍的,它对应一个时间常数,决定了修正的快慢。系数太偏向陀螺仪,漂移修正不过来;太偏向加速度计,振动噪声全进来了。
2.2 卡尔曼滤波到底比互补滤波强在哪
互补滤波够用,但它是“手工调权重”,没有严格的数学最优性。卡尔曼滤波则是在统计意义上做最优估计:它同时建模了过程噪声(陀螺仪漂移、模型误差)和观测噪声(加速度计噪声),然后根据两者的置信度动态分配权重。
实际飞控里用得最多的是扩展卡尔曼滤波(EKF),因为姿态动力学是非线性的。Pixhawk 的 EKF2 就是典型代表,它不只估姿态,还把位置、速度、陀螺仪零偏、加速度计零偏、磁力计偏置、甚至风速都塞进状态向量里一起估。状态维度能到二十多维,运算量不小,所以早期飞控跑不动,得靠专门的浮点运算单元。
这里有个很多人忽略的点:EKF 的调参比互补滤波难得多。互补滤波你调一个系数就行,EKF 要调过程噪声协方差矩阵 Q 和观测噪声协方差矩阵 R。Q 调大了,滤波器更信观测,响应快但噪声大;Q 调小了,更信模型,平滑但滞后。我见过不少人直接抄别人的 Q/R 参数,结果换一套机架、换一批桨叶就完全不对了,因为振动特性变了,观测噪声的统计特性也变了。
实操心得:如果你只是飞着玩,互补滤波完全够,调参直观。如果你要做自动航线、视觉定位、载重飞行,老老实实上 EKF,并且一定要用飞控自带的传感器校准流程把零偏和尺度因子标定准,否则 EKF 再强也救不回来。
2.3 磁力计和气压计:偏航与高度的定海神针
加速度计和陀螺仪能定俯仰和横滚,但偏航角(机头朝向)它们定不了,因为重力方向对偏航不敏感。这时候需要磁力计提供地磁北向参考。磁力计最怕的是电机电流产生的磁场干扰,所以外置 GPS/罗盘模块通常要架高,远离动力线。校准的时候要远离铁磁物体,做完整的椭球拟合校准,把硬铁和软铁偏差都消掉。
气压计负责定高。它测的是大气压,换算成高度。问题是气压随天气变化,而且桨叶旋转会在机身周围产生低压区,导致气压读数偏低。所以定高算法里通常要做气压基线动态估计,把缓慢变化的天气因素和快速的桨叶扰动分开。Pixhawk 里有个EKF2_HGT_MODE参数,可以选择用气压计、GPS、测距仪还是视觉来定高,多传感器融合的时候优先级和权重都要配好。
3. 控制律:从“想要什么姿态”到“电机转多快”
3.1 串级 PID 为什么是标配
姿态解算出来的是“当前姿态”,而你要的是“目标姿态”。两者之间的误差怎么变成电机指令?最经典也最实用的方案是串级 PID。
外环是角度环:输入是目标角度和当前角度的差,输出是期望角速度。内环是角速度环:输入是期望角速度和陀螺仪测到的实际角速度的差,输出是力矩指令。为什么非要串两级?因为角度环响应慢、抗扰差,角速度环响应快、能抑制振动和突发扰动。外环负责“往哪转”,内环负责“转得多快多稳”。
用生活类比:你开车想保持车道居中,眼睛看的是“车离车道线多远”(角度环),但手上打方向盘的动作其实是在控制“车头转动的角速度”(角速度环)。如果只看距离直接打方向,车会画龙;加上角速度内环,方向就稳了。
PID 三个项各有分工。P 是比例,误差越大纠正越猛;I 是积分,消除稳态误差,比如飞机总往一边偏,I 项会慢慢累积把它拉回来;D 是微分,预测误差变化趋势,提前刹车防止超调。多旋翼里 D 项特别重要,因为机架有惯性,没有 D 就会来回振荡。
3.2 参数整定的顺序和踩坑记录
调 PID 有个铁律:先内环后外环,先 P 后 D 再 I。我见过新手一上来三个参数一起调,结果飞机抖得像筛糠,根本分不清是哪个参数的问题。
具体步骤我一般这么走:
- 把外环角度环的 P 设小,I 和 D 归零,内环角速度环也只留小 P。
- 慢慢加内环 P,直到飞机对扰动有快速响应但还没开始高频抖动。这时候用手轻推机臂,能感觉到飞控在“顶”你。
- 加内环 D,抑制 P 带来的超调和振荡。D 太大会引入高频噪声,表现为电机发热、声音刺耳。
- 内环稳了之后,加外环 P,直到飞机能快速回到水平但不过冲。
- 最后加一点点 I,消除悬停时的缓慢漂移。I 太大会导致“积分饱和”,飞机在大误差后恢复特别慢,甚至振荡。
这里有个隐藏坑:桨叶不平衡和机架共振会伪装成 PID 问题。如果你的飞机在某个特定油门区间抖得厉害,其他油门正常,那大概率是共振,不是 PID。这时候调 PID 是治标不治本,得先做动平衡、加减震垫。
3.3 从 PID 到更高级的控制:LQR、MPC 和自适应
PID 够用,但它的局限在于“一套参数打天下”。载重变化、电池电压下降、风速变化,都会让最优参数漂移。所以进阶方案有:
- LQR(线性二次型调节器):基于状态空间模型,能同时优化多个状态量的控制效果。需要比较准的动力学模型,适合机型固定的场景。
- MPC(模型预测控制):在每一步预测未来若干步的状态,滚动优化控制量。能显式处理约束(比如电机转速上限、姿态角限制),但算力要求高,一般跑在机载计算机上而不是飞控 MCU 上。
- 自适应控制:在线估计模型参数并调整控制律,能应对载重变化和部分故障。实现复杂,调不好容易发散。
我的建议是:先把串级 PID 吃透,再考虑高级算法。很多所谓“高级控制”在实际飞行里的表现,未必比调好的 PID 强多少,但调试成本和炸机风险高得多。
4. 混控与电机分配:算法落地的最后一公里
4.1 四轴、六轴、八轴的混控矩阵差异
控制律算出来的是三个力矩指令(俯仰、横滚、偏航)加一个总推力指令。这四个量要分配到每个电机上,靠的是混控矩阵。
以最常见的 X 型四轴为例,四个电机两两对角同向。俯仰力矩靠前后电机差速,横滚靠左右差速,偏航靠对角电机差速(利用桨叶反扭矩)。写成矩阵大概是这样:
电机1(右前) = 油门 + 俯仰 + 横滚 - 偏航 电机2(左后) = 油门 + 俯仰 - 横滚 + 偏航 电机3(左前) = 油门 - 俯仰 + 横滚 + 偏航 电机4(右后) = 油门 - 俯仰 - 横滚 - 偏航六轴和八轴的矩阵更复杂,但原理一样。关键点在于:混控矩阵的符号和电机编号必须和实际机架完全对应。我见过有人把电机顺序接错,结果一解锁飞机就疯狂自旋,因为偏航修正方向反了。
4.2 电机饱和与推力分配优化
混控有个现实约束:电机转速有上限,也有下限(一般不能停转,否则失去控制)。当总推力需求很高、同时又要大姿态修正时,某些电机可能被要求输出超过 100% 的推力,这就是饱和。饱和一旦发生,姿态控制就失效了,飞机可能直接翻。
解决办法是推力分配优化:在满足总推力和力矩需求的前提下,尽量让各电机输出均衡,避免个别电机顶到上限。简单做法是先算需求,如果发现最大输出超过上限,就整体降低总推力指令,优先保姿态。更高级的做法是解一个带约束的优化问题,但飞控 MCU 上一般用简化的优先级策略。
注意:电池电压下降时,同样的油门指令对应的实际推力会变小。所以好的飞控会做电压补偿,根据实时电压调整混控输出,保证操控手感一致。这个补偿系数没调好,低电量时飞机就会变得“软绵绵”。
5. 位置与高度控制:从“稳得住”到“飞得准”
5.1 高度控制的串级结构
高度控制也是串级:外环是高度环,输入目标高度和当前高度差,输出期望爬升率;内环是速度环(垂直方向),输入期望爬升率和实际垂直速度差,输出总推力修正。
这里的气压计噪声和 GPS 高度噪声要处理好。气压计短期准但会漂,GPS 高度长期准但噪声大、更新慢。EKF 会把两者融合,输出一个平滑的高度估计。定高模式下如果发现飞机像坐电梯一样上下晃,通常是高度环的 P 太大或者 D 太小,也可能是气压计受桨叶气流干扰太严重,需要加海绵罩或者改安装位置。
5.2 水平位置控制与路径规划的关系
水平位置控制依赖 GPS、光流、视觉等定位源。控制结构和高度类似:位置环输出期望速度,速度环输出期望姿态角,然后交给姿态环执行。
这里和路径规划直接相关。路径规划算法(比如 A*、RRT、人工势场)给出的是一个个航点或一条期望轨迹,飞控的位置环负责跟踪这条轨迹。如果位置环响应太慢,飞机切弯就会切得很大,甚至飞出安全边界;如果响应太快,又会在航点附近振荡。所以做自动航线时,航点间距、飞行速度、转弯半径这些参数要和位置环的带宽匹配。
我个人的经验是:先把定点悬停调稳,再调航线跟踪。定点都飘的飞机,航线一定飞得稀烂。定点悬停时观察飞机在 GPS 坐标里的漂移范围,如果超过一两米,先查罗盘干扰和 GPS 星况,别急着调位置环 PID。
5.3 视觉感知与视觉定位的介入点
现在很多无人机用视觉做定位和避障。视觉里程计输出的位置和速度,可以替代或补充 GPS。视觉的好处是室内也能用,缺点是受光照和纹理影响大,算力消耗高。
视觉定位接入飞控时,关键是坐标系对齐和时间同步。视觉算法算出来的位置是在相机坐标系下的,要转到机体坐标系再转到导航坐标系。时间戳对不齐,高速飞行时位置估计就会滞后,表现为飞机“反应慢半拍”。所以视觉和飞控之间的时间同步精度最好做到毫秒级。
6. 仿真与硬件在环:不上天也能调算法
6.1 软件在环仿真的价值与局限
调飞控算法最怕的就是炸机。软件在环仿真(SITL)让你在电脑里跑一个虚拟飞机,飞控固件原封不动地跑,只是传感器数据来自仿真模型。这样你可以随便试参数、试极端情况,不用担心摔飞机。
常用的仿真环境有 Gazebo、jMAVSim 等,配合 MAVLink 协议和地面站通信。你可以模拟 GPS 丢失、磁力计干扰、电机失效等故障,观察飞控的应对。局限在于仿真模型再准也和真机有差距,尤其是振动、气流、电机响应非线性这些,仿真里很难完全复现。
6.2 硬件在环仿真的接线与注意事项
硬件在环(HIL)是把真实飞控板接上,传感器数据由仿真机注入,执行机构信号也回传给仿真机。这样飞控跑的是真实固件、真实运算,只是“身体”是虚拟的。
接线时要注意电平匹配和接口协议。Pixhawk 一般通过串口或 USB 和仿真机通信,注入传感器数据需要走特定的 MAVLink 消息。常见坑是仿真机的实时性不够,导致数据注入有抖动,飞控以为传感器在抖,控制效果就失真了。所以 HIL 对仿真机的性能有一定要求,最好用实时内核或者至少保证高优先级线程。
6.3 从仿真到真机的参数迁移
仿真里调好的参数,搬到真机上通常还要再调。因为真机的振动谱、电机响应、桨叶效率都和模型不同。我的做法是:仿真里确定参数的大致范围和趋势,真机上从小往大微调。特别是 D 项,仿真里往往可以给得比较大,真机上因为噪声大,D 要给得保守些。
7. 那些没人告诉你但一定会遇到的坑
7.1 振动是飞控算法的头号敌人
再好的算法,遇到烂机架也白搭。振动会让加速度计数据失真,EKF 估计发散,PID 的 D 项疯狂放大噪声。判断振动是否超标,可以看飞控日志里的加速度计频谱,如果某个频率的峰值特别高,说明机架在那个频率共振。
解决办法:做桨叶动平衡、电机做动平衡、飞控用减震胶安装、机架加强刚度避开共振频率。这些机械层面的功夫,比调任何参数都管用。
7.2 罗盘干扰的排查链路
飞机自旋、偏航漂移、定点画圈,很多时候是罗盘被干扰。排查顺序我一般这么走:先看罗盘校准是否通过,再看外置罗盘是否远离动力线,然后看电机电流变化时罗盘读数是否跟着跳。如果跳,说明磁场干扰严重,要么换罗盘位置,要么加屏蔽,要么在算法里做电流补偿。
7.3 参数不是越“高级”越好
我见过有人一上来就开 EKF、开视觉、开 MPC,结果基础 PID 都没调好,飞机连稳定悬停都做不到。飞控算法是层层叠加的,底层不稳,上层全是空中楼阁。老老实实从姿态环开始,一层一层往上调,才是最快的路。
8. 写在最后的一点个人体会
飞控算法这东西,看公式觉得不难,真正上手调才知道细节全是坑。我自己的习惯是每次飞行都开日志,飞完回来看姿态跟踪误差、电机输出、振动频谱,比凭感觉调参数靠谱得多。另外,别迷信别人的参数表,机架、电机、桨叶、重量任何一项变了,参数都得重新过一遍。把姿态解算、串级 PID、混控分配这三块吃透,大部分飞行问题你都能自己定位到根因,而不是到处问“为什么我的飞机抖”。