В этом примере показано, как сгенерировать информацию о маршруте с помощью зарегистрированных данных. Этот рабочий процесс позволяет вам добавить технические требования маршрута в дорожную сеть, импортированную из данных о карте стандартного определения (SD) с помощью зарегистрированных данных из камеры и датчика GPS.
Можно использовать виртуальные ведущие сценарии, чтобы воссоздать действительные сценарии из записанных данных о транспортном средстве. Генерация дорожных сетей является важным этапом в создании виртуального ведущего сценария. Используя drivingScenario
возразите или приложение Driving Scenario Designer, можно импортировать дорожную сеть из OpenStreetMap®, который обеспечивает данные о карте SD. Однако такие дорожные сети испытывают недостаток в подробной информации о маршруте, которая важна для навигации в автономной системе. В этом примере вы создаете виртуальный ведущий сценарий путем генерации drivingScenario
объект с помощью данных записал от теста (эго) файл OpenStreetMap и транспортное средство. Файл OpenStreetMap описывает информацию о дорожной сети в области, где данные были зарегистрированы.
Записанные данные включают:
Данные о GPS — Содержат широту, долготу и высоту автомобиля, оборудованного датчиком в каждой метке времени.
Видеоданные — файл MP4, зарегистрированный от монокулярной камеры по ходу движения, смонтированной на автомобиле, оборудованном датчиком.
Отследите данные — Содержит обнаруженные дорожки маршрута в каждой метке времени траектории эго в системе координат локальной координаты автомобиля, оборудованного датчиком.
Чтобы создать технические требования маршрута и симулировать сценарий, выполните эти шаги:
Исследуйте записанные данные о транспортном средстве.
Импортируйте дорожную сеть OpenStreetMap в ведущий сценарий.
Добавьте данные об автомобиле, оборудованном датчиком от GPS до ведущего сценария.
Идентифицируйте дороги, на которых перемещается автомобиль, оборудованный датчиком.
Создайте технические требования маршрута.
Сгенерируйте новый сценарий.
Симулируйте и визуализируйте сгенерированный сценарий.
Эта схема показывает, как вы используете записанные данные в этом примере. Обратите внимание на то, что вы создаете ведущий сценарий из данных о 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 (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 и сохранены как файл 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