exponenta event banner

Проверка собственных столкновений манипулятора с помощью сетей коллизий

В этом примере показано, как проверять наличие самовлияний манипулятора при выполнении траектории. Сети столкновения загружаются через <collision> тег, определенный в URDF модели робота. В следующих связанных примерах показано, как загружать данные о столкновениях другими способами и как проверять наличие столкновений в окружающей среде:

Создание представления робота

Импорт файла URDF последовательного манипулятора KUKA ® IIWA-14 в качестве rigidBodyTree модель. URDF захватывает файлы сетей столкновения для жестких тел робота. Для индивидуального добавления объектов столкновения к жесткому телу можно использовать 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 функция на каждой конфигурации в траектории. Включите исчерпывающую проверку, чтобы продолжить проверку на наличие конфликтов после обнаружения первого.

isConfigInCollision переменная отслеживает состояние коллизий каждой конфигурации. 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);

Figure contains an axes. The axes contains 29 objects of type patch, line. These objects represent world, iiwa_link_0, iiwa_link_1, iiwa_link_2, iiwa_link_3, iiwa_link_4, iiwa_link_5, iiwa_link_6, iiwa_link_7, iiwa_link_ee, iiwa_link_ee_kuka, iiwa_link_0_mesh, iiwa_link_1_mesh, iiwa_link_2_mesh, iiwa_link_3_mesh, iiwa_link_4_mesh, iiwa_link_5_mesh, iiwa_link_6_mesh, iiwa_link_7_mesh.

Создание траектории без столкновений

Это первое столкновение на самом деле происходит в начальной конфигурации, потому что положение соединения задается за его пределами. Звонить 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