上一篇讲了最小化Jerk轨迹——用多项式保证运动平滑。今天讲另一种表示平滑轨迹的数学工具:B样条曲线。

B样条在计算机图形学中用了几十年(CAD、动画路径),近几年在机器人轨迹规划中也火了起来。原因在于B样条有几个特别适合轨迹优化的性质:局部控制性(移动一个控制点只影响局部曲线形状)、凸包性(曲线一定在控制点构成的凸包内)、任意阶连续性。

说白了,B样条让你用少量控制点就能表示一条任意平滑度的曲线,而且调一个控制点不会让整条曲线变形——这是贝塞尔曲线做不到的。

一、B样条的数学定义

一条k阶B样条曲线由三要素定义:控制点序列{P0, P1, ..., Pn}、节点向量{knot vector}、阶数k。

曲线上的点P(u)是控制点的加权和:P(u) = Σ Ni,k(u) * Pi,其中Ni,k(u)是B样条基函数——由Cox-de Boor递推公式计算。

# B样条基函数的Cox-de Boor递推
def basis_function(i, k, u, knots):
    if k == 1:
        return 1.0 if knots[i] <= u < knots[i+1] else 0.0
    # k阶基函数由两个k-1阶基函数组合
    left = (u - knots[i]) / (knots[i+k-1] - knots[i]) * basis(i, k-1, u)
    right = (knots[i+k] - u) / (knots[i+k] - knots[i+1]) * basis(i+1, k-1, u)
    return left + right

基函数有几个重要性质:非负性(Ni,k(u) ≥ 0)、单位分解性(所有基函数之和为1)、局部支撑性(Ni,k只在k个节点区间内非零)。这些性质决定了B样条的所有优良特性。

二、B样条为什么适合轨迹规划

B样条有几个性质让它特别适合做轨迹的参数化表示。

局部控制性:移动控制点Pi只影响曲线上k个节点区间内的形状。如果你只想调整轨迹的一小段,改对应的控制点就行,不用动整条轨迹。这在轨迹优化中特别有用——优化器可以局部调整轨迹避开障碍物。

凸包性:B样条曲线一定在控制点构成的凸包内。这意味着如果你把控制点放在安全区域内,曲线大概率也在安全区域内(严格说需要更细的检查,但凸包性质提供了一个快速筛选手段)。

连续性保证:k阶B样条在节点处具有C^(k-2)连续性。常用的三次B样条(k=4)在节点处C²连续——位置和速度连续,加速度也连续。这对轨迹来说够用了。

导数也是B样条:B样条曲线的导数仍然是B样条(阶数降一)。这意味着速度曲线和加速度曲线也可以用B样条表示——速度是二阶B样条,加速度是一阶B样条(分段常数)。这个性质在约束处理中很有用:速度约束变成对速度B样条控制点的约束,加速度约束变成对加速度B样条控制点的约束。

凸优化友好:B样条曲线的平滑度代价(曲率积分)可以写成控制点的二次型——c^T Q c的形式。碰撞约束可以近似为控制点的线性约束。整个优化问题变成二次规划(QP),有成熟高效的求解器。

# B样条轨迹优化的QP形式
# min  c^T Q c + q^T c    # Q: 平滑度矩阵, q: 路径长度项
# s.t. A_eq c = b_eq      # 起止点约束
#      A_ineq c <= b_ineq # 碰撞约束(线性化)
#      lb <= c <= ub      # 控制点范围
# 求解: 用OSQP或qpOASES,通常10ms内

三、均匀B样条 vs 非均匀B样条

节点向量等间距的叫均匀B样条,不等间距的叫非均匀B样条(NURBS的前身)。

均匀B样条计算简单,基函数可以预计算,适合在线规划。大多数机器人轨迹规划用的就是均匀三次B样条——控制点等间距排列在参数空间上。

非均匀B样条更灵活——可以在曲率大的地方加密节点,在直线段稀疏节点。但计算更复杂,基函数不能简单预计算。CAD领域常用NURBS(非均匀有理B样条),机器人领域用得少。

工程建议:做轨迹规划用均匀三次B样条就够了。控制点数量通常取路径点数量的1.5-2倍——太少拟合不好,太多优化变量大。

