主要内容

履带间融合在汽车安全中的应用

这个例子展示了如何融合两辆车的履带,以提供比每辆车所能看到的更全面的环境估计。该示例演示了如何使用跟踪级fuser和对象跟踪数据格式。在本例中,您将使用自动驾驶工具箱™中的驾驶场景和视觉检测生成器、雷达工具箱™中的雷达数据生成器以及传感器融合和跟踪工具箱™中的跟踪和跟踪融合模型。

动机

汽车安全应用依赖于车载不同传感器系统的数据融合。单个车辆融合传感器检测要么使用集中跟踪器,要么采用更分散的方法,并融合由单个传感器产生的轨迹。除了车内数据融合,来自多辆车辆的数据融合还提供了其他好处,包括更好的覆盖范围、态势感知和安全性[1].这种车间传感器融合方法利用了传感器的多样性,并为每辆车提供了更好的覆盖,因为它使用了该地区其他车辆上的传感器更新的数据。政府和汽车制造商早就认识到,为了提高汽车安全性,有必要在车辆之间共享信息。例如,V2X协议和蜂窝通信链路正在开发中。

虽然多车传感器融合是有益的,但大多数车辆都需要满足一定的安全要求,即使只有内部传感器可用。因此,车辆很可能配备一个跟踪器,一个履带加热器,或两者。这些跟踪算法在单个车辆层面提供态势感知。因此,本例中所做的假设是,车辆通过广播履带和执行履带到履带融合来共享态势感知。

本例演示了融合两辆车辆履带的好处,以增强态势感知和安全性。本示例不模拟通信系统。相反,该示例假设通信系统提供了在两辆车之间传输轨道所需的带宽。

进行航迹架构

以下方框图描述两辆运载工具的主要功能,其中:

  • 车辆1号有两个传感器,每个传感器向本地车辆跟踪器提供检测。跟踪器使用来自本地传感器的检测来跟踪对象,并将这些本地轨迹输出到车辆轨迹热控器。

  • 2号车有一个传感器,这是一个跟踪雷达。跟踪雷达输出轨迹,并作为车辆2的本地跟踪器。来自跟踪雷达的航迹输入到车辆2上的车辆航迹融合器。

  • 每辆车上的履带熔断器将本地车辆履带与从另一辆车的履带熔断器接收的履带熔断。每次更新后,每辆车上的履带预热器都会广播其融合的履带,这些履带将传送到另一辆车上履带预热器的下一次更新中。

V2VFusion.png

在本例中,您使用的是trackerJPDA(传感器融合和跟踪工具箱)对象来定义车辆1跟踪器。

为车辆1创建跟踪器v1Tracker = trackerJPDA (“TrackerIndex”, 1“DeletionThreshold”(4 - 4),“AssignmentThreshold”, 100年正);%车辆1跟踪器posSelector = [1 0 0 0 0 0 0;0 0 1 0 0 0];

在此体系结构中,一辆车的融合履带将更新另一辆车上的融合履带。这些融合的轨道随后被广播回第一辆车。为了避免谣言传播,要小心从另一辆车的履带如何更新履带预热器。

考虑以下谣言传播的例子:在某个更新步骤,车辆1使用其内部传感器跟踪一个对象。然后,车辆1将目标轨道融合,并将其传输给车辆2,现在,车辆2将轨道与自己的轨道融合,并意识到目标。到目前为止,这正是履带融合的目标:利用车辆1的信息增强车辆2的态势感知能力。由于车辆2现在知道了该物体,它也开始广播轨道,可能是为了另一辆车辆的利益(在示例中没有显示)。

然而,车辆1现在从车辆2接收到关于只有车辆1实际跟踪的对象的轨迹信息。所以,飞行器1上的航迹融合器必须知道它从飞行器2上得到的物体的航迹实际上不包含任何由独立来源更新的新信息。要区分包含新信息的履带和只重复信息的履带,必须将车辆2定义为外部来源给一号车的轨道预热器。类似地,必须将车辆1定义为车辆2上的轨道融合器的外部源。此外,您只需要定义由曲目融合器根据来自内部源的信息更新的曲目为自我报告的.这样一来,每辆车的履带熔断器就会忽略履带在熔断器之间来回反弹而没有任何新信息的更新。

