Генерация сценария от записанных данных об автомобиле

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

Обзор

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

В этом примере вы создаете виртуальный ведущий сценарий путем генерации объекта drivingScenario от данных, которые были зарегистрированы от теста (эго) автомобиль и файл OpenDRIVE®. Файл OpenDRIVE описывает дорожную сеть области, где данные были зарегистрированы. Записанные данные об автомобиле включают:

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

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

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

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

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

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

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

  4. Добавьте агентов неэго от списка объектов лазерного дальномера до ведущего сценария.

  5. Моделируйте и визуализируйте сгенерированный сценарий.

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

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

Положения автомобиля, оборудованного датчиком были получены с помощью GPS UBlox датчик NEO M8N. Датчик GPS был помещен в центр крыши автомобиля, оборудованного датчиком. Эти данные сохранены в текстовом файле EgoUrban.txt.

Положения агентов неэго были получены с помощью датчика лазерного дальномера Velodyne® VLP-16 с областью значений 30 метров. Датчик VLP-16 был помещен в крышу автомобиля, оборудованного датчиком в положении и высоте, которая старается не иметь датчик, сталкиваются с телом автомобиля, оборудованного датчиком. Облако точек от датчика лазерного дальномера было обработано на автомобиле, чтобы обнаружить объекты и их положения относительно автомобиля, оборудованного датчиком. Эти данные сохранены в текстовом файле NonEgoUrban.txt.

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

Сгенерируйте предварительный просмотр городского сценария трафика, используемого в этом примере.

vidObj = VideoReader('urbanpreview.mp4');
fig = figure;
set(fig,'Position',[0, 0, 800, 600]);
movegui(fig,'center');
pnl = uipanel(fig,'Position',[0 0 1 1],'Title','Urban Traffic Scenario');
plt = axes(pnl);
while hasFrame(vidObj)
    vidFrame = readFrame(vidObj);
    image(vidFrame,'Parent',plt);
    currAxes.Visible = 'off';
    pause(1/vidObj.FrameRate);
end

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

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

Данные о дорожной сети для генерации виртуального сценария получены из OpenStreetMap®. Файлы данных OpenStreetMap преобразованы в файлы OpenDRIVE и сохраненные с дополнительным .xodr. Используйте функцию roadNetwork, чтобы импортировать эти данные о дорожной сети к ведущему сценарию.

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

scenario = drivingScenario;
openDRIVEFile = 'OpenDRIVEUrban.xodr';
roadNetwork(scenario,'OpenDRIVE',openDRIVEFile);

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

Данные об автомобиле, оборудованном датчиком собраны от датчика GPS и сохранены как текстовый файл. Текстовый файл состоит из трех столбцов, которые хранят широту, долготу и значения метки времени для автомобиля, оборудованного датчиком. Используйте функцию helperGetEgoData, чтобы импортировать данные об автомобиле, оборудованном датчиком из текстового файла в структуру в рабочей области MATLAB®. Структура содержит три поля, задающие широту, долготу и метки времени.

egoFile = 'EgoUrban.txt';
egoData = helperGetEgoData(egoFile);

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

% Specify latitude and longitude at origin of OpenDRIVE file
lat0 = 17.425853702697903;
lon0 = 78.44939480188313;
% Specify latitude and longitude of ego vehicle
lat = egoData.lat;
lon = egoData.lon;
% Compute waypoints of ego vehicle
[X,Y,~] = geodetic2enu(lat,lon,0,lat0,lon0,0,wgs84Ellipsoid);
egoWaypoints(:,1) =  X;
egoWaypoints(:,2) =  Y;

Визуализируйте путь к 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

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

[egoSpeed,egoAngle] = helperComputeEgoData(egoData,X,Y);

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

ego = vehicle(scenario,'Length',1,'Width',0.6,'Height',0.6);

Создайте траекторию для автомобиля, оборудованного датчиком от вычисленного набора эго waypoints и скорости. Автомобиль, оборудованный датчиком следует за траекторией на заданной скорости.

trajectory(ego,egoWaypoints,egoSpeed);

