You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
4.8 KiB
148 lines
4.8 KiB
%SerialLink.COLLISIONS Perform collision checking
|
|
%
|
|
% C = R.collisions(Q, MODEL) is true if the SerialLink object R at
|
|
% pose Q (1xN) intersects the solid model MODEL which belongs to the
|
|
% class CollisionModel. The model comprises a number of geometric
|
|
% primitives and associate pose.
|
|
%
|
|
% C = R.collisions(Q, MODEL, DYNMODEL, TDYN) as above but also checks
|
|
% dynamic collision model DYNMODEL whose elements are at pose TDYN.
|
|
% TDYN is an array of transformation matrices (4x4xP), where
|
|
% P = length(DYNMODEL.primitives). The P'th plane of TDYN premultiplies the
|
|
% pose of the P'th primitive of DYNMODEL.
|
|
%
|
|
% C = R.collisions(Q, MODEL, DYNMODEL) as above but assumes TDYN is the
|
|
% robot's tool frame.
|
|
%
|
|
% Trajectory operation::
|
|
%
|
|
% If Q is MxN it is taken as a pose sequence and C is Mx1 and the collision
|
|
% value applies to the pose of the corresponding row of Q. TDYN is 4x4xMxP.
|
|
%
|
|
% Notes::
|
|
% - Requires the pHRIWARE package which defines CollisionModel class.
|
|
% Available from: https://code.google.com/p/phriware/ .
|
|
% - The robot is defined by a point cloud, given by its points property.
|
|
% - The function does not currently check the base of the SerialLink
|
|
% object.
|
|
% - If MODEL is [] then no static objects are assumed.
|
|
%
|
|
% Author::
|
|
% Bryan Moutrie
|
|
%
|
|
% See also CollisionModel, SerialLink.
|
|
|
|
% Copyright (C) Bryan Moutrie, 2013-2015
|
|
% Licensed under the GNU Lesser General Public License
|
|
% see full file for full statement
|
|
%
|
|
% LICENSE STATEMENT:
|
|
%
|
|
% This file is part of pHRIWARE.
|
|
%
|
|
% pHRIWARE is free software: you can redistribute it and/or modify
|
|
% it under the terms of the GNU Lesser General Public License as
|
|
% published by the Free Software Foundation, either version 3 of
|
|
% the License, or (at your option) any later version.
|
|
%
|
|
% pHRIWARE is distributed in the hope that it will be useful,
|
|
% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
% GNU General Public License for more details.
|
|
%
|
|
% You should have received a copy of the GNU Lesser General Public
|
|
% License along with pHRIWARE. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
function c = collisions(robot, q, cmdl, dyn_cmdl, dyn_T)
|
|
|
|
if ~exist('pHRIWARE')
|
|
error('rtb:collisions:nosupport', 'You need to install pHRIWARE in order to use this functionality');
|
|
end
|
|
|
|
% VERSION WITH BASE CHECKING
|
|
% pts = robot.points;
|
|
pts = robot.points(end-robot.n+1:end);
|
|
for i = length(pts): -1: 1
|
|
numPts(i) = size(pts{i},1);
|
|
pts{i}(:,4) = 1;
|
|
pts{i} = pts{i}';
|
|
end
|
|
|
|
if isempty(cmdl), checkfuns = []; else checkfuns = cmdl.checkFuns; end
|
|
if nargin > 3
|
|
dyn_checkfuns = dyn_cmdl.checkFuns;
|
|
if nargin == 4 || isempty(dyn_T)
|
|
tool = robot.tool;
|
|
dyn_T = [];
|
|
end
|
|
else
|
|
dyn_checkfuns = [];
|
|
end
|
|
|
|
% VERSION WITH BASE CHECKING
|
|
% base = length(pts) - robot.n;
|
|
% switch base
|
|
% case 0
|
|
% % No base
|
|
% case 1
|
|
% T = robot.base;
|
|
% trPts = T * pts{1};
|
|
% points = trPts (1:3,:)';
|
|
% if any(checkfuns{1}(points(:,1),points(:,2),points(:,3)))
|
|
% C(:) = 1;
|
|
% display('Base is colliding');
|
|
% return;
|
|
% end
|
|
% otherwise
|
|
% error('robot has missing or extra points');
|
|
% end
|
|
|
|
poses = size(q,1);
|
|
c = false(poses, 1);
|
|
|
|
nan = any(isnan(q),2);
|
|
c(nan) = true;
|
|
notnan = find(~nan)';
|
|
|
|
T0 = robot.base;
|
|
|
|
for p = notnan
|
|
T = T0;
|
|
prevPts = 0;
|
|
for i = 1: robot.n;
|
|
T = T * robot.links(i).A(q(p,i));
|
|
if numPts(i) % Allows some links to be STLless
|
|
% VERSION WITH BASE CHECKING
|
|
% nextPts = prevPts+numPts(i+base);
|
|
% trPts(:,prevPts+1:nextPts) = T * pts{i+base};
|
|
nextPts = prevPts+numPts(i);
|
|
trPts(:,prevPts+1:nextPts) = T * pts{i};
|
|
prevPts = nextPts;
|
|
end
|
|
end
|
|
|
|
% Does same thing as cmdl.collision(trPoints(1:3,:)'), but
|
|
% Does not have to access object every time - quicker
|
|
for i = 1: length(checkfuns)
|
|
if any(checkfuns{i}(trPts(1,:), trPts(2,:), trPts(3,:)))
|
|
c(p) = true;
|
|
break;
|
|
end
|
|
end
|
|
|
|
% Then check the dynamic collision models, if any
|
|
for i = 1: length(dyn_checkfuns)
|
|
if isempty(dyn_T)
|
|
dyn_trPts = T*tool \ trPts;
|
|
else
|
|
dyn_trPts = dyn_T(:,:,p,i) \ trPts;
|
|
end
|
|
if any(dyn_checkfuns{i}(dyn_trPts(1,:), dyn_trPts(2,:), ...
|
|
dyn_trPts(3,:)))
|
|
c(p) = true;
|
|
break;
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|