В этом примере показано, как автоматизировать генерацию сценария с помощью drivingScenario
объект. В этом примере вы автоматизируете:
Размещение транспортного средства в сценарии путем определения их начального и целевого положения
Выбор путевой точки и генерация траектории для транспортных средств для перехода от их начальных положений к положениям цели.
Регулировка скорости таким образом, чтобы транспортные средства ускорялись или замедлялись, избегая столкновения между другими транспортными средствами, которые перемещаются по той же полосе.
Можно использовать этот пример, чтобы синтезировать ряд случайных сценариев для проверки алгоритмов вождения.
The drivingScenario
объект и приложение Driving Scenario Designer в Automated Driving Toolbox™ являются эффективными инструментами для генерации синтетических сценариев вождения. Можно создать дорожную сеть или импортировать дорожную сеть из OpenDRIVE ®, HERE HD Live Map и OpenStreetMap ®. Затем можно добавить актёров или транспортные средства в дорожную сеть и определить их траектории, чтобы синтезировать сценарий вождения. Точки пути, необходимые для генерации траекторий, должны быть тщательно выбраны таким образом, чтобы траектории транспортных средств находились в пределах дорожной сети, а транспортные средства не сталкивались, когда они перемещаются по их траекториям. Определение таких размещений транспортных средств и траекторий часто требует нескольких испытаний и занимает много времени, если у вас есть большие дорожные сети и много транспортных средств, чтобы сконфигурировать.
Этот пример предоставляет вспомогательные функции и демонстрирует шаги для автоматизации размещения транспортного средства и генерации траектории при помощи drivingScenario
объект. Можно также экспортировать сгенерированный сценарий в приложение Driving Scenario Designer. Остальная часть примера демонстрирует эти шаги, участвующие в автоматизации генерации сценария.
Импорт дорожной сети - Импорт дорожной сети OpenStreetMap ® в объект сценария вождения с помощью функции helper helperOSMimport
.
Задайте начальное и целевое положения - Задайте видимые области (ROIs) в дорожной сети, чтобы выбрать начальное и целевое положения для транспортных средств с помощью вспомогательной функции helperSamplePositions
.
Сгенерируйте траектории транспортного средства - Сгенерируйте путевые точки и траектории при помощи функции helper helperGenerateWaypoints
и trajectory
функциональные .
Измените профили скорости, чтобы избежать столкновения - Измените профили скорости транспортных средств в сценарии с помощью модели Simulink ® CollisionFreeSpeedManipulator
. Модель проверяет профиль скорости каждого транспортного средства и препятствует им сталкиваться друг с другом, когда они перемещаются по их траекториям. Выходом из модели является обновленный сценарий, который свободен от столкновения между транспортными средствами. Можно преобразовать выход из CollisionFreeSpeedManipulator
Модель Simulink к объекту сценария вождения при помощи функции helper helpergetCFSMScenario
.
Симулируйте и визуализируйте сгенерированный сценарий - Моделируйте и отображайте автоматически сгенерированный сценарий при помощи plot
функция. Вы также можете читать и моделировать сценарий с помощью приложения Driving Scenario Designer.
Вы можете загрузить дорожную сеть из https://www.openstreetmap.org, которая обеспечивает доступ к картографическим данным по всему миру. Данные лицензированы под лицензией Open Data Commons Open Database License (ODbL), https://opendatacommons.org/licenses/odbl/.
Задайте координаты ограничивающего прямоугольника, чтобы импортировать карту тестового средства MCity из openstreetmap.org
при помощи helperOSMImport
функция. Функция возвращает объект сценария вождения, который содержит дорожную сеть из импортированных данных карты. Можно также использовать roadNetwork
функция для импорта дорожной сети из файлов OpenDRIVE ®, HERE HD Live Map или OpenStreetMap ® .
% Import the road network of MCity minLat = 42.2990; maxLat = 42.3027; minLon = -83.6996; maxLon = -83.6965; bbox = [minLat maxLat;minLon maxLon]; scenario = helperOSMImport(bbox); % Create another scenario object for plotting purposes scenario_in = helperOSMImport(bbox);
Отображение дорожной сети MCity при помощи plot
функция.
figure
plot(scenario_in)
title('Imported Road Network')
xlim([-50 190])
ylim([-85 330])
Чтобы создать сценарий вождения, необходимо сначала определить конкретные точки на дорожной сети, которые могут служить начальным и целевым положениями для транспортных средств в сценарии. Используйте helperSamplePositions
функция для генерации случайного набора этих точек в дорожной сети. Можно использовать один или несколько из этих аргументов пары "имя-значение" helperSamplePositions
функций для настройки начального и целевого положения различными способами "
Используйте 'Seed
', чтобы задать настройки случайного генератора, которые будут использоваться для генерации случайных точек. Можно выбрать любые точки в сгенерированном наборе как начальное и целевое положения.
Используйте 'ROI
', чтобы задать один или несколько ROI в дорожной сети, в пределах которых вы хотите определить начальное и целевое положения. ROI могут быть круглыми, прямоугольными или многоугольными областями с любым количеством вершин. Значение для информации только для чтения является матрицей N-by-2, задающей пространственные координаты замкнутой области. Если это значение не задано, функция генерирует случайные точки по всей дорожной сети.
Используйте 'Lanes
', чтобы задать полосы движения, в которых необходимо задать начальное и целевое положения. Чтобы выбрать одну полосу, задайте номер полосы как скалярное значение. Для нескольких маршрутов значение 'Lanes
'должен быть вектором, содержащим требуемые номера маршрутов. Если это значение не задано, функция выбирает полосы случайным образом.
Используйте 'LongitudinalDistance
', чтобы задать продольное расстояние между двумя последовательными точками. Если это значение не задано, функция накладывает не менее 5 метров расстояния между двумя последовательными точками в одной полосе. Это означает, что продольное расстояние между двумя последовательными транспортными средствами, расположенными в одной полосе, составляет не менее 5 метров.
Во время симуляции транспортные средства нерестятся в начальных точках, а затем перемещаются, чтобы достичь целевых точек.
Сгенерируйте 10 случайных точек для использования в качестве потенциальных начальных положений. Задайте флаг для установки генератора случайных чисел. Установите значение для setSeed
Значение 1, чтобы задать seed для генератора случайных чисел. Передайте настройки случайного генератора как вход в helperSamplePositions
функция при помощи 'Seed
Аргумент в виде пары имя-значение.
The helperSamplePositions
функция выводит 3-D пространственные координаты случайным образом выбранных точек в импортированной дорожной сети. Функция также выводит углы рыскания относительно выбранных точек. Угол рыскания, полученный относительно точки, определяет ориентацию транспортного средства, которое должно быть помещено в этой точке.
numPoints = 10; setSeed = 1; if setSeed == 1 seed = 2; rng(seed); s = rng; [points,yaw] = helperSamplePositions(scenario,numPoints,'Seed',s); else [points,yaw] = helperSamplePositions(scenario,numPoints); end
Укажите количество транспортных средств, которые будут помещены в сценарий, равным 3. Выберите три точки в сгенерированном наборе в качестве начальных позиций для транспортных средств.
numVehicles = 3; startSet1 = [points(2,:);points(4,:);points(7,:)]; yaw1 = [yaw(2);yaw(4);yaw(7)];
Поместите транспортные средства в выбранные точки с помощью vehicle
функция.
for idx = 1 : numVehicles vehicle(scenario,'Position',startSet1(idx,:),'Yaw',yaw1(idx),'ClassID',1); end
Сгенерируйте другой набор точек путем определения ROIs. Вычислите координаты для задания кругового информация только для чтения.
xCor = 0; yCor = 0; radius = 50; theta = 0: pi/10: 2*pi; roiCircular(:,1) = xCor+radius*cos(theta); roiCircular(:,2) = yCor+radius*sin(theta);
Укажите число точек, которые будут сгенерированы в информация только для чтения, и количество транспортных средств, которые будут помещены в информация только для чтения, равное 3. Выберите все точки в круговом информация только для чтения в качестве начальных позиций для транспортных средств.
numPoints = 3; numVehicles = numPoints; [startSet2,yaw2] = helperSamplePositions(scenario,numPoints,'ROI',roiCircular); for idx = 1 : size(startSet2,1) vehicle(scenario,'Position',startSet2(idx,:),'Yaw',yaw2(idx),'ClassID',1); end
Задайте координаты для прямоугольного информация только для чтения. Установите число точек, генерируемых в информация только для чтения, и количество транспортных средств, помещаемых в информация только для чтения, равным 3. Установите продольное расстояние между двумя последовательными точками в одной полосе движения равным 30 метрам. Если информация только для чтения недостаточно велика, чтобы разместить заданное число точек на заданном продольном расстоянии, то helperSamplePositions
функция возвращает только то число точек, которое может быть использовано в информация только для чтения. Чтобы получить необходимое число точек, необходимо либо уменьшить продольное расстояние, либо увеличить площадь информации только для чтения.
roiRectangular = [0 0;100 100]; numPoints = 3; [startSet3,yaw3] = helperSamplePositions(scenario,numPoints,'ROI',roiRectangular,'LongitudinalDistance',30);
Разместите транспортные средства в выбранных точках с помощью vehicle
функция.
for idx = 1 : size(startSet3,1) vehicle(scenario,'Position',startSet3(idx,:),'Yaw',yaw3(idx),'ClassID',1); end
Постройте график сгенерированных точек выборки и ROIs.
figScene = figure('Name','AutomaticScenarioGeneration'); set(figScene,'Position',[0,0,900,500]); hPanel1 = uipanel(figScene,'Position',[0 0 0.5 1]); hPlot1 = axes(hPanel1); plot(scenario_in,'Parent',hPlot1); title('Points for Selecting Start Positions') hold on plot(points(:,1),points(:,2),'ro','MarkerSize',5,'MarkerFaceColor','r'); plot(roiCircular(:,1),roiCircular(:,2),'LineWidth',1.2,'Color','k') plot(startSet2(:,1),startSet2(:,2),'ko','MarkerSize',5,'MarkerFaceColor','k'); plot([roiRectangular(1,1);roiRectangular(1,1);roiRectangular(2,1);roiRectangular(2,1);roiRectangular(1,1)],... [roiRectangular(1,2);roiRectangular(2,2);roiRectangular(2,2);roiRectangular(1,2);roiRectangular(1,2)],... 'LineWidth',1.2,'Color','b'); plot(startSet3(:,1),startSet3(:,2),'bo','MarkerSize',5,'MarkerFaceColor','b'); xlim([-50 190]) ylim([-85 330]) hold off
Отображение начальных позиций и транспортных средств в сценарии.
3 начальных положения красного цвета были выбраны из 10 случайных точек, определенных в сценарии.
3 начальных положения в черном были выбраны из 3 случайных точек, определенных в круговом информация только для чтения.
3 начальных положения синего цвета были выбраны из 3 случайных точек, определенных в прямоугольной информация только для чтения.
hPanel2 = uipanel(figScene,'Position',[0.5 0 0.5 1]); hPlot2 = axes(hPanel2); plot(scenario,'Parent',hPlot2); title('Start Positions and Vehicle Placement') hold on plot(startSet1(:,1),startSet1(:,2),'rs','MarkerSize',15,'LineWidth',1.2); plot(startSet2(:,1),startSet2(:,2),'ks','MarkerSize',15,'LineWidth',1.2); plot(startSet3(:,1),startSet3(:,2),'bs','MarkerSize',15,'LineWidth',1.2); xlim([-50 190]) ylim([-85 330]) hold off
Объедините все начальные положения в одну матрицу. Количество стартовых позиций подразумевает общее количество транспортных средств в сценарии вождения.
startPositions = [startSet1;startSet2;startSet3];
Отобразите объект сценария и проверьте его свойства. The Actors
свойство scenario
объект является массивом 1 на 9, который хранит информацию о 9 транспортных средствах, которые добавляются к сценарию вождения. Доступ к деталям каждого транспортного средства в Actors
свойство при помощи индексации через точку. Отображение подробных данных о первом транспортном средстве в сценарии вождения. The Position
свойство содержит начальное положение транспортного средства.
scenario
scenario = drivingScenario with properties: SampleTime: 0.0100 StopTime: Inf SimulationTime: 0 IsRunning: 1 Actors: [1×9 driving.scenario.Vehicle]
scenario.Actors(1)
ans = 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: [130.7903 -12.2335 -2.0759e-04] Velocity: [0 0 0] Yaw: 96.6114 Pitch: 0 Roll: 0 AngularVelocity: [0 0 0] Length: 4.7000 Width: 1.8000 Height: 1.4000 Mesh: [1×1 extendedObjectMesh] RCSPattern: [2×2 double] RCSAzimuthAngles: [-180 180] RCSElevationAngles: [-90 90]
Сгенерируйте позиции целей для транспортных средств в сценарии с помощью helperSamplePositions
функция. Общее количество позиций цели должно совпадать с общим количеством начальных позиций.
numGoalPositions = length(startPositions)
numGoalPositions = 9
Задайте координаты для многоугольника информации только для чтения и найдите 5 случайных точек в многоугольнике информации только для чтения. Выберите эти точки в качестве позиций цели для первых 5 транспортных средств в сценарии.
roiPolygon = [-50 170;30 250;72 170;-50 170];
numPoints1 = 5;
goalSet1 = helperSamplePositions(scenario,numPoints1,'ROI',roiPolygon);
Сгенерируйте оставшийся набор положений цели таким образом, чтобы все они лежали в определенной полосе. Используйте 'Lanes
Аргумент в виде пары имя-значение для определения номера маршрута для позиций цели.
numPoints2 = 4;
goalSet2 = helperSamplePositions(scenario,numPoints2,'Lanes',1);
Отображение сценария и выбранных позиций цели.
5 очков красного цвета показа целевые положения, заданные в многоугольник информации только для чтения.
На 4 точках синего цвета показаны положения цели, определенные во всем сценарии.
figure plot(scenario); title('Goal Positions') hold on plot(roiPolygon(:,1), roiPolygon(:,2),'LineWidth',1.2,'Color','r') plot(goalSet1(:,1), goalSet1(:,2),'ro','MarkerSize',5,'MarkerFaceColor','r') plot(goalSet2(:,1),goalSet2(:,2),'bo','MarkerSize',5,'MarkerFaceColor','b') xlim([-50 190]) ylim([-85 310]) hold off
Объедините все положения цели в одну матрицу.
goalPositions = [goalSet1;goalSet2];
Отображение начальных и целевых позиций относительно каждого транспортного средства в сценарии.
vehicleNum = 1:length(startPositions); table(vehicleNum(:),startPositions,goalPositions,'VariableNames',{'Vehicle','Start positions','Goal positions'})
ans=9×3 table
Vehicle Start positions Goal positions
_______ _____________________________________ _____________________________________
1 130.79 -12.233 -0.00020759 49.544 173.51 0.0009993
2 113.86 -44.576 -0.00076866 53.168 198.75 0.00070254
3 143.37 297.8 -0.00188 3.5187 187.51 0.00057965
4 -25.863 37.977 0.00020468 30.912 175.81 0.00087745
5 24.74 -28.221 -0.00031535 -3.3494 178.66 0.00055764
6 -29.047 -7.817 -0.00053606 108.15 -34.789 -0.00049719
7 26.393 62.042 0.00095438 118.42 192.5 0.00054377
8 73.989 42.717 0.00094018 110.09 248.17 -0.00032446
9 73.996 64.436 0.0011401 177.2 267.68 -0.0015615
Используйте helperGenerateWaypoints
функция для вычисления путевых точек, которые соединяют начальное и целевое положения. Функция возвращает массив структур, который содержит центры дорог, вычисленные точки пути и угол рыскания для каждого транспортного средства в сценарии. Считайте информацию о транспортном средстве из scenario
объект и задайте значения случайной скорости для каждого транспортного средства. Используйте trajectory
функция для генерации траекторий для каждого транспортного средства с помощью вычисленных точек пути и значений случайной скорости.
info = helperGenerateWaypoints(scenario,startPositions,goalPositions); for indx = 1:length(startPositions) vehicleData = scenario.Actors(indx); speed = randi([10,25],1,1); waypts = info(indx).waypoints; trajectory(vehicleData,waypts,speed); end
Установите время остановки для сценария.
scenario.StopTime = 50;
Создайте пользовательский рисунок и отобразите моделируемый сценарий вождения.
close all; figScene = figure; set(figScene,'Position',[0,0,600,600]); movegui(figScene,'center'); hPanel = uipanel(figScene,'Position',[0 0 1 1]); hPlot = axes(hPanel); plot(scenario,'Parent',hPlot); title('Generated Scenario') % Run the simulation while advance(scenario) pause(0.01) end
В сгенерированном сценарии все транспортные средства проходят по своим траекториям с определенной скоростью, чтобы достичь своих целевых положений. Можно также наблюдать столкновение между двумя актёрами, когда они проходят вдоль своих траекторий. В то время как вы синтезируете сценарий для проверки алгоритмов вождения, важно, чтобы транспортные средства в сценарии не сталкивались. Чтобы предотвратить столкновение, вы должны настроить скорость транспортных средств, чтобы они не сталкивались друг с другом во время движения по своим путям.
Используйте модель Simulink CollisionFreeSpeedManipulator
скорректировать скорость транспортных средств таким образом, чтобы они не сталкивались, когда они проходят вдоль своих траекторий. Модель использует нелинейное масштабирование времени, чтобы реактивно ускорить или замедлить транспортное средство, не изменяя ее траекторию [1].
% Open the Simulink system block open_system('CollisionFreeSpeedManipulator'); % Pass the scenario object as input set_param('CollisionFreeSpeedManipulator/VelocityUpdate',... 'ScenarioName','scenario') % Run the simulation and log the output out = sim('CollisionFreeSpeedManipulator','StopTime','50'); % Clear all the temporary variables and close the Simulink block bdclose
Используйте helpergetCFSMScenario
функция для преобразования выхода модели Simulink в объект сценария вождения. Моделируйте и отображайте сценарий вождения. Можно увидеть, что транспортные средства перемещаются по заданным траекториям, чтобы достичь своих целевых положений.
newScenario = helpergetCFSMScenario(out,scenario); close all; figScene = figure; set(figScene,'Position',[0,0,600,600]); movegui(figScene,'center'); hPanel = uipanel(figScene,'Position',[0 0 1 1]); hPlot = axes(hPanel); plot(newScenario,'Parent',hPlot); title('Updated Scenario') hold on h1 = plot(goalPositions(:,1),goalPositions(:,2),'gs','MarkerSize',15,'LineWidth',1.2); h2 = plot(startPositions(:,1),startPositions(:,2),'rs','MarkerSize',15,'LineWidth',1.2); legend([h2 h1],{'Start Positions';'Goal Positions'},'Location','southoutside','Orientation','horizontal') hold off % Run the simulation while advance(newScenario) pause(0.01) end
Можно также экспортировать сценарий в приложение Driving Scenario Designer и запустить симуляцию.
drivingScenarioDesigner(newScenario)
Модель Simulink CollisionFreeSpeedManipulator
регулирует только профиль скорости активных транспортных средств. Когда транспортное средство достигает положения цели и становится неактивной в сценарии, она не рассматривается для проверки столкновений. Если вы хотите сгенерировать сценарий вождения с не сталкивающимися транспортными средствами, выберите точки с меньшей близостью и в различных полосах в качестве начального и целевого положений. Если существует другое транспортное средство, чье целевое положение близко к неактивному транспортному средству, и траектория совпадает с траекторией неактивного транспортного средства, то между этими транспортными средствами произойдет столкновение. Аналогично столкновение происходит, когда два транспортных средства, движущиеся по одной или разным полосам, находятся в непосредственной близости от перекрестков дорог. Кроме того, шансы на столкновение больше, если две или более позиций ворот лежат в одной полосе.
2.
[1] Сингх, Арун Кумар, и К. Мадхава Кришна. «Предотвращение реактивных столкновений для нескольких роботов путем нелинейного масштабирования времени». На 52-й Конференции IEEE по принятию решений и контролю, 952-58. Фиренце: IEEE, 2013. https://doi.org/10.1109/CDC.2013.6760005.
drivingScenario
| plot
| roadNetwork
| vehicle