位置环:三环控制的最外层大脑
位置环,说白了就是整个控制系统的「总指挥」。它不关心电机怎么转、电流怎么流,它只盯着一个目标——让机械末端到达我想要的位置。
我刚开始做运动控制时,总觉得位置环就是简单的比例调节。直到有一次做高精度贴片机项目,位置环调不好,贴出来的芯片全偏了。嗯,从那以后我才真正重视起这个「外环」来。
位置环的作用与目标
位置环的核心任务就三个字:定到位。具体来说:
- 消除位置误差:把实际位置和期望位置的差值,通过控制算法变成速度指令
- 保证运动平滑:不能出现急停急启,否则机械结构会抖动
- 抵抗外部扰动:比如负载变化、摩擦力干扰,位置环要能稳住
位置环的终极目标:在满足系统稳定性、快速性和精度的前提下,让被控对象的位置输出精确跟踪期望位置指令。
你想想看,如果位置环没调好,内环再快也没用。就像你开车,方向盘(位置环)指歪了,油门(速度环)踩再猛也到不了目的地。
位置环的输入与输出
搞清楚输入输出,是理解位置环的第一步。我习惯用一张表来总结:
| 信号类型 | 信号名称 | 说明 |
|---|---|---|
| 输入 | 位置指令 P_ref |
上位机或轨迹规划器给出的期望位置 |
| 输入 | 位置反馈 P_fb |
编码器、光栅尺等传感器实测位置 |
| 输出 | 速度指令 V_ref |
送给速度环的期望速度值 |
| 内部变量 | 位置误差 e = P_ref - P_fb |
位置环控制器的输入量 |
位置环的输入是位置误差,输出是速度指令。这个速度指令会传给速度环,速度环再传给电流环,形成完整的三环级联。
我的经验:位置环的输出限幅非常重要。我曾经在一个项目中忘记设置速度上限,位置环直接给速度环发了一个 5000 rpm 的指令,电机差点飞出去。所以,位置环输出一定要做饱和处理,限制在电机和机械系统能承受的范围内。
位置环的典型应用
位置环的应用场景,我把它分成两大类:定点运动和轨迹跟踪。这两者的控制逻辑有本质区别。
定点运动
定点运动,就是从一个位置跑到另一个位置,中间怎么走不重要,只要终点准就行。典型的例子:
- 工业机械臂的点到点搬运
- 3D打印机的归零动作
- 数控机床的快速定位
定点运动的核心是位置超调控制。我做过一个晶圆搬运项目,要求定位精度 ±1μm,而且不能超调——超调就意味着撞坏晶圆。那时候我用了位置环的 PD 控制器,配合 S 型速度规划,才把超调压到零。
// 定点运动位置环伪代码(PD控制)
void PositionLoop_PointToPoint(void)
{
// 读取当前位置
float pos_fb = ReadEncoder();
// 计算位置误差
float error = pos_ref - pos_fb;
// PD控制:比例+微分
float derivative = (error - error_last) / dt;
float speed_ref = Kp * error + Kd * derivative;
// 输出限幅
if (speed_ref > SPEED_MAX) speed_ref = SPEED_MAX;
if (speed_ref < -SPEED_MAX) speed_ref = -SPEED_MAX;
// 更新上一误差
error_last = error;
// 发送速度指令给速度环
SetSpeedReference(speed_ref);
}
避坑指南:我曾经在定点运动中只用了比例控制,结果位置误差永远消不掉——这就是静差。后来加了积分项才解决。但积分项不能加太大,否则会震荡。我的建议是:定点运动用 PI 或 PID,但积分限幅要设小一点。
轨迹跟踪
轨迹跟踪就复杂多了。它要求系统实时跟随一条连续路径,比如:
- 数控机床的轮廓加工
- 机器人的弧焊、涂胶
- AGV小车的路径导航
轨迹跟踪的核心是动态响应和轮廓误差控制。我做过一个激光切割项目,要求切割速度 100mm/s,轮廓误差 < 0.05mm。那时候我用了前馈+反馈的复合控制结构:
// 轨迹跟踪位置环(前馈+反馈)
void PositionLoop_TrajectoryTracking(void)
{
// 读取当前位置和期望位置
float pos_fb = ReadEncoder();
float pos_ref = trajectory_generator.position;
float vel_ref_ff = trajectory_generator.velocity; // 前馈速度
// 计算位置误差
float error = pos_ref - pos_fb;
// 反馈控制(PI)
float integral += error * dt;
float speed_fb = Kp * error + Ki * integral;
// 前馈+反馈合成
float speed_ref = speed_fb + vel_ref_ff * Kff;
// 输出限幅
speed_ref = Saturate(speed_ref, -SPEED_MAX, SPEED_MAX);
// 发送速度指令
SetSpeedReference(speed_ref);
}
为什么轨迹跟踪要加前馈?因为纯反馈控制有滞后。你想想看,系统先有误差,控制器才去纠正,这个过程中误差已经产生了。前馈相当于「预判」,提前把需要的速度给出去,反馈只负责修正残余误差。
定点运动 vs 轨迹跟踪的关键区别:
- 定点运动:终点精度优先,允许中间过程有误差
- 轨迹跟踪:全程精度优先,每个时刻都要准
- 定点运动:可以用大增益快速收敛
- 轨迹跟踪:增益要平衡,否则路径会抖动
位置环的知识体系总览
下面这张图,是我自己总结的位置环知识框架。每次做项目前,我都会对照着检查一遍:
位置环的调参心得
最后,分享几个我调位置环的实战经验:
- 先调内环,再调外环:速度环和电流环没调稳,位置环怎么调都没用。这是三环控制的基本顺序。
- 位置环增益不能太大:增益太大,系统会震荡。我一般从 Kp=1 开始,慢慢往上加,直到出现轻微震荡再回调 30%。
- 微分项要慎用:微分对噪声敏感。如果编码器分辨率不高,微分反而会引入抖动。我习惯先不加 D,等 P 和 I 调好了再考虑。
- 积分限幅是保命符:位置环的积分项如果无限幅,系统卡住时积分会一直累积,恢复时就会产生巨大的超调。一定要设积分限幅。
一个小技巧:调试位置环时,可以用示波器同时观察位置指令、位置反馈和速度指令三个信号。如果位置反馈能平滑跟随指令,且速度指令没有毛刺,说明位置环调得差不多了。我每次调完都会录一段波形,方便后续对比。
位置环说难不难,说简单也不简单。关键是要理解它在三环中的定位——它是「大脑」,负责决策;速度环和电流环是「肌肉」,负责执行。大脑想清楚了,肌肉才能干好活。