这个例子展示了如何为合成传感器数据和跟踪算法生成地面真相。它还展示了如何在开环和闭环模拟中更新演员姿势。最后,它展示了如何使用驾驶场景来执行坐标转换,并将它们合并到鸟瞰图中。
在本例中,您将从MATLAB®命令行以编程方式创建驾驶场景。方法以交互方式创建场景驾驶场景设计示例请参见交互式创建驾驶场景并生成合成传感器数据.
驾驶场景的目标之一是生成“地面真相”测试用例,用于特定车辆上使用的传感器检测和跟踪算法。
这个基本真理通常在全局坐标系中定义;但是,由于传感器通常安装在移动的车辆上,因此需要将这些数据转换为随车辆移动的参考框架。驾驶场景自动促进了这种转换,允许您在全局坐标中指定道路和物体的轨迹,并提供了在场景中任何参与者的参考框架中转换和可视化此信息的工具。
一个drivingScenario
包括道路模型和可移动物体,称为演员。您可以使用角色来建模场景中的行人、停车计时器、消防栓和其他对象。actor由具有长、宽、高和雷达截面(RCS)的长方体组成。一个actor的位置和方向是围绕其底面中心的一个点。
一种特殊的在轮子上运动的物体是汽车,它的位置和方向位于后轴中心正下方的地面上,后轴中心是一个更自然的旋转中心。
通过指定各自的角色,所有角色(包括工具)都可以放置在场景中的任何位置位置
,卷
,球场
,偏航
,速度
,AngularVelocity
属性。
下面是一个场景的例子,由两辆相距10米的车辆组成,分别以每秒3米和4米的速度向原点行驶:
scenario = drivingScenario;V1 =车辆(场景,“ClassID”1 ',“位置”,[6 0 0],“速度”,[-3 0 0],“偏航”, 180)
v1 = Vehicle with properties: FrontOverhang: 0.9000 RearOverhang: 1 Wheelbase: 2.8000 EntryTime: 0 ExitTime: Inf ActorID: 1 ClassID: 1 Name: "" PlotColor: [0 0.4470 0.7410] Position: [6 00] Velocity: [-3 000] Yaw: 180 Pitch: 0 Roll: 0 AngularVelocity: [0 000] Length: 4.7000 Width: 1.8000 Height: 1.4000 Mesh: [1x1 extendedObjectMesh] rcspatn: [2x2 double] RCSAzimuthAngles: [-180 180] RCSElevationAngles: [-90 90]
V2 =车辆(场景,“ClassID”, 1“位置”,[0 10 0],“速度”,[0 -4 0],“偏航”, -90)
v2 = Vehicle with properties: FrontOverhang: 0.9000 RearOverhang: 1 Wheelbase: 2.8000 EntryTime: 0 ExitTime: Inf ActorID: 2 ClassID: 1 Name: "" PlotColor: [0.8500 0.3250 0.0980] Position: [0 10 0] Velocity: [0 -4 0] Yaw: -90 Pitch: 0 Roll: 0 AngularVelocity: [0 000] Length: 4.7000 Width: 1.8000 Height: 1.4000 Mesh: [1x1 extendedObjectMesh] rcspatn: [2x2 double] RCSAzimuthAngles: [-180 180] RCSElevationAngles: [-90 90]
为了可视化一个场景,调用情节
它的功能:
情节(场景);集(gcf,“名字”,“场景情节”) xlim([-20 20]);ylim (20 [-20]);
创建了场景中的所有参与者之后,您可以通过检查场景坐标中所有参与者的姿势信息位置
,卷
,球场
,偏航
,速度
,AngularVelocity
属性,或者您可以通过调用actorPoses
场景功能:
ap =演员姿势(场景)
ap = 2x1结构数组,包含字段:ActorID位置速度滚摇俯仰偏航角速度
要获得特定参与者在其自己的参考系中所看到的所有其他对象(或目标)的姿态信息,可以调用targetPoses
在actor本身上的函数:
v2targetpositions = targetpositions (v2)
v2targetpose = struct with fields: ActorID: 1 ClassID: 1 Position: [10 6.0000 0] Velocity: [-4 -3.0000 0] Roll: 0 Pitch: 0偏航:-90.0000 AngularVelocity: [0 000]
我们可以通过添加车辆的追逐图来定性地确定相对的车辆位置。默认情况下,追逐图显示的是从车辆后面固定距离的投影视角。
这里我们展示了第二辆车(红色)后面的视角。第二辆车看到的目标姿态显示另一辆车(蓝色部分)的位置在第二辆车前方6米,左侧10米。我们可以在追逐情节中看到这一点:
chasePlot (v2)组(gcf,“名字”,“追逐情节”)
通常,与驾驶场景相关的所有图都在模拟过程中更新推进
函数。如果手动更新另一个参与者的位置属性,则可以调用updatePlots
立即看到结果:
v1。偏航= 135;updatePlots(场景);
驾驶场景还可以用于检索场景中定义的道路边界。
在这里,我们使用简单的椭圆轨道描述以编程方式定义道路布局它的面积长约200米,宽约100米,弧度为9度:
scenario = drivingScenario;roadCenters =...[0 40 49 50 100 50 49 40 -40 -49 -50 -100 -50 -49 -40 0 -50 -50 -50 -50 0 50 50 50 50 50 50 50 0 -50 -50 -50 00 00 .45 .45 .45 .45 .45 .45 .45 .45 .45 .45 .45 00 0];bankAngles =...[0 0 9 9 9 9 9 9 9 0 0 9 9 9 9 9 9 0 0];道路(场景,道路中心,银行角度,“道”lanespec (2));情节(场景);
方法获取定义道路边界的线roadBoundaries
用于驾驶场景。它返回一个包含道路边界的单元格数组(在上面的场景图中显示为黑色实线)。
rb =道路边界(场景)
Rb = 1x2 cell array {258x3 double} {258x3 double}
在上面的例子中,有两个道路边界(外部边界和内部边界)。你可以自己绘制如下图:
figure outerBoundary = rb{1};innerBoundary = rb{2};plot3 (innerBoundary (: 1) innerBoundary (:, 2), innerBoundary (:, 3),“r”,...outerBoundary (: 1), outerBoundary (:, 2), outerBoundary (:, 3),‘g’)轴平等的
您可以使用roadBoundaries
函数在参与者上获取参与者坐标中的道路边界。要做到这一点,只需将参与者作为第一个参数传递,而不是场景。
要看到这一点,添加一个“自我车辆”并将其放置在轨道上:
egoCar =车辆(场景,“ClassID”, 1“位置”,[80 -40 0.45],“偏航”, 30);
接下来,调用roadBoundaries
功能的车辆和绘图它之前。它将相对于车辆的坐标进行渲染:
figure rb = roadBoundaries(egoCar) outerBoundary = rb{1};innerBoundary = rb{2};plot3 (innerBoundary (: 1) innerBoundary (:, 2), innerBoundary (:, 3),“r”,...outerBoundary (: 1), outerBoundary (:, 2), outerBoundary (:, 3),‘g’)轴平等的
Rb = 1x2 cell array {258x3 double} {258x3 double}
您可以沿着预定义的三维路径定位和绘制任何特定的参与者。
这里有一个例子,两辆车分别以30米/秒和50米/秒的速度在赛道上行驶,每辆车都在自己的车道上。我们通过将偏移位置设置为车道宽度的一半,即2.7米,并将轨道倾斜角度部分设置为两侧垂直高度的一半,从而将汽车从道路中心偏移:
chasePlot (egoCar);fastCar =车辆(场景,“ClassID”1);D = 2.7/2;H = .45/2;roadOffset = [0 0 0 0 0 d 0 0 0 0 d 0 0 0 0 -d -d -d 0 d d d d d d d 0 0 h h h h h 0 0 h h h h h h h h h 0 0 h h h h h h 0 0 0]';rWayPoints = roadCenters + roadOffset;lWayPoints = roadCenters - roadOffset;绕轨道绕四圈rWayPoints = [repmat(rWayPoints(1:end-1,:),5,1);: rWayPoints (1)];lWayPoints = [repmat(lWayPoints(1:end-1,:),5,1);: lWayPoints (1)];smoothTrajectory (egoCar rWayPoints (:,:), 30);smoothTrajectory (fastCar lWayPoints (:,:), 50);
遵循轨迹的参与者通过调用来更新推进
关于驾驶场景。当推进
时,每个遵循轨迹的参与者将向前移动,并且相应的情节将被更新。只有定义了轨迹的参与者才会进行更新。这样,您就可以在模拟运行时提供自己的逻辑。
的SampleTime
属性控制更新之间的时间间隔。默认值是10毫秒,但你可以用任意分辨率指定它:
场景。SampleTime = 0.02
scene = drivingScenario with properties: SampleTime: 0.0200 StopTime: Inf SimulationTime: 0 IsRunning: 1 Actors: [1x2 driving.scenario. properties]车辆]障碍物:[0x0驾驶。场景。停车场:[0x0 driving.scenario.ParkingLot]
您可以通过调用运行模拟推进
在while循环的条件中,并在循环体中放置命令来检查或修改场景。
当任何飞行器的轨迹完成或可选时,while循环将自动终止StopTime
已经到达。
场景。StopTime= 4;而推进(场景)暂停(0.001)结束
为方便起见,当所有行动者的轨迹预先已知时,您可以调用记录
函数返回一个结构,该结构包含每个参与者在每个时间步的姿势信息。
例如,您可以检查模拟的前100毫秒中每个演员的姿势信息,并检查第五个记录的样本:
关闭所有场景。StopTime= 0.100; poseRecord = record(scenario) r = poseRecord(5) r.ActorPoses(1) r.ActorPoses(2)
poseRecord = 1x5 struct array with fields: SimulationTime actorpose r = struct with fields: SimulationTime: 0.0800 actorpose: [2x1 struct] ans = struct with fields: ActorID: 1 Position: [2.4000 -51.3502 0] Velocity: [30.000 -0.0038 0] Roll: 0 Pitch: 0 Yaw: -0.0073 AngularVelocity: [0 0 -0.0823] ans = struct with fields: ActorID: 2 Position: [4.0000 -48.6504 0] Velocity: [50.0000 -0.0105 0] Roll: 0 Pitch: 0 Yaw: -0.0120 AngularVelocity: [0 0 -0.1235]
在调试模拟时,您可能希望报告特定参与者的鸟瞰图中的“ground truth”数据,同时查看由场景生成的图。要做到这一点,你可以首先创建一个轴放置在自定义排列的图形:
关闭所有;hFigure =图;hFigure.Position(3) = 900;hPanel1 = uipanel(hFigure,“单位”,“归一化”,“位置”,[0 1/4 /2 / 3/4],“标题”,“场景情节”);hPanel2 = uipanel(hFigure,“单位”,“归一化”,“位置”,[0 0 1/2 /4],“标题”,“追逐情节”);hPanel3 = uipanel(hFigure,“单位”,“归一化”,“位置”,[1/2 0 1/2 1],“标题”,“鸟”眼中的阴谋”);hAxes1 =坐标轴(“父”, hPanel1);hAxes2 =坐标轴(“父”, hPanel2);hAxes3 =坐标轴(“父”, hPanel3);
定义了坐标轴之后,可以通过父
属性在创建图时:
将场景图分配到第一个轴,并为actorid 1和2添加指标情节(场景中,“父”hAxes1,“ActorIndicators”[1, 2]);%将追逐图分配到第二个轴chasePlot (egoCar“父”, hAxes2);%将鸟瞰图分配到第三轴egoCarBEP = birdsEyePlot(“父”hAxes3,“XLimits”(-200 200),“YLimits”240年[-240]);fastTrackPlotter = trackPlotter(egoCarBEP,“MarkerEdgeColor”,“红色”,“DisplayName的”,“目标”,“VelocityScaling”5);egoTrackPlotter = trackPlotter(egoCarBEP,“MarkerEdgeColor”,“蓝”,“DisplayName的”,“自我”,“VelocityScaling”5);egoLanePlotter = laneBoundaryPlotter(egoCarBEP);plotTrack(egoTrackPlotter, [0 0]);egoOutlinePlotter = outlinePlotter(egoCarBEP);
现在可以重新启动模拟并运行它直至完成,这一次提取目标汽车的位置信息targetPoses
在鸟瞰图中显示出来。类似地,您也可以调用roadBoundaries
而且targetOutlines
直接从自我车辆中提取出道路边界和行动者的轮廓。鸟瞰图能够直接显示这些函数的结果:
重启(场景)的场景。StopTime = Inf;而advance(scenario) t = targetpose (egoCar);plotTrack(fastTrackPlotter, t.Position, t.Velocity);rbs = roadBoundaries(egoCar);plotLaneBoundary (egoLanePlotter,苏格兰皇家银行);[位置,偏航,长度,宽度,originOffset, color] = targetOutlines(egoCar);(egoOutlinePlotter,位置,偏航,长度,宽度,“OriginOffset”originOffset,“颜色”、颜色);结束
这个例子展示了如何生成和可视化地面真相的合成传感器数据和跟踪算法使用drivingScenario
对象。要在交互式环境中模拟、可视化或修改此驾驶场景,请尝试导入drivingScenario
对象到驾驶场景设计器应用程序中:
drivingScenarioDesigner(场景)
有关如何定义参与者和道路的详细信息,请参见以编程方式创建角色和车辆轨迹而且以编程方式定义道路布局.
有关如何使用带有探测和跟踪的鸟瞰图的更深入示例,请参见可视化传感器覆盖,检测和跟踪.
有关使用驾驶场景来协助生成合成数据的示例,请参见雷达传感器探测模型,模型视觉传感器检测,基于合成雷达和视觉数据的传感器融合.