每个车辆的本地跟踪器相对于车辆参考框架(称为自我框架)跟踪对象。轨迹到轨迹的融合是在场景框架中完成的,这是全局级别的框架。助手egoToScenario功能将轨迹从自我框架转换到情景框架。同样地,函数scenarioToEgo将轨迹从场景框架转换到任何自我框架。两个转换都依赖于StateParameters财产的objectTrack(传感器融合和跟踪工具箱)对象。当trackFuser对象计算场景帧中的中心轨迹到任意帧中的本地轨迹的距离时,它使用StateParameters的局部轨迹来执行坐标转换。

实现前面所述trackFuser定义,定义以下源代码作为fuserSourceConfiguration(传感器融合和跟踪工具箱)对象。

为每辆车定义来源v1TrackerConfiguration = fuserSourceConfiguration (“SourceIndex”, 1“IsInternalSource”,真的,...% v1Tracker是v1Fuser内部的“CentralToLocalTransformFcn”@scenarioToEgo,“LocalToCentralTransformFcn”, @egoToScenario);%坐标变换v2FuserConfiguration = fuserSourceConfiguration (“SourceIndex”4“IsInternalSource”、假);% v2Fuser是v2Fuser的外部v1Sources = {v1TrackerConfiguration;v2FuserConfiguration};v2TrackerConfiguration = fuserSourceConfiguration (“SourceIndex”2,“IsInternalSource”,真的,...% v2Tracker是v2Fuser内部的“CentralToLocalTransformFcn”@scenarioToEgo,“LocalToCentralTransformFcn”, @egoToScenario);%坐标变换v1FuserConfiguration = fuserSourceConfiguration (“SourceIndex”,3,“IsInternalSource”、假);% v1Fuser是v2Fuser的外部v2Sources = {v2TrackerConfiguration;v1FuserConfiguration};

你现在可以定义每个车辆履带加热器作为trackFuser(传感器融合和跟踪工具箱)对象。

stateParams =结构(“帧”“矩形”“位置”(0 0 0),“速度”, 0 0 0);v1Fuser = trackFuser (“FuserIndex”,3,...“AssignmentThreshold”, 100年正无穷,...“MaxNumSources”2,“SourceConfigurations”v1Sources,...“StateFusion”“十字路口”“DeletionThreshold”3 [3],...“StateParameters”, stateParams);v2Fuser = trackFuser (“FuserIndex”4...“AssignmentThreshold”, 100年正无穷,...“MaxNumSources”2,“SourceConfigurations”v2Sources,“StateFusion”...“十字路口”“DeletionThreshold”3 [3],...“StateParameters”, stateParams);初始化以下变量fusedTracks1 = objectTrack.empty (0,1);fusedTracks2 = objectTrack.empty (0,1);wasFuser1Updated = false;wasFuser2Updated = false;

定义场景

下面的场景显示两辆汽车行驶在街道上。车辆1是前导车辆,配备两个前视传感器:一个近程雷达传感器和一个视觉传感器。2号车与1号车相距10米,装有远程雷达。街道的右边停着车辆。一个行人站在车辆之间。这个行人在X = 60米处显示为一个点。

由于2号车与1号车距离较近,2号车的大部分雷达传感器覆盖被1号车遮挡。因此,车辆2上的履带融合器所维护的大多数履带首先由车辆1广播的履带初始化。

创建driingscenario对象和两个车辆。[scenario, vehicle1, vehicle2] = createDrivingScenario;创建所有传感器[sensors, numSensors, attachdvehicle] = createSensors(场景);%创建显示[f, ploters] = createV2VDisplay(场景,传感器,附加车辆);

下面的追逐情节是从第二辆车的角度看的。箭头表示几乎完全被停放的车辆和第一辆车辆挡住的行人的位置。

