一、轨迹规划基础:从路径到轨迹的转变,为什么需要平滑?

大家好,我是你们的老朋友。今天咱们正式开始聊轨迹规划。

说实话,我刚开始做机器人那会儿,也分不清「路径」和「轨迹」有啥区别。不就是让机器人从A点走到B点吗?后来在项目里吃过亏,才明白这两者天差地别。

1.1 路径 vs 轨迹:一字之差,天壤之别

先问个问题:你让机器人「走过去」,到底给了它什么?

路径(Path),说白了就是一条几何线。它只关心「走哪条路」,不关心「怎么走」。比如从客厅到厨房,路径就是绕过沙发、穿过门框的那条折线。路径本身没有时间概念。

轨迹(Trajectory),则是在路径上加了「时间戳」。它告诉你:什么时间,机器人应该在什么位置,速度是多少,加速度是多少。

我举个例子你就明白了:

  • 路径:从(0,0)到(10,0),中间经过(5,0)。
  • 轨迹:0秒在(0,0),速度0;2秒到(5,0),速度1m/s;4秒到(10,0),速度0。

你看,轨迹才是真正能下发给执行器的指令。电机要的是「每秒转多少圈」,而不是「你沿着这条线走」。

核心区别一句话:路径是几何的,轨迹是时间的。路径是静态的,轨迹是动态的。

1.2 为什么需要平滑?—— 三个血泪教训

好,既然轨迹要带时间,那问题就来了:如果轨迹不平滑,会怎样?

我在项目里遇到过三次惨痛教训,分享给你:

教训一:电机「咔咔」响

有一次调试AGV小车,路径规划用的是A*算法,出来的路径全是直角拐弯。我直接把路径当轨迹下发,结果电机在拐角处剧烈抖动,发出「咔咔」的异响。拆开一看,减速齿轮磨损了。

原因:直角拐弯意味着速度方向瞬间变化,加速度无穷大。电机物理上做不到,只能硬扛。

教训二:货物甩飞了

做仓储机器人时,托盘上放了一箱易碎品。轨迹没做平滑处理,启动和停止都是急停急起。结果一个急刹车,箱子直接飞出去两米远。

原因:加速度突变产生冲击力,货物惯性太大。

教训三:路径跟踪误差大

用纯追踪算法跟踪一条折线路径,发现机器人总是「过冲」——到了拐点停不住,冲出路径一大截才回来。

原因:不平滑的轨迹导致控制器来不及响应,跟踪误差累积。

警告:不平滑的轨迹不仅影响舒适度,更会损坏硬件、降低精度、甚至引发安全事故。这不是「锦上添花」,而是「刚需」。

1.3 平滑的本质:约束加速度和加加速度

那平滑到底在平滑什么?

嗯,这里要注意。平滑不是把路径「磨圆」那么简单。它本质上是对运动状态的约束。

我们来看三个关键指标:

指标 符号 物理意义 不平滑的后果
速度 v 位置变化率 速度突变导致冲击
加速度 a 速度变化率 加速度突变导致抖动
加加速度 j 加速度变化率 加加速度过大导致震荡

你想想看,如果加速度不连续,比如从0瞬间跳到2m/s²,那电机输出的力矩就得瞬间跳变。力矩跳变意味着什么?意味着机械结构要承受冲击载荷。

我个人习惯把平滑分为三个层次:

  1. C0连续:位置连续。这是最基本的要求,路径不能断开。
  2. C1连续:速度连续。轨迹不能有「折角」,速度不能突变。
  3. C2连续:加速度连续。这是「舒适」的门槛,加速度不能跳变。

大多数工业场景,做到C2连续就够用了。但如果你做的是高精度加工或者人形机器人,可能还需要C3连续(加加速度连续)。

小技巧:判断轨迹是否平滑,最简单的方法就是看加速度曲线。如果加速度曲线有「尖角」或者「台阶」,那一定不平滑。

1.4 从路径到轨迹的转变流程

好了,理论说完了。咱们看看实际工程中,从路径到轨迹到底怎么转?

我画了一张流程图,帮你理清思路:

从路径到轨迹的转变流程 路径规划 A* / RRT / Dijkstra 路径平滑 B样条 / 贝塞尔曲线 时间分配 梯形 / S形速度规划 轨迹生成 位置-速度-加速度曲线 关键输出 • 离散路径点 • 无碰撞约束 • 连续曲线参数 • C2连续保证 • 速度/加速度约束 • 时间-位置映射 • 完整轨迹函数 • 可执行指令

流程其实就四步:

  1. 路径规划:先找出一条无碰撞的几何路径。这一步只关心「能不能走」,不关心「好不好走」。
  2. 路径平滑:把折线路径变成光滑曲线。常用B样条、贝塞尔曲线。这一步去掉「尖角」。
  3. 时间分配:给路径上的每个点分配时间。这一步决定了速度曲线是梯形还是S形。
  4. 轨迹生成:最终输出位置、速度、加速度随时间变化的函数。

我曾经在第三步踩过坑。当时图省事,用了最简单的梯形速度规划,结果加速度在起点和终点处突变,机器人启动时「窜」了一下。后来换成S形速度规划,问题才解决。

1.5 一个简单的代码示例

光说不练假把式。我写个极简的Python代码,帮你感受一下「平滑」的效果。

import numpy as np
import matplotlib.pyplot as plt

# 不平滑的轨迹:速度突变
t = np.array([0, 1, 2, 3, 4])
pos_rough = np.array([0, 2, 4, 6, 8])  # 位置
vel_rough = np.diff(pos_rough) / np.diff(t)  # 速度

# 平滑的轨迹:S形速度曲线
def s_curve(t, T=4, total_dist=8):
    """简单的S形速度曲线"""
    v_max = total_dist / T * 1.5
    a_max = v_max / (T/4)
    
    if t < T/4:
        return 0.5 * a_max * t**2
    elif t < 3*T/4:
        return v_max * (t - T/4) + 0.5 * a_max * (T/4)**2
    else:
        return total_dist - 0.5 * a_max * (T - t)**2

t_smooth = np.linspace(0, 4, 100)
pos_smooth = np.array([s_curve(ti) for ti in t_smooth])

print("不平滑轨迹的速度变化:", vel_rough)
print("平滑轨迹的速度变化:连续且无突变")

你看,不平滑的轨迹速度是跳变的,而平滑轨迹的速度是连续变化的。这就是本质区别。

我的建议:刚开始做轨迹规划时,别急着上复杂算法。先用梯形速度规划跑通流程,再升级到S形。一步到位容易出bug,而且调试起来很痛苦。

1.6 本章小结

好,咱们捋一下今天的内容:

  • 路径 vs 轨迹:路径是几何线,轨迹是时间函数。轨迹才是下发给执行器的指令。
  • 平滑的必要性:不平滑会导致电机抖动、货物甩飞、跟踪误差大。这不是理论问题,是工程问题。
  • 平滑的本质:约束加速度和加加速度的连续性。C2连续是工业场景的及格线。
  • 转变流程:路径规划 → 路径平滑 → 时间分配 → 轨迹生成。每一步都有坑,别跳步。

我记得刚入行时,带我的老工程师说过一句话:「路径规划决定你能不能到,轨迹规划决定你到得好不好。」这句话我一直记到现在。

下一章,咱们会深入聊路径平滑的具体算法——B样条曲线。到时候我会手撕代码,带你看看实际工程中怎么用。

可可精品资料库