Part IV · 第 13 章 反馈控制 · 13.1

PID 控制

机器人里几乎每一个电机背后都跑着一个 PID:比例项看现在的误差,积分项记住过去,微分项预判将来。这一节在一个受重力的关节上把三项拆开来玩,再看真实硬件上它会怎样出问题:微分冲击与噪声、饱和与积分饱和(windup)、采样率;最后学会整定(Ziegler–Nichols 与手动)、前馈,以及伺服驱动器和无人机里层层嵌套的串级回路。

约 45 分钟 前置:2.1 导数 · 2.3 积分 · 2.5 常微分方程 · 8.3 质量矩阵与科氏力 · 9.4 执行器与传感器 7 个交互

    1为什么机器人需要它

    规划器说"关节 2 在 0.5 秒后要到 60°",电机却只听得懂电压和电流。中间隔着摩擦、重力、没建模的负载、会变的电池电压。要让关节真的到达 60° 并停在那里,就得不停地测量、比较、修正:这就是反馈。PID 是反馈控制里最简单、最普遍的形式,它只看一个数:误差 \(e=q_d-q\)(目标角减实际角)。

    • 每一个关节伺服:工业臂、协作臂、舵机里都有位置环、速度环、电流环,几乎全是 P、PI 或 PID。
    • 无人机:姿态角的 P 环套着角速度的 PID 环,几百赫兹到上千赫兹地跑。
    • 足式机器人:强化学习策略常常只输出"关节目标角",真正驱动电机的是每个关节上的 PD 环。
    • 其他一切:轮速、夹爪力、3D 打印机喷头温度、云台……

    Åström 与 Murray 的教科书引用了一项对炼油、化工和造纸行业一万一千多个控制器的调查(Desborough 与 Miller,2002):97% 的常规控制器用的是 PID 算法,其中很多实际上只是 PI。它好用,是因为不需要模型就能工作;它难用,是因为真实硬件的饱和、噪声、延迟会让教科书公式出各种问题。2.5 节的 FIG 5 已经用 PD 控制过一个受重力的关节,并看到它停在离目标差一截的地方。这一节从那里接着走。

    2直觉:现在、过去、将来

    想象你伸直手臂提着一桶水,要把它举到某个高度。差得越多,越用力:这是比例项,像一根弹簧。可是桶有重量,弹簧只有在被拉开一截时才出力,所以你会停在比目标低一点的地方,那一截正好让弹簧的力等于桶的重量。于是你会"越等越用力":只要还差一点,就持续加力,直到差距消失。这是积分项,它记住了过去所有的误差。最后,快到的时候你会提前收力,免得冲过头:这是微分项,它看误差变化的速度,预判将来。三项加起来就是

    $$ u(t)\;=\;\hl{P}{K_p\,e(t)}\;+\;\hl{I}{K_i\!\int_0^t e(s)\,ds}\;+\;\hl{D}{K_d\,\dot e(t)},\qquad e=q_d-q . $$

    三项从左到右依次对应现在、过去和将来。这里的输出 \(u\) 是关节力矩 \(\tau\)(N·m)。被控的就是 2.5 节那根关节:\(J\ddot q+b\dot q+mg\ell\sin q=\tau\),\(J=0.5\) kg·m²,\(b=0.1\) N·m·s/rad,\(mg\ell=4\) N·m,\(q\) 从竖直向下量起。电机最多给 ±10 N·m。下图是实时仿真:拖动紫色手柄改目标角,用滑块调三个增益,或者点预设。三项各自的贡献画在右下,也列在下方的条形图里。

    FIG 1三个旋钮:一根受重力的关节,实时运行
    关节:拖动紫色手柄设目标
    P 项 Kpe
    I 项 Ki∫e
    D 项 −Kdq̇
    电机力矩 u
    左:琥珀色是关节,紫色虚线是目标角 \(q_d\)。右上:琥珀色 \(q(t)\),紫色虚线 \(q_d(t)\)(单位:度)。右下:红色 P 项、绿色 I 项、蓝色 D 项、青色总力矩 \(u\)(N·m),虚线是 ±10 N·m 的电机上限。条形图量程 ±12 N·m。这里的 D 项取的是测量值的导数 \(-K_d\dot q\)(目标不动时它就等于 \(K_d\dot e\),FIG 2 解释为什么这样取),积分项带"条件积分"抗饱和(FIG 3 解释)。把 \(K_i\) 调到 0 时,积分状态也一并清零。"推一下"给关节一个突然的角速度;"负载"在末端挂一个重物(\(mg\ell\) 增加 2 N·m,惯量增加 0.16 kg·m²)。
    试一试
    • 只用 P(\(K_i=0\))时手臂在默认目标附近晃个不停。保留 \(K_p>0\),加一点 \(K_d\)(大于 0)让它停下来,目标设在离竖直向下 30° 到 150° 之间(重力矩足够大的地方):它停在离目标超过 2° 的位置(静止 1 秒以上)。把 \(K_p\) 加大,差距缩小了,但消失了吗?
    • 打开积分(\(K_i>0\)),在同样受重力的目标处让手臂静止 1 秒,误差小于 0.2°。下方绿色的 I 项最后停在多少 N·m?它和重力矩 \(mg\ell\sin q_d\) 比如何?
    • 在上一步的状态下(\(K_i>0\)、静止、误差小于 0.5°)点"负载":手臂先下沉超过 1°,然后在 6 秒内自己爬回到 0.2° 以内。谁做了这件事?
    核心洞见

    P 是弹簧,D 是阻尼,I 是记忆。只有 P 和 D 时,静止的关节上 \(\dot q=0\),D 项为零,唯一能抵消重力的是 P 项 \(K_pe\),所以误差必须不为零:\(e_{ss}\approx mg\ell\sin q_d/K_p\)。I 项不一样:只要误差不为零,它就一直在变,所以手臂只可能在 \(e=0\) 的地方停下,那时积分正好等于重力矩。代价是:积分有"惯性",加得太猛(试试 PI 预设,\(K_d=0\))会让关节振荡甚至发散。

    3动手玩:真实硬件上的 D 和 I

    微分项:冲击、噪声与滤波

    控制器是一段每 1 ms 跑一次的代码,导数只能用差分算:\(\dot e\approx(e_k-e_{k-1})/T_s\)。2.1 节和 9.4 节已经看到,差分会把测量噪声除以一个很小的 \(T_s\),放大成很大的速度误差。PID 里这还要再乘 \(K_d\)。另一个问题来自目标:目标角突然跳 60°,\(e\) 在一个采样周期里跳 1.05 rad,\(K_d\Delta e/T_s\) 就是几千 N·m 的尖峰,叫微分冲击(derivative kick)。

    两个标准对策:(1) 对测量值求导:用 \(-K_d\dot q\) 代替 \(K_d\dot e\)。目标不动时两者相同,目标跳变时前者不受影响;(2) 给 D 项加一阶低通,截止频率 \(f_c\)。下图是同一个关节、同一组 \(K_p=30,\ K_i=20\),0.3 s 时目标从 0 跳到 60°,编码器 12 位(每圈 4096 格),读数再叠加标准差 \(\sigma\) 的噪声。

    FIG 2数字控制器里的微分项
    上:琥珀色是关节角 \(q\),紫色虚线是目标。下:青色是实际送给电机的力矩 \(u\)(被限制在 ±10 N·m,虚线),琥珀色细线是控制器"想要"的指令 \(v\)(饱和之前),超出画面时它的峰值写在读数里。"力矩波动"是 \(t\ge1.8\) s(手臂已基本停稳)之后 \(u\) 的标准差:电机在静止时还在"嗡嗡"抖的程度。噪声序列固定(同一个随机种子),所以每次结果一样。
    试一试
    • 切换到"对误差求导",不开滤波:控制器想要的指令峰值超过 1000 N·m,是电机上限的 100 多倍。切回"对测量值求导",峰值降到多少?
    • 保持"对测量值求导",调滤波截止频率 \(f_c\),让力矩波动小于 0.3 N·m,同时超调小于 15%。再把 \(f_c\) 降到 1 Hz 以下:为什么超调反而变大了?

    积分项:饱和与积分饱和(windup)

    电机力矩有上限。上限一到,控制器再"想要"更大的力矩也没用,可积分项不知道这件事,它照样把误差一点点加上去。等手臂终于追上目标,积分里已经存了一大笔"欠账",必须先反向误差很久才能还清:结果是巨大的超调。这叫积分饱和(integrator windup)。在机器人上特别常见:大步长的目标、手臂被人或障碍物挡住、关节碰到限位、急停后恢复。

    两种标准的抗饱和(anti-windup):条件积分(clamping):输出已经饱和、并且误差还在把它往饱和方向推时,暂停积分;反算(back-calculation):把"想要的"与"实际给的"之差 \(u-v\) 乘上增益 \(k_t=1/T_t\) 反馈进积分器,饱和期间积分被拉回到刚好不饱和的值。下图:增益 \(K_p=30\)、\(K_i=30\)、\(K_d=5\),目标在 0.2 s 时从 0 跳到 90°。"被手挡住"情景下,前 2.5 s 有一只手把手臂挡在 30°。

    FIG 3积分饱和与抗饱和
    关节(按"播放")
    右图三栏:(1) 琥珀色关节角 \(q\)、紫色虚线目标;(2) 青色实际力矩 \(u\),琥珀色细线是饱和前的指令 \(v\),虚线是力矩上限;(3) 绿色是积分项 \(I\)(N·m),虚线同样是力矩上限:绿线远远冲出虚线,就是积分饱和。竖虚线是播放时间。超调与调节时间从目标跳变(或手松开)起算,调节时间用 ±2% 带。
    试一试
    • 选"被手挡住"、不抗饱和:手一松,超调超过 100%,手臂甚至甩过头顶。手被挡住的 2.3 秒里,积分涨到了力矩上限的多少倍?
    • 同一个情景,换成条件积分或反算:超调小于 5%,并且松手后 2.5 秒内进入 ±2% 带。反算的 \(k_t\) 取太小或太大会怎样?
    核心洞见

    教科书里的 PID 是一个线性系统,真实的执行器不是:它有上限、有噪声、按采样周期工作。微分项的问题出在"高频"(目标跳变和噪声都是高频),所以对策是不让高频进入 D(对测量值求导、低通);积分项的问题出在"控制器以为在出力、其实没有",所以对策是让积分知道执行器的真实输出(条件积分、反算)。工程里的 PID 代码,一大半篇幅都在处理这两件事。

    4第二、第三视角:怎样整定,多快采样

    整定:Ziegler–Nichols 的"临界增益"实验

    没有模型时怎样选三个增益?Ziegler 与 Nichols(1942)给了一个纯实验的办法:先只用 P,把 \(K_p\) 一点点加大,直到系统出现不增也不减的等幅振荡。这时的增益叫临界增益 \(K_u\),振荡周期叫 \(T_u\)。两个数刻画了"系统离不稳定还有多远、有多快",查表就得到 PID 增益。

    这个实验需要一个"加大 \(K_p\) 终究会失稳"的对象。FIG 1 的关节是一个阻尼极小的二阶系统(没有延迟),加多少 P 都只是振荡得更快,永远不会失稳,不适合。真实伺服里常见的是用电压驱动的直流电机关节:沿用 9.4 节的电机(\(k_t=k_e=0.06\),\(R=0.5\ \Omega\),\(J_m=10^{-4}\) kg·m²),经 50:1 减速器带动同一根 0.5 kg·m² 的连杆(水平放置,不受重力)。反电动势提供了很强的阻尼,再加上 10 ms 的回路延迟(滤波、通信、PWM,见 9.4 节 FIG 6),加大 \(K_p\) 终究会失稳。控制器输出电压,1 kHz,目标是 1° 的小阶跃(电压远小于 24 V 的电源上限,所以这里不考虑饱和)。

    FIG 4Ziegler–Nichols 与手动整定
    琥珀色是关节角(度),紫色虚线是 1° 的目标,青色细线是电压 \(u\)(右侧刻度,V)。"① 找 \(K_u\)"模式只用 P,画 3 秒,读数给出相隔一个周期的两个峰值之比(大于 1 发散,小于 1 衰减)和测得的周期。"② PID"模式画 1.5 秒;三个 Z–N 按钮按表格填入增益(用本图的 \(K_u\approx299\) V/rad、\(T_u\approx0.136\) s)。
    试一试
    • 在"① 找 \(K_u\)"模式里调 \(K_p\),让峰值比落在 0.97 到 1.03 之间(几乎等幅振荡)。读出 \(K_u\) 和 \(T_u\)。
    • 切到"② PID",点"Z–N PID":超调约 76%,太猛了。手动调(保留积分 \(K_i>0\)),让超调小于 5% 且调节时间小于 0.25 s。提示:这个对象本身就带一个积分器(电压决定的是速度),需要的 \(K_i\) 很小。

    采样率:控制器多快才够快

    数字控制器每 \(T_s\) 秒才看一眼传感器,中间输出保持不变(零阶保持,2.5 节)。而且"读传感器 → 计算 → 写电机"这一步本身要花时间,很多实现里算出的力矩要到下一个周期才生效,这是一拍延迟。两者合起来大约是 \(1.5\,T_s\) 的延迟。延迟吃掉相位裕度(9.4 节),采样越慢越接近失稳。下图:FIG 1 的关节去掉重力,用连续时间设计好的 PD(\(K_p=50,\ K_d=7\),\(\omega_n=10\) rad/s,\(\zeta\approx0.7\),闭环带宽约 1.6 Hz),目标跳 30°,力矩限 ±30 N·m。

    FIG 5采样率与一拍延迟
    上:琥珀色是采样控制下的关节角,紫色虚线是同一组增益的连续时间控制器(理想参考)。下:青色台阶是采样后送给电机的力矩,每个台阶就是一个采样周期。D 项用测量值的后向差分。
    试一试
    • 保持"一拍延迟",把采样率往下调,找到超调仍小于 10% 的最低采样率(不高于 45 Hz)。它是闭环带宽 1.6 Hz 的多少倍?再往下调一两档,会怎样?
    一个概念,三个视角

    时域视角(FIG 1–3):P、I、D 分别是现在、过去、将来的误差。频域视角(FIG 4–5):P 决定"多快"(穿越频率),D 在穿越频率附近补相位,I 在低频把增益抬到无穷大(所以稳态误差为零),而延迟和采样在高频吃相位;整定就是在这些之间找平衡。极点视角:线性化后的闭环是一个三阶系统,三个增益决定三个极点的位置(第 5 节写出特征多项式;极点配置是 13.2 节的主题)。

    5再看数学

    提示:把鼠标悬停在公式中带底色的符号上,对应的图元素会被高亮(FIG 1 的 P、I、D 条形与曲线,FIG 2 的力矩曲线,FIG 3 的积分曲线,FIG 4 的关节角曲线,FIG 6 的前馈力矩曲线)。

    稳态误差:为什么 P 停不到目标

    PD 控制(D 取测量值)下,手臂静止时 \(\dot q=\ddot q=0\),运动方程只剩 \(mg\ell\sin q=K_p(q_d-q)\)。所以静止点满足下式(右边是 \(e_{ss}\) 很小时的近似):

    $$ K_p\,e_{ss}=mg\ell\,\sin(q_d-e_{ss})\qquad\Longrightarrow\qquad e_{ss}\approx\frac{mg\ell\sin q_d}{K_p+mg\ell\cos q_d} . $$

    FIG 1 的数:\(K_p=20\),\(q_d=60°\),\(e_{ss}=0.156\) rad \(=8.9°\)(近似式给 9.0°);\(K_p=60\) 时 3.2°。误差与 \(K_p\) 成反比,永远不为零。(若关节的负载是常值摩擦或别的常值扰动,结论一样。)

    积分为什么消除它:闭环的三阶方程

    在目标附近线性化:\(q=q_d-e\),\(\sin q\approx\sin q_d-e\cos q_d\),记重力"刚度" \(k_g=mg\ell\cos q_d\)(向下挂着时为正,过了水平线、手臂朝上时为负)。代入 PID(D 取测量值,\(\dot q=-\dot e\)):

    $$ J\ddot e+(b+K_d)\,\dot e+(K_p+k_g)\,e+K_i\!\int\! e\,dt\;=\;mg\ell\sin q_d . $$

    右边 \(mg\ell\sin q_d\) 是一个常值负载。对时间求一次导,它就消失了;右边是这个三阶方程的特征多项式:

    $$ J\,\dddot e+(b+K_d)\,\ddot e+(K_p+k_g)\,\dot e+K_i\,e=0,\quad Js^3+(b+K_d)s^2+(K_p+k_g)s+K_i . $$

    只要闭环稳定,\(e\to0\),不管负载多大:积分把"常值扰动"变成了方程右边求导后消失的东西。三阶多项式稳定(三个根都在左半平面)的充要条件(Routh–Hurwitz)是所有系数为正,并且

    $$ (b+K_d)\,(K_p+k_g)\;>\;J\,K_i . $$

    这解释了 FIG 1 的 PI 预设(\(K_p=20,\ K_i=15,\ K_d=0\),\(q_d=60°\),\(k_g=2\)):\(0.1\times22=2.2<0.5\times15=7.5\),不稳定:手臂停不下来,只是因为力矩饱和才被限制在一个持续的大幅摆动里(约 5° 到 85°)。加上 \(K_d=3\):\(3.1\times22=68>7.5\),稳定。积分要靠阻尼来"托住":增大 \(K_i\) 就要有足够的 \(K_d\)(或物理阻尼)。另外 \(q_d\) 越过水平线后 \(k_g<0\),同一组增益的裕度会变小。极点、稳定性与极点配置在 13.2 节系统地讲。

    离散 PID、滤波微分与抗饱和

    工程上常写成"标准形式":\(u=K_p\big(e+\tfrac1{T_i}\int e+T_d\dot e\big)\),积分时间 \(T_i=K_p/K_i\),微分时间 \(T_d=K_d/K_p\)。实际实现的微分是一阶滤波的:

    $$ \begin{gathered} D(s)=\hl{Df}{\frac{K_d\,s}{1+s/\omega_f}}\,\big(-Q(s)\big),\qquad \omega_f=2\pi f_c,\\[6pt] d_k=\alpha\,d_{k-1}+(1-\alpha)\,\frac{-(y_k-y_{k-1})}{T_s},\quad \alpha=e^{-\omega_fT_s}. \end{gathered} $$

    右式就是 FIG 2 的代码。测量 \(y_k\) 带独立噪声(标准差 \(\sigma\))时,未滤波的差分噪声标准差是 \(\sqrt2\,\sigma/T_s\):\(\sigma=0.05°=8.7\times10^{-4}\) rad、\(T_s=1\) ms 给出 1.2 rad/s,乘 \(K_d=4\) 就是约 5 N·m 的力矩抖动,与 FIG 2 读数(5.2 N·m,含量化)一致。低通让噪声按 \(f_c\) 下降,但给 D 加了相位滞后:\(f_c\) 接近闭环带宽时,阻尼来得太晚,就会超调(FIG 2 的 \(f_c\le1\) Hz)。对目标跳变 \(\Delta r\),未滤波的"对误差求导"给出一拍的尖峰 \(K_d\Delta r/T_s\):\(4\times1.047/0.001\approx4200\) N·m。

    抗饱和。记控制器想要的输出 \(v\)、执行器实际输出 \(u=\mathrm{sat}(v)\)。(a) 是条件积分,(b) 是反算:

    $$ \text{(a)}\ \ \dot I=\begin{cases}0, & u\ne v\ \wedge\ e\,v>0\\ K_i\,e, & u=v\ \vee\ e\,v\le0\end{cases}\qquad\qquad \text{(b)}\ \ \dot I=K_i\,e+\hl{aw}{\tfrac{1}{T_t}\,(u-v)} . $$

    反算在饱和时把 \(I\) 以时间常数 \(T_t\) 拉向"刚好不饱和"的值。\(T_t\) 太大(\(k_t\) 太小)等于没有抗饱和;太小则积分被压得太死,离开饱和后要慢慢爬(FIG 3:\(k_t=10\) 时不再超调,但调节要约 3 s)。Åström 与 Hägglund 建议 \(T_t\approx\sqrt{T_iT_d}\):FIG 3 的 \(T_i=1\) s、\(T_d=1/6\) s 给出 \(T_t\approx0.41\) s,即 \(k_t\approx2.4\),落在 FIG 3 的好区间里:默认的 8 N·m 上限下,"被手挡住"情景中 \(k_t\) 取 1.5 到 2.5 都能完成上面的任务。

    把它们合起来,就是一个可以直接用的控制循环(本页所有图都用这段逻辑):

    // 每 Ts 秒执行一次
    e      = r - y                          // 误差
    P      = Kp * e
    dRaw   = -(y - y_prev) / Ts             // 对测量值求导:目标跳变时没有冲击
    dF     = a * dF + (1 - a) * dRaw        // 一阶低通,a = exp(-2π fc Ts)
    v      = P + I + Kd * dF + u_ff         // 想要的输出(u_ff:前馈)
    u      = clamp(v, -umax, umax)          // 执行器能给的输出
    I     += (Ki * e + (u - v) / Tt) * Ts   // 积分 + 反算抗饱和
    y_prev = y
    send(u)

    另一种常见写法是增量式(velocity form):每拍只算增量 \(\Delta u_k=K_p(e_k-e_{k-1})+K_iT_se_k+K_d(e_k-2e_{k-1}+e_{k-2})/T_s\),再令 \(u_k=\mathrm{sat}(u_{k-1}+\Delta u_k)\)。因为累加的是饱和后的 \(u\),它天然不会积分饱和,切换手动/自动时也没有跳变(无扰切换)。还要注意:如果代码里存的是"每拍增益" \(K_iT_s\) 和 \(K_d/T_s\),改变采样周期就会悄悄改变实际的 \(K_i\)、\(K_d\)。用 Tustin(双线性)变换 \(s\leftarrow\tfrac2{T_s}\tfrac{z-1}{z+1}\) 离散化比后向差分更接近连续设计,但在 \(f_s\) 远高于带宽时差别很小。

    Ziegler–Nichols 表与采样率经验法则

    Ziegler–Nichols 的"临界增益"表(目标是每个周期振幅衰减到 1/4):

    \(K_p\)\(T_i\)\(T_d\)FIG 4 中(\(K_i=K_p/T_i,\ K_d=K_pT_d\))
    P\(0.5\,\hl{Ku}{K_u}\)——\(K_p=149\)
    PI\(0.45\,\hl{Ku}{K_u}\)\(T_u/1.2\)—\(K_p=134,\ K_i=1186\)
    PID\(0.6\,\hl{Ku}{K_u}\)\(T_u/2\)\(T_u/8\)\(K_p=179,\ K_i=2637,\ K_d=3.05\)

    在 FIG 4 的对象上,Z–N PID 的超调是 76%,Z–N PI 在 1.5 s 内都没有调节下来。原因有二:Z–N 本来是为"抑制负载扰动"、按 1/4 衰减设计的,对目标阶跃本来就猛;而这个对象(电压 → 速度 → 位置)自带一个积分器,再加一个强积分就太多了。手动调到 \(K_p=100,\ K_i=10,\ K_d=4\),超调 0.7%,0.18 s 调节完。所以 Z–N 是起点,不是终点。手动整定的常用顺序:先只用 P,加到响应够快、略有超调;再加 D 压住振荡;最后加一点 I 消除稳态误差;若有噪声或执行器抖动,回头降 D 或加滤波。对串级回路,从内环往外调(FIG 7)。

    FIG 5 的结果给出一个经验法则:带一拍延迟时,40 Hz(闭环带宽 1.6 Hz 的 25 倍)超调 8%,35 Hz 已到 16%,到 25 Hz 及以下就成了持续振荡。教科书常说采样率至少取闭环带宽的 20 倍左右,再留出噪声与延迟的余量;机械臂关节环常用 1 kHz,电流环 10 kHz 量级,正是这个道理。

    前馈与串级

    反馈只能在误差出现之后才纠正。如果知道要走的轨迹 \(q_d(t)\) 和模型,就可以提前把需要的力矩送出去:

    $$ u=\hl{ff}{\underbrace{\hat J\,\ddot q_d+\hat b\,\dot q_d+\widehat{mg\ell}\,\sin q_d}_{u_{ff}}}\;+\;\underbrace{K_p\,e+K_d\,\dot e\,(+K_i\!\textstyle\int e)}_{u_{fb}} . $$

    \(u_{ff}\) 是前馈,\(u_{fb}\) 是反馈。模型精确时,代入运动方程得 \(J\ddot e+(b+K_d)\dot e+K_pe+\dots\approx0\)(在轨迹附近线性化):误差方程不再有"驱动项",不论轨迹多快,误差都只会衰减。模型不准时,驱动项正比于模型误差,反馈只需要处理这部分残差。这和 8.3 节的计算力矩控制是同一个思路(计算力矩还把反馈项乘上模型惯量,并在测得的状态而不是目标轨迹上计算模型项);多关节时 \(u_{ff}\) 由逆动力学(8.2 节的 RNEA)给出。

    串级把一个难对象拆成一串简单对象,每层一个 P 或 PI。以 FIG 7 的伺服驱动器为例:电流环的对象是绕组 \(1/(Ls+R)\),用 PI 且令零点抵消极点,\(K_p=L\omega_c\)、\(K_i=R\omega_c\),闭环近似 \(\omega_c/(s+\omega_c)\);速度环的对象(电流环看作 1)是 \(k_t/(J_ts)\),PI 取 \(K_p=J_t\omega_v/k_t\),零点放在 \(\omega_v/4\);位置环的对象(速度环看作 1)是积分器,P 增益就是带宽 \(\omega_p\)。"内环看作 1"成立的前提是带宽分离:每层比外层快 4–10 倍。

    6机器人中的它:前馈与串级伺服

    机械臂很少只是"停在一个角度",它要跟踪一条轨迹。下图让 FIG 1 的关节跟踪 \(q_d(t)=70°+50°\sin(2\pi t/T)\),反馈是固定的 PD(\(K_p=30\),\(K_d=4\),D 取误差导数,因为轨迹是光滑的,不会有冲击)。三个按钮分别打开重力、速度(粘滞摩擦)、加速度(惯量)三项前馈;"模型误差"让控制器以为 \(J,b,mg\ell\) 都是真实值的 \(1+\delta\) 倍。

    FIG 6反馈追,前馈领
    关节(按"播放")
    右图三栏:(1) 琥珀色 \(q\)、紫色虚线 \(q_d\)(度);(2) 红色跟踪误差 \(e\)(度,量程自动);(3) 绿色是前馈力矩 \(u_{ff}\),青色是反馈力矩 \(u_{fb}\)(N·m)。RMS 误差从 \(t=2\) s 起算(跳过初始过渡)。前馈全开且模型准确时,反馈几乎无事可做,青色线贴近零。
    试一试
    • 周期 3 s 时只开重力前馈,RMS 误差从约 5.8° 降到约 2.7°;周期 2 s 时只降了一点点,为什么?然后打开全部三项前馈,并把模型误差调到 \(|\delta|\ge20\%\):RMS 误差仍小于 1.5°。

    最后看一个真实伺服驱动器内部。位置环(1 kHz)输出速度指令,速度环(5 kHz)输出电流指令,电流环(20 kHz)输出电压。电机沿用 9.4 节(24 V 供电,绕组电感取 0.5 mH),驱动器限流设为 20 A(低于 9.4 节电机 30 A 的峰值),50:1 减速,负载就是 FIG 4 的连杆。目标在 0.05 s 时跳 10°,0.6 s 时有人在关节上加 10 N·m 的负载("负载阶跃")。电流环带宽固定为 1 kHz(\(2\pi\times1000\) rad/s),你可以调位置环带宽 \(\omega_p\) 和速度环与位置环的带宽比。

    FIG 7伺服驱动器的三层串级
    qd→ 位置 P1 kHz · ωp→ ωref → 速度 PI5 kHz · ωv→ iref → 电流 PI20 kHz · ωc→ V → 电机 + 50:1 + 连杆
    三栏从上到下对应三层回路:(1) 琥珀色关节角 \(q\)、紫色虚线目标(度);(2) 电机转速:紫色是速度环收到的指令 \(\omega_{ref}\),琥珀色是实际转速(rad/s,电机侧);(3) 电流:青色是电流指令 \(i_{ref}\),琥珀色是实际电流(A),虚线是 ±20 A 限流。默认设置下,阶跃一开始电流就顶到限流:速度环的输出饱和,驱动器以最大力矩加速,这正是串级的另一个好处,限流天然在里面。竖虚线是负载阶跃时刻。
    试一试
    • 在默认 \(\omega_p=20\) rad/s 下先把带宽比调到 1(速度环和位置环一样快):超调超过 20%。再调 \(\omega_p\) 和带宽比,让阶跃超调小于 1%,且负载阶跃造成的位置下沉小于 0.25°。带宽比至少要多大?
    真实系统里

    伺服驱动器与智能舵机:工业伺服和无刷驱动器都是 FIG 7 的串级结构,电流环跑在 10 kHz 量级(9.4 节)。开源的 ODrive 把三层的增益直接暴露为 pos_gain、vel_gain、vel_integrator_gain;Dynamixel X 系列舵机的控制表里有位置环的 P/I/D 增益、速度环的 P/I 增益,以及速度和加速度两项前馈增益(Feedforward 1st/2nd Gain),与 FIG 6 的速度、加速度前馈是同一个思路。无人机:PX4 的多旋翼姿态控制是"角度误差 → P → 角速度指令 → 角速度 PID → 力矩",参数名如 MC_ROLL_P、MC_ROLLRATE_P/I/D;ArduPilot 对应 ATC_ANG_RLL_P 与 ATC_RAT_RLL_P/I/D。内环(角速度)比外环快,与 FIG 7 同理。足式机器人:Unitree 的底层电机指令包含目标位置、目标速度、前馈力矩和 \(K_p\)、\(K_d\),电机按 \(\tau=K_p(q_d-q)+K_d(\dot q_d-\dot q)+\tau_{ff}\) 执行;强化学习策略通常以几十赫兹输出 \(q_d\),关节 PD 以高得多的频率跟踪。ROS 2:ros2_control 的 control_toolbox 提供带积分限幅(抗饱和)选项的 PID;关节轨迹控制器在以速度或力矩为指令接口时,可以在每个关节上闭一个 PID 环,并加上速度前馈。自动整定:Åström 与 Hägglund(1984)的继电器(relay)法用开关控制激出极限环,安全地测出 \(K_u\)、\(T_u\);3D 打印机固件 Marlin 的 M303 命令就用这种继电器振荡来自动整定喷头温度 PID。

    7常见误区

    误区 1:仿真里调好的 D,上真机就抖

    仿真里的速度是"干净"的,真机的速度来自编码器差分,量化和噪声被 \(1/T_s\) 放大(FIG 2 里 \(\sigma=0.05°\) 就带来 5 N·m 的力矩抖动)。症状是电机发热、发出啸叫、减速器磨损。对策:D 取测量值,加低通(截止频率取闭环带宽的几倍到十几倍),能直接测速度(测速电机、驱动器内的观测器)就别差分;仿真时把编码器量化和噪声也加进去。

    误区 2:忘了积分在"后台"一直在累加

    手臂碰到限位、被人抓住、夹爪夹住物体、急停后电机断使能:误差还在,积分照样累加。重新使能或松开的那一刻,积好的力矩一下子释放(FIG 3 里积分涨到上限的 10 倍,手臂甩过头顶)。除了抗饱和,还要在控制器失能时冻结或清零积分,切换模式时做无扰切换。接触任务(13.5 节)里常干脆不用积分,或给它很小的限幅。

    误区 3:用积分去干前馈的活

    重力矩随姿态变化,而积分是慢的:每次姿态改变,积分都要重新"找"一遍,期间就有误差和超调。已知的力(重力、粘滞摩擦、惯性力)应该用前馈直接给出(FIG 6:周期 3 s 时 RMS 误差从 5.8° 降到 0.002°),积分只留给真正未知的、慢变的残差。增大 \(K_i\) 去追轨迹,换来的往往是振荡(第 5 节的稳定条件)。

    误区 4:串级回路从外往里调,或者内外一样快

    外环的设计假设"内环像一根导线"(增益为 1、没有延迟)。内环没调好,外环的增益就是在补偿内环的毛病;内外带宽太接近,两层的动态耦合,超调和振荡就来了(FIG 7 默认 \(\omega_p=20\) rad/s、带宽比为 1 时超调超过 20%)。正确顺序是先电流环、再速度环、最后位置环,每层比外一层快 4–10 倍。无人机同理:先调角速度环,再调角度环。

    误区 5:以为增益越大越好

    大 \(K_p\) 让稳态误差变小、响应变快,但每个真实回路都有延迟(采样、滤波、通信、PWM)。一段延迟 \(\Delta\) 在穿越频率 \(\omega_{gc}\) 处吃掉 \(\omega_{gc}\Delta\) 弧度的相位(9.4 节),增益加到某处必然失稳(FIG 4 的 \(K_u\approx299\) V/rad 就是这个边界)。噪声也随增益放大,执行器也会饱和。好的控制器是在"够快"和"够稳、够安静"之间的平衡,而不是增益的竞赛;想要又快又准,靠的是前馈和更好的模型,不是更大的反馈增益。

    8小练习

    1. FIG 1 的关节(\(mg\ell=4\) N·m)只用 PD,\(K_p=20\) N·m/rad,目标 \(q_d=90°\)(水平)。手臂停下后,稳态误差大约是多少?
    静止时 \(K_pe=mg\ell\sin(q_d-e)=4\cos e\)。水平处 \(k_g=mg\ell\cos90°=0\),近似 \(e\approx4/20=0.2\) rad \(\approx11.5°\);精确解 \(20e=4\cos e\) 给出 0.196 rad \(\approx11.2°\)。所以是选项 C。D 项在静止时为零,帮不上忙。
    2. 为什么加了积分项之后,常值负载下的稳态误差变成了零?
    选项 B。平衡时所有状态不变,其中积分状态的导数就是 \(e\),所以必须 \(e=0\)。前提是闭环稳定(第 5 节的 Routh 条件)。选项 A 只是减小误差而不能消除;选项 C 描述的是微分项;积分让系统的阶数升高一阶,而不是变成一阶。
    3. 机械臂每次收到新的目标点,电机都会"咯噔"一下,电流尖峰触发了驱动器过流保护。增益本身调得没问题。最可能的原因和对策是?
    选项 A。目标在一个采样内跳 \(\Delta r\),\(K_d\Delta r/T_s\) 是巨大的尖峰(FIG 2 里约 4200 N·m)。对测量值求导时目标跳变不进入 D,P 项的跳变 \(K_p\Delta r\) 还在,所以实际中还会把目标轨迹做平滑。加大 \(K_i\)、降采样率都与此无关,后者还会损害稳定性(FIG 5)。
    4. 一个协作臂被人用手挡住几秒,松手后猛地冲过目标很远。下列哪个改动最直接地解决这个问题?
    选项 D。被挡住期间误差持续存在,力矩早已顶到上限,积分却还在累加(FIG 3 中涨到上限的约 10 倍)。松手后这笔"欠账"要靠反向误差慢慢还,于是冲过头。抗饱和直接阻止了这件事。加大 \(K_d\) 只是部分压住冲势;提高上限只是把问题推后(被挡住时同样会累积),而且让碰撞更危险。
    5. 一个伺服的速度环带宽是 30 rad/s,有人把位置环带宽调到了 25 rad/s,结果超调很大。最合理的做法是?
    选项 B。外环设计假设内环"像一根导线",这需要带宽分离。带宽比约 1.2 时两层动态强烈耦合(FIG 7 在默认 \(\omega_p\) 下带宽比为 1 时超调超过 20%)。选项 C 让问题更糟;给外环加积分只会再添相位滞后;采样率不是瓶颈。

    9延伸阅读

    • K. J. Åström & R. M. Murray, Feedback Systems: An Introduction for Scientists and Engineers, Princeton University Press, 2008 (2nd ed. 2021) — PID 一章:积分作用、抗饱和、滤波微分与整定;全书免费在线
    • K. J. Åström & T. Hägglund, PID Controllers: Theory, Design, and Tuning, 2nd ed., ISA, 1995; Advanced PID Control, ISA, 2006 — PID 的权威专著:实现细节、抗饱和、自动整定
    • J. G. Ziegler & N. B. Nichols, Optimum Settings for Automatic Controllers, Trans. ASME 64, 1942 — 临界增益法的原始论文
    • K. J. Åström & T. Hägglund, Automatic Tuning of Simple Regulators with Specifications on Phase and Amplitude Margins, Automatica 20(5), 1984 — 继电器自动整定
    • N. Minorsky, Directional Stability of Automatically Steered Bodies, J. American Society of Naval Engineers 34, 1922 — 为船舶自动操舵写下的三项控制律,PID 的早期理论分析
    • G. F. Franklin, J. D. Powell & M. L. Workman, Digital Control of Dynamic Systems, 3rd ed., Addison-Wesley, 1998 — 离散化、采样率选择与零阶保持
    • M. W. Spong, S. Hutchinson & M. Vidyasagar, Robot Modeling and Control, 2nd ed., Wiley, 2020 — 独立关节控制:PID、前馈与执行器动力学
    • K. Lynch & F. Park, Modern Robotics, Ch. 11 — 机器人控制:误差动力学、PID 与前馈加反馈
    • B. Beauregard, Improving the Beginner's PID, blog series, 2011 — 从最简 PID 一步步加上采样时间、微分冲击、抗饱和与无扰切换的实践教程