TrackToTrackChasePlot.png

将每辆车定义为参与者、传感器、跟踪器和绘图仪的组合。v1 =结构(“演员”{vehicle1},“传感器”,{传感器(attachedVehicle = = 1)},“追踪”{v1Tracker},“DetPlotter”{plotters.veh1DetPlotter},“TrkPlotter”, {plotters.veh1TrkPlotter});v2 =结构(“演员”{vehicle2},“传感器”,{传感器(attachedVehicle = = 2)},“追踪”{{}},“DetPlotter”{{}},“TrkPlotter”, {plotters.veh2TrkPlotter});2号车没有发现或追踪器

运行仿真

下面的代码运行模拟。

运行= true;对于可重复的结果,设置随机数种子s =提高;Rng (2019) snaptimes = [0.5, 2.8, 4.4, 6.3, inf];照片=细胞(元素个数(snaptimes 1));i = 1;f.Visible =“上”运行&& ishhandle (f) time = scenario.SimulationTime;在车辆级别进行检测和跟踪[tracks1, wasTracker1Updated] = detectAndTrack (v1、时间posSelector);[tracks2, wasTracker2Updated] = detectAndTrack (v2、时间posSelector);%保留从以前的fuser更新的跟踪oldFusedTracks1 = fusedTracks1;oldFusedTracks2 = fusedTracks2;更新熔断器如果wasFuser2Updated tracksToFuse1 = [tracks1;oldFusedTracks2];如果isLocked(v1Fuser) || ~isempty(tracksToFuse1) [fusedTracks1,~,~,info1] = v1Fuser(tracksToFuse1,time);wasFuser1Updated = true;pos = getTrackPositions (fusedTracks1 posSelector);字符串id = ((fusedTracks1.TrackID) ');plotTrack (plotters.veh1FusePlotter、pos、ids);其他的wasFuser1Updated = false;fusedTracks1 = objectTrack.empty (0,1);结束其他的wasFuser1Updated = false;fusedTracks1 = objectTrack.empty (0,1);结束如果wasFuser1Updated tracksToFuse2 = [tracks2;oldFusedTracks1];如果isLocked(v2Fuser) || ~isempty(tracksToFuse2) [fusedTracks2,~,~,info2] = v2Fuser(tracksToFuse2,time);wasFuser2Updated = true;pos = getTrackPositions (fusedTracks2 posSelector);字符串id = ((fusedTracks2.TrackID) ');plotTrack (plotters.veh2FusePlotter、pos、ids);其他的wasFuser2Updated = false;fusedTracks2 = objectTrack.empty (0,1);结束其他的wasFuser2Updated = false;fusedTracks2 = objectTrack.empty (0,1);结束%更新显示updateV2VDisplay(绘图仪,场景,传感器,附加的车辆)前进场景一个时间步,如果场景完成则退出循环。运行=进步(场景);在指定时间捕获帧的图像。如果时间>= snaptimes(i) snaps{i} = taksnap (f);I = I + 1;结束结束

