赞
踩
注:全文为本人见解,如有错误请指点!
以下代码直接对robotics工具箱中的ikine函数进行解释
%SerialLink.ikine Inverse kinematics by optimization without joint limits % % Q = R.ikine(T) are the joint coordinates (1xN) corresponding to the robot % end-effector pose T which is an SE3 object or homogenenous transform % matrix (4x4), and N is the number of robot joints. % % This method can be used for robots with any number of degrees of freedom. % 这个方法适用于任意自由度的机器人 % % Options:: % 'ilimit',L maximum number of iterations (default 500) 迭代次数 % 'rlimit',L maximum number of consecutive step rejections (default 100) 最大连续拒绝次数 % 'tol',T final error tolerance (default 1e-10) 最终误差容限 % 'lambda',L initial value of lambda (default 0.1) 步长 % 'lambdamin',M minimum allowable value of lambda (default 0) 步长的最小值 % 'quiet' be quiet 输出保持安静 % 'verbose' be verbose 输出内容详细 % 'mask',M mask vector (6x1) that correspond to translation in X, Y and Z, % and rotation about X, Y and Z respectively. mask向量,表示机器人自由度 % 'q0',Q initial joint configuration (default all zeros) 迭代的初始关节形位 % 'search' search over all configurations 搜索所有形位 % 'slimit',L maximum number of search attempts (default 100) 最大搜索尝试数目 % 'transpose',A use Jacobian transpose with step size A, rather than % Levenberg-Marquadt 使用步长为A的雅可比转置,而不是LM方法 % % Trajectory operation:: % % In all cases if T is a vector of SE3 objects (1xM) or a homogeneous % transform sequence (4x4xM) then returns the joint coordinates % corresponding to each of the transforms in the sequence. Q is MxN where % N is the number of robot joints. The initial estimate of Q for each time % step is taken as the solution from the previous time step. % 使用上一步的解作为当前步的初始值 % % Underactuated robots:: 欠驱动机器人 % % For the case where the manipulator has fewer than 6 DOF the solution % space has more dimensions than can be spanned by the manipulator joint % coordinates. % 欠驱动机器人解空间维数比关节坐标维数多? % % In this case we specify the 'mask' option where the mask % vector (1x6) specifies the Cartesian DOF (in the wrist coordinate % frame) that will be ignored in reaching a solution. The mask vector % has six elements that correspond to translation in X, Y and Z, and rotation % about X, Y and Z respectively. The value should be 0 (for ignore) or 1. % The number of non-zero elements should equal the number of manipulator DOF. % 使用“mask”矢量指定失去的自由度,机器人自由度等于改矢量的非零元素的个数。 % % For example when using a 3 DOF manipulator rotation orientation might be % unimportant in which case use the option: 'mask', [1 1 1 0 0 0]. % 举个例子,当使用三自由度机械手时,旋转方向可能不重要(不影响逆运动学求解),mask向量设置为[1 1 1 0 0 0] % % For robots with 4 or 5 DOF this method is very difficult to use since % orientation is specified by T in world coordinates and the achievable % orientations are a function of the tool position. % 对于4或5个自由度的机器人,这种方法较难使用 % % References:: % - Robotics, Vision & Control, P. Corke, Springer 2011, Section 8.4. % % Notes:: % - This has been completely reimplemented in RTB 9.11 % - Does NOT require MATLAB Optimization Toolbox. 不需要matlab优化工具箱 % - Solution is computed iteratively. 采用迭代的方法 % - Implements a Levenberg-Marquadt variable step size solver. % 通过LM变步长求解器实现 % - The tolerance is computed on the norm of the error between current % and desired tool pose. This norm is computed from distances % and angles without any kind of weighting. % 误差是根据当前工具姿态和期望(求解)姿态的范数计算 % - The inverse kinematic solution is generally not unique, and % depends on the initial guess Q0 (defaults to 0). % 求解的值不唯一,且与初值有关,初值Q0默认为0 % - The default value of Q0 is zero which is a poor choice for most % manipulators (eg. puma560, twolink) since it corresponds to a kinematic % singularity. % Q0设置为[0 0 0 0 0 0],这对于部机器人(puma560,twolink)不是好选择,因为其对应运动学奇点 % - Such a solution is completely general, though much less efficient % than specific inverse kinematic solutions derived symbolically, like % ikine6s or ikine3. % 这是通用的解法,所以效率不高 % - This approach allows a solution to be obtained at a singularity, but % the joint angles within the null space are arbitrarily assigned. % 此方法可能在奇异点求出解 % - Joint offsets, if defined, are added to the inverse kinematics to % generate Q. % 如果定义了关节偏移,将添加到逆运动学中以生成Q % - Joint limits are not considered in this solution. % 不考虑关节的范围限制 % - The 'search' option peforms a brute-force search with initial conditions % chosen from the entire configuration space. % “search”选项形成一个强力搜索,初始条件从整个关节空间中随机选择 % - If the 'search' option is used any prismatic joint must have joint % limits defined. % 如果使用“搜索”选项,则任何移动关节都必须定义关节范围 % % See also SerialLink.ikcon, SerialLink.ikunc, SerialLink.fkine, SerialLink.ikine6s. % Copyright (C) 1993-2017, by Peter I. Corke % % This file is part of The Robotics Toolbox for MATLAB (RTB). % % RTB 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. % % RTB 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 Lesser General Public License for more details. % % You should have received a copy of the GNU Leser General Public License % along with RTB. If not, see <http://www.gnu.org/licenses/>. % % http://www.petercorke.com %TODO: % search do a broad search from random points in configuration space function qt = ikine(robot, tr, varargin) n = robot.n; %关节变量的个数 TT = SE3.check(tr); %转换为SE3矩阵 % set default parameters for solution 默认参数设置 opt.ilimit = 500; %默认迭代次数 opt.rlimit = 100; %最大连续拒绝次数 opt.slimit = 100; %最大尝试次数 opt.tol = 1e-10; %默认迭代误差 opt.lambda = 0.1; %默认步长 opt.lambdamin = 0; %默认步长最小值 opt.search = false; %默认关闭搜索初值 opt.quiet = false; %保持安静,减少输出 opt.verbose = false; %输出的信息详细 opt.mask = [1 1 1 1 1 1]; %默认六自由度 opt.q0 = zeros(1, n); %初始关节形位为零位 opt.transpose = NaN; %默认使用LM方法 [opt,args] = tb_optparse(opt, varargin); %输入参数传递 if opt.search %如果为true,执行,随机选取迭代初值 % randomised search for a starting point opt.search = false; %关闭搜索初值 opt.quiet = true; %保持安静 %args = args{2:end}; for k=1:opt.slimit %循环到最大尝试次数 for j=1:n qlim = robot.links(j).qlim; %传递机器人关节变量的范围 if isempty(qlim) %是否为空集 if robot.links(j).isrevolute %是否为旋转关节 q(j) = rand*2*pi - pi; %产生-pi到pi的随机初值 else error('For a prismatic joint, search requires joint limits'); %对于移动关节,需要定义关节范围 end else q(j) = rand*(qlim(2)-qlim(1)) + qlim(1); %产生关节范围内的随机初值 end end fprintf('Trying q = %s\n', num2str(q)); %输出“尝试q的值为 ” q = robot.ikine(tr, q, args{:}, 'setopt', opt); %以此为初值,计算结果 if ~isempty(q) qt = q; %如果不为空集,q为所求值 return; end end error('no solution found, are you sure the point is reachable?'); %找不到解,你确定该点可到达?(尝试完最大尝试次数) qt = []; return end assert(numel(opt.mask) == 6, 'RTB:ikine:badarg', 'Mask matrix should have 6 elements'); %如果mask没有6个参数,报错 assert(n >= numel(find(opt.mask)), 'RTB:ikine:badarg', 'Number of robot DOF must be >= the same number of 1s in the mask matrix'); %如果机器人自由度小于mask矩阵的1元素个数,报错 W = diag(opt.mask); %W为以mask矩阵为对角线的矩阵 qt = zeros(length(TT), n); % preallocate space for results 为解预分配空间 tcount = 0; % total iteration count 初始化总迭代次数 rejcount = 0; % rejected step count 初始化持续拒绝的迭代次数 q = opt.q0; %给迭代初值 failed = false; %迭代失败的标签 revolutes = robot.isrevolute(); %给机器人的关节构型(移动为0或旋转为1,全为旋转为[1 1 1 1 1 1]) for i=1:length(TT) %循环到输入的SE3的个数 T = TT(i); %给其中某个SE3 lambda = opt.lambda; %给默认步长 iterations = 0; %初始化迭代次数 if opt.debug %是否调试程序,默认不调试,跳 if e = tr2delta(robot.fkine(q), T); %给从初始零位的位姿到输入位姿的对应微分运动,d=(dx, dy, dz, dRx, dRy, dRz) fprintf('Initial: |e|=%g\n', norm(W*e)); end while true %开始进行迭代 % update the count and test against iteration limit iterations = iterations + 1; %计数迭代次数 if iterations > opt.ilimit %超过迭代最大次数 if ~opt.quiet %quiet值为0,不保持安静,执行 warning('ikine: iteration limit %d exceeded (pose %d), final err %g', ... opt.ilimit, i, nm); end failed = true; break %迭代失败,并跳出循环 end e = tr2delta(robot.fkine(q), T); % are we there yet if norm(W*e) < opt.tol break; %如果小于容许误差,跳出循环 end % compute the Jacobian J = jacobe(robot, q); %给当前形位下的雅各比矩阵 JtJ = J'*W*J; if ~isnan(opt.transpose) %是否使用LM方法,进行 % do the simple Jacobian transpose with constant gain dq = opt.transpose * J' * e; else % do the damped inverse Gauss-Newton with Levenberg-Marquadt % 用LM法做阻尼逆高斯牛顿 dq = inv(JtJ + (lambda + opt.lambdamin) * eye(size(JtJ)) ) * J' * W * e; %迭代公式 % compute possible new value of 得到新的关节值 qnew = q + dq'; % and figure out the new error 得到新的误差值 enew = tr2delta(robot.fkine(qnew), T); % was it a good update? if norm(W*enew) < norm(W*e) %该步是否成功 % step is accepted if opt.debug %是否调试程序,默认不调试,跳 if fprintf('ACCEPTED: |e|=%g, |dq|=%g, lambda=%g\n', norm(W*enew), norm(dq), lambda); end q = qnew; e = enew; %给迭代新值 lambda = lambda/2; rejcount = 0; %持续拒绝的迭代次数置0 else % step is rejected, increase the damping and retry % 该步被拒绝,增加阻尼并重试 if opt.debug %是否调试程序,默认不调试,跳 if fprintf('rejected: |e|=%g, |dq|=%g, lambda=%g\n', norm(W*enew), norm(dq), lambda); end lambda = lambda*2; rejcount = rejcount + 1; if rejcount > opt.rlimit %超过最大拒绝次数,进行 if ~opt.quiet %是否保持输出安静,默认保持,跳 else warning('ikine: rejected-step limit %d exceeded (pose %d), final err %g', ... opt.rlimit, i, norm(W*enew)); end failed = true; break; %迭代失败,跳出循环 end continue; % try again 修改步长后继续尝试 end end % wrap angles for revolute joints 将旋转关节的关节值移到-pi~pi中 k = (q > pi) & revolutes; q(k) = q(k) - 2*pi; k = (q < -pi) & revolutes; q(k) = q(k) + 2*pi; nm = norm(W*e); end % end ikine solution for this pose qt(i,:) = q'; tcount = tcount + iterations; %总共迭代次数,包括多个SE3值的情况 if opt.verbose && ~failed %是否保持输出详细且迭代成功 fprintf('%d iterations\n', iterations); end if failed if ~opt.quiet %是否失败且不保持安静 warning('failed to converge: try a different initial value of joint coordinates'); %未能收敛,尝试不同的初值 end qt = []; end end if opt.verbose && length(TT) > 1 %如果详细且有多个SE3值 fprintf('TOTAL %d iterations\n', tcount); %输出总迭代次数 end end
设置的”search“选项不起作用
我经过多次尝试,发现无论其随机选取的迭代初值q为多少,程序实际上还是从q0=[0 0 0 0 0 0]开始迭代。
我猜测,q = robot.ikine(tr, q, args{:}, 'setopt', opt);
这行代码有问题。
随机选取的迭代初值q,并没有被传递进去。
将这行代码改为 q = robot.ikine(tr, 'setopt', opt, 'q0',q, args{:});
有效果,但不知是否有其他影响,请慎重
迭代公式
未完待续~