Clamped vs Unclamped:Clamped B样条(也叫open/clamped knot vector)的特点是曲线通过首末控制点。做法是把节点向量的前k个和后k个节点设为相同值。轨迹规划中几乎都用clamped版本——因为你通常需要轨迹精确通过起点和终点。Unclamped版本的曲线不通过首末点,在轨迹规划中没用。

和最小化Jerk的对比:最小化Jerk用多项式表示轨迹,系数由边界条件唯一确定。B样条用控制点表示轨迹,控制点作为优化变量可以灵活调整。最小化Jerk适合waypoint少且无碰撞约束的场景(机械臂),B样条适合waypoint多且有障碍物约束的场景(无人机、自动驾驶)。

四、B样条在轨迹优化中的实际应用

典型的B样条轨迹优化流程:

  1. 用路径规划器(A*/RRT/混合A*)得到一条粗略路径
  2. 沿路径等距采样N个点作为初始控制点
  3. 以控制点坐标为优化变量,建立QP问题
  4. 目标函数:平滑度(控制点的二阶差分平方和)+ 离障碍物距离
  5. 约束:起止点位置和速度、速度/加速度限制
# B样条轨迹优化的核心循环
control_points = init_from_path(rough_path, num_points=20)
for iteration in range(max_iter):
    # 计算当前轨迹的碰撞代价
    collision_cost = evaluate_collision(control_points, obstacle_map)
    # 求解QP
    control_points = solve_qp(Q, q, collision_cost, constraints)
    if collision_cost < threshold:
        break

浙江大学的EGO-Planner和香港科技大学的Fast-Planner都是基于B样条的无人机轨迹规划框架——在无人机比赛中跑出了很好的成绩。这两个框架都开源了,建议读源码学习。

实测数据:在10m×10m的室内环境中规划一条避障轨迹,EGO-Planner(B样条方案)的规划时间约8ms,Fast-Planner(梯度优化方案)约15ms。两者轨迹质量差不多,但B样条方案更快——因为QP求解器比梯度下降收敛更快。

五、面试实战

Q:B样条和贝塞尔曲线有什么区别? A:贝塞尔曲线的所有控制点都影响整条曲线(全局性),B样条的每个控制点只影响局部。贝塞尔曲线的阶数等于控制点数减一,阶数太高会数值不稳定。B样条的阶数和控制点数无关,可以固定为3或4。

Q:B样条的凸包性在轨迹规划中有什么用? A:两个用处。一是快速碰撞检测——如果控制点构成的凸包和障碍物不交,曲线一定不碰撞。二是约束构造——把控制点限制在安全区域内,就能保证轨迹安全(虽然保守,但计算快)。

Q:你在项目中怎么用的B样条? A:做无人机的局部轨迹规划。前端用RRT*生成初始路径,后端用均匀三次B样条优化。15个控制点,QP求解用OSQP,单次优化约5ms。优化后的轨迹平滑且无碰撞,无人机飞行速度8m/s时跟踪误差<5cm。

Q:B样条优化的缺点是什么? A:两个问题。一是凸包碰撞检测太保守——可能把安全的轨迹也排除掉。需要用更精确的碰撞检测方法(比如离散采样检测)。二是控制点数量需要手工调——太少不够灵活,太多计算慢。工程上通常根据路径长度自适应调整控制点数量。

小结

B样条用少量控制点参数化平滑曲线,具有局部控制性、凸包性、任意阶连续性。在轨迹优化中,B样条把连续的轨迹优化问题转化为有限维的二次规划问题,求解高效可靠。

EGO-Planner和Fast-Planner是基于B样条的代表性开源框架。理解B样条的核心性质(局部性、凸包性、凸优化友好)比记住递推公式更重要——面试时考官考的是你的理解深度,不是让你手推Cox-de Boor。

下一篇讲轨迹时间参数化——TOPP-RA和速度约束处理。


如果这篇文章对你有帮助,欢迎点赞、在看、转发三连。 你的支持是我持续更新的最大动力。

「机器人软件开发面试·从入门到精通」连载系列 

上一篇:第227篇 最小化Jerk轨迹——让运动丝滑的数学方法

下一篇预告:第229篇 轨迹时间参数化——TOPP-RA和速度约束处理

有任何问题欢迎评论区留言,我会尽量回复。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