Добавьте агентов неэго от списков объектов лазерного дальномера до сгенерированного сценария

Данные об агенте неэго собраны от датчика лазерного дальномера и сохранены как текстовый файл. Текстовый файл состоит из пяти столбцов, которые хранят идентификаторы агента, x - положения, y - положения, z - положения и значения метки времени, соответственно. Используйте функцию helperGetNonEgoData, чтобы импортировать данные об агенте неэго из текстового файла в структуру в рабочей области MATLAB®. Вывод является структурой с тремя полями:

  1. ActorID - Заданный сценарием идентификатор агента, заданный как положительное целое число.

  2. Положение Position - агента, заданного как [x y z] вектор действительных чисел. Модули исчисляются в метрах.

  3. Время- Метка времени записи датчика.

nonEgoFile = 'NonEgoUrban.txt';
nonEgoData = helperGetNonEgoData(nonEgoFile);

Используйте helperComputeNonEgoData, чтобы вычислить траекторию waypoints и скорость каждого агента неэго в каждой метке времени. Траектория waypoints вычисляется относительно автомобиля, оборудованного датчиком.

actors = unique(nonEgoData.ActorID);
[nonEgoSpeed, nonEgoWaypoints] = helperComputeNonEgoData(egoData,egoWaypoints,nonEgoData,egoAngle);

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

for i = 1:length(actors)
    actor = vehicle(scenario,'Length',1,'Width',0.6,'Height',0.6);
    trajectory(actor,nonEgoWaypoints{i},nonEgoSpeed{i});
end

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

% Create a custom figure window and define an axes object
fig = figure;
set(fig,'Position',[0, 0, 800, 600]);
movegui(fig,'center');
hViewPnl = uipanel(fig,'Position',[0 0 1 1],'Title','Ego Vehicle and Actors');
hCarPlt = axes(hViewPnl);

% Plot the generated driving scenario.
plot(scenario,'Parent',hCarPlt);
axis([270 320 80 120]);
legend('Imported Road Network','Lanes','Ego Vehicle','Actor 1','Actor 2','Actor 3','Actor 4','Actor 5')
legend(hCarPlt,'boxoff');

figure,
plot(egoWaypoints(:,1),egoWaypoints(:,2),'Color',[0 0.447 0.741],'LineWidth',2)
hold on
cMValues = [0.85 0.325 0.098;0.929 0.694 0.125;0.494 0.184 0.556;0.466 0.674 0.188;0.301 0.745 0.933];
for i =1:length(actors)
    plot(nonEgoWaypoints{i}(:,1),nonEgoWaypoints{i}(:,2),'Color',cMValues(i,:),'LineWidth',2)
end
axis('tight')
xlabel('X (m)')
ylabel('Y (m)')
title('Computed Ego Vehicle and Actor Trajectories')
legend('Ego Vehicle', 'Actor 1', 'Actor 2', 'Actor 3','Actor 4','Actor 5','Location','Best')
hold off

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

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

% Create a custom figure window to show the scenario and chase plot
close all;
figScene = figure('Name','Driving Scenario','Tag','ScenarioGenerationDemoDisplay');
set(figScene,'Position',[0, 0, 1032, 1032]);
movegui(figScene,'center');

% Add the chase plot
hCarViewPanel = uipanel(figScene,'Position',[0.5 0 0.5 1],'Title','Chase Camera View');
hCarPlot = axes(hCarViewPanel);
chasePlot(ego,'Parent',hCarPlot);

% Add the top view of the generated scenario
hViewPanel = uipanel(figScene,'Position',[0 0 0.5 1],'Title','Top View');
hCarPlot = axes(hViewPanel);
plot(scenario,'Parent',hCarPlot);
% Set the axis limits to display only the active area
xMin = min(egoWaypoints(:,1));
xMax = max(egoWaypoints(:,1));
yMin = min(egoWaypoints(:,2));
yMax = max(egoWaypoints(:,2));
limits = [xMin xMax yMin yMax];
axis(limits);

% Run the simulation
while advance(scenario)
    pause(0.01)
end

Сводные данные

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

