4、轨迹规划入门:关节空间与笛卡尔空间

轨迹规划,说白了就是告诉机器人「怎么动」。不是简单地从A点到B点,而是要考虑速度、加速度、甚至加加速度。我刚开始接触这个领域时,总觉得规划就是插值,后来踩了不少坑才明白——规划的质量直接决定了机器人是「丝滑」还是「抽搐」。

这一章,我们重点聊两种最常用的规划方式:关节空间轨迹规划和笛卡尔空间轨迹规划。前者控制每个关节的角度变化,后者控制末端执行器在三维空间中的位姿。

核心观点:关节空间规划适合点到点运动,笛卡尔空间规划适合对末端路径有严格要求的场景。两者没有的好坏,关键看应用场景。
轨迹规划知识体系 轨迹规划 关节空间规划 笛卡尔空间规划 梯形速度曲线 S形速度曲线 直线插补 圆弧插补 关键区别 关节空间:只控制关节角度,末端路径不可预测,但计算简单 笛卡尔空间:末端路径可控,但需要逆解算,计算量大 选型原则:无路径约束用关节空间,有路径约束用笛卡尔空间

4.1 关节空间轨迹规划

关节空间规划,就是直接对每个关节的角度进行插值。你给机器人一个起始角度和目标角度,规划器算出一条平滑的曲线。它的好处是——不用考虑逆运动学,计算量小,实时性好。

我个人习惯把关节空间规划分成两类:梯形速度曲线和S形速度曲线。两者各有千秋,下面细说。

4.1.1 梯形速度曲线

梯形速度曲线,顾名思义,速度曲线像个梯形。分为三个阶段:匀加速、匀速、匀减速。实现简单,计算量极小,适合对平滑度要求不高的场景。

公式其实不复杂:

// 梯形速度曲线参数
q0 = 起始位置
q1 = 目标位置
v_max = 最大速度
a_max = 最大加速度

// 加速段时间
t_acc = v_max / a_max
// 加速段位移
q_acc = 0.5 * a_max * t_acc²

// 如果总位移不够加速到最大速度
if (q1 - q0 < 2 * q_acc) {
    // 三角形速度曲线(没有匀速段)
    t_acc = sqrt((q1 - q0) / a_max)
    v_peak = a_max * t_acc
} else {
    // 标准梯形
    t_const = (q1 - q0 - 2 * q_acc) / v_max
}
我的经验:梯形曲线最大的问题是加速度突变。在加速段结束瞬间,加速度从a_max跳变到0,会产生冲击。对于重载机器人,这种冲击可能导致末端抖动。我曾经在一个码垛项目里吃过这个亏——机器人抓取时总是掉件,最后发现是梯形曲线的加速度突变导致的。

4.1.2 S形速度曲线

S形曲线比梯形曲线多了一个「加加速度」的概念。它把加速段又分成了三个阶段:加加速度增加、加加速度恒定、加加速度减小。说白了,就是让加速度也平滑变化。

你想想看,为什么需要S形曲线?因为梯形曲线的加速度突变会产生「急动度」(Jerk),也就是加加速度。急动度过大会激发机械结构的谐振频率,导致振动。

S形曲线有7个阶段:

阶段 描述 加速度变化
1 加加速度增加 加速度从0线性增加到a_max
2 匀加速 加速度保持a_max
3 加加速度减小 加速度从a_max线性减小到0
4 匀速 加速度为0
5 加加速度增加(减速) 加速度从0线性减小到-a_max
6 匀减速 加速度保持-a_max
7 加加速度减小(减速) 加速度从-a_max线性增加到0
// S形曲线核心参数
j_max = 最大加加速度
a_max = 最大加速度
v_max = 最大速度

// 加加速度变化时间
t_j = a_max / j_max

// 加速段时间
t_a = t_j + (v_max - a_max * t_j) / a_max

