Этот пример показывает, как считать и визуализировать настройки маршрута для записанного ведущего маршрута от HD HERE Живая Карта (HERE HDLM) сервис. Эта визуализация может использоваться, чтобы проверить настройки маршрута, обнаруженные системой восприятия встроенного датчика, такие как монокулярная камера.
В этом примере вы изучаете, как получить доступ к плиточным слоям от сервиса HDLM и идентифицировать соответствующую топологию дорожного уровня и уровня маршрута, геометрию и атрибуты.
Чтобы считать данные, вы используете объект
. Использование HD HERE Живой Картографический сервис требует допустимых учетных данных HERE HDLM. Необходимо заключить отдельное соглашение с HERE в порядке получить доступ к сервисам HDLM и получить необходимые учетные данные (app_id и app_code) для использования Сервиса HERE.hereHDLMReader
Карты высокой четкости (HD) относятся к отображению сервисов, разработанных специально для автоматизированных ведущих приложений. Точная геометрия этих карт (с разрешением на максимум 1 см около экватора) делает их подходящими для автоматизированных ведущих рабочих процессов вне приложений планирования маршрута традиционных планов действий. Такие рабочие процессы включают верификацию уровня маршрута, локализацию и планирование пути. Этот пример показывает вам, как проверить производительность системы обнаружения маршрута с помощью информации об уровне маршрута от данных об отображении HD.
Точность данных об отображении HD включает свое использование в качестве источника наземных данных об истине для верификации встроенных систем восприятия датчика. Эта высокая точность включает более быструю и более точную верификацию существующих развернутых алгоритмов.
HD HERE Живая Карта (HERE HDLM) является облачным картографическим сервисом HD, разработанным HERE Technologies, чтобы поддержать высоко автоматизированное управление. Данные состоят из мозаичных слоев отображения, которые обеспечивают доступ к точной геометрии и устойчивым атрибутам дорожной сети. Слои сгруппированы в следующие модели:
Дорожная Модель Средней линии: Обеспечивает дорожную топологию (заданный как узлы и ссылки в графике), геометрия формы и другие атрибуты дорожного уровня.
Модель Маршрута HD: Обеспечивает топологию маршрута (как группы маршрута и коннекторы группы маршрута), очень точная геометрия и атрибуты уровня маршрута.
Модель Локализации HD: Обеспечивает функции, чтобы поддержать стратегии локализации автомобиля.
Для обзора слоев HERE HDLM смотрите, что HD HERE Живет Слои Карты.
Камеры используются в автоматизированном управлении, чтобы собрать семантическую информацию о дорожной топологии вокруг автомобиля. Обнаружение контура маршрута, классификация типов маршрута и алгоритмы обнаружения дорожного знака формируют ядро такого конвейера обработки камеры. Можно использовать сервис HERE HDLM, наряду с GPS высокой точности, смонтированным на автомобиле, чтобы оценить точность таких алгоритмов и проверить их производительность.
В этом примере вы учитесь как:
Рид-Роуд и информация о маршруте от сервиса HERE HDLM для записанной последовательности GPS.
Примените эвристический подход соответствия маршрута к записанным данным о GPS. Поскольку данные о GPS часто неточны, необходимо решить проблему соответствия с записанными географическими координатами к представлению дорожной сети.
Идентифицируйте экологические атрибуты, относящиеся к автомобилю. Если автомобиль успешно расположен в контексте карты, можно использовать дорогу, и маршрут приписывает относящийся к автомобилю, чтобы проверить данные, зарегистрированные встроенным датчиком камеры автомобиля.
Запустите путем загрузки данных из записанного диска. Записанные данные в этом примере от ведущего набора данных, собранного командой Udacity® Self-Driving Car. Эти данные включают видео, записанное обращенной к передней стороне монокулярной камерой и положениями автомобиля и скоростями, регистрируемыми GPS.
Загрузите видеоданные камеры centerCamera.avi
и соответствующие видео метки времени.
recordedData = fullfile(toolboxdir('driving'), 'drivingdata', ... 'udacity', 'drive_segment_09_29_16'); [videoReader, videoTime] = helperLoadCameraData(fullfile(recordedData)); % Show the first frame of the camera data imageFrame = readFrame(videoReader); imshow(imageFrame, 'Border', 'tight');
Загрузите данные о GPS из MAT-файла gpsSequence.mat
.
data = load(fullfile(recordedData, 'gpsSequence.mat')); gpsData = data.gpsTT; % Plot the full route and the first position recorded from the GPS gpsPlayer = geoplayer(gpsData.Latitude(1), gpsData.Longitude(1), 18); plotRoute(gpsPlayer, gpsData.Latitude, gpsData.Longitude); plotPosition(gpsPlayer, gpsData.Latitude(1), gpsData.Longitude(1));
Создайте читателя для чтения HD HERE Живые мозаики Карты, которые покрывают все записанные местоположения GPS в диске. Если вы ранее не настроили учетные данные HERE HDLM, диалоговое окно предлагает вам вводить их. Введите идентификатор Приложения и Код Приложения, что вы получили отсюда Технологии, и нажать ОК.
reader = hereHDLMReader(gpsData.Latitude, gpsData.Longitude);
Считайте и отобразите дорожные данные о топологии на графике из слоя TopologyGeometry
. Этот слой представляет настройку дорожной сети. Узлы сети соответствуют пересечениям и тупикам. Ссылки между узлами представляют форму соединяющихся улиц как ломаные линии. Возможность соединения и геометрия для этих функций содержатся в полях LinksStartingInTile
и NodesInTile
.
topologyLayer = read(reader, 'TopologyGeometry') figure('Name', 'TopologyGeometry'); topologyAxes = plot(topologyLayer); hold(topologyAxes, 'on'); geoplot(topologyAxes, gpsData.Latitude, gpsData.Longitude, ... 'bo-', 'DisplayName', 'Route');
topologyLayer = TopologyGeometry with properties: Data: HereTileId: 309106790 IntersectingLinkRefs: [59×1 struct] LinksStartingInTile: [603×1 struct] NodesInTile: [443×1 struct] TileCenterHere2dCoordinate: [37.3865 -122.1130] Metadata: Catalog: 'here-hdmap-ext-na-1' CatalogVersion: 2349 Use plot to visualize TopologyGeometry data.
Функциональность графического вывода получена в функции helperPlotLayer
, которая визуализирует доступные данные из слоя HD Live Map с записанным диском на тех же географических осях. Эта функция, заданная в конце примера, будет использоваться, чтобы построить последующие слои.
Учитывая местоположение GPS, зарегистрированное вдоль диска, можно использовать алгоритм соответствия маршрута, чтобы определить, какой дороге в сети записанное положение соответствует. Этот пример использует эвристический алгоритм соответствия маршрута, который рассматривает самые близкие ссылки пространственно на записанную географическую точку. Алгоритм применяет направление автомобиля перемещения, чтобы определить самую вероятную ссылку. Этот подход соответствия маршрута не рассматривает дорожной возможности соединения, доступа транспортных средств или данных о GPS с высокой позиционной ошибкой. Поэтому этот подход не может примениться ко всем сценариям.
Функция helperGetGeometry
извлекает информацию о геометрии от данного слоя топологии и возвращает эту информацию в таблице с соответствующими ссылками.
topologyTable = helperGetGeometry(topologyLayer.LinksStartingInTile, ... {'LinkId', 'Geometry.Here2dCoordinateDiffs'}); topologyTable.Properties.VariableNames = {'LinkId', 'Geometry'};
Класс HelperLinkMatcher
создает ссылку matcher, который содержит геометрию формы для каждой ссылки в желаемой мозаике карты. Этот класс использует основной пространственный анализ, чтобы совпадать с записанным положением к координатам формы дорожных ссылок.
linkMatcher = HelperLinkMatcher(topologyTable); % Match first point of the recorded route to the most probable link [linkId, linkLat, linkLon] = match(linkMatcher, gpsData.Latitude(1), ... gpsData.Longitude(1), gpsData.Velocity(1,1:2)); % Plot the shape geometry of the link geoplot(gpsPlayer.Axes, linkLat, linkLon, 'r.-');
Характеристики, характерные для всех маршрутов вдоль данной дороги, приписаны элементу ссылки, который описывает ту дорогу. Один такой атрибут, ограничение скорости, описывает максимальную легальную скорость для автомобилей, перемещающихся на ссылке. Если данная географическая координата является соответствующей к ссылке, можно идентифицировать ограничение скорости вдоль той ссылки. Поскольку функции как ограничения скорости часто изменяются вдоль ссылки, эти атрибуты идентифицированы для определенных областей значений ссылки.
Слой SpeedAttributes
содержит информацию об ожидаемой скорости автомобиля на ссылке, включая отправленное ограничение скорости.
speedLayer = read(reader, 'SpeedAttributes');
Функция helperGetSpeedLimits
извлекает данные об ограничении скорости для соответствующей длины и направления ссылки. Как с извлечением информации о геометрии для ссылки, в частности собирая данные об ограничении скорости требует специализированного кода.
speedTable = helperGetSpeedLimits(speedLayer);
% Find the speed limit entry for the matched link
speed = speedTable(speedTable.LinkId == linkId, :);
Модель Маршрута HD содержит геометрию уровня маршрута и атрибуты дороги, обеспечивая деталь, необходимую, чтобы поддержать автоматизированные ведущие приложения. Во многом как Дорожная Модель Средней линии Модель Маршрута HD также следует за шаблоном использования топологии, чтобы описать дорожную сеть на уровне маршрута. Затем функции групп маршрута приписаны элементам этой топологии. В Модели Маршрута HD первичный топологический элемент является группой маршрута.
Считайте и отобразите данные о топологии маршрута на графике из слоя LaneTopology
. Этот слой представляет топологию маршрута как группы маршрута и коннекторы группы маршрута. Группы маршрута представляют группу маршрутов в ссылке (дорожный сегмент). Коннекторы группы маршрута соединяют отдельные группы маршрута друг с другом. Возможность соединения и геометрия для этих функций содержатся в полях LaneGroupsStartingInTile
и LaneGroupConnectorsInTile
, для групп маршрута и коннекторов группы маршрута, соответственно.
laneTopologyLayer = read(reader, 'LaneTopology') laneAxes = helperPlotLayer(laneTopologyLayer, ... gpsData.Latitude, gpsData.Longitude); geolimits(laneAxes, [37.3823, 37.3838], [-122.1151, -122.1128]);
laneTopologyLayer = LaneTopology with properties: Data: HereTileId: 309106790 IntersectingLaneGroupRefs: [55×1 struct] LaneGroupConnectorsInTile: [1212×1 struct] LaneGroupsStartingInTile: [1848×1 struct] TileCenterHere2dCoordinate: [37.3865 -122.1130] Metadata: Catalog: 'here-hdmap-ext-na-1' CatalogVersion: 2349 Use plot to visualize LaneTopology data.
Группа маршрута представляет несколько маршрутов. Поэтому геометрия этого элемента дана многоугольной формой, которую группа принимает, как выражено левыми и правыми контурами группы маршрута. Получите эту геометрию маршрута из контуров маршрута при помощи функции helperGetGeometry
.
laneGroupFields = {'LaneGroupId', ... 'BoundaryGeometry.LeftBoundary.Here2dCoordinateDiffs', ... 'BoundaryGeometry.RightBoundary.Here2dCoordinateDiffs'}; laneTopologyTable = helperGetGeometry(laneTopologyLayer.LaneGroupsStartingInTile, ... laneGroupFields); laneTopologyTable.Properties.VariableNames = {'LaneGroupId', ... 'LeftGeometry', 'RightGeometry'};
Как с разработкой соответствующего алгоритма, чтобы идентифицировать самую вероятную ссылку перемещения, совпадая с данными данными о GPS самой вероятной группе маршрута может следовать за несколькими подходами. Подход, описанный здесь, использует два слоя: LaneRoadReferences
и LaneTopology
.
Слой LaneRoadReferences
позволяет вам перевести позицию по Дорожной Модели Средней линии (данный ссылкой) к соответствующей позиции по Модели Маршрута HD (данный группой маршрута). Поскольку ссылка была ранее идентифицирована, можно отфильтровать кандидатов на соответствие группы маршрута к меньшему подмножеству всех групп маршрута, доступных в мозаике.
Слой LaneTopology
дает данные о геометрии, которые могут использоваться, чтобы рассмотреть данные, которые существуют пространственно в контурах каждой группы маршрута кандидата. Как с пространственным соответствием с данными о GPS к ссылкам, такой подход подвержен ошибке и подвергается точности записанных данных о GPS. В дополнение к соответствию с группой маршрута также необходимо совпадать с вектором направления автомобиля относительно ориентации группы маршрута. Этот шаг необходим, потому что атрибуты маршрутов заданы относительно ориентации топологии.
Используйте функцию helperGetReferences
, чтобы сгенерировать таблицу всех групп маршрута, которые существуют для, по крайней мере, некоторой длины ссылки.
referenceLayer = read(reader, 'LaneRoadReferences');
referenceTable = helperGetReferences(referenceLayer);
Создайте группу маршрута matcher, который содержит граничную геометрию для каждой группы маршрута в желаемой мозаике карты. Класс HelperLaneGroupMatcher
создает группу маршрута matcher, который содержит граничную геометрию формы для каждой группы маршрута в желаемой мозаике карты. Это также содержит таблицу ссылок ссылок на группы маршрута. Как с классом HelperLinkMatcher
, этот класс использует простой пространственный аналитический подход, чтобы определить, существует ли данная записанная координата в контурах группы маршрута.
laneGroupMatcher = HelperLaneGroupMatcher(referenceTable, laneTopologyTable); % Match the lane group and relative direction [laneGroupId, isForward, boundGeometry] = match(laneGroupMatcher, linkId, ... gpsData.Latitude(1), gpsData.Longitude(1), gpsData.Velocity(1,1:2)); % Plot the boundary geometry of the lane group geoplot(gpsPlayer.Axes, boundGeometry(:,1), boundGeometry(:,2), 'm.-');
Как с атрибутами скорости, которые сопоставлены со ссылками идентификатором, атрибуты маршрута также присваивают функции группам маршрута при помощи ID группы маршрута. Слой LaneAttributes
содержит информацию о группы маршрута, включая типы каждого маршрута в группе и характеристиках контуров маршрута.
Используйте функцию helperGetLaneAttributes
, чтобы извлечь различные типы маршрута и маркировки контура маршрута для каждой группы маршрута в мозаике.
laneAttributesLayer = read(reader, 'LaneAttributes'); laneAttributesTable = helperGetLaneAttributes(laneAttributesLayer); % Find the lane attribute entry for the matched lane group laneAttribute = laneAttributesTable.LaneGroupId == laneGroupId;
Соответствующие алгоритмы и таблицы, сгенерированные, чтобы идентифицировать дорогу и свойства маршрута, могут быть расширены к последовательности записанных координат GPS. Для каждого временного шага положение автомобиля является соответствующим к ссылке и группе маршрута на дороге. Кроме того, ограничение скорости и настройки маршрута отображены наряду с соответствующими изображениями камеры.
Класс HelperHDLMUI
создает инструмент для потокового видео и данных о GPS из записанного диска и отображающий релевантную информацию от выбранных слоев HERE HD Live Map в каждом записанном положении автомобиля.
hdlmUI = HelperHDLMUI(gpsData.Latitude(1), gpsData.Longitude(1)); % Synchronize the camera and GPS data into a common timetable synchronizedData = synchronize(videoTime, gpsData); videoReader.CurrentTime = 0; maxDisplayRate = videoReader.FrameRate * 5; % Initialize some variables to maintain history prevLinkId = 0; prevLaneGroupId = 0; for idx = 1 : height(synchronizedData) timeStamp = synchronizedData.Time(idx); % Check if the current timestamp has GPS data hasGPSFrame = ~(ismissing(synchronizedData.Latitude(idx)) || ... ismissing(synchronizedData.Longitude(idx))); if hasGPSFrame latitude = synchronizedData.Latitude(idx); longitude = synchronizedData.Longitude(idx); velocity = synchronizedData.Velocity(idx, 1:2); % Match GPS position to link [linkId, linkLat, linkLon] = match(linkMatcher, ... latitude, longitude, velocity); if linkId ~= prevLinkId % Update link updateLink(hdlmUI, linkLat, linkLon); prevLinkId = linkId; % Update speed limit speed = speedTable(speedTable.LinkId == linkId, :); updateSpeed(hdlmUI, speed.Value); end % Match GPS position to lane group [laneGroupId, isForward, boundGeometry] = match(laneGroupMatcher, linkId, ... latitude, longitude, velocity); if laneGroupId ~= prevLaneGroupId % Update lane group updateLaneGroup(hdlmUI, boundGeometry); prevLaneGroupId = laneGroupId; % Update lane types and boundary markings laneAttribute = laneAttributesTable.LaneGroupId == laneGroupId; plotLanes(hdlmUI, laneAttributesTable.Lanes{laneAttribute}, ... laneAttributesTable.LaneBoundaries{laneAttribute}, isForward); end updatePosition(hdlmUI, latitude, longitude); else % Read frame of the video imageFrame = readFrame(videoReader); end updateImage(hdlmUI, imageFrame); updateTime(hdlmUI, timeStamp); pause(1/maxDisplayRate); end
В этом примере вы исследовали как к:
Доступ к данным об отображении HD для данной последовательности GPS от HD HERE Живой Картографический сервис и импортирует те данные в MATLAB.
Совпадайте с зарегистрированными данными о GPS против импортированных данных о дорожной сети, чтобы найти необходимую ссылку и группу маршрута для каждой географической координаты.
Запросите атрибуты совпадающей ссылки и группы маршрута, такие как ограничение скорости и типы маршрута, чтобы разработать инструмент для того, чтобы визуально проверить функции дороги против записанных данных о камере.
Методы, обсужденные в этом примере, могут быть далее расширены, чтобы поддержать автоматизированную верификацию алгоритмов восприятия.
helperPlotLayer
отображает на графике данные о слое и маршрут на географическом графике.
function gx = helperPlotLayer(layer, latitude, longitude) %helperPlotLayer Create geographic plot with layer data and route % gx = helperPlotLayer(layer, latitude, longitude) creates a geographic % axes plot with the plottable HDLM layer and the route given by latitude % and longitude on a new figure. figure; % Plot layer gx = plot(layer); % Enable adding data to the plot hold(gx, 'on'); % Plot latitude, longitude data geoplot(gx, latitude, longitude, 'bo-', 'DisplayName', 'Route'); hold(gx, 'off'); end
helperGetGeometry
извлекает геометрию для элементов топологии от слоя в форме таблицы.
function geometryTable = helperGetGeometry(layer, fields) %helperGetGeometry Create a table with geometry for topology elements % geometryTable = helperGetGeometry(layer, fields) returns a table % formatted with the specified geometry fields of the TopologyGeometry % and LaneTopology layers. % Pre-allocate struct S = repmat(struct, size(layer)); for field = fields C = strsplit(field{:}, '.'); for idx = 1:numel(layer) fieldname = strjoin(C, ''); S(idx).(fieldname) = getfield(layer, {idx}, C{:}); end end geometryTable = struct2table(S); end
helperGetSpeedLimits
извлекает данные об ограничении скорости из слоя в форме таблицы.
function speedTable = helperGetSpeedLimits(layer) %helperGetSpeedLimits Create a data table with speed limits % speedTable = helperGetSpeedLimits(layer) returns a table formatted with % the speed limit start, end, direction, and value along a specified link % as given by the SpeedAttributes layer object specified by layer. speed = struct(... 'LinkId', {}, ... 'Start', {}, ... 'End', {}, ... 'Direction', {}, ... 'Value', {}); for idx = 1 : numel(layer.LinkAttribution) % Assign the link ID link = layer.LinkAttribution(idx); attributions = link.ParametricAttribution; % Examine each attribute assigned to the link for attrIndex = 1 : numel(attributions) linkAttr = vertcat(attributions.LinkParametricAttribution); % For each attribute, check if the speed limit information is % listed. If speed limit is provided, make an entry. for linkAttrIndex = 1 : numel(linkAttr) if ~isempty(linkAttr(linkAttrIndex).SpeedLimit) % Assign speed limit to specified link speedLimit = struct; speedLimit.LinkId = link.LinkLocalRef; speedLimit.Start = attributions(attrIndex).AppliesToRange.RangeOffsetFromStart; speedLimit.End = attributions(attrIndex).AppliesToRange.RangeOffsetFromEnd; speedLimit.Direction = attributions(attrIndex).AppliesToDirection; speedLimit.Value = linkAttr(linkAttrIndex).SpeedLimit.Value; % Convert KPH to MPH if strcmpi(linkAttr(linkAttrIndex).SpeedLimit.Unit, 'KILOMETERS_PER_HOUR') speedLimit.Value = speedLimit.Value / 1.609; end if strcmpi(speedLimit.Direction, 'BOTH') speed = [speed; speedLimit]; %#ok<AGROW> end end end end end speedTable = struct2table(speed); end
helperGetReferences
извлекает ссылки дороги маршрута от расположенного на слое объекта в форме таблицы.
function laneRoadReferenceTable = helperGetReferences(layer) %helperGetReferences Create a data table with lane road references % laneRoadReferenceTable = helperGetReferences(layer) returns a table % formatted with a list of all lane groups existing on a specified link % as given by the LaneRoadReferences layer object specified by layer. numLinks = numel(layer.LinkLaneGroupReferences); reference = repmat(struct('LinkId', {}, 'LaneGroupId', {}), numLinks, 1); % Get references from links to lane groups for idx = 1 : numLinks link = layer.LinkLaneGroupReferences(idx); laneGroups = vertcat(link.LaneGroupReferences.LaneGroupRef); reference(idx).LinkId = link.LinkLocalRef; reference(idx).LaneGroupId = [laneGroups(:).LaneGroupId]'; end laneRoadReferenceTable = struct2table(reference); end
helperGetLaneAttributes
извлекает атрибуты маршрута от расположенного на слое объекта в форме таблицы.
function laneAttributesTable = helperGetLaneAttributes(layer) %helperGetLaneAttributes Create a table with lane and boundary types % laneAttributesTable = helperGetLaneAttributes(layer) returns a table % formatted with the lane types and the lane boundary markings for each % lane group in the LaneAttributes layer object specified by layer. for laneGroupAttrIndex = 1 : numel(layer.LaneGroupAttribution) laneGroup = layer.LaneGroupAttribution(laneGroupAttrIndex); attributes(laneGroupAttrIndex).LaneGroupId = laneGroup.LaneGroupRef; %#ok % Get lane types for each lane group for laneAttrIndex = 1 : numel(laneGroup.LaneAttribution) lane = laneGroup.LaneAttribution(laneAttrIndex); laneAttr = vertcat(lane.ParametricAttribution); laneAttr = vertcat(laneAttr.LaneParametricAttribution); for idx = 1 : numel(laneAttr) if ~isempty(laneAttr(idx).LaneType) attributes(laneGroupAttrIndex).Lanes{lane.LaneNumber} = ... laneAttr(idx).LaneType; end end end % Get lane boundaries for each lane group for laneBoundaryIndex = 1 : numel(laneGroup.LaneBoundaryAttribution) laneBoundary = laneGroup.LaneBoundaryAttribution(laneBoundaryIndex); boundaries = vertcat(laneBoundary.ParametricAttribution.LaneBoundaryParametricAttribution); attributes(laneGroupAttrIndex).LaneBoundaries{laneBoundary.LaneBoundaryNumber} = ... boundaries.LaneBoundaryMarking; end end laneAttributesTable = struct2table(attributes); end
helperLoadCameraData
загружает видео читателя и метки времени от папки.
function [videoReader, videoTime] = helperLoadCameraData(dirName) %helperLoadCameraData Load camera images from folder in a timetable % [videoReader, videoTime] = helperLoadCameraData(dirName) loads a video % from the folder dirName. Timestamps for the video are read from a % MAT-file in the folder named timeStamps.mat. if ~isfolder(dirName) error('Expected dirName to be a path to a folder.') end matFileName = fullfile(dirName, 'centerCameraTime.mat'); if exist(matFileName, 'file') ~= 2 error('Expected dirName to have a MAT-file named centerCameraTime.mat containing timestamps.') end % Load the MAT-file with timestamps ts = load(matFileName); fieldNames = fields(ts); Time = ts.(fieldNames{1}); videoFileName = fullfile(dirName, 'centerCamera.avi'); if exist(matFileName, 'file') ~= 2 error('Expected dirName to have a video file named centerCamera.avi.') end % Load the video file videoTime = timetable(Time); videoReader = VideoReader(videoFileName); end
hereHDLMReader
| plot
| read