描述基于车道线方程的曲率计算-转载其他博主

目录

前言

一、利用三次多项式曲线对车道线建模

二、三次多项式系数的物理释义

三、MATLAB代码



前言

        车道线检测和识别是自动驾驶汽车前端环境感知的组成部分,检测结果为后端的规划和决策板块提供重要的信息参考,LDW(车道偏离预警)、LKA(车道保持辅助)、ACC(自适应巡航控制)等功能模块都依赖于连续稳定的车道线检测。
        如下图1(来源于网络,侵删)所示,智能汽车首先利用摄像头采集到视觉图像,然后通过二值化等数学处理,最后可以提取结构化道路下的清晰车道线。

图1 基于视觉图像的车道线提取

        车道线检测结果在向后端规控板块进行数据流传递的过程中,若直接将检测到的车道线用若干密集散点进行输出,一方面会增加系统的运算成本,另一方面也会导致检测结果失真。
        因此,可以通过建立车道线函数模型,该模型的待定系数根据本周期的检测结果散点进行函数拟合得到。如此一来,车道线检测结果只需向后端传递较少的几个函数模型的参数,后端接收到参数再通过函数模型还原为车道线。
        三次多项式曲线拟合车道中心线线不仅拟合精度较高,拟合结果的几个待定系数也具有一定的物理属性。

一、利用三次多项式曲线对车道线建模

        关于车道线函数模型,首先需要基于本车建立车体坐标系,坐标系原点设为车辆质心。如下图2所示为利用MATLAB的自动驾驶工具箱函数生成的一条模拟路段,蓝车为主车,其余车辆为交通车。

图2 同向三车道弯道场景

        左右侧车道线的数学模型可以利用三次多项式进行描述(MATLAB的自动驾驶工具箱库函数提供了三次方车道边界模型函数,cubicLaneBoudary),如下式所示:

fcsd

 式中,ai和bi 分别表示左侧车道线和右侧车道线的待定系数。

        为了求解式上式的待定系数,可以基于蓝车所在的中间车道的双侧车道线离散点,利用MATLAB的poliyfit函数进行多项式拟合,拟合结果如下所示:

系数

a0a1a2a3b0b1b2b3

数值

1.6752

0.1101

-0.016

5.14e-5

-1.964

0.1139

-0.017

6.5e-5

        为验证拟合结果的有效性,我们将左右侧车道线的待定系数拟合结果代入上式,绘制三次多项式曲线,结果如下图3的蓝色虚线所示。可以看出,利用三次多项式曲线拟合车道线能达到较高的拟合精度,拟合结果令人满意。

图3 利用三次多项曲线拟合车道线

        进一步的,考虑到左右侧车道线均能用三次多项式曲线进行拟合,易知车道中心线也可以用三次多项式进行描述。我们设车道中心线的三次函数曲线及一阶导、二阶导如下式所示,并计算x=0处的各阶导数值,得到:

二、三次多项式系数的物理释义

        对于零阶导,即原三次函数在起点x=0处的函数值为系数c0,代表截距,由于此时蓝车质心位置为坐标原点,且刚好位于车道中心线附近,故此时截取较小;

        对于一阶导,其导函数在起点x=0处的函数值为系数c1,代表在起点处的斜率,根据斜率定义可知当斜率值较小时,斜率值约等于切线与x轴的夹角 ,即车身相对于车道中心线的航向角:

        对于二阶导,其导函数在起点x=0处的函数值为2c2 ,由于一阶导数值远小于1,故车道中心线处的曲率可近似处理为:

         对于三阶导,其数值可粗略视为曲率变化率。

        综上,利用三次多项式曲线拟合车道线或车道中心线,不仅降低数据传输量,保证数据高保真,而且其系数的物理意义明确,在一定误差范围内可以根据系数直接计算参考线的截距、航向角和曲率,是一种既有理论支撑又便于工程实践应用的车道线模型。值得注意的是,某些资料将三次多项式函数曲线的三阶导粗略视为车道中心线的曲率变化率,此物理量可以用于进行横向轨迹跟踪控制,感兴趣的读者可以参考资料了解。


