Этот пример демонстрирует, как вычислить путь без препятствий между двумя местоположениями на заданной карте с помощью планировщика пути Вероятностной дорожной карты (PRM). Планировщик пути PRM создает дорожную карту в свободном пространстве заданной карты, используя случайным образом выбранные узлы в свободном пространстве и соединяя их друг с другом. После создания маршрутной карты можно запросить путь от заданного начального местоположения до заданного конечного местоположения на карте.
В этом примере карта представлена как сетчатая карта заполнения с использованием импортированных данных. При дискретизации узлов в свободном пространстве карты PRM использует это двоичное представление сетки заполнения, чтобы вывести свободное пространство. Кроме того, PRM не учитывает размерность робота при вычислении пути без препятствий на карте. Следовательно, вы должны надуть карту по размерности робота, порядок позволить расчету путь без препятствий, который учитывает размер робота и обеспечивает предотвращение столкновения для фактического робота. Определите начальное и конечное местоположения на карте для планировщика пути PRM, чтобы найти путь без препятствий.
load exampleMaps.mat
Импортированные карты: simpleMap
, complexMap
и ternaryMap
.
whos *Map*
Name Size Bytes Class Attributes complexMap 41x52 2132 logical emptyMap 26x27 702 logical simpleMap 26x27 702 logical ternaryMap 501x501 2008008 double
Используйте импортированную simpleMap
Данные и конструкция представление сетки заполнения с помощью binaryOccupancyMap
объект. Установите разрешение 2 камеры на метр для этой карты.
map = binaryOccupancyMap(simpleMap,2);
Отобразите карту с помощью show
функция на binaryOccupancyMap
объект
show(map)
Чтобы убедиться, что робот не сталкивается с какими-либо препятствиями, необходимо надуть карту на размерность робота, прежде чем подавать ее в планировщик пути PRM.
Здесь размерностью робота может быть принята окружность радиусом 0,2 метра. Затем можно надуть карту по этой размерности, используя inflate
функция.
robotRadius = 0.2;
Как упоминалось выше, PRM не учитывает размерность робота, и, следовательно, предоставление надувной карты в PRM учитывает размерность робота. Создайте копию карты перед использованием inflate
функция для сохранения исходной карты.
mapInflated = copy(map); inflate(mapInflated,robotRadius);
Отобразите надутую карту
show(mapInflated)
Теперь необходимо задать планировщик пути. Создайте mobileRobotPRM
и задайте связанные атрибуты.
prm = mobileRobotPRM;
Присвойте завышенную карту объекту PRM
prm.Map = mapInflated;
Определите количество узлов PRM, которые будут использоваться во время конструкции PRM. PRM создает дорожную карту с использованием заданного числа узлов на данной карте. Основываясь на размерности и сложности карты входа, это один из основных атрибутов, который можно настроить, порядок получить решение между двумя точками на карте. Большое число узлов создаёт плотную дорожную карту и увеличивает вероятность нахождения пути. Однако наличие большего количества узлов увеличивает время расчета как для создания дорожной карты, так и для нахождения решения.
prm.NumNodes = 50;
Задайте максимально допустимое расстояние между двумя связанными узлами на карте. PRM соединяет все узлы, разделенные этим расстоянием (или менее) на карте. Это другой атрибут для настройки в случае больших и/или сложных входных карт. Большое расстояние соединения увеличивает связность между узлами, чтобы легче найти путь, но может увеличить время расчета создания дорожной карты.
prm.ConnectionDistance = 5;
Определите начало и конец местоположения на карте для использования планировщиком пути.
startLocation = [2 1]; endLocation = [12 10];
Поиск пути между начальным и конечным местоположениями с помощью findpath
функция. Решение представляет собой набор путевых точек от начального местоположения до конечного местоположения. Обратите внимание, что path
будет отличаться из-за вероятностного характера алгоритма PRM.
path = findpath(prm, startLocation, endLocation)
path = 7×2
2.0000 1.0000
1.9569 1.0546
1.8369 2.3856
3.2389 6.6106
7.8260 8.1330
11.4632 10.5857
12.0000 10.0000
Отображение решения PRM.
show(prm)
Используйте импортированную complexMap
данные, который представляет собой большой и сложный план этажа и создает представление двухкомпонентной сетки заполнения с заданным разрешением (1 камера на метр)
map = binaryOccupancyMap(complexMap,1);
Отобразите карту.
show(map)
Скопируйте и надьте карту в коэффициент размера робота для предотвращения препятствий
mapInflated = copy(map); inflate(mapInflated, robotRadius);
Отобразите надутую карту.
show(mapInflated)
Обновите объект PRM с помощью только что завышенной карты и задайте другие атрибуты.
prm.Map = mapInflated;
Установите NumNodes
и ConnectionDistance
свойства.
prm.NumNodes = 20; prm.ConnectionDistance = 15;
Отобразите график PRM.
show(prm)
Задайте начальное и конечное расположение на карте, чтобы найти путь без препятствий.
startLocation = [3 3]; endLocation = [45 35];
Поиск решения между начальным и конечным местоположением. Для сложных карт может не быть допустимого пути для данного числа узлов (возвращает пустой путь).
path = findpath(prm, startLocation, endLocation);
Поскольку вы планируете путь на большой и сложной карте, могут потребоваться большие числа узлов. Однако часто непонятно, сколько узлов будет достаточно. Настройте число узлов, чтобы убедиться, что между расположением начала и конца есть допустимый путь.
while isempty(path) % No feasible path found yet, increase the number of nodes prm.NumNodes = prm.NumNodes + 10; % Use the |update| function to re-create the PRM roadmap with the changed % attribute update(prm); % Search for a feasible path with the updated PRM path = findpath(prm, startLocation, endLocation); end
Отобразите путь.
path
path = 12×2
3.0000 3.0000
4.2287 4.2628
7.7686 5.6520
6.8570 8.2389
19.5613 8.4030
33.1838 8.7614
31.3248 16.3874
41.3317 17.5090
48.3017 25.8527
49.4926 36.8804
⋮
Отобразите решение PRM.
show(prm)