3. 点位控制插补:从原理到速度曲线实战
点位控制,说白了就是让运动轴从A点跑到B点,中间路径怎么走我不关心,我只关心起点和终点准不准。听起来简单?嗯,但实际做起来坑不少。我刚开始做运动控制时,觉得这不就是发脉冲嘛,结果被速度规划折腾得够呛。
3.1 点位控制的核心原理
点位控制(Point-to-Point Control)在工业现场太常见了。比如数控机床的换刀动作、PCB钻孔机的定位、点胶机的移动——都是典型的点位控制场景。
它的核心逻辑就三条:
- 起点定位:轴从当前位置开始运动
- 快速移动:以规划好的速度曲线到达目标位置
- 终点精准停止:在目标位置精确停下,不能过冲
关键区别:点位控制不插补中间路径的几何形状。它只保证起点和终点的位置精度,中间怎么走都行。这和直线插补、圆弧插补完全不同。
我在一个PCB钻孔项目里遇到过这样的问题:客户要求钻孔位置精度±0.01mm,但轴跑到目标点后总是有0.03mm左右的过冲。查了半天,发现是速度规划没做好——减速段太短,电机惯性把位置冲过了。后来改了S形曲线的减速参数才解决。
3.2 点位控制的速度规划
速度规划是点位控制的灵魂。你想想看,如果直接全速冲到目标点再急停,那冲击力能把机械结构震散架。所以必须规划一个合理的速度曲线。
我个人习惯把速度规划分成三个阶段:
- 加速阶段:从0或低速加速到目标速度
- 匀速阶段:以目标速度稳定运行(如果距离够长)
- 减速阶段:从目标速度减速到0,准备停止
这里有个关键参数——加加速度(Jerk)。它决定了加速度的变化率,直接影响运动的平顺性。
| 参数 | 符号 | 单位 | 说明 |
|---|---|---|---|
| 位置 | P | mm 或 pulse | 目标位置 |
| 速度 | V | mm/s 或 pulse/s | 运动速度 |
| 加速度 | A | mm/s² | 速度变化率 |
| 加加速度 | J | mm/s³ | 加速度变化率 |
实战建议:在运动控制卡上配置参数时,我一般先设一个保守的加速度值(比如电机额定加速度的60%),然后根据实际运行效果微调。别一上来就拉满,容易烧驱动器。
3.3 梯形速度曲线
梯形速度曲线是最基础的速度规划方式。它的速度-时间图像像个梯形——加速、匀速、减速三段。
先看代码实现:
// 梯形速度曲线规划(简化版)
typedef struct {
float target_pos; // 目标位置(脉冲数)
float max_vel; // 最大速度
float accel; // 加速度
float decel; // 减速度
float current_pos; // 当前位置
float current_vel; // 当前速度
} TrapezoidProfile;
void TrapezoidPlan(TrapezoidProfile *profile) {
float dist = profile->target_pos - profile->current_pos;
float accel_dist = (profile->max_vel * profile->max_vel) / (2 * profile->accel);
float decel_dist = (profile->max_vel * profile->max_vel) / (2 * profile->decel);
// 判断是否能达到最大速度
if (accel_dist + decel_dist <= fabs(dist)) {
// 有匀速段
profile->cruise_dist = fabs(dist) - accel_dist - decel_dist;
} else {
// 没有匀速段,三角形曲线
// 需要重新计算能达到的最大速度
float v_peak = sqrt(2 * profile->accel * profile->decel * fabs(dist)
/ (profile->accel + profile->decel));
profile->max_vel = v_peak;
profile->cruise_dist = 0;
}
}
梯形曲线的优缺点很明显:
- 优点:实现简单,计算量小,适合低精度、低速度的场景
- 缺点:加速度突变,在加速段和减速段的起点终点有冲击
避坑指南:我曾经在一个高速贴片机项目里用了梯形曲线,结果机器在加速切换点产生明显振动,贴片精度直接超差。后来换成S形曲线才解决。梯形曲线只适合对冲击不敏感的重载或低速场景。
3.4 S形速度曲线
S形速度曲线是梯形曲线的升级版。它通过引入加加速度(Jerk),让加速度平滑变化,从而消除冲击。
S形曲线通常分7段:
- 加加速度段:加速度从0线性增加到目标值
- 匀加速段:以恒定加速度加速
- 减加速度段:加速度线性减小到0
- 匀速段:速度保持不变
- 加减速度段:减速度从0线性增加到目标值
- 匀减速段:以恒定减速度减速
- 减减速度段:减速度线性减小到0
代码实现比梯形复杂不少:
// S形速度曲线规划(核心逻辑)
typedef struct {
float target_pos;
float max_vel;
float max_accel;
float max_jerk; // 加加速度
float current_pos;
float current_vel;
float current_accel;
} SCurveProfile;
void SCurvePlan(SCurveProfile *profile) {
float dist = profile->target_pos - profile->current_pos;
float sign = (dist > 0) ? 1.0f : -1.0f;
dist = fabs(dist);
// 计算各阶段所需时间和距离
float t_accel = profile->max_accel / profile->max_jerk; // 加加速度段时间
float v_at_end_of_accel = 0.5f * profile->max_jerk * t_accel * t_accel;
// 判断是否能达到最大速度
float accel_dist = profile->max_jerk * t_accel * t_accel * t_accel;
float decel_dist = accel_dist; // 假设加减速对称
if (accel_dist + decel_dist <= dist) {
// 有匀速段
profile->cruise_dist = dist - accel_dist - decel_dist;
} else {
// 三角形S形曲线,需要重新计算
// 实际项目中这里需要迭代求解
profile->cruise_dist = 0;
}
// 应用方向
profile->target_pos = profile->current_pos + sign * dist;
}
两种曲线的对比:
| 特性 | 梯形曲线 | S形曲线 |
|---|---|---|
| 加速度变化 | 阶跃变化 | 连续变化 |
| 机械冲击 | 大 | 小 |
| 计算复杂度 | 低 | 中高 |
| 运动时间 | 短 | 略长(约5-10%) |
| 适用场景 | 低速、重载 | 高速、高精度 |
我的经验:在运动控制卡上实现S形曲线时,加加速度的取值很关键。我一般取最大加速度的10-20倍作为加加速度的初始值。太小了曲线接近梯形,太大了又失去S形的意义。
3.5 速度规划的核心逻辑图
下面这张图展示了点位控制中速度规划的完整决策流程:
这张图把决策逻辑讲得很清楚。实际项目中,我一般先按梯形曲线算一遍,如果发现没有匀速段(三角形曲线),再判断是否需要切换到S形曲线。为什么?因为三角形曲线意味着运动距离太短,这时候S形曲线的优势更明显——它能更好地控制加减速的平滑性。
3.6 实战中的选择建议
说了这么多,到底什么时候用梯形,什么时候用S形?我根据多年经验总结了几条:
- 步进电机+低速应用(如传送带定位):梯形曲线就够了,别折腾
- 伺服电机+中等速度(如点胶机):建议用S形曲线,Jerk设小一点
- 高速高精度(如贴片机、数控机床):必须用S形曲线,而且要仔细调Jerk参数
- 重载设备(如大型龙门架):梯形曲线反而更安全,因为S形曲线的加速过程太柔和,可能导致电机堵转
重要提醒:不管用哪种曲线,一定要在运动控制卡上做限位保护。我曾经见过一个同事,调试时忘了设软限位,结果轴直接撞到机械硬限位,把丝杠都顶弯了。安全第一,速度规划第二。
好了,点位控制的速度规划就讲到这里。梯形曲线和S形曲线是运动控制的基础,掌握了它们,后面的连续轨迹插补就好理解了。