
1. 先看全局位置环、速度环在PX4控制链里的确切位置1.1 一条命令从“航点”到“电机转速”要过几道关卡先说结论PX4的多旋翼控制是一个标准级联结构从上到下大致是“期望位置 → 位置环 → 期望速度 → 速度环 → 期望加速度 → 姿态环 → 期望角速度 → 角速度环 → 混控器 → 电机转速”。位置环和速度环位于整个控制链路最靠外的两层它们负责的是“飞去哪、飞多快、以什么加速度改变运动状态”而姿态环和角速度环负责的是“机体该怎么倾斜、转得多快”混控器最后才把控制量分给四个或更多电机。如果你在地面站里下发一个航点飞控并不是直接算“油门多少、倾斜多少”然后飞过去。它先要把航点转换成位置设定点再把位置偏差变成期望速度接着把速度偏差变成期望加速度最后才由姿态控制去执行这个加速度。我见过不少刚接触PX4源码的开发者一进代码目录就直接去找“油门输出”结果绕了半天都串不起来。根源就在于没有先在脑子里搭出这条级联路径。在自动任务模式下期望位置来自航线脚本或任务规划器在Position模式下操纵杆会被映射成速度设定点位置环更多起修正作用在自稳模式里位置环和速度环甚至会直接旁路。无论输入来源怎么变mc_pos_control模块最终对外输出的统一接口都是“推力矢量”也就是期望加速度。记住这一点你就拿到了读源码的第一把钥匙。1.2 为什么非要拆成两个环不直接一个PID从位置算推力新手最容易问的问题就是位置偏差直接映射到期望加速度不行吗从控制理论的角度看确实可行但实际工程里这样做的下场多半是炸鸡原因有两个。第一个原因是物理约束。飞行器的最大速度、最大加速度都不是无限的。如果直接从位置算加速度位置误差一大输出加速度立刻顶到推力上限电机进入饱和飞机变成“油门和姿态乱打”的状态。中间加一个速度环以后我们可以把期望速度限制在安全范围内比如MPC_XY_CRUISE把期望加速度限制在推力范围内比如MPC_ACC_HOR。位置环只负责“该往哪飞”速度环只负责“该推多重”各管一摊参数也更容易整定。第二个原因是模式切换。PX4有手动、高度、位置、任务等一大票模式不同模式下用户输入可能是速度、角度甚至是角速度。如果所有模式都统一换算成加速度指令从自稳切到Position模式时飞控看到的只是速度期望的变化而不是猛然进入一套全新的控制逻辑。这个“软切换”体验靠单个大PID是做不出来的。理解了这两个原因再去读PositionControl相关源码你会明显感觉思路顺了外环输出速度内环输出加速度这个划分本身就是工程对物理世界妥协的产物。2. 位置环把“位置差”翻译成“飞多快”2.1 位置环的输入、输出和那条基础比例公式位置环的输入在mc_pos_control模块里通常来自三个地方期望位置航线、任务、RTL等产生、当前位置由EKF等估计器融合输出、期望速度前馈航点生成器提供的参考速度。它要做的事情就是算出一个合理的期望速度。核心公式很朴素期望速度 Kp_pos × 期望位置 − 当前位置 期望速度前馈水平方向的Kp_pos对应参数MPC_XY_P垂直方向对应MPC_Z_P。位置误差越大期望速度越大误差为零时期望速度只保留前馈部分。这里要特别注意位置环在PX4里基本是纯比例控制没有积分微分也几乎不用。为什么位置环不加积分因为位置误差的积分会带来明显的过冲和回弹而且位置环已经是外环积分积累的错误没有更外层的环节去兜底。真正需要积分去消除常值误差的地方在速度环位置环只要保证“方向正确、速度受限”就够了。位置环输出也不是无上限的。水平方向不能超过MPC_XY_CRUISE这个参数决定了自动模式下的水平巡航速度垂直方向则受上升、下降最大速度限制。换句话说就算飞机离目标点十米远位置环也不会命令它以几十米每秒的速度飙过去而是会顶到限幅值以一个安全速度匀速靠近。这条限幅逻辑在排查“飞机为什么飞得像没睡醒”时经常被人忽略。2.2 航点生成器位置环前面的“隐形规划师”如果你只在悬停模式下做小范围移动位置环看起来确实就是一条比例公式而已。但只要开始跑航线任务你就会发现飞机并不是“直愣愣地冲向目标点”而是会提前减速、平滑转弯、甚至在多航点连续切换时走出很柔和的曲线。这个效果来自航点生成器也常被叫作轨迹生成器。航点生成器的职责是把一个位置跳跃变成一条带速度约束的路径。它会根据当前位置、目标位置以及最大速度、最大加速度、最大加加速度这三个限制生成一组“位置设定点 速度设定点”序列。每个控制周期位置环拿到的不是“最终目标点”而是这条平滑路径上当前该去的位置和当前该有的速度。这个细节经常被教程一句带过但恰恰是决定飞行是否“丝滑”的核心。位置环里的“速度前馈”项就因为航点生成器的存在才有意义。如果没有前馈位置环只能靠比例项去“追”位置靠近目标时速度自然衰减但响应总有滞后有了前馈位置环只需要承担修正偏差的工作跟踪精度和顺滑度都会明显提升。这就是为什么两台同样机架、同样参数的飞机一个用航线模式跑起来行云流水另一个却显得一顿一顿。相关参数里MPC_JERK_MAX是最容易被忽略的一个。加加速度描述的是加速度变化快慢值越小飞机启动和刹车的过渡越柔和值太大飞机会有“弹出去又急停”的感觉。很多人调了半天位置环P手感还是怪最后发现是Jerk限制在捣乱。2.3 位置环P值的手感按收敛曲线判断而不是凭感觉拿水平位置环MPC_XY_P来说常见初值在0.9上下。这个值的物理含义可以粗略理解为1米的位置误差大约会产生1米每秒的期望速度。这个比例关系很直观也是我判断参数大小最常用的方法。P值调大位置收敛更快但对位置估计噪声和风扰更敏感P值调小飞行姿态更平稳但到达目标点附近会显得“懒洋洋”半天才停稳。实际调试时我习惯在Position模式下做小步长阶跃在地面站里把期望位置挪动0.5米到1米然后观察位置环输出和实际位置的收敛过程。如果收敛过程中有一次明显超调说明P偏大如果收敛慢且稳态误差长时间不消失说明P偏小或者该去检查速度环状态。有一句话我在新手培训时反复强调位置环调的是“外面那层皮”真正决定响应手感的是里面那层速度环。所以别对着位置环P猛调先把速度环的收敛速度调到位再回来动位置环。这个顺序保证了你能分清“外环过度驱动”和“内环响应不足”两种完全不同的故障特征。3. 速度环读取“速度差”输出“加速度”3.1 速度环的PID三项在真实飞行中各自是什么角色速度环的输入是期望速度与实际速度的差输出是期望加速度。水平方向是一个完整的PID核心关系可以写成期望加速度 Kp_vel × 速度误差 Ki_vel × 速度误差积分 Kd_vel × 速度误差微分比例项MPC_XY_VEL_P是主力。速度慢了命令加速度向前速度快了命令加速度向后。它和位置环的比例项叠加在一起构成一个典型的二阶阻尼系统位置环提供“弹性”速度环提供“阻尼”二者配合飞机才不会像弹簧一样乱跳。这个类比我在代码评审会上经常用位置环是弹簧速度环是减震器缺了减震器的弹簧一定会来回弹。积分项MPC_XY_VEL_I负责长时偏差。悬停时如果一直有风或者重心不居中速度误差不会归零比例项无法完全消除这个偏差积分项就在后面慢慢“补账”直到实际速度等于期望速度。但积分项也是最容易翻车的一项后边我会专门讲抗饱和的问题。微分项MPC_XY_VEL_D平时用得最少。因为它要对速度误差求导而速度估计本身带有噪声微分项会把噪声放大成加速度抖动表现出来就是电机声音发涩、机身高频微抖。所以我的建议是先不开D等P和I都调完确认阻尼确实不足再给一点点。多数机架根本不需要这D项。3.2 加速度怎么变成机体的“歪头”和“油门”速度环输出的是期望加速度。这个加速度在PX4里会跟重力加速度合成变成一个期望推力矢量。为了产生水平方向的加速度机体必须倾斜为了保持高度推力在垂直方向的分量必须刚好抵消重力。一句话总结水平加速度越大机体倾斜角越大总推力越大油门越大。这段关系意味着速度环之后还有一个姿态环。姿态环的任务是执行期望倾斜角角速度环再去执行期望角速度。如果你把速度环参数调得很激进期望加速度很大但姿态环增益不够高机体倾斜跟不上实际加速度就不会按期望值出现。表现在飞行日志里就是期望速度收敛很快实际速度却拖了一条长长的尾巴。这解释了为什么有些飞机速度环怎么调都“调不猛”。问题可能根本不在速度环而在姿态环接收端。调参顺序必须由内向外先确认姿态环能快速精确执行期望姿态再去动位置和速度这两层外环。内环响应不到位外环参数再漂亮也是空中楼阁。3.3 积分抗饱和速度环里最容易被忽略的安全机制积分项最容易出问题的地方就是“积分饱和”。我拿一个真实场景说明飞机在Position模式下被强风吹偏位置误差瞬间变大位置环输出的期望速度直接顶到MPC_XY_CRUISE限幅速度误差也变得很大于是速度环积分项开始快速累积。等飞机回到目标点附近位置误差变小、速度误差也变小但积分项里还留着刚才那一大笔“旧账”继续输出额外加速度飞机就会冲过目标再抽回来形成明显的来回抽动严重时甚至会“点头”。PX4源码对积分项做了限幅处理一旦输出加速度触顶积分就不再继续增加整体输出还会限制在MPC_ACC_HOR等加速度上限内。这是一种标准的抗饱和做法但不同固件版本的实现细节有差异有的加条件分支有的做积分冻结有的干脆重置积分。排查问题时如果发现“速度环好像总在乱发力”先看限幅逻辑有没有按预期工作。我带过的不少开发者都踩过同一个坑速度环I值照抄别人的“神参数”结果自己一飞就抽风。原因多半不是I数值本身不对而是飞行条件、机体重量、限幅参数都不一样。我的建议是I初值给一个很小的量比如0.1到0.2先让系统稳定再根据悬停漂移情况慢慢加每次幅度不超过50%。3.4 垂直速度环跟水平方向有哪些不一样垂直方向同样有位置环和速度环结构类似但有两个差异值得单独说。第一垂直方向不需要“倾斜”来实现加速度它直接改变总推力。所以垂直速度环的输出大部分直接映射为推力指令响应通常比水平方向更直接、更快。你在日志里对比水平方向和垂直方向的速度跟踪曲线会发现垂直方向收敛更快、超调更小。第二垂直方向的加速度上限不对称。多旋翼的上升推力通常远大于下降能力所以PX4用MPC_ACC_UP_MAX和MPC_ACC_DOWN_MAX分开限制上升和下沉加速度。下降过快时电机转得再慢也受气动阻力限制所以下降速度通常比上升速度低。调参时不要把上下限设成同一个值也不要觉得“参数越大越灵活”上限设置不当会让高度控制变得非常生硬。调垂直速度环的方法和水平方向类似但高度估计多来自气压计和加速度计融合气压计受气流影响明显。测试时不要在风机、空调出风口附近进行否则高度数据跳动会让你误判控制器参数。这一点说起来是常识但真到了现场很多人都会被一块跳动的气压计带偏。4. 参数速查表与一套可复现的调参顺序4.1 主要参数一览先放一张速查表方便后续对照。要注意的是不同固件版本、不同机架类型的默认值和参数命名可能有差异以下数值更多是经验参考区间落地时务必以你自己固件版本的源码注释和地面站参数说明为准。控制层面参数名称作用说明参考建议位置环水平XYMPC_XY_P位置偏差到期望速度的增益常见初值0.9左右位置环垂直ZMPC_Z_P高度偏差到期望垂直速度的增益常见初值1.0附近速度环水平PMPC_XY_VEL_P速度偏差到期望加速度的增益常见初值3到5从小往大调速度环水平IMPC_XY_VEL_I消除水平常值速度偏差建议从0.1到0.3开始速度环水平DMPC_XY_VEL_D速度误差变化率的阻尼默认很小多数情况不需要速度环垂直PMPC_Z_VEL_P垂直速度偏差到推力冗余的增益常见值2到4水平速度限制MPC_XY_CRUISE自动模式水平巡航速度上限根据任务速度需求设置水平加速度限制MPC_ACC_HOR水平期望加速度上限也决定最大倾斜角常见值6左右垂直加速度限制MPC_ACC_UP_MAX / MPC_ACC_DOWN_MAX上升/下降最大加速度上升值通常大于下降值轨迹平滑MPC_JERK_MAX加加速度上限影响航线顺滑度需要柔和就调小这张表最右侧一列是经验区间不是精确默认值。固件升级后参数名都可能变死记数值没有意义理解每个参数的作用才重要。你看日志和地面站的参数说明时心里要有这么一张“功能地图”而不是盯着数字发愣。4.2 从自稳到位置模式的完整调参流程我自己惯用的调参顺序基本遵循“由内而外、一次只动一个”的原则。按这个顺序走能最大程度避免“动了位置环结果速度环在振荡”这种认知混乱。第一步在自稳模式确认姿态环稳定。解锁后小幅打杆听电机声、看机身响应。如果姿态环本身就在振荡后面所有外环都白调。这一步很多教程会跳过但它是整条链路的基石。第二步切到Position模式先调速度环P。不急着挪位置设定点就在原地悬停用手轻轻推一下飞机观察它回到悬停点的速度和超调。P从小往大加出现来回抽动就退回约20%。这个阶段你会看到速度环收敛变紧实但机身不该出现高频抖动。第三步调速度环I。悬停时如果发现飞机往某个方向持续漂移给一点I观察漂移是否收敛。I大了以后最常见的问题是“回来时过头一点又拉回”看到这种就说明I过头了。第四步调位置环P。在地面站发一个小距离阶跃比如前后挪1米看收敛速度。轻微超调可以接受明显来回绕一圈以上就降P。第五步航线大范围测试。在足够空旷的场地飞几段连续航点观察转弯段落是否平滑。这一步主要调MPC_ACC_HOR和MPC_JERK_MAX让加减速曲线符合任务手感。以上每一步都建议用飞行日志记录。落地后拉出期望速度、实际速度、期望加速度、实际加速度曲线对照比只看现场手感要可靠得多。手感是定性的曲线是定量的两者结合才高效。4.3 定参数时的三条“铁律”说起来都是老生常谈但我确实见过太多人在同一个地方摔跤第一一次只动一个参数。别同时改P和I否则出了问题你根本分不清是哪个参数引起的。哪怕只动一个参数也要先看一个完整稳定周期的日志再判断。调参最忌讳的就是“一串参数一起改然后祈祷它能飞”。第二改动幅度别太大。每次调整控制在20%以内比较安全。位置环P从0.9直接跳到2.0这种事结果多半是激烈振荡甚至现场事故。调参是收紧一个区间不是赌一次运气。第三确认当前控制模式。很多参数只在对应的控制模式下生效。你在高度模式里调位置环P当然看不出任何变化在自稳模式里调速度环参数也不会起作用。实验前先在地面站确认当前模式和位置估计状态省得白忙一场。5. 从源码角度看过位置环和速度环是怎么跑起来的5.1 模块入口和核心调用链PX4里负责位置和速度控制的源码主要在mc_pos_control模块下。不同版本文件组织略有差异但核心逻辑基本围绕两个层面展开一层负责模式管理、任务状态、输入话题接收另一层是真正的位置/速度控制类核心的PositionControl类里就是位置环和速度环的迭代计算。控制周期内模块会做这几件事读取当前控制模式读取期望位置/速度/加速度设定点来自航线或航点生成器读取EKF输出的当前位置与速度估计然后调用PositionControl的更新接口输出期望推力矢量或期望加速度最后交给姿态控制器。如果你自己去看源码建议从PositionControl的核心更新函数入手。它内部的执行顺序基本就是“先位置环、后速度环、最后输出推力矢量”。位置环先算出期望速度把这个期望速度作为速度环的输入速度环再算出期望加速度。这个顺序和前面讲的级联结构完全一致代码只是把理论翻译成了可执行步骤。5.2 源码里藏着哪些容易被忽略的细节第一处是速度前馈。位置环公式里的前馈项不是简单等于航点生成器的速度PX4里还可能有缩放系数。前馈权重设置得当可以让跟踪误差明显变小设置过大又会掩盖位置环本身的修正作用导致系统对风扰不敏感。看懂这一项你就能解释为什么同样的参数别人飞得比你稳。第二处是限幅逻辑。位置环输出限幅、速度环输出限幅、积分项限幅这些逻辑在源码里往往分散在不同的子函数中。出问题时很多“怪现象”其实都是限幅在起作用。比如期望速度被顶到上限曲线平得跟直线一样比如积分被冻结实际速度迟迟追不上期望速度。看日志时如果发现某条曲线异常平直第一反应应该是找限幅参数。第三处是模式切换的衔接。PX4在模式切换时会做状态重置或目标值初始化比如从手动切到Position模式位置环会先把当前位置作为新目标避免“先飞到远处再回来”这类突变。这一块在不同版本的实现细节不一样升级固件后若发现切换行为变化优先去查这部分逻辑。5.3 姿态环到底在消费什么需要再强调一次姿态环接收的不是“位置”也不是“速度”而是一个期望推力矢量。这个推力矢量由期望加速度与重力加速度合成再被拆解成期望姿态角和期望总推力。正因为如此姿态环参数与位置/速度环参数之间存在耦合。速度环给出一个期望倾斜角姿态环的响应速度决定了这个倾斜角能不能快速到位。一个实用的排查技巧是当位置环、速度环调了很久都调不好时把姿态环的响应拉出来看看是不是“慢半拍”。如果是先解决内环响应再回头看外环参数。很多人卡在“速度环振荡”上最后发现根因是姿态环带宽不足。6. 实测中的常见问题与排查思路6.1 位置设定点附近来回抽动现象Position模式下飞机到达目标点后不是稳稳停住而是在小范围里来回“画小圈”或前后抽动周期大约一秒左右。排查先看日志里的期望速度与实际速度。如果两条曲线呈明显的正弦状且期望速度始终领先实际速度基本可以判断是位置环P过大速度期望被过度放大。解决办法是降MPC_XY_P观察一到两个周期。若抽动频率接近姿态环带宽则需要检查姿态环相位裕度以及前后通道是否串扰。还有一种情况是限幅在起作用位置误差大时速度命令顶到巡航速度上限速度环跟踪不及时产生低频回路振荡。这时除了降P还可以适当降低MPC_XY_CRUISE让外环不至于总在极限状态下工作。极限状态下任何小扰动都会被放大成振荡这不是玄学是控制系统的基本特性。6.2 悬停漂移和常值位置偏差现象飞控明明处于Position模式飞机却缓慢向一个方向漂手动修正回来后过一会儿又漂过去。排查顺序先确认机体校准特别是加速度计零偏和水平校准再看位置估计输出是否稳定EKF状态是否健康。如果估计本身没问题再看速度环积分项是否太小。积分项的存在本来就是吸收外界常值干扰的太小了就吸收不完。但积分项不是万金油。如果机体本身重心偏斜或者机架振动导致加速度计数据带偏差速度环I会给一个与实际需求相反的“补偿”反而让姿态维持变得奇怪。所以遇到漂移时先查机械和校准再动I值。机械问题靠积分硬补补到最后就是积分饱和然后触发前面说的振荡现象。6.3 高频抖动和电机发涩现象悬停时电机声音发涩机身有高频微小抖动手摸机臂能感到明显振感。排查这种抖振频率通常远高于位置环和速度环的带宽多半来自姿态环的D项偏大或角速度估计中的噪声被放大。如果日志里角速度曲线有明显毛刺优先降低姿态环微分增益而不是去调速度环。位置环和速度环参数在这个频段几乎帮不上忙反而可能因为输入信号被处理得过于激烈而诱导姿态环进入极限环。也有人会碰到“油门轻一下重一下”的低频抽动这个一般和垂直速度环积分有关或者和电池电压下降后的推力补偿逻辑有关要分开排查。高频看姿态环低频看速度环这是最初步的“频率分层法”。6.4 改了参数但完全没反应现象在地面站里把参数改了飞行器实际表现没有任何变化。排查先确认模式。只有使用了位置环和速度环的模式这两个模块才会在回路里起作用。其次确认参数名和固件版本是否匹配不同版本之间参数编号或命名可能调整。再者检查参数是否真正写入成功很多情况下飞控重启后才生效。最后一种可能是你的测试动作根本没有触发这个环节比如只做原地悬停测试却想验证航点生成器的平滑效果自然什么都看不出来。这个案例特别适合提醒大家调参前先给自己一分钟想清楚“我要验证的参数在哪个环节生效、在哪个模式下才参与控制”。这一步省下来后面能少飞很多冤枉架次。6.5 载荷和重心变化后原来的参数忽然失效有时候同一套参数换个电池、加个云台表现就完全不一样。这不是参数记忆出错而是飞行器模型变化导致外环增益和姿态增益的相对关系变了。载荷加重时速度环P通常需要适当增加因为相同加速度对应更大的推力需求重心偏移时左右通道的参数可能需要差异化调整如果差异过大先考虑配重而不是改参。这类问题最典型的表现是同一台飞机空机调好了挂上载荷后出现“右偏后抬头”之类的不对称响应。这时候不要怀疑自己的调参能力先看重心和机臂刚性再决定是否动参数。结构问题用参数硬顶顶出来的参数一定畸形。7. 我个人试飞过程中积累的三个习惯最后分享几个很零碎但确实管用的习惯算不上高深理论实战里帮了我不少忙。第一个习惯把每次调参记录写在表格里。包括改动前的值、改动后的值、天气、风速、电池电量、载荷状态、飞控固件版本。没有这些记录你调了三轮以后就会出现“到底哪版参数最好”的记忆错乱。人的记忆在连续调试时是不可靠的只有表格不会骗你。第二个习惯先用日志说话再信手感。手感能帮你快速定位方向但真正决定最终参数的是日志里那几条响应曲线。尤其是速度环和位置环的振荡只有曲线能告诉你它是1Hz还是5Hz是饱和振荡还是增益裕度不足。方向对了再微调效率能高一倍。第三个习惯改参数前先备份当前参数文件。地面站都支持参数导入导出飞行前导出一份出了异常还能回到上一个稳定点。这个习惯成本极低收益却是实打实的。真遇到“越调越差”的时刻你会发现一个能一键回滚的备份文件比什么都宝贵。调位置环和速度环这件事说难也难说简单也简单。难在它是一个从内环到外环、从参数到机械再到传感器融合的链条任何一环出问题都会在位置响应上表现出各种形态简单在只要你理解了级联结构掌握了“由内而外、一次只动一个参数、一切以日志为准”这三个原则大部分问题都能找到落脚点。这个系列如果继续往下走我比较想写的是航点生成器与轨迹控制的实现细节以及怎么把今天这些调参结论跟具体航线速度剖面匹配起来。希望对正在啃PX4源码、正在飞调参真机的你能有点用。