Этот пример демонстрирует, как вычислить препятствие свободный путь между двумя местами на данной карте с помощью Вероятностной Дорожной карты (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
и создайте представление сетки заполнения с помощью robotics.BinaryOccupancyGrid
класса. Установите разрешение 2 ячеек на метр для этой карты.
map = robotics.BinaryOccupancyGrid(simpleMap,2);
Отобразите карту с помощью функции show
на объекте
robotics.BinaryOccupancyGrid
show(map)
Чтобы гарантировать, что робот не сталкивается ни с какими препятствиями, необходимо раздуть карту размерностью робота прежде, чем предоставить его планировщику пути PRM.
Здесь размерность робота может быть принята, чтобы быть кругом с радиусом 0,2 метров. Можно затем раздуть карту этой размерностью с помощью функции
inflate
.
robotRadius = 0.2;
Как упомянуто прежде, PRM не составляет размерность робота, и следовательно обеспечение расширенной карты к PRM учитывает размерность робота. Создайте копию карты перед использованием функции inflate
, чтобы сохранить исходную карту.
mapInflated = copy(map); inflate(mapInflated,robotRadius);
Отобразите раздутую карту
show(mapInflated)
Теперь необходимо задать планировщика пути. Создайте объект
robotics.PRM
и задайте связанные атрибуты.
prm = robotics.PRM;
Присвойте расширенную карту объекту PRM
prm.Map = mapInflated;
Задайте количество узлов PRM, которые будут использоваться во время конструкции PRM. PRM создает дорожную карту с помощью данного количества узлов на данной карте. На основе размерности и сложности входной карты, это - один из первичных атрибутов, чтобы настроить порядок получить решение между двумя точками на карте. Большое количество узлов создает плотную дорожную карту, и увеличивает вероятность нахождения пути. Однако наличие большего количества узлов увеличивает время вычисления и для создания дорожной карты и для нахождения решения.
prm.NumNodes = 50;
Задайте максимальное позволенное расстояние между двумя связанными узлами на карте. PRM соединяет все узлы, разделенные этим расстоянием (или меньше) на карте. Это - другой атрибут, чтобы настроиться в случае больших и/или сложных входных карт. Большое расстояние связи увеличивает возможность соединения между узлами, чтобы найти путь легче, но может увеличить время вычисления создания дорожной карты.
prm.ConnectionDistance = 5;
Задайте запускают и заканчивают местоположения на карте для планировщика пути, чтобы использовать.
startLocation = [2 1]; endLocation = [12 10];
Ищите путь между запуском и местоположениями конца с помощью функции
findpath
. Решение является набором waypoints от местоположения запуска в конец местоположение. Обратите внимание на то, что 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 = robotics.BinaryOccupancyGrid(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)
Создайте объект
robotics.OccupancyGrid
с помощью импортированных ternaryMap
данных. ternaryMap
представляет среду с помощью вероятностей, где вероятность заполнения для свободного пространства 0, поскольку занятое место равняется 1, и для неизвестного пробела 0.5. Здесь, разрешение 20 ячеек на метр используется.
map = robotics.OccupancyGrid(ternaryMap,20); show(map)
Скопируйте и раздуйте карту, чтобы включить размер робота для предотвращения препятствия
mapInflated = copy(map); inflate(mapInflated, robotRadius);
Отобразите раздутую карту.
show(mapInflated)
Обновите объект PRM с недавно расширенной картой и задайте другие атрибуты. PRM использует FreeThreshold
на объекте OccupancyGrid определить свободное пространство препятствия и вычисляет путь в этом свободном пространстве препятствия. Значение неизвестных ячеек в ternaryMap
0.5, в то время как FreeThreshold
по умолчанию на объекте OccupancyGrid mapInflated
0.2. В результате PRM не запланирует путь в неизвестной области.
prm.Map = mapInflated;
Установите NumNodes
и свойства ConnectionDistance
prm.NumNodes = 60; prm.ConnectionDistance = 5;
Отобразите график PRM.
show(prm)
Задайте запускают и заканчивают местоположение на карте, чтобы найти препятствие свободным путем.
startLocation = [7 22]; endLocation = [15 5];
Ищите решение между местоположением конца и запуском. Продолжите добавлять узлы, пока путь не будет найден.
path = findpath(prm, startLocation, endLocation); while isempty(path) prm.NumNodes = prm.NumNodes + 10; update(prm); path = findpath(prm, startLocation, endLocation); end
Отобразите путь.
path
path = 10×2
7.0000 22.0000
7.9059 22.1722
10.6881 22.3734
11.7508 19.3716
13.7982 17.1659
17.5826 14.6769
16.8227 9.9964
15.1329 8.3100
14.9489 5.7648
15.0000 5.0000
Отобразите решение PRM.
show(prm)