第三节:经典PID力矩控制
各位同学,今天我们来聊聊力矩控制里最经典、也最实用的方法——PID控制。说实话,我在这个行业摸爬滚打十几年,PID控制几乎无处不在。你想想看,从工业机器人到无人机,从伺服电机到手术机器人,PID都是那个最靠谱的“老黄牛”。
3.1 PID控制原理
PID控制,说白了就是三个字:比例、积分、微分。它的核心思想很简单——根据当前误差、过去误差的累积、以及误差的变化趋势,来调整输出。
公式长这样:
u(t) = Kp * e(t) + Ki * ∫e(τ)dτ + Kd * de(t)/dt
其中:
- Kp(比例项):直接响应当前误差。误差大,输出就大。我习惯先调Kp,让它能快速响应。
- Ki(积分项):消除稳态误差。说白了就是“算旧账”,把过去累积的误差补回来。
- Kd(微分项):预测未来趋势。误差变化快了,它就提前刹车,防止超调。
我在项目中遇到过一件事:有个六轴机器人,末端抖动得厉害。我一开始以为是机械间隙,后来发现是Kd设得太小,微分项没起作用。调大Kd后,抖动立刻消失了。嗯,这就是微分项的妙用。
核心要点:PID三个参数各有分工。Kp决定响应速度,Ki消除静差,Kd抑制振荡。调参顺序我建议:先P,再I,最后D。
3.2 力矩环PID设计
力矩环PID,和位置环、速度环不太一样。它的控制对象是电机输出的力矩(或电流),响应速度要求极高。一般力矩环的采样频率在1kHz到10kHz之间,比位置环快得多。
设计力矩环PID时,我通常会考虑以下几点:
- 带宽匹配:力矩环的带宽要远高于速度环和位置环。一般力矩环带宽是速度环的5-10倍。
- 抗噪声:力矩信号(电流信号)噪声大,微分项容易放大噪声。我建议加一个低通滤波器。
- 饱和处理:电机输出力矩有限,积分项容易饱和。这个我们后面细说。
一个典型的力矩环PID结构是这样的:
// 力矩环PID伪代码
float torque_pid_control(float target_torque, float actual_torque) {
float error = target_torque - actual_torque;
// 比例项
float p_out = Kp * error;
// 积分项(带抗积分饱和)
integral += Ki * error * dt;
integral = clamp(integral, -integral_limit, integral_limit);
// 微分项(带滤波)
derivative = (error - last_error) / dt;
derivative = lowpass_filter(derivative, cutoff_freq);
float d_out = Kd * derivative;
last_error = error;
return p_out + integral + d_out;
}
个人经验:力矩环的Ki不要设太大。我见过很多新手把Ki调得过高,结果系统低频振荡,嗡嗡响。Ki的作用是消除静差,不是用来提高响应速度的。
3.3 抗积分饱和
积分饱和,是PID控制里最坑的问题之一。为什么会这样?
你想想看,当电机输出已经达到最大力矩(比如10Nm),但误差还在,积分项还在不断累积。等误差反向时,积分项里已经存了一大笔“旧账”,需要很长时间才能消化掉。这段时间里,系统响应会严重滞后,甚至振荡。
我曾经在一个焊接机器人项目上吃过这个亏。机器人启动时,积分项疯狂累积,导致启动瞬间力矩过冲,直接把焊枪撞歪了。从那以后,我再也不敢忽视抗积分饱和了。
常用的抗积分饱和方法有三种:
| 方法 | 原理 | 优缺点 |
|---|---|---|
| 限幅法 | 积分项输出超过阈值时截断 | 简单,但可能引起积分项突变 |
| 积分回退法 | 输出饱和时,积分项回退到饱和值对应的积分量 | 效果好,但计算稍复杂 |
| 条件积分法 | 只在特定条件下才积分(如误差较小或未饱和时) | 灵活,但需要调条件阈值 |
我个人最常用的是限幅法,简单可靠。代码实现如下:
// 抗积分饱和实现
float integral = 0;
float integral_limit = 5.0; // 积分限幅值
void update_integral(float error, float dt) {
integral += Ki * error * dt;
// 限幅
if (integral > integral_limit) integral = integral_limit;
if (integral < -integral_limit) integral = -integral_limit;
}
注意:积分限幅值不是随便设的。我建议根据电机最大输出力矩的10%-20%来设定。设得太小,积分项没作用;设得太大,抗饱和效果差。
3.4 前馈补偿
前馈补偿,说白了就是“提前给力”。PID是事后纠偏,前馈是事前预防。两者结合,效果翻倍。
在力矩控制中,前馈补偿主要用来抵消已知的干扰,比如:
- 重力补偿:机器人关节在重力作用下需要额外的力矩保持位置
- 摩擦力补偿:电机和减速器的摩擦力,尤其在低速时明显
- 惯性力补偿:加速过程中需要的额外力矩
前馈补偿的公式很简单:
u_total = u_pid + u_feedforward
其中u_feedforward是根据模型计算出来的。比如重力补偿:
// 重力前馈补偿
float gravity_feedforward(float joint_angle) {
// 根据关节角度计算重力矩
float torque = m * g * L * sin(joint_angle);
return torque;
}
我在做协作机器人时,重力补偿是必须的。没有重力补偿,机器人一断电就往下掉,夹到人手可不是闹着玩的。加了重力补偿后,机器人可以悬停在任意位置,推都推不动——嗯,这就是前馈的魅力。
关键点:前馈补偿不改变系统稳定性,只提高响应速度和精度。PID负责处理未知扰动,前馈负责处理已知扰动。两者是互补关系,不是替代关系。
知识体系总览
下面这张图,是我自己画的PID力矩控制知识体系。你可以把它当作学习地图:
这张图把今天讲的内容串起来了。从PID原理出发,到力矩环设计,再到抗积分饱和和前馈补偿。每个模块之间都有联系,不是孤立的。
好了,这一节的内容就到这里。PID力矩控制看起来简单,但真正用好它,需要大量的实践和调试。我建议你回去后,找个电机试试手,调一调Kp、Ki、Kd,感受一下每个参数的作用。纸上得来终觉浅,绝知此事要躬行。
最后一个小建议:调试PID时,先把积分项关掉(Ki=0),只调P和D。等系统稳定了,再慢慢加积分。这样不容易翻车。
可可精品资料库