第1章:力矩控制算法入门
PID控制在力矩环中的应用
说到力矩控制,很多刚入行的朋友第一反应就是「PID嘛,调三个参数就行了」。嗯,这话对了一半。PID确实是力矩环最基础的算法,但真正把它用好,没那么简单。
我个人习惯把力矩环的PID看作一个「弹簧-阻尼」系统。比例项P就是弹簧刚度,积分项I负责消除静差,微分项D则提供阻尼。你想想看,如果弹簧太硬(P太大),系统会震荡;阻尼太大(D太大),响应又太慢。这个平衡点,就是调参的功夫所在。
τcmd = Kp · e(t) + Ki · ∫e(t)dt + Kd · de(t)/dt
我在项目中遇到过一件事:有个六轴机械臂的末端抖动特别厉害,怎么调P和D都没用。后来发现是积分项饱和了——误差一直累积,积分项输出过大,导致系统失控。从那以后,我每次做力矩环都会加上积分限幅和抗饱和处理。
前馈补偿的基本概念
纯PID有个天生的缺陷:它只能「事后纠偏」。也就是说,必须等到误差产生了,它才开始调整。这在高速运动中就很被动。
前馈补偿的思路很简单——提前把已知的干扰算出来,直接加到输出里。比如重力补偿,就是最典型的前馈应用。你想想看,一个机械臂在竖直方向运动时,重力始终存在。如果只靠PID去扛,那积分项得一直憋着劲。但如果我们提前把重力矩算出来加进去,PID只需要处理剩下的那点误差就够了。
前馈的数学模型其实不复杂:
// 重力前馈补偿示例
float gravity_compensation(float q, float mass, float length) {
return mass * GRAVITY * length * sin(q);
}
// 最终力矩指令
tau_cmd = pid_output + feedforward_term;
说白了,前馈就是「把能算清楚的先算清楚」。我建议你在做力矩控制时,先把所有能建模的力都做成前馈项,剩下的交给PID去兜底。
摩擦补偿的基本概念
摩擦这个东西,是所有做控制的人最头疼的。为什么?因为它非线性、时变、还跟温度有关。
摩擦模型有很多种,最常用的是库仑+粘滞摩擦模型:
| 摩擦类型 | 表达式 | 特点 |
|---|---|---|
| 库仑摩擦 | τc = μ · sgn(ω) | 与速度方向有关,大小恒定 |
| 粘滞摩擦 | τv = B · ω | 与速度成正比 |
| Stribeck效应 | 低速时摩擦先降后升 | 容易引起低速抖动 |
摩擦补偿的实现,我一般分两步走:
- 离线辨识: 让电机匀速跑不同速度,记录力矩值,拟合出摩擦曲线
- 在线补偿: 根据当前速度查表或计算,把摩擦力矩加进去
// 摩擦补偿示例
float friction_compensation(float velocity) {
float coulomb = 0.1; // 库仑摩擦系数
float viscous = 0.05; // 粘滞摩擦系数
// 加一个平滑过渡,避免过零跳变
float smooth_sign = tanh(velocity * 100.0);
return coulomb * smooth_sign + viscous * velocity;
}
知识体系总览
下面这张图,是我自己总结的力矩控制知识框架。你可以把它当作本章的「地图」:
实际调试中的几点建议
说了这么多理论,最后分享几个实战中的小技巧:
- 先调P,再加D: 我习惯先把I设为0,只调P让系统不震荡,然后加D抑制超调,最后加I消除静差
- 前馈要「软」着加: 不要一下子把100%的前馈加进去,先加50%,观察系统反应,再逐步提高
- 摩擦补偿要「温柔」: 尤其是过零点的处理,用tanh或sigmoid函数做平滑,比直接符号函数好得多
嗯,这一章的内容就到这里。力矩控制入门其实不难,难的是把每个细节都做到位。记住:PID是基础,前馈是进阶,摩擦补偿是细节。三者缺一不可。