{

如图所示为场景结束时的场景和跟踪结果。本示例的后续部分将分析关键时刻的跟踪结果。

分析仿真开始时的跟踪

当模拟开始时,车辆1检测停在街道右侧的车辆。然后,车辆1跟踪器确认与停放车辆相关的轨迹。此时,车辆2的跟踪器检测和跟踪的唯一目标是车辆1,它就在它的前面。一旦车辆1轨道熔断器确认了轨道,它就广播它们,然后车辆2轨道熔断器将它们熔断。因此,车辆2在自己探测到这些车辆之前就会意识到它们的存在。

showsnap(四合扣,1)

{

路边行人跟踪分析

随着模拟的继续进行,车辆2也能够检测和跟踪停在旁边的车辆,并将它们与车辆1的履带融合。车辆2在模拟开始后大约4秒就能检测并跟踪行人,车辆2在模拟开始后大约4.4秒就能融合与行人相关的轨迹(见快照2)。然而,车辆2需要大约2秒才能通过自身的传感器检测并跟踪行人(见快照3)。提前2秒检测到街上的行人可以显著提高安全性。

showsnap(四合扣,2)

{

showsnap(四合扣,3)

{

避免谣言传播

当两辆车相互通信轨道时,它们会继续通过重复另一辆车通信的内容来通信它们不再检测到的物体的信息,这是有风险的。这种情况被称为谣言传播。

当车辆经过这些物体时,这些物体离开了他们的视野,与这些物体相关的融合履带就会被两个跟踪器丢弃(见快照4)。丢弃履带表明融合履带在两辆车之间来回广播,而不是用来传播谣言。

showsnap(断了,4)

{

重新启动驾驶场景,将参与者返回到初始位置。重启(场景);释放所有传感器对象,以便它们可以再次使用sensorIndex = 1:numSensors释放(sensors{sensorIndex});结束将随机种子返回到它以前的值rng (s)

总结

在本例中,您了解了履带间融合如何在汽车应用中增强态势感知并提高安全性。你知道如何设置trackFuser类来执行声道到声道融合以及如何将声源定义为内部或外部fuserSourceConfiguration对象。通过这样做,你可以避免谣言的传播,只保留被每辆车辆真正观察到的融合轨道。

参考文献

[1]杜莱萨米,B, T.施瓦茨,C.维勒。汽车安全应用的履带级融合算法。在2013年信号处理,图像处理和模式识别国际会议, 179 - 84年,2013年。https://doi.org/10.1109/ICSIPR.2013.6497983

支持功能

createDrivingScenario

中定义的驾驶场景驾驶场景设计师应用程序。

函数[scenario, egoVehicle, secondVehicle] = createDrivingScenario构造一个driingscenario对象场景= drivingScenario (“SampleTime”, 0.1);添加所有路段roadCenters = [50.8 0.5 0;253.4 - 1.5 0);roadWidth = 12;路(场景、roadCenters roadWidth);roadCenters = [100.7 -100.6 0;100.7 - 103.7 0);路(场景,roadCenters);roadCenters = [2011 -99.2 0;199.7 - 99.5 0);路(场景,roadCenters);添加自我载具egoVehicle =车辆(场景中,“ClassID”, 1“位置”, [65.1 -0.9 0],“PlotColor”, [0 0.7410 0.4470]);航路点= [71 -0.5 0;148.7 - -0.5 0);速度= 12;轨迹(egoVehicle、锚点、速度);添加第二辆车secondVehicle =车辆(场景中,“ClassID”, 1“位置”, [55.1 -0.9 0]);航路点= [61 -0.5 0;138.7 - -0.5 0);速度= 12;轨迹(secondVehicle、锚点、速度);加上停放的汽车车辆(场景中,“ClassID”, 1“位置”, [111.0 -3.6 0]);车辆(场景中,“ClassID”, 1“位置”, [140.6 -3.6 0]);车辆(场景中,“ClassID”, 1“位置”, [182.6 -3.6 0]);车辆(场景中,“ClassID”, 1“位置”, [211.3 -4.1 0]);%增加行人演员(场景中,“ClassID”4“长度”, 0.5,“宽度”, 0.5,...“高度”, 1.7,“位置”, [130.3 -2.7 0],“RCSPattern”[-8 -8;-8 -8]);%添加停放的卡车车辆(场景中,“ClassID”2,“长度”, 8.2,“宽度”, 2.5,...“高度”, 3.5,“位置”, [117.5 -3.5 0]);结束

createSensors

创建场景中使用的传感器,并列出它们与车辆的附件。

函数[sensors, numSensors, attachdvehicle] = createSensors(场景)% createSensors返回生成检测的所有传感器对象%单位用于createSensors和createDrivingScenario%距离/位置-米%速度-米/秒%角度-度% RCS模式- dBsm为每个传感器分配所有参与者的物理和雷达配置文件。概要文件= actorProfiles(场景);1号车的雷达报告发现集群传感器{1}= radarDataGenerator (“没有扫描”“SensorIndex”, 1“UpdateRate”10...“MountingLocation”, [3.7 0 0.2],“RangeLimits”, 50 [0],“FieldOfView”60, [5],...“RangeResolution”, 2.5,“AzimuthResolution”4...“配置文件”配置文件,“HasOcclusion”,真的,“HasFalseAlarms”假的,...“TargetReportFormat”“集群检测”);2号车的雷达发现了轨迹传感器{2}= radarDataGenerator (“没有扫描”“SensorIndex”2,“UpdateRate”10...“MountingLocation”, [3.7 0 0.2],“RangeLimits”120年[0],“FieldOfView”30 [5],...“RangeResolution”, 2.5,“AzimuthResolution”4...“配置文件”配置文件,“HasOcclusion”,真的,“HasFalseAlarms”假的,...“TargetReportFormat”“跟踪”“DeletionThreshold”3 [3]);车辆1号视觉传感器报告检测传感器{3}= visionDetectionGenerator (“SensorIndex”3,...“MaxRange”, 100,“SensorLocation”1.9 [0],“DetectorOutput”“只将对象”...“ActorProfiles”,概要文件);attachedVehicle = [1, 2, 1];numSensors =元素个数(传感器);结束

scenarioToEgo

执行从场景坐标到自我坐标的坐标转换。

trackInScenarioStateParameters定义了将它从场景坐标转换为自我坐标。

这种状态采用恒定速度模型[x;vx;y;vy;z;vz]。

函数trackInEgo = scenarioToEgo(trackInScenario) egoPosInScenario = trackInScenario. stateparameters.originposition;egoVelInScenario = trackInScenario.StateParameters.OriginVelocity;stateInScenario = trackInScenario.State;stateShift = [egoPosInScenario (1); egoVelInScenario (1); egoPosInScenario (2); egoVelInScenario (2); egoPosInScenario (3); egoVelInScenario (3)];stateInEgo = stateInScenario - statesshift;trackInEgo = objectTrack (“UpdateTime”, trackInScenario。UpdateTime,“状态”stateInEgo,“StateCovariance”, trackInScenario。StateCovariance,“StateParameters”, trackInScenario.StateParameters);结束

egoToScenario

执行从自我坐标到场景坐标的坐标转换。

trackInEgoStateParameters定义了将它从自我坐标转换为场景坐标。

这种状态采用恒定速度模型[x;vx;y;vy;z;vz]。

函数trackInScenario = egoToScenario(trackInEgo) egopoinscenario = trackInEgo. stateparameters . originposition;egoVelInScenario = trackInEgo.StateParameters.OriginVelocity;stateInScenario = trackInEgo.State;stateShift = [egoPosInScenario (1); egoVelInScenario (1); egoPosInScenario (2); egoVelInScenario (2); egoPosInScenario (3); egoVelInScenario (3)];stateInEgo = stateInScenario + statesshift;trackInScenario = objectTrack (“UpdateTime”, trackInEgo。UpdateTime,“状态”stateInEgo,“StateCovariance”, trackInEgo。StateCovariance,“StateParameters”, trackInEgo.StateParameters);结束

detectAndTrack

该函数用于从一辆车上的传感器收集所有检测结果,并用它们更新跟踪器。

代理是一个结构,它包含参与者信息和传感器、跟踪器和绘图器,用于绘制检测和车辆轨迹。

函数[追踪,wasTrackerUpdated] = detectAndTrack(代理,时间,posSelector)从车辆中创建检测提出了= targetPoses (agent.Actor);[检测,isValid] = vehicleDetections (agent.Actor.Position agent.Sensors,姿势、时间agent.DetPlotter);更新跟踪器以从报告检测的传感器获取跟踪。如果isValid agent.Tracker.StateParameters = struct(...“帧”“矩形”...“OriginPosition”agent.Actor.Position,...“OriginVelocity”, agent.Actor.Velocity);跟踪= agent.Tracker(检测、时间);tracksInScenario =跟踪;i = 1:numel(tracks) tracksInScenario(i) = egoToScenario(tracks(i));结束pos = getTrackPositions (tracksInScenario posSelector);plotTrack(agent.TrkPlotter,pos) wasTrackerUpdated = true;其他的跟踪= objectTrack.empty (0,1);wasTrackerUpdated = false;结束从跟踪传感器获得额外的跟踪。[sensorTracks, wasSensorTrackerUpdated] = vehicleTracks (agent.Actor agent.Sensors,姿势、时间agent.TrkPlotter);跟踪= vertcat(跟踪、sensorTracks);|| wasSensorTrackerUpdated;结束

vehicleDetections

收集车辆上所有返回检测的传感器的检测结果。

函数[objectDetections,isValid] = vehicleDetections(位置,传感器,姿势,时间,绘图器)numSensors = numel(传感器);objectDetections = {};isValidTime = false(1, numSensors);为每个传感器生成检测sensorIndex = 1:numSensors sensor = sensors{sensorIndex};如果isa(传感器,“visionDetectionGenerator”) | | ~ strcmpi(传感器。TargetReportFormat,“跟踪”) [objectDets, ~, sensorConfig] =传感器(姿势,时间);如果islogic (sensorConfig) isValidTime(sensorIndex) = sensorConfig;其他的isValidTime (sensorIndex) = sensorConfig.IsValidTime;结束= cellfun(@(d) setAtt(d), objectDets,“UniformOutput”、假);numObjects =元素个数(objectDets);objectDetections = [objectDetections;objectDets (1: numObjects)];% #好< AGROW >结束结束isValid = (isValidTime);%绘制检测如果numel(objectDetections)>0 detPos = cellfun(@(d)d. measurement (1:2), objectDetections,“UniformOutput”、假);detPos = cell2mat(detPos')' + position(1:2);plotDetection(绘图仪,detPos);结束结束函数d = setAtt (d)设置属性为结构d.ObjectAttributes =结构;只保留位置测量和移除速度。如果numel(d.Measurement)==6 d.Measurement = d.Measurement(1:3);d.MeasurementNoise = d.MeasurementNoise (1:3, 1:3);d.MeasurementParameters{1}。HasVelocity = false;结束结束

vehicleTracks

从报告车辆轨迹的传感器上收集所有轨迹。

函数[tracks,wasTrackerUpdated] = vehicleTracks(演员,传感器,姿势,时间,绘图仪)从车辆中创建检测numSensors =元素个数(传感器);跟踪= objectTrack.empty;isValidTime = false(1, numSensors);为每个传感器生成检测sensorIndex = 1:numSensors sensor = sensors{sensorIndex};如果isa(传感器,“radarDataGenerator”) & & strcmpi(传感器。TargetReportFormat,“跟踪”) [sensorTracks, ~, sensorConfig] =传感器(姿势,时间);如果islogic (sensorConfig) isValidTime(sensorIndex) = sensorConfig;其他的isValidTime (sensorIndex) = sensorConfig.IsValidTime;结束numObjects =元素个数(sensorTracks);跟踪=[跟踪;sensorTracks (1: numObjects)];% #好< AGROW >结束结束wasTrackerUpdated = (isValidTime);如果~ wasTrackerUpdated没有安装车辆跟踪传感器返回结束在履带状态参数中添加车辆位置和速度i = 1:numel(tracks) tracks(i). state参数。.StateParameters OriginPosition =歌曲(我)。OriginPosition + actor.Position ';跟踪.StateParameters(我)。.StateParameters OriginVelocity =歌曲(我)。OriginVelocity + actor.Velocity ';结束%的阴谋跟踪如果numel(tracks)>0 trPos = arrayfun(@(t)t. state ([1,3]), tracks,“UniformOutput”、假);trPos = cell2mat(trPos')' + actor.Position(1:2);plotTrack(绘图仪,trPos);结束结束
Baidu
map