三、MATLAB代码


   
   
  1. clc
  2. clear
  3. close all
  4. %% 构建道路场景
  5. % 场景初始化
  6. scenario = drivingScenario; % 初始化场景
  7. scenario.SampleTime = 0.1; % 采样时间
  8. % 道路中心坐标
  9. roadCenters = [ 0 0 0; 2 0 0; 4 0 0 ; 30 -15 0; 60 -40 0];
  10. % 建立道路
  11. marking = [laneMarking( 'Solid') ...
  12. laneMarking( 'Dashed') laneMarking( 'Dashed') laneMarking( 'Solid')]; % 分界线线型
  13. laneSpecification = lanespec( 3, 'Marking', marking); % 道路规范
  14. road(scenario, roadCenters, 'Lanes', laneSpecification); % 生成道路
  15. % 获得道路边界,先把边界点位置重新整理次序
  16. rdbdy = roadBoundaries(scenario);
  17. rdbdy = rdbdy{ 1, 1}( 1: end -1,:);
  18. rdbdy = [rdbdy( 3: end,:); rdbdy( 1: 2,:)];
  19. rdbdy( 1, 3) = 0;
  20. %% 构建车辆信息
  21. % 分别三条车道的中心线坐标,以生成车辆航迹点
  22. ptNums = size(rdbdy, 1);
  23. for j = 1:ptNums/ 2
  24. rightBdyPt = rdbdy( j,:);
  25. leftBdyPt = rdbdy(ptNums- j+ 1,:);
  26. leftWaypoints( j,:) = leftBdyPt + (rightBdyPt - leftBdyPt)* 1/ 6;
  27. centerWaypoints( j,:) = leftBdyPt + (rightBdyPt - leftBdyPt)* 3/ 6;
  28. rightWaypoints( j,:) = leftBdyPt + (rightBdyPt - leftBdyPt)* 5/ 6;
  29. leftLaneLine( j,:) = leftBdyPt + (rightBdyPt - leftBdyPt)* 1/ 3;
  30. rightLaneLine( j,:) = leftBdyPt + (rightBdyPt - leftBdyPt)* 2/ 3;
  31. end
  32. % 本车信息
  33. ego.vehicle = [];
  34. ego.waypoints = centerWaypoints;
  35. ego.pos = ego.waypoints( 1,:);
  36. ego.speed = 15;
  37. % 1号交通车信息
  38. obs = struct;
  39. obs( 1).vehicle = [];
  40. obs( 1).waypoints = leftWaypoints( 30: end,:);
  41. obs( 1).pos = obs( 1).waypoints( 1,:);
  42. obs( 1).speed = 0.001;
  43. % 2号交通车信息
  44. obs( 2).vehicle = [];
  45. obs( 2).waypoints = centerWaypoints( 15: end,:);
  46. obs( 2).pos = obs( 2).waypoints( 1,:);
  47. obs( 2).speed = 10;
  48. % 2号交通车信息
  49. obs( 3).vehicle = [];
  50. obs( 3).waypoints = rightWaypoints( 10: end,:);
  51. obs( 3).pos = obs( 3).waypoints( 1,:);
  52. obs( 3).speed = 8;
  53. %% 在场景增加车辆
  54. % 根据自车信息增加车辆
  55. ego.vehicle = vehicle(scenario, 'Position',ego.pos, 'PlotColor', 'b');
  56. trajectory(ego.vehicle, ego.waypoints,ego.speed);
  57. % 根据交通车信息增加车辆
  58. obs( 1).vehicle = vehicle(scenario, 'Position',obs( 1).pos, 'PlotColor', 'k');
  59. trajectory(obs( 1).vehicle, obs( 1).waypoints,obs( 1).speed);
  60. obs( 2).vehicle = vehicle(scenario, 'Position',obs( 2).pos, 'PlotColor', 'g');
  61. trajectory(obs( 2).vehicle, obs( 2).waypoints,obs( 2).speed);
  62. obs( 3).vehicle = vehicle(scenario, 'Position',obs( 3).pos, 'PlotColor', 'g');
  63. trajectory(obs( 3).vehicle, obs( 3).waypoints,obs( 3).speed);
  64. %% 启动仿真
  65. plot(scenario)
  66. tjty = [];
  67. step = 1;
  68. while advance(scenario)
  69. pause( 0.05)
  70. tjty(step).time = scenario.SimulationTime;
  71. tjty(step).pos = scenario.Actors( 1, 3).Position( 1: 2);
  72. step = step + 1;
  73. end
  74. grid off
  75. axis off
  76. xlim([ -5, 70])
  77. ylim([ -50, 10])
  78. hold on
  79. %% 利用三次多项式对车道线进行拟合
  80. % 拟合得到双侧车道线和车道中心线的三次多项式系数
  81. poly_left = polyfit(leftLaneLine(:, 1),leftLaneLine(:, 2), 3);
  82. f_left = polyval(poly_left,leftLaneLine(:, 1));
  83. poly_right = polyfit(rightLaneLine(:, 1),rightLaneLine(:, 2), 3);
  84. f_right = polyval(poly_right,rightLaneLine(:, 1));
  85. poly_center = polyfit(centerWaypoints(:, 1),centerWaypoints(:, 2), 3);
  86. f_center = polyval(poly_center,centerWaypoints(:, 1));
  87. % 画拟合结果图
  88. plot(leftLaneLine(:, 1),f_left, 'b--')
  89. plot(rightLaneLine(:, 1),f_right, 'b--')
  90. plot(centerWaypoints(:, 1),f_center, 'b', 'linewidth', 2)

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
计算流体力学(Computational Fluid Dynamics,简称CFD)是一种通过数值方法解决流体力学问题的工程学科。对于流体力学方程的数值求解,基于控制体积法的Navier-Stokes方程是其中最基本的方程。 Navier-Stokes方程描述流体力学中运动的基本方程,包括质量守恒方程、动量守恒方程和能量守恒方程。它是由质量守恒方程和牛顿运动方程得到的偏微分方程组。 质量守恒方程描述了流体的质量在空间和时间上的守恒,它的数学形式是连续性方程。动量守恒方程描述了流体中各部分之间动量的传递,它包括流体的加速度、压力、粘性力和体积力的影响。能量守恒方程描述了流体的能量在空间和时间上的守恒,它包括内能、压力和粘性导热的影响。 计算流体力学控制方程是指在求解CFD问题时所采用的各种数值方法所得到的方程组。这些方程组包括控制体积方程(基于质量守恒方程)、动量方程和能量方程计算流体力学控制方程的求解方法包括有限差分法、有限元法和有限体积法等。其中有限体积法是目前应用最为广泛的方法。有限体积法将计算区域划分为许多小的控制体积,对每个控制体积应用质量守恒方程、动量方程和能量方程,得到离散的代数方程。然后通过迭代计算,求解出流体流动的数值解。 总之,计算流体力学控制方程是基于Navier-Stokes方程的数值方法,在求解流体力学问题中起到关键作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值