欢迎光临
我们一直在努力

参考线平滑算法详解(FEM-Based Path Smoothing)

参考线平滑算法详解(FEM-Based Path Smoothing)

目录

  • 算法概述
  • 数学理论基础
  • 优化问题建模
  • 有限元法离散化
  • 二次规划求解
  • 代码实现详解
  • 参数调优指南

  • 1. 算法概述

    1.1 问题定义

    输入:离散的原始参考路径点

    {

    (

    x

    i

    r

    e

    f

    ,

    y

    i

    r

    e

    f

    )

    }

    i

    =

    0

    n

    −

    1

    \\{(x_i^{ref}, y_i^{ref})\\}_{i=0}^{n-1}

    {(xiref​,yiref​)}i=0n−1​

    输出:平滑后的路径点

    {

    (

    x

    i

    ,

    y

    i

    )

    }

    i

    =

    0

    n

    −

    1

    \\{(x_i, y_i)\\}_{i=0}^{n-1}

    {(xi​,yi​)}i=0n−1​

    目标:在保持接近原始路径的同时,生成一条平滑、连续、曲率变化小的路径。

    1.2 应用场景

    在自动驾驶路径规划中,参考线平滑主要用于:

    • 全局路径平滑:优化路径规划模块输出的折线路径
    • 局部路径优化:消除DP动态规划产生的锯齿状路径
    • 曲率优化:确保车辆可以平稳跟踪(减少急转弯)

    1.3 核心思想

    使用**有限元法(FEM)将路径点之间的连续性约束转化为代价函数,通过求解二次规划(QP)**问题得到最优平滑路径。


    2. 数学理论基础

    2.1 有限元法基本原理

    有限元法将连续的路径用分段线性/多项式近似:

    p

    (

    s

    )

    =

    ∑

    i

    =

    0

    n

    −

    1

    N

    i

    (

    s

    )

    ⋅

    p

    i

    (1)

    p(s) = \\sum_{i=0}^{n-1} N_i(s) \\cdot p_i \\tag{1}

    p(s)=i=0∑n−1​Ni​(s)⋅pi​(1)

    其中:

    • p

      (

      s

      )

      p(s)

      p(s):路径在弧长

      s

      s

      s 处的位置

    • N

      i

      (

      s

      )

      N_i(s)

      Ni​(s):第

      i

      i

      i 个形状函数(shape function)

    • p

      i

      p_i

      pi​:第

      i

      i

      i 个控制点(优化变量)

    2.2 三点有限元估计

    对于路径点

    p

    i

    p_i

    pi​,使用相邻三点的有限元估计:

    p

    ^

    i

    =

    p

    i

    −

    1

    +

    p

    i

    +

    1

    2

    (2)

    \\hat{p}_i = \\frac{p_{i-1} + p_{i+1}}{2} \\tag{2}

    p^​i​=2pi−1​+pi+1​​(2)

    物理意义:如果路径是一条直线,则中间点应该是两端点的平均值。

    偏差:

    e

    i

    =

    p

    i

    −

    p

    ^

    i

    =

    p

    i

    −

    p

    i

    −

    1

    +

    p

    i

    +

    1

    2

    (3)

    e_i = p_i – \\hat{p}_i = p_i – \\frac{p_{i-1} + p_{i+1}}{2} \\tag{3}

    ei​=pi​−p^​i​=pi​−2pi−1​+pi+1​​(3)

    2.3 路径长度估计

    相邻两点之间的路径长度(一阶差分):

    Δ

    p

    i

    =

    p

    i

    +

    1

    −

    p

    i

    (4)

    \\Delta p_i = p_{i+1} – p_i \\tag{4}

    Δpi​=pi+1​−pi​(4)

    总路径长度:

    L

    =

    ∑

    i

    =

    0

    n

    −

    2

    ∥

    Δ

    p

    i

    ∥

    2

    =

    ∑

    i

    =

    0

    n

    −

    2

    (

    p

    i

    +

    1

    −

    p

    i

    )

    T

    (

    p

    i

    +

    1

    −

    p

    i

    )

    (5)

    L = \\sum_{i=0}^{n-2} \\|\\Delta p_i\\|^2 = \\sum_{i=0}^{n-2} (p_{i+1} – p_i)^T (p_{i+1} – p_i) \\tag{5}

    L=i=0∑n−2​∥Δpi​∥2=i=0∑n−2​(pi+1​−pi​)T(pi+1​−pi​)(5)


    3. 优化问题建模

    3.1 代价函数

    参考线平滑的总代价函数由三部分组成:

    J

    t

    o

    t

    a

    l

    =

    J

    f

    e

    m

    +

    J

    l

    e

    n

    g

    t

    h

    +

    J

    r

    e

    f

    (6)

    J_{total} = J_{fem} + J_{length} + J_{ref} \\tag{6}

    Jtotal​=Jfem​+Jlength​+Jref​(6)

    (1) 有限元偏差代价

    J

    f

    e

    m

    J_{fem}

    Jfem​

    惩罚路径的非平滑性(曲率大的位置):

    J

    f

    e

    m

    =

    w

    f

    e

    m

    ∑

    i

    =

    1

    n

    −

    2

    ∥

    p

    i

    −

    p

    i

    −

    1

    +

    p

    i

    +

    1

    2

    ∥

    2

    (7)

    J_{fem} = w_{fem} \\sum_{i=1}^{n-2} \\left\\| p_i – \\frac{p_{i-1} + p_{i+1}}{2} \\right\\|^2 \\tag{7}

    Jfem​=wfem​i=1∑n−2​

    ​pi​−2pi−1​+pi+1​​

    ​2(7)

    物理意义:

    • 如果

      p

      i

      p_i

      pi​ 偏离相邻两点的中点,说明路径在此处有"弯曲"

    • 该项越小,路径越平滑(接近直线)

    展开形式(针对点

    p

    i

    p_i

    pi​):

    ∥

    p

    i

    −

    p

    i

    −

    1

    +

    p

    i

    +

    1

    2

    ∥

    2

    =

    ∥

    2

    p

    i

    −

    p

    i

    −

    1

    −

    p

    i

    +

    1

    2

    ∥

    2

    (8)

    \\left\\| p_i – \\frac{p_{i-1} + p_{i+1}}{2} \\right\\|^2 = \\left\\| \\frac{2p_i – p_{i-1} – p_{i+1}}{2} \\right\\|^2 \\tag{8}

    ​pi​−2pi−1​+pi+1​​

    ​2=

    ​22pi​−pi−1​−pi+1​​

    ​2(8)

    =

    1

    4

    (

    p

    i

    −

    1

    −

    2

    p

    i

    +

    p

    i

    +

    1

    )

    T

    (

    p

    i

    −

    1

    −

    2

    p

    i

    +

    p

    i

    +

    1

    )

    (9)

    = \\frac{1}{4} (p_{i-1} – 2p_i + p_{i+1})^T (p_{i-1} – 2p_i + p_{i+1}) \\tag{9}

    =41​(pi−1​−2pi​+pi+1​)T(pi−1​−2pi​+pi+1​)(9)

    这是路径的二阶差分,近似于曲率的平方。

    (2) 路径长度代价

    J

    l

    e

    n

    g

    t

    h

    J_{length}

    Jlength​

    惩罚路径总长度(鼓励走捷径):

    J

    l

    e

    n

    g

    t

    h

    =

    w

    l

    e

    n

    g

    t

    h

    ∑

    i

    =

    0

    n

    −

    2

    ∥

    p

    i

    +

    1

    −

    p

    i

    ∥

    2

    (10)

    J_{length} = w_{length} \\sum_{i=0}^{n-2} \\|p_{i+1} – p_i\\|^2 \\tag{10}

    Jlength​=wlength​i=0∑n−2​∥pi+1​−pi​∥2(10)

    物理意义:

    • 最小化路径长度,避免绕远路
    • 与FEM项平衡:太平滑可能导致路径变长
    (3) 参考点偏差代价

    J

    r

    e

    f

    J_{ref}

    Jref​

    惩罚偏离原始参考路径:

    J

    r

    e

    f

    =

    w

    r

    e

    f

    ∑

    i

    =

    0

    n

    −

    1

    ∥

    p

    i

    −

    p

    i

    r

    e

    f

    ∥

    2

    (11)

    J_{ref} = w_{ref} \\sum_{i=0}^{n-1} \\|p_i – p_i^{ref}\\|^2 \\tag{11}

    Jref​=wref​i=0∑n−1​∥pi​−piref​∥2(11)

    物理意义:

    • 确保平滑后的路径不会偏离原始意图太远
    • 例如:不能为了平滑而切到对向车道

    3.2 二次型矩阵形式

    将所有路径点堆叠成向量:

    p

    =

    [

    x

    0

    ,

    y

    0

    ,

    x

    1

    ,

    y

    1

    ,

    …

    ,

    x

    n

    −

    1

    ,

    y

    n

    −

    1

    ]

    T

    ∈

    R

    2

    n

    (12)

    \\mathbf{p} = [x_0, y_0, x_1, y_1, \\ldots, x_{n-1}, y_{n-1}]^T \\in \\mathbb{R}^{2n} \\tag{12}

    p=[x0​,y0​,x1​,y1​,…,xn−1​,yn−1​]T∈R2n(12)

    总代价函数可以写成标准二次型:

    J

    t

    o

    t

    a

    l

    =

    1

    2

    p

    T

    P

    p

    +

    q

    T

    p

    +

    c

    o

    n

    s

    t

    (13)

    J_{total} = \\frac{1}{2} \\mathbf{p}^T \\mathbf{P} \\mathbf{p} + \\mathbf{q}^T \\mathbf{p} + const \\tag{13}

    Jtotal​=21​pTPp+qTp+const(13)

    其中

    P

    \\mathbf{P}

    P 是 Hessian 矩阵(对称半正定),

    q

    \\mathbf{q}

    q 是线性项。


    4. 有限元法离散化

    4.1 Hessian矩阵构造

    对于

    n

    n

    n 个路径点(

    2

    n

    2n

    2n 个变量),Hessian矩阵

    P

    ∈

    R

    2

    n

    ×

    2

    n

    \\mathbf{P} \\in \\mathbb{R}^{2n \\times 2n}

    P∈R2n×2n 的结构如下:

    矩阵块结构(以6个点为例)

    定义:

    • I

      \\mathbf{I}

      I:

      2

      ×

      2

      2 \\times 2

      2×2 单位矩阵

    • X

      =

      w

      f

      e

      m

      ⋅

      I

      \\mathbf{X} = w_{fem} \\cdot \\mathbf{I}

      X=wfem​⋅I

    • Y

      =

      w

      l

      e

      n

      g

      t

      h

      ⋅

      I

      \\mathbf{Y} = w_{length} \\cdot \\mathbf{I}

      Y=wlength​⋅I

    • Z

      =

      w

      r

      e

      f

      ⋅

      I

      \\mathbf{Z} = w_{ref} \\cdot \\mathbf{I}

      Z=wref​⋅I

    • 0

      \\mathbf{0}

      0:

      2

      ×

      2

      2 \\times 2

      2×2 零矩阵

    则 Hessian 矩阵为(仅上三角,对称矩阵):

    P

    =

    [

    X

    +

    Y

    +

    Z

    −

    2

    X

    −

    Y

    X

    0

    0

    0

    ⋅

    5

    X

    +

    2

    Y

    +

    Z

    −

    4

    X

    −

    Y

    X

    0

    0

    ⋅

    ⋅

    6

    X

    +

    2

    Y

    +

    Z

    −

    4

    X

    −

    Y

    X

    0

    ⋅

    ⋅

    ⋅

    6

    X

    +

    2

    Y

    +

    Z

    −

    4

    X

    −

    Y

    X

    ⋅

    ⋅

    ⋅

    ⋅

    5

    X

    +

    2

    Y

    +

    Z

    −

    2

    X

    −

    Y

    ⋅

    ⋅

    ⋅

    ⋅

    ⋅

    X

    +

    Y

    +

    Z

    ]

    (14)

    \\mathbf{P} = \\begin{bmatrix} \\mathbf{X}+\\mathbf{Y}+\\mathbf{Z} & -2\\mathbf{X}-\\mathbf{Y} & \\mathbf{X} & \\mathbf{0} & \\mathbf{0} & \\mathbf{0} \\\\ \\cdot & 5\\mathbf{X}+2\\mathbf{Y}+\\mathbf{Z} & -4\\mathbf{X}-\\mathbf{Y} & \\mathbf{X} & \\mathbf{0} & \\mathbf{0} \\\\ \\cdot & \\cdot & 6\\mathbf{X}+2\\mathbf{Y}+\\mathbf{Z} & -4\\mathbf{X}-\\mathbf{Y} & \\mathbf{X} & \\mathbf{0} \\\\ \\cdot & \\cdot & \\cdot & 6\\mathbf{X}+2\\mathbf{Y}+\\mathbf{Z} & -4\\mathbf{X}-\\mathbf{Y} & \\mathbf{X} \\\\ \\cdot & \\cdot & \\cdot & \\cdot & 5\\mathbf{X}+2\\mathbf{Y}+\\mathbf{Z} & -2\\mathbf{X}-\\mathbf{Y} \\\\ \\cdot & \\cdot & \\cdot & \\cdot & \\cdot & \\mathbf{X}+\\mathbf{Y}+\\mathbf{Z} \\end{bmatrix} \\tag{14}

    P=

    ​X+Y+Z⋅⋅⋅⋅⋅​−2X−Y5X+2Y+Z⋅⋅⋅⋅​X−4X−Y6X+2Y+Z⋅⋅⋅​0X−4X−Y6X+2Y+Z⋅⋅​00X−4X−Y5X+2Y+Z⋅​000X−2X−YX+Y+Z​

    ​(14)

    4.2 系数推导

    以中间点

    p

    i

    p_i

    pi​(

    2

    ≤

    i

    ≤

    n

    −

    3

    2 \\leq i \\leq n-3

    2≤i≤n−3)为例,展开代价函数:

    FEM项贡献:

    J

    f

    e

    m

    (

    i

    )

    =

    w

    f

    e

    m

    (

    p

    i

    −

    1

    −

    2

    p

    i

    +

    p

    i

    +

    1

    )

    T

    (

    p

    i

    −

    1

    −

    2

    p

    i

    +

    p

    i

    +

    1

    )

    (15)

    J_{fem}^{(i)} = w_{fem} (p_{i-1} – 2p_i + p_{i+1})^T (p_{i-1} – 2p_i + p_{i+1}) \\tag{15}

    Jfem(i)​=wfem​(pi−1​−2pi​+pi+1​)T(pi−1​−2pi​+pi+1​)(15)

    对

    p

    i

    p_i

    pi​ 的 Hessian:

    ∂

    2

    J

    f

    e

    m

    (

    i

    )

    ∂

    p

    i

    2

    =

    4

    w

    f

    e

    m

    I

    (16)

    \\frac{\\partial^2 J_{fem}^{(i)}}{\\partial p_i^2} = 4 w_{fem} \\mathbf{I} \\tag{16}

    ∂pi2​∂2Jfem(i)​​=4wfem​I(16)

    但注意

    p

    i

    p_i

    pi​ 出现在三个FEM项中:

    • J

      f

      e

      m

      (

      i

      −

      1

      )

      J_{fem}^{(i-1)}

      Jfem(i−1)​:作为

      p

      i

      +

      1

      p_{i+1}

      pi+1​

    • J

      f

      e

      m

      (

      i

      )

      J_{fem}^{(i)}

      Jfem(i)​:作为

      p

      i

      p_i

      pi​(中心点)

    • J

      f

      e

      m

      (

      i

      +

      1

      )

      J_{fem}^{(i+1)}

      Jfem(i+1)​:作为

      p

      i

      −

      1

      p_{i-1}

      pi−1​

    总贡献:

    4

    w

    f

    e

    m

    +

    w

    f

    e

    m

    +

    w

    f

    e

    m

    =

    6

    w

    f

    e

    m

    4w_{fem} + w_{fem} + w_{fem} = 6w_{fem}

    4wfem​+wfem​+wfem​=6wfem​

    长度项贡献:

    J

    l

    e

    n

    g

    t

    h

    (

    i

    )

    =

    w

    l

    e

    n

    g

    t

    h

    [

    (

    p

    i

    −

    p

    i

    −

    1

    )

    T

    (

    p

    i

    −

    p

    i

    −

    1

    )

    +

    (

    p

    i

    +

    1

    −

    p

    i

    )

    T

    (

    p

    i

    +

    1

    −

    p

    i

    )

    ]

    (17)

    J_{length}^{(i)} = w_{length} [(p_i – p_{i-1})^T(p_i – p_{i-1}) + (p_{i+1} – p_i)^T(p_{i+1} – p_i)] \\tag{17}

    Jlength(i)​=wlength​[(pi​−pi−1​)T(pi​−pi−1​)+(pi+1​−pi​)T(pi+1​−pi​)](17)

    对

    p

    i

    p_i

    pi​ 的 Hessian:

    ∂

    2

    J

    l

    e

    n

    g

    t

    h

    ∂

    p

    i

    2

    =

    2

    w

    l

    e

    n

    g

    t

    h

    I

    (18)

    \\frac{\\partial^2 J_{length}}{\\partial p_i^2} = 2 w_{length} \\mathbf{I} \\tag{18}

    ∂pi2​∂2Jlength​​=2wlength​I(18)

    参考点偏差项:

    J

    r

    e

    f

    (

    i

    )

    =

    w

    r

    e

    f

    (

    p

    i

    −

    p

    i

    r

    e

    f

    )

    T

    (

    p

    i

    −

    p

    i

    r

    e

    f

    )

    (19)

    J_{ref}^{(i)} = w_{ref} (p_i – p_i^{ref})^T (p_i – p_i^{ref}) \\tag{19}

    Jref(i)​=wref​(pi​−piref​)T(pi​−piref​)(19)

    对

    p

    i

    p_i

    pi​ 的 Hessian:

    ∂

    2

    J

    r

    e

    f

    (

    i

    )

    ∂

    p

    i

    2

    =

    w

    r

    e

    f

    I

    (20)

    \\frac{\\partial^2 J_{ref}^{(i)}}{\\partial p_i^2} = w_{ref} \\mathbf{I} \\tag{20}

    ∂pi2​∂2Jref(i)​​=wref​I(20)

    总Hessian(对角块):

    P

    i

    i

    =

    (

    6

    w

    f

    e

    m

    +

    2

    w

    l

    e

    n

    g

    t

    h

    +

    w

    r

    e

    f

    )

    I

    (21)

    \\mathbf{P}_{ii} = (6w_{fem} + 2w_{length} + w_{ref}) \\mathbf{I} \\tag{21}

    Pii​=(6wfem​+2wlength​+wref​)I(21)

    对应代码:fem_pos_deviation_osqp_interface.cpp 第172-173行:

    col_index, 6.0 * weight_fem_pos_deviation_ +
    2.0 * weight_path_length_ + weight_ref_deviation_


    5. 二次规划求解

    5.1 标准QP问题

    优化问题最终形式:

    min

    ⁡

    p

    1

    2

    p

    T

    P

    p

    +

    q

    T

    p

    s.t.

    l

    ≤

    A

    p

    ≤

    u

    (22)

    \\begin{aligned} \\min_{\\mathbf{p}} \\quad & \\frac{1}{2} \\mathbf{p}^T \\mathbf{P} \\mathbf{p} + \\mathbf{q}^T \\mathbf{p} \\\\ \\text{s.t.} \\quad & \\mathbf{l} \\leq \\mathbf{A} \\mathbf{p} \\leq \\mathbf{u} \\end{aligned} \\tag{22}

    pmin​s.t.​21​pTPp+qTpl≤Ap≤u​(22)

    其中:

    • P

      \\mathbf{P}

      P:Hessian矩阵(

      2

      n

      ×

      2

      n

      2n \\times 2n

      2n×2n,稀疏对称)

    • q

      \\mathbf{q}

      q:线性项,来自参考点偏差

    • A

      \\mathbf{A}

      A:约束矩阵(盒约束,这里是单位矩阵)

    • l

      ,

      u

      \\mathbf{l}, \\mathbf{u}

      l,u:下界和上界(横向偏移限制)

    5.2 线性项

    q

    \\mathbf{q}

    q 的计算

    参考点偏差项展开:

    J

    r

    e

    f

    =

    w

    r

    e

    f

    ∑

    i

    =

    0

    n

    −

    1

    (

    p

    i

    −

    p

    i

    r

    e

    f

    )

    T

    (

    p

    i

    −

    p

    i

    r

    e

    f

    )

    (23)

    J_{ref} = w_{ref} \\sum_{i=0}^{n-1} (p_i – p_i^{ref})^T (p_i – p_i^{ref}) \\tag{23}

    Jref​=wref​i=0∑n−1​(pi​−piref​)T(pi​−piref​)(23)

    =

    w

    r

    e

    f

    ∑

    i

    =

    0

    n

    −

    1

    (

    p

    i

    T

    p

    i

    −

    2

    p

    i

    T

    p

    i

    r

    e

    f

    +

    (

    p

    i

    r

    e

    f

    )

    T

    p

    i

    r

    e

    f

    )

    (24)

    = w_{ref} \\sum_{i=0}^{n-1} (p_i^T p_i – 2 p_i^T p_i^{ref} + (p_i^{ref})^T p_i^{ref}) \\tag{24}

    =wref​i=0∑n−1​(piT​pi​−2piT​piref​+(piref​)Tpiref​)(24)

    线性项系数:

    q

    i

    =

    −

    2

    w

    r

    e

    f

    p

    i

    r

    e

    f

    (25)

    q_i = -2 w_{ref} p_i^{ref} \\tag{25}

    qi​=−2wref​piref​(25)

    对应代码:fem_pos_deviation_osqp_interface.cpp 第218-219行:

    q->push_back(–2.0 * weight_ref_deviation_ * ref_point_xy.first);
    q->push_back(–2.0 * weight_ref_deviation_ * ref_point_xy.second);

    5.3 约束条件

    盒约束(Box Constraints):限制平滑后的点不能偏离原始点太远

    p

    i

    r

    e

    f

    −

    b

    i

    ≤

    p

    i

    ≤

    p

    i

    r

    e

    f

    +

    b

    i

    (26)

    p_i^{ref} – b_i \\leq p_i \\leq p_i^{ref} + b_i \\tag{26}

    piref​−bi​≤pi​≤piref​+bi​(26)

    其中

    b

    i

    b_i

    bi​ 是第

    i

    i

    i 个点的横向边界(lateral bound)。

    特殊处理:

    • 起点和终点:

      b

      0

      =

      b

      n

      −

      1

      =

      0

      b_0 = b_{n-1} = 0

      b0​=bn−1​=0(强制固定)

    • 中间点:

      b

      i

      b_i

      bi​ 根据道路宽度设置

    对应代码:discrete_points_reference_line_smoother.cpp 第25-26行:

    anchorpoints_lateralbound.front() = 0.0; // 起点固定
    anchorpoints_lateralbound.back() = 0.0; // 终点固定


    6. 代码实现详解

    6.1 算法流程

    主流程(DiscretePointsReferenceLineSmoother::Smooth)

    // discrete_points_reference_line_smoother.cpp: 8-51行
    bool Smooth(const MatrixXd& raw_reference_line, MatrixXd &smoothed_reference_line) {
    // 步骤1:提取原始参考点
    std::vector<std::pair<double, double>> raw_point2d;
    for (const auto& anchor_point : anchor_points_) {
    raw_point2d.emplace_back(anchor_point.x, anchor_point.y);
    anchorpoints_lateralbound.emplace_back(anchor_point.lateral_bound);
    }

    // 步骤2:归一化(相对于起点)
    NormalizePoints(&raw_point2d);

    // 步骤3:调用FEM优化求解器
    std::vector<std::pair<double, double>> smoothed_point2d;
    bool status = FemPosSmooth(raw_point2d, anchorpoints_lateralbound, &smoothed_point2d);

    // 步骤4:反归一化(恢复全局坐标)
    DeNormalizePoints(&smoothed_point2d);

    // 步骤5:计算曲率、航向角等几何属性
    referencePath(xy, smoothed_reference_line);

    return true;
    }

    数学映射:

    原始路径

    →

    归一化

    局部坐标

    →

    QP求解

    优化路径

    →

    反归一化

    全局平滑路径

    (27)

    \\text{原始路径} \\xrightarrow{\\text{归一化}} \\text{局部坐标} \\xrightarrow{\\text{QP求解}} \\text{优化路径} \\xrightarrow{\\text{反归一化}} \\text{全局平滑路径} \\tag{27}

    原始路径归一化

    ​局部坐标QP求解

    ​优化路径反归一化

    ​全局平滑路径(27)

    6.2 Hessian矩阵构造(核心算法)

    矩阵填充规则

    第0, 1点(起点和第二个点):

    // fem_pos_deviation_osqp_interface.cpp: 145-159行
    // 对角元素
    P[0,0] = weight_fem + weight_length + weight_ref // X+Y+Z
    P[1,1] = 5*weight_fem + 2*weight_length + weight_ref // 5X+2Y+Z

    // 非对角元素
    P[0,2] = –2*weight_fem – weight_length // -2X-Y
    P[1,3] = –4*weight_fem – weight_length // -4X-Y

    中间点

    i

    i

    i(

    2

    ≤

    i

    ≤

    n

    −

    3

    2 \\leq i \\leq n-3

    2≤i≤n−3):

    // fem_pos_deviation_osqp_interface.cpp: 162-176行
    P[i,i–2] = weight_fem // X
    P[i,i–1] = –4*weight_fem – weight_length // -4X-Y
    P[i,i] = 6*weight_fem + 2*weight_length + weight_ref // 6X+2Y+Z

    倒数第2, 1点:

    // fem_pos_deviation_osqp_interface.cpp: 180-199行
    // 对称于起点的处理
    P[n–2,n–2] = 5*weight_fem + 2*weight_length + weight_ref
    P[n–1,n–1] = weight_fem + weight_length + weight_ref

    推导过程

    以中间点

    p

    2

    p_2

    p2​ 为例(6点系统中的第3个点):

    FEM项:

    J

    f

    e

    m

    =

    w

    X

    [

    (

    p

    0

    −

    2

    p

    1

    +

    p

    2

    )

    2

    +

    (

    p

    1

    −

    2

    p

    2

    +

    p

    3

    )

    2

    +

    (

    p

    2

    −

    2

    p

    3

    +

    p

    4

    )

    2

    ]

    (28)

    J_{fem} = w_X \\left[ (p_0 – 2p_1 + p_2)^2 + (p_1 – 2p_2 + p_3)^2 + (p_2 – 2p_3 + p_4)^2 \\right] \\tag{28}

    Jfem​=wX​[(p0​−2p1​+p2​)2+(p1​−2p2​+p3​)2+(p2​−2p3​+p4​)2](28)

    对

    p

    2

    p_2

    p2​ 求二阶偏导:

    ∂

    2

    J

    f

    e

    m

    ∂

    p

    2

    2

    =

    w

    X

    (

    1

    +

    4

    +

    1

    )

    =

    6

    w

    X

    (29)

    \\frac{\\partial^2 J_{fem}}{\\partial p_2^2} = w_X(1 + 4 + 1) = 6w_X \\tag{29}

    ∂p22​∂2Jfem​​=wX​(1+4+1)=6wX​(29)

    ∂

    2

    J

    f

    e

    m

    ∂

    p

    2

    ∂

    p

    1

    =

    w

    X

    (

    −

    2

    −

    2

    )

    =

    −

    4

    w

    X

    (30)

    \\frac{\\partial^2 J_{fem}}{\\partial p_2 \\partial p_1} = w_X(-2 – 2) = -4w_X \\tag{30}

    ∂p2​∂p1​∂2Jfem​​=wX​(−2−2)=−4wX​(30)

    长度项:

    J

    l

    e

    n

    g

    t

    h

    =

    w

    Y

    [

    (

    p

    2

    −

    p

    1

    )

    2

    +

    (

    p

    3

    −

    p

    2

    )

    2

    ]

    (31)

    J_{length} = w_Y \\left[ (p_2 – p_1)^2 + (p_3 – p_2)^2 \\right] \\tag{31}

    Jlength​=wY​[(p2​−p1​)2+(p3​−p2​)2](31)

    对

    p

    2

    p_2

    p2​ 求二阶偏导:

    ∂

    2

    J

    l

    e

    n

    g

    t

    h

    ∂

    p

    2

    2

    =

    2

    w

    Y

    (32)

    \\frac{\\partial^2 J_{length}}{\\partial p_2^2} = 2w_Y \\tag{32}

    ∂p22​∂2Jlength​​=2wY​(32)

    ∂

    2

    J

    l

    e

    n

    g

    t

    h

    ∂

    p

    2

    ∂

    p

    1

    =

    −

    w

    Y

    (33)

    \\frac{\\partial^2 J_{length}}{\\partial p_2 \\partial p_1} = -w_Y \\tag{33}

    ∂p2​∂p1​∂2Jlength​​=−wY​(33)

    总Hessian(

    p

    2

    p_2

    p2​ 对应的块):

    P

    22

    =

    6

    w

    X

    +

    2

    w

    Y

    +

    w

    Z

    (34)

    \\mathbf{P}_{22} = 6w_X + 2w_Y + w_Z \\tag{34}

    P22​=6wX​+2wY​+wZ​(34)

    P

    21

    =

    −

    4

    w

    X

    −

    w

    Y

    (35)

    \\mathbf{P}_{21} = -4w_X – w_Y \\tag{35}

    P21​=−4wX​−wY​(35)


    7. 可视化示意图

    7.1 有限元估计示意图

    原始路径(有锯齿):

    p₂ ●
    / \\
    / \\
    / \\
    ● ●
    p₁ p₃

    FEM估计:中点应该在p₁和p₃的中间

    p̂₂ = (p₁ + p₃)/2

    p₂ ● ← 实际位置
    |
    | ← 偏差 e₂
    |
    p̂₂ ● ← FEM估计位置
    / \\
    / \\
    ●──────●
    p₁ p₃

    平滑后的路径:

    ●
    / \\
    / \\ ← 更平滑的曲线
    / \\
    ● ●

    7.2 三种代价的几何意义

    (a) FEM代价 (b) 长度代价 (c) 参考偏差代价

    ● ● ●ref
    \\ \\ |
    \\ ← 曲率大 \\ ← 路径长 | ← 偏移
    ● ●―――――――● ●actual
    / 代价高 代价高 代价高
    ●

    优化目标:平衡三者

    ●―――●―――● ← 太平滑但偏离原路径且过长

    ●⌒●⌒● ← 跟随原路径但不平滑

    ●~●~● ← 最优:平滑且不过度偏离


    8. 代码实现对照

    8.1 Hessian矩阵构造

    理论公式:

    P

    i

    i

    =

    6

    w

    f

    e

    m

    +

    2

    w

    l

    e

    n

    g

    t

    h

    +

    w

    r

    e

    f

    (36)

    \\mathbf{P}_{ii} = 6w_{fem} + 2w_{length} + w_{ref} \\tag{36}

    Pii​=6wfem​+2wlength​+wref​(36)

    对应代码:

    // fem_pos_deviation_osqp_interface.cpp: 172-173行
    columns[col_index].emplace_back(
    col_index, 6.0 * weight_fem_pos_deviation_ +
    2.0 * weight_path_length_ + weight_ref_deviation_);

    8.2 线性项计算

    理论公式:

    q

    i

    =

    −

    2

    w

    r

    e

    f

    ⋅

    p

    i

    r

    e

    f

    (37)

    q_i = -2 w_{ref} \\cdot p_i^{ref} \\tag{37}

    qi​=−2wref​⋅piref​(37)

    对应代码:

    // fem_pos_deviation_osqp_interface.cpp: 218-219行
    q->push_back(–2.0 * weight_ref_deviation_ * ref_point_xy.first);
    q->push_back(–2.0 * weight_ref_deviation_ * ref_point_xy.second);

    8.3 约束条件

    理论公式:

    p

    i

    r

    e

    f

    −

    b

    i

    ≤

    p

    i

    ≤

    p

    i

    r

    e

    f

    +

    b

    i

    (38)

    p_i^{ref} – b_i \\leq p_i \\leq p_i^{ref} + b_i \\tag{38}

    piref​−bi​≤pi​≤piref​+bi​(38)

    对应代码:

    // fem_pos_deviation_osqp_interface.cpp: 238-241行
    upper_bounds->push_back(ref_point_xy.first + bounds_around_refs_[i]);
    upper_bounds->push_back(ref_point_xy.second + bounds_around_refs_[i]);
    lower_bounds->push_back(ref_point_xy.first – bounds_around_refs_[i]);
    lower_bounds->push_back(ref_point_xy.second – bounds_around_refs_[i]);

    8.4 归一化处理

    理论意义:

    将坐标原点移到起点,提高数值稳定性(避免处理很大的坐标值)。

    对应代码:

    // discrete_points_reference_line_smoother.cpp: 112-127行
    void NormalizePoints(std::vector<std::pair<double, double>>* xy_points) {
    zero_x_ = xy_points->front().first; // 记录起点x
    zero_y_ = xy_points->front().second; // 记录起点y

    // 所有点减去起点坐标
    std::for_each(xy_points->begin(), xy_points->end(),
    [this](std::pair<double, double>& point) {
    point.first -= zero_x_; // x相对化
    point.second -= zero_y_; // y相对化
    });
    }

    数学表示:

    p

    ~

    i

    =

    p

    i

    −

    p

    0

    (39)

    \\tilde{p}_i = p_i – p_0 \\tag{39}

    p~​i​=pi​−p0​(39)

    8.5 OSQP求解器调用

    求解流程:

    // fem_pos_deviation_osqp_interface.cpp: 71-88行
    // 1. 配置OSQP参数
    osqp_set_default_settings(settings);
    settings->max_iter = max_iter_; // 最大迭代次数
    settings->time_limit = time_limit_; // 时间限制
    settings->verbose = verbose_; // 是否输出详细信息
    settings->warm_start = warm_start_; // 热启动

    // 2. 设置优化问题数据
    data->P = csc_matrix(...); // Hessian矩阵(CSC稀疏格式)
    data->q = q->data(); // 线性项
    data->A = csc_matrix(...); // 约束矩阵
    data->l = lower_bounds; // 下界
    data->u = upper_bounds; // 上界

    // 3. 初始化workspace并求解
    osqp_setup(&work, data, settings);
    osqp_warm_start_x(*work, primal_warm_start);
    osqp_solve(*work);

    // 4. 提取解
    for (int i = 0; i < num_of_points_; ++i) {
    x_[i] = work->solution->x[2*i]; // 优化后的x坐标
    y_[i] = work->solution->x[2*i+1]; // 优化后的y坐标
    }


    9. 矩阵示例推导

    9.1 4点系统完整示例

    假设有4个路径点

    p

    0

    ,

    p

    1

    ,

    p

    2

    ,

    p

    3

    p_0, p_1, p_2, p_3

    p0​,p1​,p2​,p3​,权重

    w

    X

    =

    1

    ,

    w

    Y

    =

    1

    ,

    w

    Z

    =

    1

    w_X=1, w_Y=1, w_Z=1

    wX​=1,wY​=1,wZ​=1。

    Hessian矩阵(

    8

    ×

    8

    8 \\times 8

    8×8,每个点2维):

    P

    =

    [

    3

    I

    −

    3

    I

    I

    0

    ⋅

    7

    I

    −

    5

    I

    I

    ⋅

    ⋅

    7

    I

    −

    3

    I

    ⋅

    ⋅

    ⋅

    3

    I

    ]

    (40)

    \\mathbf{P} = \\begin{bmatrix} 3\\mathbf{I} & -3\\mathbf{I} & \\mathbf{I} & \\mathbf{0} \\\\ \\cdot & 7\\mathbf{I} & -5\\mathbf{I} & \\mathbf{I} \\\\ \\cdot & \\cdot & 7\\mathbf{I} & -3\\mathbf{I} \\\\ \\cdot & \\cdot & \\cdot & 3\\mathbf{I} \\end{bmatrix} \\tag{40}

    P=

    ​3I⋅⋅⋅​−3I7I⋅⋅​I−5I7I⋅​0I−3I3I​

    ​(40)

    展开为标量形式(

    I

    =

    diag

    (

    1

    ,

    1

    )

    \\mathbf{I} = \\text{diag}(1,1)

    I=diag(1,1)):

    P

    =

    [

    3

    0

    −

    3

    0

    1

    0

    0

    0

    0

    3

    0

    −

    3

    0

    1

    0

    0

    ⋅

    ⋅

    7

    0

    −

    5

    0

    1

    0

    ⋅

    ⋅

    0

    7

    0

    −

    5

    0

    1

    ⋅

    ⋅

    ⋅

    ⋅

    7

    0

    −

    3

    0

    ⋅

    ⋅

    ⋅

    ⋅

    0

    7

    0

    −

    3

    ⋅

    ⋅

    ⋅

    ⋅

    ⋅

    ⋅

    3

    0

    ⋅

    ⋅

    ⋅

    ⋅

    ⋅

    ⋅

    0

    3

    ]

    (41)

    \\mathbf{P} = \\begin{bmatrix} 3 & 0 & -3 & 0 & 1 & 0 & 0 & 0 \\\\ 0 & 3 & 0 & -3 & 0 & 1 & 0 & 0 \\\\ \\cdot & \\cdot & 7 & 0 & -5 & 0 & 1 & 0 \\\\ \\cdot & \\cdot & 0 & 7 & 0 & -5 & 0 & 1 \\\\ \\cdot & \\cdot & \\cdot & \\cdot & 7 & 0 & -3 & 0 \\\\ \\cdot & \\cdot & \\cdot & \\cdot & 0 & 7 & 0 & -3 \\\\ \\cdot & \\cdot & \\cdot & \\cdot & \\cdot & \\cdot & 3 & 0 \\\\ \\cdot & \\cdot & \\cdot & \\cdot & \\cdot & \\cdot & 0 & 3 \\end{bmatrix} \\tag{41}

    P=

    ​30⋅⋅⋅⋅⋅⋅​03⋅⋅⋅⋅⋅⋅​−3070⋅⋅⋅⋅​0−307⋅⋅⋅⋅​10−5070⋅⋅​010−507⋅⋅​0010−3030​00010−303​

    ​(41)

    线性项

    q

    \\mathbf{q}

    q:

    q

    =

    −

    2

    w

    Z

    [

    x

    0

    r

    e

    f

    y

    0

    r

    e

    f

    x

    1

    r

    e

    f

    y

    1

    r

    e

    f

    x

    2

    r

    e

    f

    y

    2

    r

    e

    f

    x

    3

    r

    e

    f

    y

    3

    r

    e

    f

    ]

    (42)

    \\mathbf{q} = -2w_Z \\begin{bmatrix} x_0^{ref} \\\\ y_0^{ref} \\\\ x_1^{ref} \\\\ y_1^{ref} \\\\ x_2^{ref} \\\\ y_2^{ref} \\\\ x_3^{ref} \\\\ y_3^{ref} \\end{bmatrix} \\tag{42}

    q=−2wZ​

    ​x0ref​y0ref​x1ref​y1ref​x2ref​y2ref​x3ref​y3ref​​

    ​(42)

    9.2 数值计算示例

    输入:

    原始点:
    p0 = (0, 0)
    p1 = (1, 0.5) ← 有偏移
    p2 = (2, 0)
    p3 = (3, 0)

    权重:w_fem=10, w_length=1, w_ref=1
    边界:b = [0, 0.5, 0.5, 0]

    FEM分析:

    • p1的FEM估计:

      p

      ^

      1

      =

      (

      p

      0

      +

      p

      2

      )

      /

      2

      =

      (

      1

      ,

      0.25

      )

      \\hat{p}_1 = (p_0 + p_2)/2 = (1, 0.25)

      p^​1​=(p0​+p2​)/2=(1,0.25)

    • 偏差:

      e

      1

      =

      p

      1

      −

      p

      ^

      1

      =

      (

      0

      ,

      0.25

      )

      e_1 = p_1 – \\hat{p}_1 = (0, 0.25)

      e1​=p1​−p^​1​=(0,0.25)

    • 代价:

      J

      f

      e

      m

      (

      1

      )

      =

      10

      ×

      0.25

      2

      =

      0.625

      J_{fem}^{(1)} = 10 \\times 0.25^2 = 0.625

      Jfem(1)​=10×0.252=0.625

    优化后(示意):

    平滑点:
    p0 = (0, 0) ← 固定
    p1 ≈ (1, 0.3) ← 偏移减小
    p2 ≈ (2, 0.05) ← 轻微调整
    p3 = (3, 0) ← 固定

    路径更平滑,偏差变小


    10. 算法特性分析

    10.1 计算复杂度

    • 变量数量:

      2

      n

      2n

      2n(

      n

      n

      n 个点,每个点2维)

    • Hessian矩阵:

      2

      n

      ×

      2

      n

      2n \\times 2n

      2n×2n,带状稀疏(每行最多5个非零元素)

    • 时间复杂度:

      O

      (

      n

      )

      O(n)

      O(n)(利用稀疏性,OSQP内部求解)

    • 空间复杂度:

      O

      (

      n

      )

      O(n)

      O(n)

    10.2 收敛性

    OSQP求解器保证:

    • 凸优化问题,全局最优解存在
    • 通常 10-50 次迭代内收敛
    • 收敛条件:原始残差和对偶残差同时满足容差

    10.3 参数敏感性分析

    参数增大效果减小效果

    w

    f

    e

    m

    w_{fem}

    wfem​

    路径更平滑(接近直线) 允许更大曲率

    w

    l

    e

    n

    g

    t

    h

    w_{length}

    wlength​

    路径更短(走捷径) 路径可以绕远

    w

    r

    e

    f

    w_{ref}

    wref​

    更接近原始路径 允许更大偏离

    推荐配置(Apollo默认值):

    weight_fem_pos_deviation = 1e10; // 强调平滑性
    weight_path_length = 1.0; // 弱惩罚长度
    weight_ref_deviation = 1.0; // 弱惩罚偏差

    物理解释:

    • FEM项权重非常大 → 平滑性优先
    • 长度和偏差项较小 → 作为软约束

    11. 关键代码段详解

    11.1 主Hessian循环

    // fem_pos_deviation_osqp_interface.cpp: 162-176行
    int second_point_from_last_index = num_of_points_ – 2;
    for (int point_index = 2; point_index < second_point_from_last_index; ++point_index) {
    int col_index = point_index * 2; // 每个点占2列(x,y)

    for (int col = 0; col < 2; ++col) {
    col_index += col;

    // 填充上三角矩阵的三个元素
    columns[col_index].emplace_back(col_index – 4, weight_fem_pos_deviation_);
    // ↑ 对应 p[i-2] 的交叉项:系数 = w_fem

    columns[col_index].emplace_back(
    col_index – 2,
    –4.0 * weight_fem_pos_deviation_ – weight_path_length_);
    // ↑ 对应 p[i-1] 的交叉项:系数 = -4w_fem – w_length

    columns[col_index].emplace_back(
    col_index,
    6.0 * weight_fem_pos_deviation_ +
    2.0 * weight_path_length_ +
    weight_ref_deviation_);
    // ↑ 对应 p[i] 的对角项:系数 = 6w_fem + 2w_length + w_ref

    ++col_num;
    }
    }

    数学对应:

    p

    i

    −

    2

    :

    w

    f

    e

    m

    p

    i

    −

    1

    :

    −

    4

    w

    f

    e

    m

    −

    w

    l

    e

    n

    g

    t

    h

    p

    i

    :

    6

    w

    f

    e

    m

    +

    2

    w

    l

    e

    n

    g

    t

    h

    +

    w

    r

    e

    f

    (43)

    \\begin{aligned} &p_{i-2}: \\quad w_{fem} \\\\ &p_{i-1}: \\quad -4w_{fem} – w_{length} \\\\ &p_i: \\quad \\quad 6w_{fem} + 2w_{length} + w_{ref} \\end{aligned} \\tag{43}

    ​pi−2​:wfem​pi−1​:−4wfem​−wlength​pi​:6wfem​+2wlength​+wref​​(43)

    11.2 曲率计算

    平滑后需要计算路径的几何属性:

    // discrete_points_reference_line_smoother.cpp: 179-180行
    double kappa = (ddy * dx – ddx * dy) / pow((pow(dx, 2) + pow(dy, 2)), (1.5));
    path(4, i) = kappa;

    理论公式:

    曲率的标准定义:

    κ

    =

    ∣

    x

    ′

    y

    ′

    ′

    −

    y

    ′

    x

    ′

    ′

    ∣

    (

    x

    ′

    2

    +

    y

    ′

    2

    )

    3

    /

    2

    (44)

    \\kappa = \\frac{|x'y'' – y'x''|}{(x'^2 + y'^2)^{3/2}} \\tag{44}

    κ=(x′2+y′2)3/2∣x′y′′−y′x′′∣​(44)

    有符号曲率(考虑左转/右转):

    κ

    =

    x

    ′

    y

    ′

    ′

    −

    y

    ′

    x

    ′

    ′

    (

    x

    ′

    2

    +

    y

    ′

    2

    )

    3

    /

    2

    (45)

    \\kappa = \\frac{x'y'' – y'x''}{(x'^2 + y'^2)^{3/2}} \\tag{45}

    κ=(x′2+y′2)3/2x′y′′−y′x′′​(45)

    其中:

    • x

      ′

      =

      d

      x

      d

      s

      x' = \\frac{dx}{ds}

      x′=dsdx​:x对弧长的一阶导数

    • y

      ′

      =

      d

      y

      d

      s

      y' = \\frac{dy}{ds}

      y′=dsdy​:y对弧长的一阶导数

    • x

      ′

      ′

      =

      d

      2

      x

      d

      s

      2

      x'' = \\frac{d^2x}{ds^2}

      x′′=ds2d2x​:x对弧长的二阶导数

    • y

      ′

      ′

      =

      d

      2

      y

      d

      s

      2

      y'' = \\frac{d^2y}{ds^2}

      y′′=ds2d2y​:y对弧长的二阶导数

    数值近似(中心差分):

    d

    x

    ≈

    x

    i

    +

    1

    −

    x

    i

    (46)

    dx \\approx x_{i+1} – x_i \\tag{46}

    dx≈xi+1​−xi​(46)

    d

    d

    x

    ≈

    x

    i

    +

    1

    +

    x

    i

    −

    1

    −

    2

    x

    i

    (47)

    ddx \\approx x_{i+1} + x_{i-1} – 2x_i \\tag{47}

    ddx≈xi+1​+xi−1​−2xi​(47)


    12. 完整算法伪代码

    def smooth_reference_line(raw_points, lateral_bounds):
    """
    参考线平滑算法

    输入:
    raw_points: List[(x, y)] – 原始路径点
    lateral_bounds: List[float] – 每个点的横向偏移限制

    输出:
    smoothed_points: List[(x, y)] – 平滑后的路径点
    """
    # 步骤1:归一化
    origin = raw_points[0]
    normalized_points = [(p.x – origin.x, p.y – origin.y) for p in raw_points]

    # 步骤2:构造QP问题
    n = len(normalized_points)
    P = construct_hessian_matrix(n, w_fem, w_length, w_ref) # 2n×2n
    q = construct_linear_term(normalized_points, w_ref) # 2n×1
    A = identity_matrix(2*n) # 2n×2n
    lb = [p_ref[i] – bounds[i] for i in range(n)] # 下界
    ub = [p_ref[i] + bounds[i] for i in range(n)] # 上界

    # 步骤3:求解QP
    solution = osqp_solve(P, q, A, lb, ub)

    # 步骤4:反归一化
    smoothed_points = [(sol.x + origin.x, sol.y + origin.y) for sol in solution]

    # 步骤5:计算几何属性(yaw, kappa, dkappa)
    compute_geometric_attributes(smoothed_points)

    return smoothed_points


    13. 参数调优指南

    13.1 权重参数配置

    场景1:城市道路(频繁转弯)

    weight_fem_pos_deviation: 1e8 # 中等平滑
    weight_path_length: 0.5 # 允许绕路
    weight_ref_deviation: 2.0 # 紧跟原路径

    场景2:高速公路(大曲率转弯少)

    weight_fem_pos_deviation: 1e10 # 强平滑
    weight_path_length: 1.0 # 走捷径
    weight_ref_deviation: 0.5 # 允许偏离

    场景3:避障路径(DP输出的锯齿路径)

    weight_fem_pos_deviation: 1e12 # 极强平滑
    weight_path_length: 2.0 # 尽量缩短
    weight_ref_deviation: 0.1 # 大幅偏离允许

    13.2 边界参数

    // reference_line_provider.cpp: 8行
    longitudinal_boundary_bound = 0.1; // 纵向偏移限制(沿路径方向)
    min_lateral_boundary_bound = 0.25; // 最小横向偏移限制
    max_lateral_boundary_bound = 2.0; // 最大横向偏移限制

    物理意义:

    • 纵向边界小 → 保持路径点的纵向分布
    • 横向边界大 → 允许横向调整(用于平滑)

    14. 数学公式总结

    14.1 优化问题完整形式

    min

    ⁡

    p

    J

    (

    p

    )

    =

    J

    f

    e

    m

    (

    p

    )

    +

    J

    l

    e

    n

    g

    t

    h

    (

    p

    )

    +

    J

    r

    e

    f

    (

    p

    )

    where

    J

    f

    e

    m

    (

    p

    )

    =

    w

    X

    ∑

    i

    =

    1

    n

    −

    2

    1

    4

    ∥

    p

    i

    −

    1

    −

    2

    p

    i

    +

    p

    i

    +

    1

    ∥

    2

    J

    l

    e

    n

    g

    t

    h

    (

    p

    )

    =

    w

    Y

    ∑

    i

    =

    0

    n

    −

    2

    ∥

    p

    i

    +

    1

    −

    p

    i

    ∥

    2

    J

    r

    e

    f

    (

    p

    )

    =

    w

    Z

    ∑

    i

    =

    0

    n

    −

    1

    ∥

    p

    i

    −

    p

    i

    r

    e

    f

    ∥

    2

    s.t.

    p

    i

    r

    e

    f

    −

    b

    i

    ≤

    p

    i

    ≤

    p

    i

    r

    e

    f

    +

    b

    i

    ,

    i

    =

    0

    ,

    1

    ,

    …

    ,

    n

    −

    1

    (48)

    \\begin{aligned} \\min_{\\mathbf{p}} \\quad & J(\\mathbf{p}) = J_{fem}(\\mathbf{p}) + J_{length}(\\mathbf{p}) + J_{ref}(\\mathbf{p}) \\\\[0.5em] \\text{where} \\quad & J_{fem}(\\mathbf{p}) = w_X \\sum_{i=1}^{n-2} \\frac{1}{4} \\|p_{i-1} – 2p_i + p_{i+1}\\|^2 \\\\[0.5em] & J_{length}(\\mathbf{p}) = w_Y \\sum_{i=0}^{n-2} \\|p_{i+1} – p_i\\|^2 \\\\[0.5em] & J_{ref}(\\mathbf{p}) = w_Z \\sum_{i=0}^{n-1} \\|p_i – p_i^{ref}\\|^2 \\\\[0.5em] \\text{s.t.} \\quad & p_i^{ref} – b_i \\leq p_i \\leq p_i^{ref} + b_i, \\quad i = 0, 1, \\ldots, n-1 \\end{aligned} \\tag{48}

    pmin​wheres.t.​J(p)=Jfem​(p)+Jlength​(p)+Jref​(p)Jfem​(p)=wX​i=1∑n−2​41​∥pi−1​−2pi​+pi+1​∥2Jlength​(p)=wY​i=0∑n−2​∥pi+1​−pi​∥2Jref​(p)=wZ​i=0∑n−1​∥pi​−piref​∥2piref​−bi​≤pi​≤piref​+bi​,i=0,1,…,n−1​(48)

    14.2 矩阵形式

    min

    ⁡

    p

    1

    2

    p

    T

    P

    p

    +

    q

    T

    p

    s.t.

    l

    ≤

    A

    p

    ≤

    u

    (49)

    \\begin{aligned} \\min_{\\mathbf{p}} \\quad & \\frac{1}{2} \\mathbf{p}^T \\mathbf{P} \\mathbf{p} + \\mathbf{q}^T \\mathbf{p} \\\\ \\text{s.t.} \\quad & \\mathbf{l} \\leq \\mathbf{A} \\mathbf{p} \\leq \\mathbf{u} \\end{aligned} \\tag{49}

    pmin​s.t.​21​pTPp+qTpl≤Ap≤u​(49)

    其中:

    P

    =

    H

    f

    e

    m

    +

    H

    l

    e

    n

    g

    t

    h

    +

    H

    r

    e

    f

    (50)

    \\mathbf{P} = \\mathbf{H}_{fem} + \\mathbf{H}_{length} + \\mathbf{H}_{ref} \\tag{50}

    P=Hfem​+Hlength​+Href​(50)

    q

    =

    −

    2

    w

    Z

    p

    r

    e

    f

    (51)

    \\mathbf{q} = -2w_Z \\mathbf{p}^{ref} \\tag{51}

    q=−2wZ​pref(51)

    14.3 关键矩阵元素

    对于中间点

    i

    i

    i (

    2

    ≤

    i

    ≤

    n

    −

    3

    2 \\leq i \\leq n-3

    2≤i≤n−3):

    P

    i

    ,

    i

    −

    2

    =

    w

    X

    P

    i

    ,

    i

    −

    1

    =

    −

    4

    w

    X

    −

    w

    Y

    P

    i

    ,

    i

    =

    6

    w

    X

    +

    2

    w

    Y

    +

    w

    Z

    P

    i

    ,

    i

    +

    1

    =

    −

    4

    w

    X

    −

    w

    Y

    P

    i

    ,

    i

    +

    2

    =

    w

    X

    (52)

    \\begin{aligned} \\mathbf{P}_{i,i-2} &= w_X \\\\ \\mathbf{P}_{i,i-1} &= -4w_X – w_Y \\\\ \\mathbf{P}_{i,i} &= 6w_X + 2w_Y + w_Z \\\\ \\mathbf{P}_{i,i+1} &= -4w_X – w_Y \\\\ \\mathbf{P}_{i,i+2} &= w_X \\end{aligned} \\tag{52}

    Pi,i−2​Pi,i−1​Pi,i​Pi,i+1​Pi,i+2​​=wX​=−4wX​−wY​=6wX​+2wY​+wZ​=−4wX​−wY​=wX​​(52)


    15. 实现文件对应表

    功能模块文件关键函数行号
    平滑器接口 discrete_points_reference_line_smoother.h Smooth 21-28
    平滑器实现 discrete_points_reference_line_smoother.cpp Smooth 8-51
    FEM求解器 fem_pos_deviation_osqp_interface.h Solve 68-75
    FEM实现 fem_pos_deviation_osqp_interface.cpp Solve 25-116
    Hessian构造 fem_pos_deviation_osqp_interface.cpp CalculateKernel 119-213
    线性项计算 fem_pos_deviation_osqp_interface.cpp CalculateOffset 215-221
    约束构造 fem_pos_deviation_osqp_interface.cpp CalculateAffineConstraint 223-243
    归一化 discrete_points_reference_line_smoother.cpp NormalizePoints 112-127
    几何计算 discrete_points_reference_line_smoother.cpp referencePath 141-203
    锚点提取 reference_line_provider.cpp GetAnchorPoints 14-30

    16. 使用示例

    16.1 基本使用

    // 创建平滑器对象
    DiscretePointsReferenceLineSmoother smoother;

    // 设置锚点(原始路径点)
    std::vector<AnchorPoint> anchor_points;
    for (const auto& point : raw_path) {
    AnchorPoint anchor;
    anchor.x = point.x;
    anchor.y = point.y;
    anchor.s = point.s;
    anchor.lateral_bound = 0.25; // 横向偏移限制
    anchor_points.push_back(anchor);
    }
    smoother.SetAnchorPoints(anchor_points);

    // 执行平滑
    Eigen::MatrixXd raw_line; // 7×n:[x, y, v, yaw, kappa, dkappa, s]
    Eigen::MatrixXd smoothed_line; // 输出
    bool success = smoother.Smooth(raw_line, smoothed_line);

    if (success) {
    // 使用平滑后的路径
    use_path(smoothed_line);
    }

    16.2 参数调整

    // 在discrete_points_reference_line_smoother.h中修改
    weight_fem_pos_deviation = 1e10; // 平滑度
    weight_path_length = 1.0; // 路径长度
    weight_ref_deviation = 1.0; // 参考偏差


    17. 参考文献

  • Apollo Planning Module https://github.com/ApolloAuto/apollo/tree/master/modules/planning

  • OSQP: Operator Splitting QP Solver Stellato, B., et al. (2020). “OSQP: An operator splitting solver for quadratic programs.” Mathematical Programming Computation, 12(4), 637-672.

  • Finite Element Method for Path Smoothing Dolgov, D., et al. (2010). “Path planning for autonomous vehicles in unknown semi-structured environments.” The International Journal of Robotics Research, 29(5), 485-501.

  • 二次规划理论 Nocedal, J., & Wright, S. (2006). “Numerical optimization.” Springer Science & Business Media.


  • 18. 附录:代码完整调用链

    main.cpp: ros2_sim_planning_callbak()
    ↓
    motion_planning.cpp: global_callback()
    ↓
    (可选)motion_planning.cpp: process()
    ↓
    (如需平滑)reference_line_provider.cpp: SmoothReferenceLine()
    ↓
    discrete_points_reference_line_smoother.cpp: Smooth()
    ↓
    discrete_points_reference_line_smoother.cpp: FemPosSmooth()
    ↓
    discrete_points_reference_line_smoother.cpp: Solve()
    ↓
    fem_pos_deviation_osqp_interface.cpp: Solve()
    ├─ CalculateKernel() // 构造P矩阵
    ├─ CalculateOffset() // 构造q向量
    ├─ CalculateAffineConstraint() // 构造约束
    └─ OptimizeWithOsqp() // 调用OSQP求解

    赞(0)
    未经允许不得转载:171主机测评 » 参考线平滑算法详解(FEM-Based Path Smoothing)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址