4、轨迹表示:轨迹的数学表示

各位同学,今天我们来聊聊轨迹的数学表示。说实话,这是整个回放测试的基石。你想想看,如果连轨迹怎么描述都搞不清楚,后面的回放、分析、评价就全是空中楼阁。

我在做自动驾驶测试的头两年,就吃过这个亏。当时拿到一批路测数据,直接用离散点去算曲率,结果算出来的值忽大忽小,根本没法用。后来才明白——嗯,轨迹的表示方式,直接决定了后续所有算法的精度和稳定性。

离散点序列:最朴素的表示方式

最直接的方式,就是用一串点来描述轨迹。每个点包含位置信息(x, y)和时间戳 t。说白了就是:

// 离散点序列示例
struct TrajectoryPoint {
    double x;      // 东向位置,单位米
    double y;      // 北向位置,单位米
    double t;      // 时间戳,单位秒
    double v;      // 速度,单位m/s
    double yaw;    // 航向角,单位弧度
};

std::vector<TrajectoryPoint> trajectory;

这种方式的优点很明显——简单、直观、不丢信息。传感器采集到的原始数据就是这种格式。但问题也来了:

  • 数据量大:10Hz的采样率,跑一小时就是36000个点
  • 噪声敏感:GPS抖动、IMU漂移都会让点序列变得毛糙
  • 插值困难:两个点之间怎么走?线性插值?那曲率就断了
注意:直接用离散点计算曲率,结果会非常不稳定。我曾经在高速场景下试过,相邻两个点的曲率能差出3-4倍,根本没法用来做评价指标。

样条曲线:让轨迹变得光滑

为了解决离散点的问题,我们引入了样条曲线。我个人最常用的是三次样条(Cubic Spline)。为什么是三次?因为二阶导数连续,曲率自然就连续了。

三次样条的核心思想很简单:

  1. 把轨迹分成若干段
  2. 每段用一个三次多项式拟合
  3. 在连接点处保证一阶、二阶导数连续
// 三次样条插值示例(简化版)
// 输入:离散点序列 points
// 输出:样条曲线参数

// 每段曲线形式:S_i(t) = a_i + b_i*t + c_i*t^2 + d_i*t^3
// 约束条件:
// 1. S_i(t_i) = points[i].x
// 2. S_i(t_{i+1}) = points[i+1].x
// 3. S'_i(t_{i+1}) = S'_{i+1}(t_{i+1})
// 4. S''_i(t_{i+1}) = S''_{i+1}(t_{i+1})
我的经验:在高速场景(时速100km/h以上)下,建议使用五次样条。虽然计算量大了点,但曲率变化更平滑,回放时车辆控制更稳定。我在京沪高速的测试中就吃过这个亏——三次样条在急弯处还是会有轻微抖动。

轨迹长度计算

轨迹长度,说白了就是路径的总里程。对于离散点序列,直接累加相邻点距离就行:

double calcTrajectoryLength(const std::vector<TrajectoryPoint>& pts) {
    double length = 0.0;
    for (size_t i = 1; i < pts.size(); ++i) {
        double dx = pts[i].x - pts[i-1].x;
        double dy = pts[i].y - pts[i-1].y;
        length += std::sqrt(dx*dx + dy*dy);
    }
    return length;
}

对于样条曲线,就需要对弧长进行积分了。这里有个小技巧——我一般用数值积分,比如高斯-勒让德求积法,精度够用,速度也快。

曲率计算:关键中的关键

曲率决定了车辆能不能安全通过。你想想看,如果轨迹曲率超过了车辆的最小转弯半径,那肯定要出问题。

对于参数曲线 (x(t), y(t)),曲率公式是:

κ = |x'y'' - y'x''| / (x'² + y'²)^(3/2)

其中:
x' = dx/dt, x'' = d²x/dt²
y' = dy/dt, y'' = d²y/dt²

实际工程中的坑:

  • 离散点求导时,差分步长不能太大也不能太小。我一般用5个点的中心差分,效果不错
  • 曲率突变点要特别关注。我曾经在高速匝道入口处发现曲率从0.001突变到0.05,这种地方最容易出事故
  • 曲率符号表示转向方向:正为左转,负为右转

知识体系总览

下面这张图,是我自己总结的轨迹表示知识体系。你看一眼就能明白各个模块之间的关系:

轨迹表示知识体系 轨迹表示 离散点序列 样条曲线 轨迹长度计算 曲率计算 插值与重采样 工程应用:轨迹回放 → 安全性评价 → 舒适性评价 → 控制精度分析 图:轨迹表示与计算知识体系

实际工程中的选择建议

场景 推荐表示方式 原因
低速泊车(<10km/h) 离散点序列 精度要求不高,计算简单
城市道路(30-60km/h) 三次样条 平衡精度与计算量
高速场景(>80km/h) 五次样条 曲率连续性好,控制稳定
极端工况(紧急避障) B样条 局部可控,便于实时调整

我的个人习惯:在做轨迹回放测试时,我会同时保留离散点和样条曲线两种表示。离散点用于快速定位和可视化,样条曲线用于精确的曲率分析和控制评价。两者互补,缺一不可。

好了,关于轨迹的数学表示就讲到这里。记住一句话:选对表示方式,后续工作事半功倍;选错了,后面全是坑。我在实际项目中见过太多因为轨迹表示不当导致的分析偏差,希望大家能少走这些弯路。

可可精品资料库