Сгенерируйте информацию о маршруте из записанных данных

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

Обзор

Можно использовать виртуальные ведущие сценарии, чтобы воссоздать действительные сценарии из записанных данных о транспортном средстве. Генерация дорожных сетей является важным этапом в создании виртуального ведущего сценария. Используя drivingScenario возразите или приложение Driving Scenario Designer, можно импортировать дорожную сеть из OpenStreetMap®, который обеспечивает данные о карте SD. Однако такие дорожные сети испытывают недостаток в подробной информации о маршруте, которая важна для навигации в автономной системе. В этом примере вы создаете виртуальный ведущий сценарий путем генерации drivingScenario объект с помощью данных записал от теста (эго) файл OpenStreetMap и транспортное средство. Файл OpenStreetMap описывает информацию о дорожной сети в области, где данные были зарегистрированы.

Записанные данные включают:

  • Данные о GPS — Содержат широту, долготу и высоту автомобиля, оборудованного датчиком в каждой метке времени.

  • Видеоданные — файл MP4, зарегистрированный от монокулярной камеры по ходу движения, смонтированной на автомобиле, оборудованном датчиком.

  • Отследите данные — Содержит обнаруженные дорожки маршрута в каждой метке времени траектории эго в системе координат локальной координаты автомобиля, оборудованного датчиком.

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

  1. Исследуйте записанные данные о транспортном средстве.

  2. Импортируйте дорожную сеть OpenStreetMap в ведущий сценарий.

  3. Добавьте данные об автомобиле, оборудованном датчиком от GPS до ведущего сценария.

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

  5. Создайте технические требования маршрута.

  6. Сгенерируйте новый сценарий.

  7. Симулируйте и визуализируйте сгенерированный сценарий.

Эта схема показывает, как вы используете записанные данные в этом примере. Обратите внимание на то, что вы создаете ведущий сценарий из данных о GPS и файл OpenStreetMap.

Исследуйте записанные данные о транспортном средстве

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

Загрузка данных

Задайте область значений меток времени для данных.

startTimeStamp = 1461634426377778;
endTimeStamp = 1461634462779242;

Загрузите данные о GPS, отследите обнаружения и данные изображения из их соответствующих файлов MAT для выбранной области значений меток времени.

[gpsData,laneDetections,cameraImages] = helperLoadFile(startTimeStamp,endTimeStamp);

Визуализируйте траекторию эго

Извлеките широту, долготу, время и высотные значения из данных о GPS.

count = size(gpsData,2);
time = arrayfun(@(x) x.timeStamp,gpsData)';
lat = arrayfun(@(x) x.latitude,gpsData)';
lon = arrayfun(@(x) x.longitude,gpsData)';
alt = arrayfun(@(x) x.altitude,gpsData)';

Визуализируйте записанные данные о GPS с помощью geoplayer объект.

zoomLevel = 17;
player = geoplayer(lat(1),lon(1),zoomLevel);
plotRoute(player,lat,lon);
for i = 1:length(lat)
    plotPosition(player,lat(i),lon(i));
end

Визуализируйте обнаружения маршрута

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

currentFigure = figure(Name="Lane Detections");
hPlot = axes(uipanel(currentFigure));
bep = birdsEyePlot(XLim=[0 60],YLim=[-35 35],Parent=hPlot);
bepPlotters.LaneLeft = laneBoundaryPlotter(bep, ...
    DisplayName="Left lane marking", ...
    Color="red",LineStyle="-");

bepPlotters.LaneRight = laneBoundaryPlotter(bep, ...
    DisplayName="Right lane marking", ...
    Color="red",LineStyle="-");
