随着车载芯片的升级、技术的更新迭代,可视化ADAS逐渐变成汽车的标配走入大家的生活中,为大家的驾车出行带来切实的便捷。那么你了解HMI端ADAS的实现过程吗?作为ADAS可视化系统的入门篇,就跟大家聊一聊目前较常见的低消耗的一种ADAS可视化实现方案。
ADAS显示场景中常见的显示元素有:障碍物、车道线、车道、导航线、路面标记、TT灯等,其中非常关键的两个显示元素是障碍物和车道线,对不了解ADAS的小伙伴来说,实现起来有一定的难度,本期我们就围绕这两个元素展开。
01
开始之前我们需要先明确ADAS的显示坐标系。ADAS的显示坐标系通常是以自车中心点或自车车尾中心点作为原点,自车正前方作为X轴正方向,自车右侧方向作为Y轴正方向(也有以自车左侧方向作为Y轴正方向的)。
描述障碍物显示的数据Struct_Obstacle通常有以下成员
► id --- 障碍物编号
► type --- 障碍物种类,如:汽车、卡车、单车、行人、防撞桶等
► pos_x --- 障碍物X轴方向坐标
► pos_y --- 障碍物Y轴方向坐标
► direction --- 障碍物方向
► color --- 障碍物颜色,通常用来表示碰撞风险等级,碰撞风险等级越高颜色越醒目
障碍物显示处理通常需要两个模块
► 数据处理模块
► 界面显示模块
由于实际场景中自车智驾系统检测到的周围的障碍物是动态变化的,所以障碍物数据通常是以动态数组vector转化的json字符串或protobuf整帧传输。数据处理模块对比接收到的前后两帧障碍物数据列表,后一帧数据列表中,
● 新出现的障碍物id对应的即为新出现的障碍物,需要在界面中新增显示出来;
● 消失的障碍物id对应的即为消失的障碍物,需要在界面中将其隐藏删除掉;
● 两帧数据列表中都存在的障碍物id对应的即为持续存在的障碍物,通常需要根据需求对其进行插值处理,以便在界面显示中顺滑地变化该障碍物的位置、角度等,避免闪烁跳变
(※关于插值:智驾系统通常每100ms发送一次障碍物数据,而界面的显示帧率通常仪表端为60FPS(即16.7ms刷新一次)、中控端为30ms(即33ms刷新一次),故而在智驾系统数据更新间隔内仪表端可插值5~6次,中控端可插值2~3次。根据需求按照实际的运行帧率进行插值即可。)
通过上述描述也可以看到,障碍物数据不能是单个障碍物单独发送,因为这样无法像上面那样在前后两个智驾系统发送周期中直观地判断各个障碍物的行为。
界面显示模块控制界面障碍物的动态显示、变化,根据数据处理模块传过来的数据,或动态地生成障碍物并显示、或动态地隐藏障碍物并销毁、或更新持续存在的障碍物显示状态。在当前的绝大多数ADAS项目中,障碍物通常由3D模型来显示,资源占用较高,动态生成、销毁障碍物可确保对系统资源的合理有效利用。
02
介绍完障碍物的实现方案,我们接着看下车道线的实现方案。
描述车道线显示的数据Struct_LaneLine通常有两种,
► 一种是连续的离散点数据,需要根据离散点动态生成相应的车道线模型并显示;
► 一种是三次函数(y=C3*x^3+C2*x^2+C1*x+C0)的四个系数,即C3、C2、C1、C0;
(※本文以第二种为例。)
此外其他的数据还有:
► id --- 车道线编号
► type --- 车道线种类,如:实线、虚线等
► color --- 车道线颜色
► pos_start/pos_end --- 起止位置等
与障碍物数据传输要求一样,自车智驾系统通常将当前检测到的车道线数据以动态数组vector转化的json字符串或protobuf整帧打包发送上来,便于后续的数据分析。
车道线显示处理通常也需要两个模块
► 车道线数据处理模块,分析前后两帧或几帧的车道线数据变化分析相应的场景并进行插值等数据处理;
► 车道线显示管理模块,接收车道线数据处理模块处理后的数据,经行相关车道线的显示、隐藏、变化
其中,车道线显示、隐藏、变化插值处理与障碍物类似,不同的是通常控制车道线模型显示隐藏即可,不需要销毁模型,原因是所有的车道线可以使用同一个车道线模型,模型面片数不多,且场景中车道线的数量也不会太多。该车道线模型是一个如下图的矩形长条
● 通过在Vertex Shader中根据输入的三次函数系数C3、C2、C1、C0、车道线宽度、长度等,相应的移动模型各顶点的位置,实现车道线长宽、弯曲的变化;
● 在Fragment Shader中根据需要输入实线、虚线、双实线等不同的贴图,变更片元颜色,实现车道线种类、颜色的变化;
(※该方法同样适用于车道、用三次函数(y=C3*x^3+C2*x^2+C1*x+C0)的四个系数描述的导航线。)
需要特别注意的是,在自车变道的瞬间,智驾系统传上来的车道线数据会有一次跳变。
以左变道为例,变道后原左侧车道线L变成了右侧车道线R,原来的右侧车道线数据变成了原来的左侧车道线(即变道后的右侧车道线)数据,车道线数据发生了一次跳变。如果不加以识别处理,会导致显示界面中的车道线都闪烁一下。
那么如何识别变道并应对变道时的车道线数据跳变?
变道场景的识别逻辑比较简单,
● 可以根据最后几帧的车道线数据中的C0(在界面显示中代表与自车Y轴方向的距离)值变化判断自车变道趋势(向左还是向右);
● 如果最后两帧数据同一车道线的C0变化超出一定范围(可以是半个车道宽度),可以判断为变道,结合前面的自车变道趋势即可确定是左变道还是右变道
关于应对在变道的场景下车道线数据的跳变,我们仍以左变道为例。
左变道场景中,变道后的右侧车道线R与变道前的左侧车道线L是同一条车道线,记住这一点,我们接下来就会用到。
其实方法很简单,在代码中对每根车道线都需要有容器(例如map<id,Struct_LaneLine>)来存储车道线数据,这些容器都有相应的车道线标记,根据车道线标记接收对应车道线数据。在判断出是左变道后,将原车道线标记为L的容器的标记变换为R,其他的容器也依次相应变换车道线标记,这样每个容器接受的还是之前同一根车道线的数据。界面中显示的车道线组件也需要类似地变换车道线标识,进而可以确保界面中显示的车道线接收的数据是连续的、不会出现跳变的情况。
03
介绍完障碍物、车道线这两个ADAS关键显示元素的实现方案,不知道您有没有感觉ADAS也没有想象中的那么难了。后续我们会持续推出根据离散点数据动态生成车道线、导引线、车道(包括匝道、十字路)模型的实现方案,欢迎关注我们,避免错过后面的精彩内容。