第四节:重力补偿与摩擦补偿
各位同学好。今天我们来聊聊力矩控制里两个绕不开的话题——重力补偿和摩擦补偿。
说实话,我刚入行那会儿,觉得力矩控制嘛,给个期望力矩,电机转就完了。结果第一次调试六轴机械臂,空载时还好,一装上负载,整个手臂往下坠,跟断了似的。嗯,那时候我才意识到:重力补偿,不是可选项,是必选项。
4.1 静态重力矩计算
先说说重力补偿的本质。说白了,就是算出机器人各个关节因为自身重量和负载重量产生的力矩,然后在控制指令里把这个力矩抵消掉。
静态重力矩的计算,核心就一句话:重力在关节轴线上产生的力矩。
对于单关节来说,公式很简单:
τ_gravity = m * g * L * sin(θ)
其中:
- m — 连杆质量
- g — 重力加速度
- L — 质心到关节轴的距离
- θ — 连杆与水平面的夹角
但实际项目中,机器人是多连杆串联结构。每个关节的重力矩,不仅受自身连杆影响,还受后面所有连杆和负载的影响。我习惯用递推法来计算:
- 从末端开始,逐级向前计算每个连杆的质心位置和重力矩
- 将后一级的力矩累加到前一级
- 最终得到每个关节的总重力补偿力矩
关键点:静态重力矩只与关节位置有关,与速度、加速度无关。所以它是个位置相关的函数,可以离线计算好,查表使用。
我在项目中遇到过一个问题:机械臂在某个姿态下,重力矩突然变得很大,导致电机过载。后来排查发现,是质心参数标定不准。所以,质心参数的准确性,直接决定了重力补偿的效果。
4.2 库仑+粘滞摩擦模型
摩擦补偿,比重力补偿要麻烦一些。为什么?因为摩擦是非线性的,而且方向总是与运动方向相反。
常用的摩擦模型是库仑+粘滞摩擦模型:
τ_friction = τ_coulomb * sign(ω) + B * ω
其中:
- τ_coulomb — 库仑摩擦力矩(常数)
- sign(ω) — 速度方向的符号函数
- B — 粘滞摩擦系数
- ω — 关节角速度
这个模型虽然简单,但实际用起来效果不错。我个人的经验是:
- 库仑摩擦主要影响低速时的启停性能。你想想看,电机刚启动时,要克服的静摩擦力往往比动摩擦力大得多。
- 粘滞摩擦则随着速度增加而线性增大。高速运行时,这部分占主导。
小技巧:实际标定时,可以让机器人以不同速度匀速运动,记录力矩值。然后做线性拟合,就能得到库仑摩擦系数和粘滞摩擦系数。
我曾经在调试一个协作机器人时,发现低速时抖动特别严重。查了半天,原来是库仑摩擦补偿值给大了,导致过补偿。嗯,这里要注意:摩擦补偿宁小勿大,过补偿会引起震荡。
4.3 前馈补偿实现
有了重力矩和摩擦力矩的计算方法,接下来就是怎么把它们用起来。
前馈补偿的思路很简单:在PID反馈控制的基础上,把已知的干扰力矩提前加到控制指令里。这样,控制器就不需要等误差出现再去调整了。
我画了一张图,帮你理解整个控制回路:
前馈补偿的实现步骤:
- 获取当前关节位置和速度 — 从编码器读取
- 计算重力补偿力矩 — 根据关节位置查表或实时计算
- 计算摩擦补偿力矩 — 根据关节速度和摩擦模型计算
- 叠加到控制输出 — 在PID输出基础上加上前馈量
代码实现大概是这样的:
// 前馈补偿计算函数
float computeFeedforward(float position, float velocity) {
// 1. 重力补偿
float gravity_torque = computeGravity(position);
// 2. 摩擦补偿
float friction_torque = COULOMB_FRICTION * sign(velocity)
+ VISCOUS_FRICTION * velocity;
// 3. 总前馈量
float feedforward = gravity_torque + friction_torque;
return feedforward;
}
// 控制循环中调用
void controlLoop() {
float pos = readEncoder();
float vel = readVelocity();
float pid_output = computePID(setpoint, pos);
float ff_output = computeFeedforward(pos, vel);
float final_torque = pid_output + ff_output;
setMotorTorque(final_torque);
}
注意事项:
- 前馈补偿不能完全替代反馈控制。反馈是兜底的,前馈是锦上添花的。
- 摩擦模型参数需要定期标定,因为机械磨损会导致参数变化。
- 重力补偿在低速时效果明显,高速时惯性力占主导,重力影响相对变小。
我记得有一次,在调试一个六自由度机械臂时,重力补偿参数没调好,结果机械臂在某个姿态下突然往下掉,差点砸到人。从那以后,我每次做重力补偿都会先做空载验证:让机械臂在无负载情况下,各个关节能否保持任意位置。如果会滑落,说明补偿不够;如果会震荡,说明补偿过了。
好了,这一节的内容就到这里。重力补偿和摩擦补偿,说白了就是把已知的干扰提前抵消掉,让PID控制器只处理那些未知的、非线性的部分。这样,控制精度和响应速度都能上一个台阶。
核心要点回顾:
- 静态重力矩只与关节位置有关,可离线计算
- 库仑+粘滞摩擦模型简单实用,参数可通过匀速运动标定
- 前馈补偿与PID反馈结合,能显著提升控制性能
- 补偿参数宁小勿大,过补偿比欠补偿更危险