olPlotter = outlinePlotter(bep);
for i= 1:size(laneDetections,2)
    plotOutline(olPlotter,[0 0],0,4.7,1.8,OriginOffset=[-1.35 0],Color=[0 0.447 0.741]);

    % Draw left lane boundary
    egoLaneLeft = cast([laneDetections(i).left.curvature,laneDetections(i).left.headingAngle, ...
        laneDetections(i).left.offset],"single");
    bepPlotters.LaneLeft.LineStyle = drivingUtils.getLaneTypeBEV(laneDetections(i).left.boundaryType);
    lb = parabolicLaneBoundary(egoLaneLeft);
    plotLaneBoundary(bepPlotters.LaneLeft,lb);

    % Draw right lane boundary
    egoLaneRight = cast([laneDetections(i).right.curvature,laneDetections(i).right.headingAngle, ...
        laneDetections(i).right.offset],"single");
    bepPlotters.LaneRight.LineStyle = drivingUtils.getLaneTypeBEV(laneDetections(i).right.boundaryType);
    rb = parabolicLaneBoundary(egoLaneRight);
    plotLaneBoundary(bepPlotters.LaneRight,rb);
    pause(0.01);
end

Импортируйте дорожную сеть OpenStreetMap в управление сценарием

Файл дорожной сети, используемый, чтобы сгенерировать виртуальный сценарий, был загружен с OpenStreetMap (OSM) веб-сайт. OpenStreetMap обеспечивает доступ к глобальным, полученным толпой данным о карте. Данные лицензируются под Открытыми Данными палата общин Открытая Лицензия Базы данных (ODbL). Для получения дополнительной информации о ODbL смотрите Открытые Данные палата общин Открытый сайт Лицензии Базы данных. Используйте данные о широте и долготе из GPS, чтобы выбрать файл OpenStreetMap, содержащий соответствующую информацию о дорожной сети. Используйте roadNetwork функционируйте, чтобы импортировать эту информацию о дорожной сети в ведущий сценарий.

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

scenario = drivingScenario;
% Fetch SD map according to GPS coordinates
url = ['https://api.openstreetmap.org/api/0.6/map?bbox=' ...
    num2str(min(lon)) ',' num2str(min(lat)) ',' ...
    num2str(max(lon)) ',' num2str(max(lat))];
fileName = websave("drive_map.osm",url,weboptions(ContentType="xml"));
roadNetwork(scenario,"OpenStreetMap",fileName);

Добавьте данные об автомобиле, оборудованном датчиком от GPS до импортированного сценария

Данные о положении автомобиля, оборудованного датчиком собраны от датчика GPS и сохранены как файл MAT. Этот файл задает широту, долготу, высоту в метрах, скорость в метрах в секунду и значения метки времени в формате метки времени POSIX Unix для каждого экземпляра данных, зарегистрированного для автомобиля, оборудованного датчиком.

Вычислите траекторию waypoints автомобиля, оборудованного датчиком от записанных координат GPS. Используйте latlon2local функционируйте, чтобы преобразовать необработанные координаты GPS в локальные Декартовы координаты "восточный север". Преобразованные координаты задают траекторию waypoints автомобиля, оборудованного датчиком.

origin = [(max(lat) + min(lat))/2,(min(lon) + max(lon))/2,0];
waypoints = zeros(count,3);
% Convert lat and lon to local coordinates to create waypoints for ego vehicle
[waypoints(:,1),waypoints(:,2)] = latlon2local(lat,lon,alt,origin);
% Filter to remove noise
window = round(count*0.2);
waypoints = smoothdata(waypoints,"rloess",window);

Вычислите скорость автомобиль, оборудованный датчиком.

distancediff = diff(waypoints);
timediff = cast(diff(time),"double")./1000000;
egoSpeed = zeros(count,1);
egoSpeed(2:end) = vecnorm(distancediff./timediff,2,2);
egoSpeed(1) = egoSpeed(2);

Добавьте автомобиль, оборудованный датчиком в импортированный сценарий.

egoVehicle = vehicle(scenario,ClassID=1,Mesh=driving.scenario.carMesh);
trajectory(egoVehicle,waypoints,egoSpeed); 

Идентифицируйте дороги, пересекающие путь к эго

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

[roads,roadData] = helperGetRoadsInEgoPath(scenario,waypoints);

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

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

Создайте технические требования маршрута

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

  • numOfLanes — Количество маршрутов на дороге. Пример принимает три маршрута, которые имеют те же ширины маршрута.

  • startingLane — ID маршрута для первого waypoint автомобиля, оборудованного датчиком. По умолчанию этот пример устанавливает это значение к 3.

Найдите маршрут эго

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