// 位置计算(以加速段为例)
if (t < t_j) {
    // 加加速度增加段
    q = q0 + (1/6) * j_max * t³
} else if (t < t_a - t_j) {
    // 匀加速段
    q = q0 + (1/6) * j_max * t_j³ 
        + 0.5 * a_max * (t - t_j)²
        + 0.5 * a_max * t_j * (t - t_j)
}
注意:S形曲线虽然平滑,但计算量比梯形曲线大得多。在嵌入式控制器上,如果规划频率很高(比如1kHz),S形曲线的计算可能成为瓶颈。我曾经在STM32F4上跑S形曲线,发现一个周期要算几十微秒,后来不得不做查表优化。

4.2 笛卡尔空间轨迹规划

笛卡尔空间规划,是对机器人末端执行器的位姿进行规划。你关心的是「手」怎么走,而不是「关节」怎么转。这就涉及到逆运动学——把笛卡尔空间的位姿映射到关节空间。

嗯,这里要注意:笛卡尔空间规划的核心是插补。常见的插补方式有直线插补和圆弧插补。

4.2.1 直线插补

直线插补,就是让末端沿着直线运动。听起来简单,但实现起来有几个坑:

  • 姿态插补:位置可以线性插值,但姿态(四元数或旋转矩阵)不能简单线性插值,需要用球面线性插值(SLERP)
  • 速度规划:笛卡尔空间的速度规划同样可以用梯形或S形曲线,但要注意——关节空间的速度限制
  • 奇异性:某些位姿下,逆运动学可能无解或产生关节速度突变
// 直线插补伪代码
function linearInterpolation(p0, p1, t):
    // 位置线性插值
    pos = p0.position + (p1.position - p0.position) * t
    
    // 姿态SLERP插值
    quat = slerp(p0.orientation, p1.orientation, t)
    
    // 逆运动学求解
    joint_angles = inverseKinematics(pos, quat)
    
    return joint_angles
避坑指南:我曾经在一个焊接机器人项目里,直接用线性插值处理姿态,结果焊接轨迹在中间点出现了奇怪的扭曲。后来才发现,旋转矩阵的线性插值会导致非单位正交矩阵,必须用SLERP。这个坑,我印象很深。

4.2.2 圆弧插补

圆弧插补比直线插补复杂一些。你需要三个点来确定一个圆弧:起点、中间点、终点。或者用起点、终点和圆心。

实现步骤:

  1. 根据三点计算圆弧的圆心、半径、起始角和终止角
  2. 在圆弧上等距采样或等角度采样
  3. 对每个采样点进行逆运动学求解
  4. 在关节空间进行速度规划

我个人建议,圆弧插补时要注意弧长参数化。如果按角度均匀采样,靠近圆心一侧的线速度会变慢。应该按弧长均匀采样,保证末端线速度恒定。

4.3 两种规划方式的对比

对比项 关节空间规划 笛卡尔空间规划
末端路径 不可预测(可能走弧线) 可控(直线/圆弧)
计算量 小(无需逆解) 大(每步需逆解)
奇异性问题 较少 较多(需处理奇异位姿)
适用场景 点到点运动、搬运 焊接、喷涂、切割
速度平滑性 容易实现 需额外处理
选型建议:如果任务只关心起点和终点(比如码垛、搬运),用关节空间规划就够了。如果对路径有严格要求(比如焊缝跟踪、曲面喷涂),必须用笛卡尔空间规划。我个人的经验是——能用关节空间解决的问题,尽量别用笛卡尔空间,省下来的计算资源可以做更多事情。

4.4 实际调参中的注意事项

说了这么多理论,最后聊点实际的。调参时,有几个参数特别关键:

  • 最大速度:受限于电机额定转速和减速比。设得太高,电机可能丢步或过载
  • 最大加速度:受限于电机扭矩和机械结构刚度。加速度太大,机器人会「点头」
  • 加加速度(Jerk):受限于机械谐振频率。Jerk太大,机器人会振动

我建议的调参顺序是:先调速度,再调加速度,最后调加加速度。每次只改一个参数,观察机器人运动是否平稳。如果出现振动,优先降低加加速度。

重要提醒:千万不要在笛卡尔空间规划中忽略关节空间的限位和速度限制。我曾经见过一个案例,工程师在笛卡尔空间规划了一条很漂亮的直线,但逆解后某个关节的速度超过了电机额定值,结果电机过载报警。记住——笛卡尔空间规划最终还是要落到关节空间执行,关节空间的约束永远不能忽略。