注:为避免引入错误,全文所有矩阵求导运算均采用分子布局
项目成果展示如下:
项目成果展示
本项目代码在跟车、多障碍物躲避、变道、超车这些常见场景下均表现良好,满足使用需求。由于项目使用C++ 在ROS架构下实现,所以使用rviz做成果展示,其中绿色矩形为主车,灰色矩形为npc车辆,尺寸均按照tesla model3设置,主车前面的绿色曲线为实时规划路径,可以看出项目在静态、动态场景下均有良好表现,可以根据决策结果不同设置不同参数,达到不同的速度与路径选择。
表1所示为本项目代码在各个测试场景下的平均迭代次数和平均求解时间,可以看出各场景下的平均迭代次数均小于10, 其中多障碍物躲避和超车场景下的平均迭代次数均小于5。表1所示的平均求解时间为处理器i7-9750h下的运行速度,单位为毫秒。结合平均迭代次数来看,算法可以快速收敛至最优解,但实际求解时间仍高于预期值,表明当前性能瓶颈可能源于硬件限制或处理器算力未充分调用,后续会将此类优化作为重点改进方向。
表1 迭代次数与求解时间
| 场景 | 平均迭代次数 | 平均求解时间/ms (i7-9750H) |
|---|---|---|
| 跟车 | 7 | 418 |
| 多障碍物躲避 | 4.5 | 529.5 |
| 变道 | 5 | 320 |
| 超车 | 2 | 215.5 |
将车辆位置姿态进行建模,其离散化状态空间方程为:
(1)
其中,(2)
(3)
对上述离散系统进行线性化,即在(xk, uk)处进行一阶Taylor展开:(4)
(5)
则车辆模型离散状态空间方程的矩阵A、B分别为:
(6)
(7)
该运动规划过程原始的最优化问题为
(8)
(1)避障约束函数推导
避障场景中,将主车近似为两个圆,障碍物考虑其速度,近似为椭圆,如图1所示。
图1 避障约束近似示意图
障碍物长轴:
(9)
障碍物短轴:
(10)
则避障约束中的矩阵P为
(11)
主车两个近似圆圆心的位置为:
(12)
(13)
则前后两个近似圆圆心处对主车状态求导如下:
(14)
同理,
(15)
分别将前后近似圆的位置坐标转换到障碍物obstacle坐标系下:
(16)
同理,
(17)
将式(8)中的第三四个不等式约束对状态量求导
(18)
则
(19)
(20)
将式(11)(14)(16)代入式(19), 式(11)(15)(17)代入式(20),即可求出避障约束对状态向量的一阶导。
(2) 避障约束函数线性化
在Xk处对上述
(21)
(22)
同理,
(23)
将线性化后的避障约束函数写为
(24)
(3) 避障约束转换为barrier function
为了将约束问题转化为无约束问题,将式(8)(24)中的避障约束不等式转换为障碍函数(barrier function)添加到目标函数中,前后两个近似圆对应的障碍函数分别为
(25)
上述barrier function对状态向量的一阶导为
(26)
将式(18)(19)(20)(24)代入式(26)可求出避障约束barrier function对状态向量的一阶导。
由于已经对避障约束函数进行了线性化,所以避障函数
(27)
所以避障约束barrier function对状态向量的二阶导为
(28)
将式(18)(19)(20)(24)代入式(28)中,即可求出barrier function的二阶导。
上述所求的barrier function的一二阶导会在使用iLQR方法进行迭代求解时用到。
本节的主要目的是将式(8)中的第一二个不等式约束转换为障碍函数形式作为目标函数的一部分,将约束问题转换为无约束问题。
由于控制约束本身就是线性的,因此无需进行线性化近似,直接转换为指数形式的障碍函数(barrier function)。首先将控制约束拆解为以下四个不等式:
(29)
再将上述四个控制约束函数转换为障碍函数:
(30)
控制约束障碍函数的一阶导为
(31)
其中,
(32)
将式(29)(32)代入式(31), 求出控制约束障碍函数的一阶导。
控制约束障碍函数的二阶导为
(33)
将式(29)(32)代入式(33)可得到控制约束障碍函数的二阶导,在后续使用iLQR方法迭代求导时会用到。
经过上述处理,该运动规划问题由2.1节的约束优化问题转换为式(34)所示的无约束优化问题。
(34)
其中M为该时刻主车周围障碍物总数,
根据LQR先验知识,代价函数J由末端代价和过程代价两部分组成,根据式(8)(34), 可将代价函数写为
(35)
when
(36)
when
(37)
令
(38)
在
(39)
则
(40)
其中
(41)
(42)
(43)
(44)
(45)
(46)
其中,
要求使得
(47)
求出
(48)
令
(49)
则
(50)
由于
(51)
由此推导出式(41)~式(46)中的
①当
②当
(52)
(53)
③当
在
(54)
(55)
结合式(51)与式(55), 可得:
(56)
(57)
(58)
Backward Pass过程计算出了
令
(59)
其中,
则根据第3部分的计算,
(60)
(61)
(62)
其中,
式(60)中的
(63)
当满足终止条件时,更新目标轨迹为新计算出的轨迹
Forward Pass算法流程总结如下:
为更好地贴近实车环境,本项目采用C++编程,将仿真场景与运动规划分为两个进程,使用ROS架构实现进程间的通信。同时为了配合控制模块,每帧都进行了规划起点的确定和轨迹拼接、规划与控制采用了不同的计算频率。项目整体架构如下:
图2 项目架构
四个测试场景的运行命令如下:
(1)Following:
roslaunch launch following_scene.launch
roslaunch launch cilqr_planner_following.launch
(2)Obstacles Avoidance:
roslaunch launch multi_obstacles_scene.launch
roslaunch launch cilqr_planner_multi_obstacles.launch
(3)Lane Change:
roslaunch launch lane_change_scene.launch
roslaunch launch cilqr_planner_lane_change.launch
(4)Overtake:
roslaunch launch overtake_scene.launch
roslaunch launch cilqr_planner_overtake.launch