numOfLanes = 3;
startingLane = 3;
% Fetch ego pose from imported scenario
[yaw,pitch,roll] = drivingUtils.getEgoPose(scenario,waypoints);
egoPose = struct("yaw",yaw,"pitch",pitch,"roll",roll);
egoLanePosition = helperGetEgoLanePosition(laneDetections,egoPose,waypoints,startingLane,numOfLanes);

Создайте технические требования маршрута из обнаружений маршрута

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

Опционально, можно также задать эти аргументы name-value:

  • showAllLanes — Установите этот параметр на true создать маркировки маршрута для всех маршрутов. В противном случае установите этот параметр на false. Когда установлено в false, функция создает маркировки маршрута только для маршрута, в котором зарегистрированы данные, который является маршрутом автомобиля, оборудованного датчиком. По умолчанию функция помощника устанавливает этот параметр на true. При создании маркировок маршрута неэго функция использует обнаружение дорожки лево-маршрута для всех маркировок маршрута между текущим обнаружением дорожки лево-маршрута и левым дорожным ребром. Функция использует обнаружение дорожки правильного маршрута для всех маркировок маршрута между текущим обнаружением дорожки правильного маршрута и правильным дорожным ребром.

  • RoadEdges — Задайте стили маркировки маршрута для левых и правых дорожных ребер, соответственно, как двухэлементный вектор из объектов маркировки маршрута. По умолчанию функция помощника применяет серьезные маркировки маршрута для обоих дорожных ребер.

helperCreateLaneSpecification функция возвращает структуру, которая хранит технические требования маршрута и идентификаторы для дорог.

% Lane marking styles for road edges
roadEdges = [laneMarking("Solid",Color="y") laneMarking("Solid")];
% Create lane markings for all lanes

% Create lane specifications
lanespecifications = helperCreateLaneSpecification(laneDetections,waypoints,egoPose,roads,numOfLanes, ...
    egoLanePosition,showAllLanes=true,RoadEdges=roadEdges);

Сгенерируйте сценарий

Создайте новый ведущий сценарий. Добавьте извлеченные дороги, технические требования маршрута, автомобиль, оборудованный датчиком и траекторию эго к сценарию.

newScenario = drivingScenario;

Добавьте дороги с их вычисленными техническими требованиями маршрута.

for i = 1:length(lanespecifications)
    roadId = lanespecifications{i}.RoadID;
    pos = arrayfun(@(x) x.ID == roadId,roadData);
    road(newScenario,roadData(pos).RoadCenters,"Lanes",lanespecifications{i}.specifications);
end

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

correction = 3.5;
waypoints = mathUtils.shiftPoints(waypoints,correction,1);
window = round(length(waypoints)*0.2);
waypoints = smoothdata(waypoints,"rloess",window);

Добавьте автомобиль, оборудованный датчиком и его waypoints.

egoVehicle = vehicle(newScenario, ...
    ClassID=1, ...
    Mesh=driving.scenario.carMesh, ...
    Length=2, ...
    Width=1);
trajectory(egoVehicle,[waypoints(:,1) waypoints(:,2) waypoints(:,3)],egoSpeed);

Симулируйте и визуализируйте сгенерированный сценарий

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

% Visualization
currentFigure = figure(Name="Generated Scenario and Ground Truth Camera Images",Position=[0 0 1400 600]);
movegui(currentFigure,"center");
% Add the chase plot
hCarViewPanel = uipanel(currentFigure,Position=[0.5 0 0.5 1],Title="Chase Plot");
hCarPlot = axes(hCarViewPanel);
chasePlot(egoVehicle,Parent=hCarPlot,ViewPitch=90,ViewHeight=120,ViewLocation=[0 0]);

% Add the top view of the generated scenario
hViewPanel = uipanel(currentFigure,Position=[0 0 0.5 1],Title="Camera View");
hPlot = axes(hViewPanel);
i = 1;
camerTime  = cast([cameraImages(:).timeStamp]' - gpsData(1).timeStamp,"double")/10^6;
while advance(newScenario)
    while i <= length(camerTime) && newScenario.SimulationTime >= camerTime(i)
        image(cameraImages(i).mov.cdata,Parent=hPlot);
        i = i + 1;
    end
    pause(0.001);
end

Похожие темы