В этом примере показано, как проверить на автоколлизии манипулятора при выполнении траектории. Сетки столкновения загружаются через <collision> тег, заданный в URDF модели робота. Следующие связанные примеры показывают, как загрузить данные о столкновениях другими способами и как проверить на столкновения окружающей среды:
Импорт файла URDF последовательного манипулятора KUKA ® IIWA-14 в качестве rigidBodyTree модель. URDF захватывает файлы mesh столкновения для твердых тел робота. Чтобы индивидуально добавить объекты столкновения в твердое тело, можно использовать addCollision функция. Чтобы загрузить предоставленную модель робота с присоединенными объектами столкновения, смотрите loadrobot функция.
iiwa = importrobot('iiwa14.urdf'); iiwa.DataFormat = 'column';
Задайте начало и конец как набор положений соединений. Эти положения должны быть свободными от столкновения.
startConfig = [0 -pi/4 pi 3*pi/2 0 -pi/2 pi/8]'; goalConfig = [0 -pi/4 pi 3*pi/4 0 -pi/2 pi/8]';
Найдите траекторию пространства соединений, которая соединяет два строений в течение трех секунд.
q = trapveltraj([startConfig goalConfig],100,'EndTime',3);Чтобы убедиться, что эта выходная траектория не содержит автоколлизий, повторите итерацию над выходными выборками и проверьте, находятся ли какие-либо точки в коллизии с помощью checkCollision функция.
Во время итерации по траектории q, вызовите checkCollision функция на каждом строении в траектории. Включите исчерпывающую проверку, чтобы продолжить проверку на наличие конфликтов после обнаружения первого.
The isConfigInCollision переменная отслеживает состояние столкновения каждого строения. The sepDistForConfig отслеживает расстояние между телами робота. Для каждого столкновения пара индексов тела сохранена в configCollisionPairs переменная. Обратите внимание, что соседние тела не проверяются, так как они всегда находятся в контакте через соединяющее их соединение.
isConfigInCollision = false(100,1); configCollisionPairs = cell(100,1); sepDistForConfig = zeros(iiwa.NumBodies+1,iiwa.NumBodies+1,100); for i = 1:length(q) [isColliding, sepDist] = checkCollision(iiwa,q(:,i),'Exhaustive','on'); isConfigInCollision(i) = isColliding; sepDistForConfig(:,:,i) = sepDist; end
Чтобы узнать индексы тел, находящихся в столкновении, найдите какие записи в sepDistForConfig являются NaN. septDist является симметричной матрицей, поэтому то же самое значение возвращается в индексах с развернутыми индексами. Упростите список при помощи unique.
for i = 1:length(q) sepDist = sepDistForConfig(:,:,i); [body1Idx,body2Idx] = find(isnan(sepDist)); collidingPairs = unique(sort([body1Idx,body2Idx],2)); configCollisionPairs{i} = collidingPairs; end
При просмотре выхода можно увидеть, как запланированная траектория проходит через ряд столкновений. Визуализируйте строение, где происходит первое столкновение, и подсвечивайте тела.
any(isConfigInCollision)
ans = logical
1
firstCollisionIdx = find(isConfigInCollision,1);
% Visualize the first configuration that is in collision.
figure;
show(iiwa,q(:,firstCollisionIdx));
exampleHelperHighlightCollisionBodies(iiwa,configCollisionPairs{firstCollisionIdx}+1,gca);
Это первое столкновение фактически происходит в начальном строении, потому что положение соединения задано за его пределами. Функции wrapToPi ограничить исходные положения соединений.
Сгенерируйте новую траекторию и снова проверяйте на столкновения.
newStartConfig = wrapToPi(startConfig); q = trapveltraj([newStartConfig goalConfig],100,'EndTime',3); isConfigInCollision = false(100,1); configCollisionPairs = cell(100,1); for i = 1:length(q) isColliding = checkCollision(iiwa,q(:,i),'Exhaustive','on'); isConfigInCollision(i) = isColliding; end
После проверки всей траектории столкновения не обнаруживаются.
any(isConfigInCollision)
ans = logical
0