点击蓝字 关注我们
在过去的几年里,自动驾驶技术在全球范围内吸引了大量关注。其潜力不仅在于提升行车安全,而且还可以改变我们的出行方式和城市规划,提高交通运输效率。国际汽车工程师学会(SAE)根据不同自动驾驶程度(从人工驾驶到完全自动驾驶)提出了正式的自动驾驶等级分类系统,即L0到L5。
近几年来,自动驾驶技术飞速发展:2023年7月21日,比亚迪在深圳市获得全国首张高快速路段有条件自动驾驶(L3级)测试牌照;2023年11月,华为和赛力斯联合打造的"全景智慧旗舰SUV"问界M9成功获得L3级自动驾驶测试牌照;同月21日,交通运输部办公厅发布了《自动驾驶汽车运输安全服务指南(试行)》;2024年5月,特斯拉计划在中国推出"无人驾驶出租车"。
2024年5月27日上午,由中国汽车工程学会、国家智能网联汽车创新中心、中新天津生态城管委会联合主办的首届车路云一体化无人驾驶挑战赛实车集训在生态城正式启动,我们复旦大学CodeWisdom团队也组队赴天津生态城参加了本次集训及比赛[4]。
车路云一体化无人驾驶挑战赛开幕式
本次赛事依托生态城实际场地精心设计车路云一体化比赛场景,考察无人驾驶车辆在复杂交通环境中的应变能力和智能水平,激发参赛选手在数据感知、路径规控、复杂场景协同决策等算法方面的创新能力,推动车-路-云三端协同技术迭代,为智能网联汽车领域的技术跃迁与产业转型升级进行赋能。选手基于开源的自动驾驶系统(Automated Driving Systems,简称ADS)代码进行二次开发和算法创新,并将其应用在无人驾驶多功能车上。
赛事中所用的实车
在本次集训和比赛过程中,我们对ADS开发有了进一步的认识,同时总结了一些可供参考的ADS开发经验。接下来我们将站在开发者的角度为大家介绍本次大赛中所采用ADS的主要功能模块,分享ADS开发和调试的经验,在此基础上对ADS开发及调试中所存在的困难进行了分析和总结。
赛事举办方工程师讲解无人驾驶多功能车功能及算法部署流程
1. 自动驾驶系统主要功能模块
本次大赛中,ADS的功能模块主要包括感知模块、决策模块和控制模块,这也是当前主流自动驾驶系统所包含的基本模块。其中,感知模块 通过各种传感器收集和解析环境数据,为车辆提供详细的周围环境感知信息,这些感知信息将在融合后作为决策模块的输入;决策模块 在自动驾驶系统中负责确定车辆的最佳行驶路径,并制定相应的行动计划,确保车辆在复杂和动态的道路环境中能够稳定、安全地行驶;控制模块负责执行决策模块制定的行动策略,实际控制车辆的运动。如下图所示,感知模块、决策模块和控制模块三部分相互配合,使得车辆能够根据实时环境做出多样化的行动策略,实现车辆的自动驾驶。接下来将分别介绍三种功能模块。
典型自动驾驶系统框架图[1]
1.1 感知模块
感知模块通过各种传感器感知获取环境信息和自车状态,然后将这些信息进行融合,其结果输入到决策模块中。因此感知模块主要包含传感器信息收集和多传感器信息融合两部分。
感知模块利用多种不同类型的传感器来获取各种感知信息,主要的传感器及其功能如下表所示:
在传感器收集到各类感知数据后,感知模块使用感知融合算法对这些数据进行融合,充分利用不同传感器的优势,以弥补各自的局限性,从而获得更准确和全面的环境感知结果。目前广泛采用特征融合的方式,先对各传感器数据进行预处理,然后进行信息融合。这样既使得各种信息充分交互,又能保证各个传感器的主要特征信息得以保留。常见的融合算法有卡尔曼滤波器 及其变种、粒子滤波器以及权衡方法等。融合过程在传感器感知和规划决策之间扮演重要的桥梁角色,融合后得到的信息将作为决策模块的输入。此外,对车辆本身进行定位也依赖于融合后的信息以及惯导轮速计等其他传感器的感知信息,得到的定位信息也是决策模块所需的关键信息。
1.2 决策模块
决策模块是自动驾驶系统实现自主驾驶的核心组成部分。其主要任务是根据当前车辆的位置、目标位置和周围环境的信息计算出最佳路径和行为策略供车辆完成预定的行驶任务。
决策模块又可以细分为行为决策模块 和轨迹规划模块。这两个模块通过实时的协同工作,确保车辆能够根据感知到的新环境及时调整行进路径。决策模块的主要工作流程为:
-
获取地图数据生成参考线:获取车辆周围环境的地图数据,包括道路结构、车道线、交通标志等信息,这些信息通常由感知模块提供。根据地图数据计算出一条以车道中心线(部分全局路径规划的车道的中心线)为基准的光滑曲线的表达式。
-
做出行为决策:行为决策模块根据本车状态信息、障碍物信息及道路信息,以路网规则,避让规则和避免碰撞为目的,对本车当前的行驶行为 作出决策。如下图所示,行车状态一般包含以下几种状态。
决策状态转移关系图
-
进行局部路径规划:首先根据参考线建立坐标系,再将障碍物和道路边界投影到该坐标系下,然后根据决策模块的局部路径规划选择合适的目标点组,根据目标点组拟合出合适的局部路径。
-
生成行动信息:根据确定好的路径规划信息,计算出合适的行动信息。行动信息主要包括车辆定位信息(例如车辆当前的位置、速度、加速度)和车辆轨迹信息(例如目标轨迹点上的位置、速度、加速度)。二者均作为控制模块的输入,确保车辆按照预定的轨迹稳定运行。
1.3 控制模块
控制模块接收来自决策模块的高级指令 ,例如加速、减速、转向、制动等,然后将这些指令转化为车辆控制系统能够理解和执行的具体控制信号。
控制模块的主要任务流程为:首先,将车辆定位信息和车辆轨迹信息输入初始化模块,完成参数初始化,启用对应回调函数,实现定位轨迹信息更新 。然后,根据定位和轨迹信息 执行纵向控制模块和横向控制模块得到输出指令 。最后将纵向与横向控制计算得到的油门、刹车、方向盘转角等指令转换成所采用通信协议规定的数据指令(例如CAN指令,是一种现代汽车电子系统主流的通信协议)下发给底盘控制器 执 行。程序循环执行,直到发送终止命令。
在纵向控制和横向控制中,关键的是控制算法的选择。主流的控制算法包括无预测的反馈控制算法、带预测的反馈控制算法以及基于学习的控制算法三类。
-
无预测的反馈控制算法。这类算法通常采用显式控制理论 ,比如PID、LQR和SMC等算法。它们主要通过测量反馈信号(例如,位置、速度等)来实时调整控制器输出,以使系统响应符合预期。它们通常基于系统当前状态和目标之间的误差来调整控制行为 ,不考虑未来状态。这类算法相对比较简单,适用于需要快速响应和需求简单的情况,例如车辆稳定性控制、速度调节以及一些简单的轨迹跟踪任务,本次大赛即选用了PID算法作为纵向控制算法。
-
带预测的反馈控制算法,即模型预测控制(Model Predict Control,MPC)。MPC通过使用系统的预测模型,推导出未来一段时间状态的发展,并基于这些预测计算最优控制序列,做出控制决策。它不仅考虑当前状态和目标之间的误差,还考虑未来时间段内系统可能出现的状态,并优化控制器输出以最小化预期的性能指标。这类算法相对复杂,适用于需要长时间跟踪和优化复杂目标的任务,如曲线驾驶和环境动态变化的响应。
-
基于学习的控制算法。这类算法通过机器学习方法,如强化学习,从环境中收集数据并通过数据不断优化控制策略。它们不依赖于预定义的模型或精确的数学描述,而是通过与环境的交互学习最优的控制策略,如MFAC算法。这类算法适用于复杂、不确定性强或难以建模的环境和任务,但也有需要大量的训练数据、计算更为复杂和模型解释困难等局限性。
2. 自动驾驶系统开发及调试过程
与一般的软件开发相比,以车辆为部署和运行载体的ADS开发更加复杂,需要充分考虑系统的复杂性、安全性以及在多种不同场景中的通用性。一个典型的自动驾驶系统开发流程主要分为三个阶段:软件开发、离线仿真调试及实车调试。
2.1 软件开发
软件开发阶段是ADS开发过程中十分重要的阶段。在这个阶段,开发团队首先需要明确系统架构、功能需求和算法设计。当这些任务目标都明确后,紧接着可以上手编辑软件代码。软件开发阶段以离线方式进行开发与仿真调试,不涉及上车调试。
开发团队根据需求文档和实际场景编写代码,以实现自动驾驶系统的环境感知、路径规划、决策制定和车辆控制等模块。这些模块需要根据基本场景需求进行联合测试。为了提高开发效率,每个功能模块可能由不同的专业开发人员负责,不同模块甚至使用不同的编程语言开发。因此,必须提前确定好每个模块之间的通信方式和消息传递机制,以确保模块间的正常通信和集成。在本次比赛中,赛事举办方采用了定制化的ROS1作为ADS开发框架。ROS,全称为Robot Operating System(机器人操作系统),是一个灵活且功能强大的开源软件框架。ROS并非传统意义上的操作系统,而是一个在操作系统上运行的中间件框架,用于管理硬件抽象、设备驱动、库集成、通用功能实现以及消息传递等任务。ROS1提供了一个灵活的工具集,帮助开发人员管理多传感器数据融合、实时控制和功能模块间的信息通信。为了协调这些复杂任务,开发团队可以利用ROS1的节点(Nodes)来实现各个模块的独立开发和测试,然后通过ROS Master进行统一管理和集成,确保整体系统的稳定性和可靠性。此外,ROS1还提供了丰富的工具和库,例如可视化工具RViz,这些工具在开发过程中起到了关键作用,并将在后续的离线仿真调试和实车调试中得到进一步应用。
如图所示,我们在完成各个模块的开发后,将源代码和配置文件编译为ROS Package,通过运行ROS Package启动各个ROS节点,节点间通过通信共同完成任务需求。
基于ROS1开发自动驾驶系统模块的流程[2]
2.2 离线仿真调试
开发人员完成软件开发后,需要对各功能模块进行离线的仿真调试,以完成场景需求、改进算法、优化性能和发现潜在的代码缺陷。相较于实车调试,离线仿真调试的优势有:
-
提高安全性,减少安全隐患。自动驾驶系统的安全性与车上乘客的人身安全相关。开发人员不能保证每次迭代的自动驾驶算法始终是符合预期的,直接进行实车调试易造成的非预期行为的代价是极高的。在实际部署到实车之前,通过仿真环境中测试和调试代码有助于规避真实环境下测试所导致的意外和风险。
-
降低调试成本。实车调试需要将代码部署到配备实际感知设备的调试车上,这些设备包括激光雷达、毫米波雷达和摄像头,以从实际环境中获取感知信息。此外,还需要与算法适配的域控制器来作为算法运行的载体。搭建各种测试场景需要耗费大量资源和时间,每次测试新场景都需要实际搭建,导致调试成本高且效率低。相比之下,离线仿真调试只需在仿真软件中设计仿真场景,无需实际硬件即可进行调试。在仿真环境中,可以模拟出更复杂和现实中难以复现的场景,这对算法调试非常重要。这种灵活性是实车调试所不具备的。
-
快速迭代,提升调试效率。实车调试往往需要实际车辆和场景作为载体进行调试,同时需要将算法部署到实车的域控制器上,一次调试周期很长。而仿真调试仅需要以计算机或开发板作为载体,开发者可以在短时间内进行多次测试和调试,根据每次调试的反馈进行改进并再次调试,不断的迅速优化算法。
当然,由于仿真场景和实际场景始终存在差异,在开发过程中并不一定要进行离线仿真调试完全满足场景后再进行实车调试。如果等到ADS完全满足仿真场景后再进行实车调试,发现仍有可优化的地方则需要优化算法后再次返回仿真调试阶段进行调试,再进行实车调试,反而降低了调试的效率。开发团队一般在ADS在仿真环境中满足基本的场景需求后即可开始实车调试,采用离线仿真调试与实车调试相结合的方式可以迅速的针对场景中的不足进行算法优化,提升调试效率。
当下,自动驾驶仿真软件百花齐放,例如经典的开源的自动驾驶模拟器CARLA。CARLA依托虚幻引擎进行开发,由一个可扩展的客户端-服务器架构组成。服务器负责与模拟本身相关的所有事情:传感器渲染、物理计算、世界状态及其参与者的更新等等。客户端由一组客户端模块组成,这些模块控制场景中演员的逻辑并设置世界条件。CARLA 支持各种传感器(如激光雷达、摄像头、雷达等)和环境的灵活配置,以及车辆动力学模型和交通流模拟。CARLA还提供Python API,方便开发者进行场景控制和算法集成;在本次比赛中,比赛举办方使用了由德国 VIRES公司开发的商用自动驾驶仿真平台VTD(Virtual Test Drive),它专为模拟复杂城市和公路驾驶场景而设计。VTD提供了高度可定制的环境、全面的传感器模拟和精确的车辆动力学模型,支持实时物理仿真和集成开发环境。开发人员可以根据实际需要选择合适的自动驾驶仿真平台进行离线仿真调试。
2.3 实车调试
我们在前文中已经提到仿真场景和实际场景始终存在差异。在仿真场景中,ADS中的感知信息来源于仿真软件,是由开发人员控制的。而在实际场景中,感知信息完全来源于感知模块中感知设备的信息采集输入,此信息是从实际场景中获取的。而实际场景中影响ADS决策和控制的因素很多,无法做到全部人为控制或仿真。同时,要确保ADS在各种实际场景中的安全性和可靠性,就必须要进行实车测试和调试,即使需要较高的成本。
在实车调试中,开发人员需要搭建实际测试场景,将ADS部署在被测车的域控上,运行各个模块以完成场景,记录测试过程中遇到的问题和不足,针对这些问题和不足进行优化改进。如果是基于ROS开发的ADS,可以用ROS提供的工具将传感器数据、主题消息和系统状态等信息记录到一个称为"bag"的文件中,这一过程被称为"录包"。这些文件随后用于分析、重放和调试,例如用前文提到过的可视化工具RViz进行重放,这一过程被称为"播包"。开发人员通过不断循环实车运行、录包、播包和优化算法的流程不断完善ADS功能,直至满足所有的场景需求。有时,开发人员需要在流程中同时进行离线仿真调试,优化之前的仿真场景,减少实车调试的频次,将离线仿真调试和实车调试相结合,提升调试效率。
2.4 开发及调试场景示例
接下我们将以比赛中的一个自动驾驶场景为例,介绍从开发到仿真和实车调试的完整流程。在比赛过程中,比赛方设置了道路尽头车辆自动掉头的场景,我们在进行离线仿真调试和实车调试的过程中发现,车辆不能自动掉头,往往行驶到离道路尽头很近的位置然后停止,不再有任何行动。仅通过肉眼观察我们不能找到问题的原因,因此我们在下一次实车调试过程中在域控制器执行录包指令,对本次掉头过程的轨迹信息进行录制。通过播包我们观察到,此过程中车辆有着明确的规划轨迹,但是由于掉头点离道路尽头过近,车辆执行掉头决策时由于障碍物阻拦已无法通过,因此停止。通过分析,我们认为ADS决策模块基于参考线执行了掉头的轨迹规划,但是由于参考线掉头点离道路尽头过近,掉头曲率过高,导致车辆无法正常通过。因此,我们决定对参考线类进行调整,让车在我们确定的新掉头点的位置触发掉头指令。我们又进行了一次实车调试,获取到道路和车道宽度信息以及新掉头点的位置信息。我们在决策代码中修改了参考线信息,同时将车道宽度和道路宽度验证阈值变大,减小参考线掉头位置的曲率,最终让车辆能够成功掉头,满足了掉头场景。在比赛过程中,这样离线调试和实车调试结合的例子还有许多。
总的来说,通过以上三个阶段,将软件开发和两种调试相结合,针对调试中的问题和不足不断对ADS进行优化,直至能够在实际场景中满足所有需求。
3. ADS开发困境之思
尽管当前ADS的实现路径与开发方法已经相对清晰,然而我们在开发过程中仍然遇到了一些阻碍。我们调研了一些ADS开发相关资料并结合自身开发经验,总结了现阶段主流ADS开发过程中普遍存在的问题,望与各位读者讨论:
1. 仿真与实车测试一致性问题。在ADS开发过程中,离线仿真调试的环境和场景与实车调试保持一致至关重要,这种一致性既包括场景的一致性也包括车辆行为的一致性。仿真环境如果缺乏对复杂道路环境的重建与模拟,就会导致自动驾驶算法在实车测试时的表现与仿真时大相径庭;如果相同的逻辑代码在仿真与实车的表现有所差异,则会导致BUG无法复现,使得仿真调试失去意义。这类仿真与实车测试一致性问题会导致不可避免地将时间投入在调试和验证的工作中,成为ADS开发中的关键阻碍。
2. 开源ADS框架文档与代码质量问题。ADS作为大型软件,又与汽车安全息息相关,其代码、文档质量水平必须采用更加严格的标准加以约束。在开源ADS调研中,我们发现某些平台代码没有彻底遵循现代软件工程的理念与思想,耦合度较高,且没有对应的开发设计文档。这将导致在后续调试过程中难以对错误根因进行快速定位,调试效率极低;由于代码不易阅读和修改,使得在此基础上进行二次开发的成本很高;此外代码的可读性较差也可能导致无法针对代码进行安全性审查工作。因此,ADS框架必须具备良好的扩展性和可维护性,并充分遵循软件开发规范和软件工程理论。
3. 开发工具链冗杂与代码调试困难问题 。汽车架构一直在持续演化,由此带来了复杂多变的硬件环境,这给ADS开发带来很多挑战。其中,开发工具链冗杂与代码调试困难一直是ADS工程师头上的两朵不大不小的乌云。目前ADS开源的工具,包括仿真工具,编译环境,运行环境随着智能驾驶域控硬件的不同而千变万化,这些工具的版本管理、启动、协作目前仍然极大依赖人工,尚缺乏一个集成的IDE环境将它们有效收纳;而工具链的混乱、仿真和实车的不一致、IDE的缺少则共同导致了代码调试的困难:当出现了一个BUG,我们无法快速了解它究竟属于仿真环境的问题、工具链中工具的版本或其自身的问题还是代码的问题。这无疑会大大增加开发人员的调试难度。这一问题也是ADS开发必须翻越的一座高峰。
4. 总结
本文结合我们参加首届车路云一体化无人驾驶挑战赛的比赛经历,聚焦于自动驾驶系统(ADS)的开发过程,首先介绍了ADS中三个主要的功能模块及其特征。然后分别介绍了主流ADS开发流程中的三个关键阶段,最后我们根据调研资料和自身开发经验总结了现阶段主流ADS开发过程中普遍存在的一些问题。本次分析较为浅薄,初衷是总结本次大赛的开发经验,并为不熟悉ADS开发的读者提供一个入门的参考,恳请各位读者进行批评指正。
本文主要引用与参考:
- 自动驾驶系统架构
https://cloudpods.csdn.net/65781258b8e5f01e1e449d60.html
- ROS与自动驾驶系统开发介绍
https://blog.csdn.net/haobbnuanmm/article/details/86513891
- 2023最新自动驾驶车辆控制全面综述!(状态估计/轨迹控制/框架应用等)
https://cloud.tencent.com/developer/article/2318016
- 首届车路云一体化无人驾驶挑战赛实车集训在生态城启动
https://baijiahao.baidu.com/s?id=1800293222882334745
作者:章文卓、胡焜、孙家正、陈其才
编辑:李佳庚
审核:孙家正、彭鑫