7、B样条曲线:B样条基础、控制点与节点向量、轨迹平滑性分析

各位工程师朋友,欢迎来到轨迹规划的进阶环节。前面我们聊了三次样条,它确实好用,但有个问题——局部修改会牵动全局。你想想看,如果只是微调一个路径点,整条曲线都得重新算,这在工业现场是很头疼的。

B样条曲线就是来解决这个问题的。我个人习惯把它叫做「可局部手术的曲线」。它把曲线分成若干段,每段只受附近几个控制点影响。你改一个点,只有局部会变,其他地方纹丝不动。这在机器人轨迹调试中,简直是救命的功能。

7.1 B样条的核心思想

说白了,B样条就是「分段贝塞尔曲线的平滑拼接」。贝塞尔曲线大家应该熟悉,但它的控制点一多,曲线就变得很难控制。B样条通过引入节点向量,把曲线切成一段段,每段用低阶多项式表示,然后保证连接处光滑。

我记得第一次在六轴机器人上调试B样条时,现场工程师问我:「这曲线怎么像蛇一样扭来扭去?」我说:「别急,那是节点没选好。」后来调整了节点分布,轨迹立马变得顺滑。嗯,这里要注意——节点向量的选择,直接决定了曲线的性格

核心公式(k阶B样条):

C(u) = Σᵢ₌₀ⁿ Nᵢₖ(u) · Pᵢ

其中:

  • Pᵢ:控制点(你手里握着的缰绳)
  • Nᵢₖ(u):基函数(由节点向量决定)
  • u:参数(0到1之间游走)

7.2 控制点与节点向量

这两个概念是B样条的左膀右臂。控制点好理解,就是你想让曲线靠近的那些点。但节点向量,很多人一开始会懵。

节点向量是一个非递减的实数序列,比如:

U = [0, 0, 0, 0.2, 0.4, 0.6, 0.8, 1, 1, 1]

它把参数空间[0,1]划分成若干区间。每个区间对应一段曲线。节点重复的次数,决定了曲线在端点处的连续性。比如开头三个0,表示曲线起点与控制点重合,且切线方向固定。

我在项目中遇到过一个问题:用均匀节点向量(节点等距分布)生成的B样条,在曲线急转弯处会出现「鼓包现象」。后来改用弦长参数化的节点分布,问题就解决了。你想想看,控制点分布不均匀时,均匀节点向量就像给高个子和小个子穿同一尺码的鞋——肯定不舒服。

节点类型 特点 适用场景
均匀节点 节点等距,计算简单 控制点分布均匀时
准均匀节点 首尾重复k次,中间均匀 工业机器人常用
弦长参数化 按控制点间距分配节点 控制点疏密不均时
切比雪夫节点 端点密集,中间稀疏 需要抑制龙格现象时

我的经验:做焊接轨迹时,我习惯用准均匀节点。因为焊缝起点和终点需要精确控制位置和方向,中间段可以稍微放松。准均匀节点正好满足——首尾重复k次保证端点插值,中间均匀保证平滑。

7.3 基函数的递推计算

B样条的基函数是用德布尔-考克斯递推公式算出来的。别看公式长,其实逻辑很简单——低阶基函数是几个高阶基函数的线性组合。

// 计算k阶B样条基函数
double BasisFunc(int i, int k, double u, vector<double>& U) {
    if (k == 0) {
        // 0阶:判断u是否在区间内
        return (U[i] <= u && u < U[i+1]) ? 1.0 : 0.0;
    } else {
        // 递推:两个低阶基函数的加权和
        double coef1 = (u - U[i]) / (U[i+k] - U[i]);
        double coef2 = (U[i+k+1] - u) / (U[i+k+1] - U[i+1]);
        return coef1 * BasisFunc(i, k-1, u, U) + 
               coef2 * BasisFunc(i+1, k-1, u, U);
    }
}

这段代码我调试过无数次。有个坑要注意——分母可能为零。当节点重复时,U[i+k] - U[i]可能等于0。这时候要约定0/0 = 0。我曾经在这个问题上卡了一下午,最后发现是节点向量写错了。

7.4 轨迹平滑性分析

B样条的平滑性,说白了就是看它的阶数和节点重复度

  • 阶数k:曲线在节点处的连续阶为C^(k-2)。比如3阶B样条(二次),节点处C^1连续(速度连续)。4阶(三次),节点处C^2连续(加速度连续)。
  • 节点重复度r:每重复一次,连续性降一阶。重复r次,连续阶变为C^(k-r-1)。

我建议做工业机器人轨迹时,至少用三次B样条(k=4)。为什么?因为机器人运动需要加速度连续,否则会有冲击。三次B样条在节点处C^2连续,刚好满足。

避坑指南:我曾经在打磨机器人上用过二次B样条,结果在节点处加速度突变,导致工件表面出现振纹。后来换成三次B样条,问题立刻消失。所以——别为了省计算量而降低阶数,该花的成本不能省

7.5 实际应用中的注意事项

最后分享几个实战经验:

  1. 控制点数量:一般比阶数多2-3个即可。太多反而容易过拟合。
  2. 节点向量初始化:我习惯用弦长参数化,效果最稳定。
  3. 曲线求值:用德布尔算法,比直接算基函数快很多。
  4. 实时性:嵌入式平台上,预计算基函数值存表,运行时查表插值。

嗯,B样条的内容就到这里。它不像三次样条那样「全局绑定」,也不像贝塞尔那样「局部难控」。说白了,它是工业轨迹规划里最灵活的工具之一。下一章我们聊聊NURBS曲线——B样条的升级版,能精确表示圆弧和圆锥曲线,到时候见。