Создайте ведущий сценарий программно

В этом примере показано, как сгенерировать основную истину для синтетических данных о датчике и алгоритмов отслеживания. Это также показывает, как обновить положения агента в разомкнутом контуре и симуляциях с обратной связью. Наконец, это показывает, как использовать ведущий сценарий, чтобы выполнить координатное преобразование и включить их в видимый с большого расстояния график.

В этом примере вы программно создаете ведущий сценарий из командной строки MATLAB®. В качестве альтернативы можно создать сценарии в интерактивном режиме при помощи приложения Driving Scenario Designer. Для примера смотрите, Создают Ведущий Сценарий В интерактивном режиме и Генерируют Синтетические Данные о Датчике.

Введение

Одна из целей ведущего сценария состоит в том, чтобы сгенерировать тесты "основной истины" для использования с алгоритмами обнаружения и отслеживания датчика, используемыми на определенном транспортном средстве.

Эта основная истина обычно задается в глобальной системе координат; но, потому что датчики обычно монтируются на движущемся транспортном средстве, эти данные должны быть преобразованы в систему координат, которая перемещается наряду с транспортным средством. Ведущий сценарий упрощает это преобразование автоматически, позволяя вам задать дороги и траектории объектов в глобальных координатах и обеспечивает инструменты, чтобы преобразовать и визуализировать эту информацию в системе координат любого агента в сценарии.

Преобразуйте информацию о положении в систему координат агента

drivingScenario состоит из модели дорог и подвижных объектов, названных агентами. Можно использовать агентов для пешеходов модели, парковочные часы, пожарные гидранты и другие объекты в рамках сценария. Агенты состоят из кубоидов с длиной, шириной, высотой и радарным поперечным сечением (RCS). Агент расположен и ориентирован об одной точке в центре ее нижней поверхности.

Специальный вид агента, который перемещается в колеса, является транспортным средством, которое расположено и ориентировано на землю непосредственно ниже центра задней оси, которая является более естественным центром вращения.

Все агенты (включая транспортные средства) могут быть помещены куда угодно в рамках сценария путем определения их соответствующего PositionКренТангаж, Yaw, Velocity, и AngularVelocity свойства.

Вот пример сценария, состоящего из двух транспортных средств на расстоянии в 10 метров и управляющего к источнику со скоростью 3 и 4 метров в секунду, соответственно:

scenario = drivingScenario;
v1 = vehicle(scenario,'ClassID',1','Position',[6 0 0],'Velocity',[-3 0 0],'Yaw',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 0 0]
              Velocity: [-3 0 0]
                   Yaw: 180
                 Pitch: 0
                  Roll: 0
       AngularVelocity: [0 0 0]
                Length: 4.7000
                 Width: 1.8000
                Height: 1.4000
                  Mesh: [1x1 extendedObjectMesh]
            RCSPattern: [2x2 double]
      RCSAzimuthAngles: [-180 180]
    RCSElevationAngles: [-90 90]

v2 = vehicle(scenario,'ClassID',1,'Position',[0 10 0],'Velocity',[0 -4 0],'Yaw',-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 0 0]
                Length: 4.7000
                 Width: 1.8000
                Height: 1.4000
                  Mesh: [1x1 extendedObjectMesh]
            RCSPattern: [2x2 double]
      RCSAzimuthAngles: [-180 180]
    RCSElevationAngles: [-90 90]

Чтобы визуализировать сценарий, вызовите plot функция на нем:

plot(scenario);
set(gcf,'Name','Scenario Plot')
xlim([-20 20]);
ylim([-20 20]);

Если все агенты в сценарии были созданы, можно смотреть информацию о положении всех агентов в координатах сценария путем осмотра PositionКренТангаж, Yaw, Velocity, и AngularVelocity свойства каждого агента, или можно получить всех их в удобной структуре путем вызова actorPoses функция на сценарии:

ap = actorPoses(scenario)
ap = 

  2x1 struct array with fields:

    ActorID
    Position
    Velocity
    Roll
    Pitch
    Yaw
    AngularVelocity

Чтобы получить информацию о положении всех других объектов (или цели) замеченный определенным агентом в его собственной системе координат, можно вызвать targetPoses функция на самом агенте:

v2TargetPoses = targetPoses(v2)
v2TargetPoses = 

  struct with fields:

            ActorID: 1
            ClassID: 1
           Position: [10 6.0000 0]
           Velocity: [-4 -3.0000 0]
               Roll: 0
              Pitch: 0
                Yaw: -90.0000
    AngularVelocity: [0 0 0]

Мы можем качественно подтвердить относительное размещение транспортного средства путем добавления графика преследования для транспортного средства. По умолчанию график преследования отображает проективный вид в перспективе от фиксированного расстояния позади транспортного средства.

Здесь мы показываем перспективу, замеченную только позади второго (красного) транспортного средства. Целевые положения, замеченные вторым транспортным средством, показывают, что местоположение другого транспортного средства (в синем) составляет 6 м вперед и 10 м слева от второго транспортного средства. Мы видим это качественно в графике преследования:

chasePlot(v2)
set(gcf,'Name','Chase Plot')

Обычно все графики, сопоставленные с ведущим сценарием, обновляются в ходе симуляции при вызове advance функция. Если вы обновляете свойство положения другого агента вручную, можно вызвать updatePlots видеть результаты сразу:

v1.Yaw = 135;
updatePlots(scenario);

Контуры Конверт-Роуд к системе координат агента

Ведущий сценарий может также использоваться, чтобы получить контуры дорог, заданных в сценарии.

Здесь мы используем простую овальную дорожку, описанную в Размещениях Дефайн-Роуд Программно, который покрывает область примерно 200 метров длиной и 100 метров шириной и чьи кривые имеют угол крена девяти градусов:

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    0  -50  -50  -50  -50
       0   0 .45 .45 .45 .45 .45  0   0 .45 .45  .45  .45  .45    0    0]';