Функции помощника

helperGetEgoData

Эта функция считывает данные об автомобиле, оборудованном датчиком из текстового файла и преобразовывает в структуру.

function [egoData] = helperGetEgoData(egoFile)
%Read the ego vehicle data from text file
fileID = fopen(egoFile);
content = textscan(fileID,'%f %f %f');
fields = {'lat','lon','Time'};
egoData = cell2struct(content,fields,2);
fclose(fileID);
end

helperGetNonEgoData

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

function [nonEgoData] = helperGetNonEgoData(nonEgoFile)
% Read the processed lidar data of non-ego actors from text file.
fileID = fopen(nonEgoFile);
content = textscan(fileID,'%d %f %f %f %f');
newcontent{1} = content{1};
newcontent{2} = [content{2} content{3} content{4}];
newcontent{3} = content{5};
fields = {'ActorID','Position','Time'};
nonEgoData = cell2struct(newcontent,fields,2);
fclose(fileID);
end

helperComputeEgoData

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

function [egoSpeed, egoAngle] = helperComputeEgoData(egoData,X,Y)
egoAngle = zeros;
egoSpeed = zeros;
for t = 1:size(egoData.Time)-1
    currTime = egoData.Time(t+1);
    prevTime = egoData.Time(t);
    timeDiff = currTime - prevTime;
    points = [X(t),Y(t);X(t+1),Y(t+1)];
    distance = pdist(points,'euclidean');
    egoSpeed(t) = distance/timeDiff;
    egoAngle(t) = atan((Y(t+1)-Y(t))/(X(t+1)-X(t)));
end
egoAngle(end+1) = egoAngle(end);
egoSpeed(end+1) = egoSpeed(end);
end

helperComputeNonEgoData

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

function [nonEgoSpeed, nonEgoWaypoints] = helperComputeNonEgoData(egoData,egoWaypoints,nonEgoData,egoAngle)
actors = unique(nonEgoData.ActorID);
[nonEgoWaypoints] = [];
[nonEgoSpeed] = [];
for i = 1:length(actors)
    id = actors(i);
    idx = find([nonEgoData.ActorID] == id);
    actorXData = nonEgoData.Position(idx,1);
    actorYData = nonEgoData.Position(idx,2);
    actorTime = nonEgoData.Time(idx);
    clear actorWaypoints actorSpeed;
    actorWaypoints(:,1) = zeros;
    actorWaypoints(:,2) = zeros;
    actorSpeed = zeros;
    for m = 1:size(actorTime)
        for n = 1:size(egoData.Time)
            if(egoData.Time(n) == actorTime(m))
                % Compute the trajectory waypoints of non-ego actor
                tempX = actorXData(m);
                tempY = actorYData(m);
                relativeX = -tempX * cos(egoAngle(n)) + tempY * sin(egoAngle(n));
                relativeY = -tempX * sin(egoAngle(n)) - tempY * cos(egoAngle(n));
                actorWaypoints(m,1) = egoWaypoints(n,1) + relativeX;
                actorWaypoints(m,2) = egoWaypoints(n,2) + relativeY;
                
                % Compute the speed values of non-ego actor
                if(size(actorWaypoints,1)>=2)
                    currTime = actorTime(m);
                    prevTime = actorTime(m-1);
                    timeDiff = currTime - prevTime;
                    points = [actorWaypoints(m-1,1),actorWaypoints(m-1,2);actorWaypoints(m,1),actorWaypoints(m,2)];
                    distance = pdist(points,'euclidean');
                    actorSpeed(m-1) = distance/timeDiff;
                end
                break;
            end
        end
    end
    actorSpeed(end+1) = actorSpeed(end);
    % Smooth the trajectory waypoints of non-ego actor
    actorWaypoints = smoothdata(actorWaypoints,'sgolay');
    % Store the values of trajectory waypoints and speed computed of each non-ego actor
    nonEgoWaypoints{i} = actorWaypoints;
    nonEgoSpeed{i} = actorSpeed';
end
end

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

Приложения

Функции

Объекты

Похожие темы

Внешние веб-сайты