bankAngles = ...
    [  0   0   9   9   9   9   9  0   0   9   9    9    9    9    0    0];

road(scenario, roadCenters, bankAngles, 'lanes', lanespec(2));
plot(scenario);

Чтобы получить линии, которые задают границы дороги, используйте roadBoundaries функция на ведущем сценарии. Это возвращает массив ячеек, который содержит дорожные границы (показанный в графике сценария выше как чистые черные линии).

rb = roadBoundaries(scenario)
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')
axis equal

Можно использовать roadBoundaries функция на агенте, чтобы получить дорожные контуры в координатах агента. Чтобы сделать это, просто передайте агента в качестве первого аргумента вместо сценария.

Чтобы видеть это, добавьте "автомобиль, оборудованный датчиком" и поместите его в дорожку:

egoCar = vehicle(scenario,'ClassID',1,'Position',[80 -40 0.45],'Yaw',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')
axis equal
rb =

  1x2 cell array

    {258x3 double}    {258x3 double}

Задайте траекторию агента

Можно расположить и построить любого определенного агента вдоль предопределенного 3D пути.

Вот пример для двух транспортных средств, которые следуют за трассой на уровне 30 м/с и 50 м/с соответственно, каждым в ее собственном соответствующем маршруте. Мы возмещаем автомобили от центра дороги путем установки положения смещения наполовину ширина маршрута 2,7 метров, и, для окруженных валом угловых разделов дорожки, половина вертикальной высоты на каждой стороне:

chasePlot(egoCar);
fastCar = vehicle(scenario,'ClassID',1);

d = 2.7/2;
h = .45/2;
roadOffset = [ 0  0  0  0  d  0  0  0  0  0  0 -d  0  0  0  0
              -d -d -d -d  0  d  d  d  d  d  d  0 -d -d -d -d
               0  0  h  h  h  h  h  0  0  h  h  h  h  h  0  0]';

rWayPoints = roadCenters + roadOffset;
lWayPoints = roadCenters - roadOffset;

% loop around the track four times
rWayPoints = [repmat(rWayPoints(1:end-1,:),5,1); rWayPoints(1,:)];
lWayPoints = [repmat(lWayPoints(1:end-1,:),5,1); lWayPoints(1,:)];

trajectory(egoCar,rWayPoints(:,:), 30);
trajectory(fastCar,lWayPoints(:,:), 50);

Усовершенствуйте симуляцию

Агенты, которые следуют за траекторией, обновляются путем вызова advance на ведущем сценарии. Когда advance называется, каждый агент, который следует за траекторией, продвинется, и соответствующие графики будут обновлены. Только агенты, которые задали траектории на самом деле, обновляются. Это так, можно обеспечить собственную логику, в то время как симуляция запускается.

SampleTime свойство в сценарии управляет интервалом времени между обновлениями. По умолчанию это - 10 миллисекунд, но можно задать его с произвольным разрешением:

scenario.SampleTime = 0.02
scenario = 

  drivingScenario with properties:

        SampleTime: 0.0200
          StopTime: Inf
    SimulationTime: 0
         IsRunning: 1
            Actors: [1x2 driving.scenario.Vehicle]

Можно запустить симуляцию путем вызова advance в условном выражении некоторое время цикла и помещающих команд, чтобы смотреть или изменить сценарий в теле цикла.

Цикл с условием продолжения автоматически завершит работу, когда траектория для любого транспортного средства закончится или дополнительный StopTime был достигнут.

scenario.StopTime = 4;
while advance(scenario)
  pause(0.001)
end

Запишите сценарий

Как удобство, когда траектории всех агентов известны заранее, можно вызвать record функция на сценарии, чтобы возвратить структуру, которая содержит информацию о положении каждого агента в каждый такт.

Например, можно смотреть информацию о положении каждого агента для первых 100 миллисекунд симуляции и смотреть пятую записанную выборку:

close all

scenario.StopTime = 0.100;
poseRecord = record(scenario)

r = poseRecord(5)
r.ActorPoses(1)
r.ActorPoses(2)
poseRecord = 

  1x5 struct array with fields:

    SimulationTime
    ActorPoses


r = 

  struct with fields:

    SimulationTime: 0.0800
        ActorPoses: [2x1 struct]


ans = 

  struct with fields:

            ActorID: 1
           Position: [2.4000 -51.3502 0]
           Velocity: [30.0000 -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]

Слияние нескольких представлений с графиком "Бердз Ай"

При отладке симуляции можно хотеть сообщить о данных "об основной истине" в видимом с большого расстояния графике определенного агента, одновременно просматривая графики, сгенерированные сценарием. Для этого можно сначала создать фигуру с осями, помещенными в пользовательское расположение:

close all;
hFigure = figure;
hFigure.Position(3) = 900;

hPanel1 = uipanel(hFigure,'Units','Normalized','Position',[0 1/4 1/2 3/4],'Title','Scenario Plot');
hPanel2 = uipanel(hFigure,'Units','Normalized','Position',[0 0 1/2 1/4],'Title','Chase Plot');
hPanel3 = uipanel(hFigure,'Units','Normalized','Position',[1/2 0 1/2 1],'Title','Bird''s-Eye Plot');

hAxes1 = axes('Parent',hPanel1);
hAxes2 = axes('Parent',hPanel2);
hAxes3 = axes('Parent',hPanel3);

Если вам задали оси, вы задаете их через Parent свойство при создании графиков:

% assign scenario plot to first axes and add indicators for ActorIDs 1 and 2
plot(scenario, 'Parent', hAxes1,'ActorIndicators',[1 2]);

% assign chase plot to second axes
chasePlot(egoCar, 'Parent', hAxes2);

% assign bird's-eye plot to third axes
egoCarBEP = birdsEyePlot('Parent',hAxes3,'XLimits',[-200 200],'YLimits',[-240 240]);
fastTrackPlotter = trackPlotter(egoCarBEP,'MarkerEdgeColor','red','DisplayName','target','VelocityScaling',.5);
egoTrackPlotter = trackPlotter(egoCarBEP,'MarkerEdgeColor','blue','DisplayName','ego','VelocityScaling',.5);
egoLanePlotter = laneBoundaryPlotter(egoCarBEP);
plotTrack(egoTrackPlotter, [0 0]);
egoOutlinePlotter = outlinePlotter(egoCarBEP);

Теперь можно перезапустить симуляцию и запустить ее к завершению, на этот раз извлекая информацию о местонахождении целевого автомобиля через targetPoses и отобразите его в видимом с большого расстояния графике. Точно так же можно также вызвать roadBoundaries и targetOutlines непосредственно от автомобиля, оборудованного датчиком, чтобы извлечь дорожные контуры и основы агентов. Видимый с большого расстояния график способен к отображению результатов этих функций непосредственно:

restart(scenario)
scenario.StopTime = Inf;

while advance(scenario)
    t = targetPoses(egoCar);
    plotTrack(fastTrackPlotter, t.Position, t.Velocity);
    rbs = roadBoundaries(egoCar);
    plotLaneBoundary(egoLanePlotter, rbs);
    [position, yaw, length, width, originOffset, color] = targetOutlines(egoCar);
    plotOutline(egoOutlinePlotter, position, yaw, length, width, 'OriginOffset', originOffset, 'Color', color);
end

Следующие шаги

Этот пример показал, как сгенерировать и визуализировать основную истину для синтетических данных о датчике и алгоритмов отслеживания с помощью drivingScenario объект. Чтобы симулировать, визуализируйте, или измените этот ведущий сценарий в интерактивной среде, попытайтесь импортировать drivingScenario объект в приложение Driving Scenario Designer:

drivingScenarioDesigner(scenario)

Дополнительная информация

Для получения дополнительной информации о том, как задать агентов и дороги, смотрите, Создают Траектории Агента и Транспортного средства Программно и Размещения Дефайн-Роуд Программно.

Для более всестороннего примера о том, как использовать видимый с большого расстояния график с обнаружениями и дорожками, смотрите, Визуализируют Покрытие Датчика, Обнаружения и Дорожки.

Для примеров, которые используют ведущий сценарий, чтобы помочь в генерации синтетических данных, смотрите Радарные Обнаружения Датчика Модели, Обнаружения Датчика Видения Модели и Fusion Датчика Используя Синтетические Данные о Радаре и Видении.

Смотрите также

Приложения

Объекты

Функции

Похожие темы