優雅的求解帶肘偏執的七自由度機械臂封閉逆解

最近做帶偏置的七軸機械臂逆解算法,經過好幾個晚上的學習,基本上算是完成了,還有一些細節有待完善,比如08組解,臂角解算出來目前還沒有時間做,後面在逐步完善吧。該版本給出了一組逆解並用於驗證了這組逆解的正解的正確。
版本:MATLAB 2019 a
工具:實時腳本

目錄
1. 機械臂構型與座標說明
2.解算函數部分
(1)RTB工具性可視化
        a. SDH 參數求解
        b. MDH 參數求解
    (2)正運動學求解
        a.SDH正運動學
        b.MDH正運動學
    (3)逆運動學解算
        1)求解初始逆解
        2)求解期望逆解
附錄:MATLAB函數庫
clc; 
clear all;

%% 帶軸偏置機械臂運動學解算
%  Refer: [1]《肘部偏置七自由度機械臂運動學研究》————哈爾濱工業大學
%         [2]《冗餘空間機器人操作臂:運動學、軌跡規劃及控制》 徐文福著 2017.11
%         [3]《Introduction to Robotics:Mechanics and Control》 John J. Craig
%             Third Edition  2014
%  Methods: 臂型角 phi
%  Date:2019/11/29
%  Update:2019/12/07
%  Author:EasyR
%  Input: 末端位置和姿態[px,py,pz,r,p,y];
%         臂型角phi;
%  Output: 關節角θi

1. 機械臂構型與座標說明



2.解算函數部分
(1)RTB工具性可視化
% Structure RTB
% Structure Parameters
Dbs=0.45; Dse=1.5; Dmm=0.3; Dew=1.5; Dwt=0.45;
a. SDH 參數求解


% theta1=-pi/2; theta2=0; theta3=pi; theta4=0; theta5=pi; theta6=0; theta7=pi/2;
% alpha1=-pi/2; alpha2=pi/2; alpha3=-pi/2; alpha4=pi/2; alpha5=-pi/2; alpha6=pi/2; alpha7=0; 
% 
% % Input vectors
% th=[theta1 theta2 theta3 theta4 theta5 theta6 theta7]';
% alp=[alpha1 alpha2 alpha3 alpha4 alpha5 alpha6 alpha7]';
% d=[Dbs 0 Dse Dmm Dew 0 Dwt]';
% % DH       th     d     a     alpha
% L1 = Link([th(1), d(1), 0, alp(1)  0], 'standard');
% L2 = Link([th(2), d(2), 0, alp(2)  0], 'standard');
% L3 = Link([th(3), d(3), 0, alp(3)  0], 'standard');
% L4 = Link([th(4), d(4), 0, alp(4)  0], 'standard');
% L5 = Link([th(5), d(5), 0, alp(5)  0], 'standard');
% L6 = Link([th(6), d(6), 0, alp(6)  0], 'standard');
% L7 = Link([th(7), d(7), 0, alp(7)  0], 'standard');
% 
% RobotSeven = SerialLink([L1 L2 L3 L4 L5 L6 L7]);
% RobotSeven.name = 'RobotSevenR';
% RobotSeven.comment = 'easyR';
% RobotSeven.display();
% % Forward Pose Kinematics
% % subplot(2,1,1);
% RobotSeven.teach(th');
% RobotSeven.plot(th');
b. MDH 參數求解
   
% Input vectors
d2=[Dbs 0 Dse Dmm Dew 0 Dwt]';
th2=[0 0 0 0 0 0 0 ]';
a2=[0 0 0 0 0 0 0]';
alp2=[0 -pi/2 pi/2 -pi/2 pi/2 -pi/2 pi/2 ]';
% Structure RTB
% DH       thi      di   ai-1   alphai-1
L1 = Link([th2(1), d2(1), a2(1), alp2(1)], 'modified');
L2 = Link([th2(2), d2(2), a2(2), alp2(2)], 'modified');
L3 = Link([th2(3), d2(3), a2(3), alp2(3)], 'modified');
L4 = Link([th2(4), d2(4), a2(4), alp2(4)], 'modified');
L5 = Link([th2(5), d2(5), a2(5), alp2(5)], 'modified');
L6 = Link([th2(6), d2(6), a2(6), alp2(6)], 'modified');
L7 = Link([th2(7), d2(7), a2(7), alp2(7)], 'modified');%座標建到tool

RobotSeven = SerialLink([L1 L2 L3 L4 L5 L6 L7]);
RobotSeven.name = 'RobotSevenR';
RobotSeven.comment = 'easyR';
RobotSeven.display();
% RobotSeven.plot(th2'); 
% RobotSeven.teach(th2')2)正運動學求解
a.SDH正運動學
%% 略

b.MDH正運動學

%% 計算工具端的位置和姿態
dh=myfunMDHTable(th2,d2,a2,alp2);
[T,T10,T20,T30,T40,T50,T60,T70]=myfunTransMatrix(dh);% 輸出末端pos


(3)逆運動學解算
%% 採用臂角計算的方式解算七軸,當d4=0時構成零偏置機械臂
%  input:輸入位置點座標和姿態[px,py,pz,r,p,y] ,6 by 1 matrix
%  outPut:輸出關節角q,column vector 7by1
%  update:
%  state:


% 將結構參數在body coordinate中表示成矢量形式
lbs0=[0 0 Dbs]';
lse3=[0 0 Dse]';
lmm3=[0 Dmm 0]';
lew5=[0 0 Dew]';
lwt7=[0 0 Dwt]';

%——————————————————————————————————————————————————————————————————————————————————————————————%
  %矢量封閉
;
% 從點S指向W的矢量xsw0
%% 驗算上述表達式正確性
%
R30=T30(1:3,1:3);  
T53=T(:,:,4)*T(:,:,5); R53=T53(1:3,1:3);
T75=T(:,:,6)*T(:,:,7); R75=T75(1:3,1:3);
R70=T70(1:3,1:3)  ;

r70=R30*R53*R75  ;
x70=lbs0+R30*((lse3+lmm3)+R53*(lew5+R75*lwt7)) ; %驗證正確

;
%% 驗算上述表達式正確性
%
xsw0=x70-lbs0-R70*lwt7 ;    %驗算正確
% 由上述方程推導可以看出,當末端pos確定後,xsw0隨之確定

%————————————————————————————————————————————————————————————————————————————————————————————%
=+(1-cos)  %繞任意直線sw旋轉角度的座標變換矩陣,3 by 3
,表示當=0時的變換矩陣
引入臂型角求解過程:
1)得到th3=0,phi=phi0時臂型;
2)肘部關節繞直線sw轉動phi,得到最終臂型;
解算逆解過程:
1)解算th3=0,phi=phi0的逆解;初始逆解Initial
2)解算繞直線sw轉動phi的逆解;期望逆解Expect
% solve the Initial ik
%已知工具端位姿[px,py,pz][r,p,y]
% 根據末端位姿求解 from base to tool的變換矩陣R70_Ecpect
% syms px py pz r p y 
px=2.44; py=0.3; pz=0.132; r=-pi; p=pi/4; y=pi;   %用於檢驗帶值解算正確性
% R70_Expect = myfunRPY2R(y,p,r)     
R70_Expect =angle2dcm(r,p,y,'zyx');   %由歐拉角轉化爲旋轉矩陣
1)求解初始逆解

%計算xsw0_Expect的矢量
xsw0_ExpectVector=[px;py;pz]-lbs0-R70_Expect*lwt7 ;       
Xsw0_Expect=norm(xsw0_ExpectVector);    %求取sw長度

%
%計算th4_In
dsw0_Initial2=Xsw0_Expect^2-Dmm^2;
temp4=(dsw0_Initial2-Dse^2-Dew^2)/(2*Dse*Dew);
th4_In=acos(temp4);    %兩組解,一個正一個負
th4_In_1=th4_In;
th4_In_2=-th4_In;
% xsw0_Initial=R30*(lse3+lmm3+R53*lew5);

%
%計算th1_In和th2_In
=
syms th1_In th2_In pi
t10_in=myfunMatrixTrans(th1_In,0.45,0,0);
R100=t10_in(1:3,1:3);
t21_in=myfunMatrixTrans(th2_In,0,0,-pi/2);
R210=t21_in(1:3,1:3);
t32_in=myfunMatrixTrans(0,1.5,0,pi/2); %when alp3=0 or pi,Horizontal stretch;
R320=t32_in(1:3,1:3);
R300=R100*R210*R320;
%當末端關節固定時,肘部關節變換矩陣R43是一個定值,這樣R430=R43
% xsw0_Expect=R300*(lse3+lmm3+R43*lew4)
lew4=[0; -Dew; 0];    %將ew轉化爲在肘部關節座標{4}中的表達便於計算
t43=myfunMatrixTrans(th4_In_1,0,0,-pi/2);
R43=t43(1:3,1:3);
lsw3_In=lse3+lmm3+R43*lew4;
% xsw0_Temp=R300*lsw3_In
% xsw0_ExpectVector
% lsw3_In

%
%解算Th2_In
a=lsw3_In(3);b=-lsw3_In(1);c=xsw0_ExpectVector(3);
d=sqrt(a^2+b^2-c^2);
th2_In_1=atan2(b,a)+atan2(d,c);
th2_In_2=atan2(b,a)-atan2(d,c);

%
%解算Th1_In
a_temp=cos(th2_In_1)*lsw3_In(1)+sin(th2_In_1)*lsw3_In(3);
b_temp=lsw3_In(2);
c1_temp=xsw0_ExpectVector(2);
c2_temp=xsw0_ExpectVector(1);
num1=a_temp*c1_temp-b_temp*c2_temp;
num2=a_temp*c2_temp+b_temp*c1_temp;
den12=a_temp^2+b_temp^2;
th1_In_1 = vpa(atan2((num1/den12),(num2/den12)),6) ; %兩組解之一

a_temp_2=cos(th2_In_2)*lsw3_In(1)+sin(th2_In_2)*lsw3_In(3);
b_temp=lsw3_In(2);
c1_temp=xsw0_ExpectVector(2);
c2_temp=xsw0_ExpectVector(1);
num1_2=a_temp_2*c1_temp-b_temp*c2_temp;
num2_2=a_temp_2*c2_temp+b_temp*c1_temp;
den12_2=a_temp_2.^2+b_temp^2;
th1_In_2 = atan2((num1_2/den12_2),(num2_2/den12_2)) ;%兩組解之二

%
%解算th5_In、th6_In、th7_In

%前四個角已知情況下,根據R47對應項相等分別求解腕部關節角度
R300_Temp=subs(R300,[th1_In th2_In],[th1_In_1 th2_In_1]); %替換參數
R47_Temp=(R43.')*(R300_Temp.')*R70_Expect;

syms th5_In th6_In th7_In
T45=myfunMatrixTrans(th5_In,1.50,0, pi/2);
T56=myfunMatrixTrans(th6_In,0.00,0,-pi/2);
T67=myfunMatrixTrans(th7_In,0.45,0, pi/2);
T47=T45*T56*T67;
R47_Temp_1=T47(1:3,1:3);


%爲方便求解,將R47_temp分解爲不同量用Wij(i=1,2,3;j=1,2,3)表示
W21=R47_Temp(2,1);
W22=R47_Temp(2,2);
W23=R47_Temp(2,3);
W13=R47_Temp(1,3);
W33=R47_Temp(3,3);

th6_In_1=acos(-W23);   %兩組解之一
th6_In_2=-th6_In_1 ;  %兩組解之二
th7_In_1=atan2(-W22,W21);
th5_In_1=atan2( W33,W13);


2)求解期望逆解
求解思想:在求解完成的條件下的初始逆解後,然後繞sw軸轉動角度獲取新的關節解算值作爲機械臂的期望逆解

% syms phi
phi=1.2;
[u0,usw0] = myfunVector2USkew(xsw0_ExpectVector);   %求取位姿已知下轉軸sw的單位反對稱矩陣,即 usw0X
As= usw0*R300_Temp;
Bs=-usw0*usw0*R300_Temp;
Cs= (u0*u0.')*R300_Temp;

R30_Expect=As*sin(phi)+Bs*cos(phi)+Cs;   %期望臂角phi下變換矩陣R30
% vpa(R30_Expect,6)
M31=R30_Expect(3,1);
M32=R30_Expect(3,2);
M33=R30_Expect(3,3);
M13=R30_Expect(1,3);
M23=R30_Expect(2,3);

%求解期望臂角下的關節逆解th1 th2 th3 th4
th1_E=atan2(M23,M13);
th2_E1=acos(M33);
th2_E2=-acos(M33);
th3_E=atan2(M32,-M31);
th4_E1=th4_In;
th4_E2=-th4_In;

%求解期望臂角下關節角th5 th6 th7
R47_Expect=(R43.')*(R30_Expect.')*R70_Expect;

th6_E1=acos(-W23);     %兩組解之一
th6_E2=-acos(-W23);      %兩組解之二
th7_E1=atan2(-W22,W21);
th5_E1=atan2( W33,W13);

disp('輸出其中一組解用於驗證運動學正解:');
t1=vpa(th1_E,10)
t2=vpa(th2_E1,10)
t3=vpa(th3_E,10)
t4=vpa(th4_E1,10)
t5=vpa(th5_E1,10)
t6=vpa(th6_E1,10)
t7=vpa(th7_E1,10)


t=[t1 t2 t3 t4 t5 t6 t7]';
dht=myfunMDHTable(t,d2,a2,alp2);
t70=myfunTransMatrix(dht);
pt=t70(1:3,4) ;%輸出正解的末端位置

Rt=t70(1:3,1:3);Rt=double(Rt);   %轉化爲雙精度double計算
[r1,r2,r3]=dcm2angle(Rt);  %輸出正解的歐拉角

disp('輸出正解末端位姿[px py pz r p y]:');
[px py pz r p y]



附錄:MATLAB函數庫
function dh=myfunMDHTable(q,d,a,alpha)
%Method:MDH
%Goal:compute transform matrix
%Author:easyR
%Date:2019/1/25
%main function is assamble the MDH table for computing
%Variable:q
%q:column vector ,7 by 1
%d: column vector ,7 by 1
%a: column vector ,7 by 1
%alpha: column vector ,7 by 1
q_1=q(1);q_2=q(2);q_3=q(3);q_4=q(4);q_5=q(5);q_6=q(6);q_7=q(7);
d_1=d(1);d_2=d(2);d_3=d(3);d_4=d(4);d_5=d(5);d_6=d(6);d_7=d(7);
a_1=a(1);a_2=a(2);a_3=a(3);a_4=a(4);a_5=a(5);a_6=a(6);a_7=a(7);
alpha_1=alpha(1);alpha_2=alpha(2);alpha_3=alpha(3);alpha_4=alpha(4);alpha_5=alpha(5);alpha_6=alpha(6);alpha_7=alpha(7);
dh=[q_1     q_2     q_3     q_4     q_5     q_6  q_7;
    d_1     d_2     d_3     d_4     d_5     d_6  d_7;
    a_1     a_2     a_3     a_4     a_5     a_6  a_7;
    alpha_1 alpha_2 alpha_3 alpha_4 alpha_5 alpha_6 alpha_7
    ]';

end

%%
%——————————————————————————————————————————————————————————————————————————————————————————————————%
function [T]=myfunMatrixTrans(theta,d,a,alpha)
%Method:MDH
%Goal:compute transform matrix
%Author:easyR
%Date:2019/1/25
T=[ 
                   cos(theta),          -sin(theta),          0,           a;
        sin(theta)*cos(alpha),cos(theta)*cos(alpha),-sin(alpha),-sin(alpha)*d;
        sin(theta)*sin(alpha),cos(theta)*sin(alpha), cos(alpha), cos(alpha)*d;
                            0,                    0,          0,            1
       ];
end

%————————————————————————————————————————————————————————————————————————————————————————————————%
%%
function [T,T10,T20,T30,T40,T50,T60,T70]=myfunTransMatrix(dh)
%Method:MDH
%Goal:compute transform matrix
%Author:easyR
%Date:2019/1/25
%dh:MDH Table
%T:Transform Matrix from endpoint to basement
for k=1:7
    for i=1:k
        T(:,:,k)=myfunMatrixTrans( dh(i,1),dh(i,2),dh(i,3),dh(i,4));
    end
end
% disp('display each transform matrix Tn:');
%%
% transform matrix
T10=(T(:,:,1));T21=(T(:,:,2));T32=(T(:,:,3));T43=(T(:,:,4));T54=(T(:,:,5));T65=(T(:,:,6));T76=(T(:,:,7));
T20=T10*T21;T30=T20*T32;T40=T30*T43;T50=T40*T54;T60=T50*T65;T70=T60*T76;
end

%————————————————————————————————————————————————————————————————————————————————————————————————%

% function [PseInvA]=myfunPseudo(A)
% %compute pseudo inverse matrix of A which det(A)=0
% PseInvA = (inv((A'*A)))*A'
% 
% end

%————————————————————————————————————————————————————————————————————————————————————————————————%
%%
% function R=myfunRPY2R(alpha,beta,gama)
% %input:歐拉角RPY
% %ouput:旋轉矩陣 3by3
% %Note:注意YPR分別表示ZYX的轉角,對應gama beta alpha
% 
% R=[cos(alpha)*cos(beta) cos(alpha)*sin(beta)*sin(gama)-sin(alpha)*cos(gama) cos(alpha)*sin(beta)*cos(gama)+sin(alpha)*sin(gama);...
%     sin(alpha)*cos(beta) sin(alpha)*sin(beta)*sin(gama)+cos(alpha)*cos(gama) sin(alpha)*sin(beta)*cos(gama)-cos(alpha)*sin(gama);...
%     -sin(beta) cos(beta)*sin(gama) cos(beta)*cos(gama)];
% 
% end

%————————————————————————————————————————————————————————————————————————————————————————————————%
%%
% function rpy=myfunR2RPY(r)
% %input:旋轉矩陣 3by3
% %ouput:歐拉角RPY
% 
% beta=atan2(-r(3,1),sqrt(r(1,1).^2+r(2,1).^2));
% 
% if -pi/2 <beta && beta<= pi/2
%     alpha=atan2(r(2,1),r(1,1));
%     gama=atan2(r(3,2),r(3,3));
%     
% elseif pi/2 <beta && beta<= 3*pi/2
%     alpha=atan2(-r(2,1),-r(1,1));
%     gama=atan2(-r(3,2),-r(3,3));
% end
% 
% rpy=[gama,beta,alpha];  %XYZ分別對應alpha beta gama角度RPY
% 
% end

%———————————————————————————————————————————————————————————————————————————————————————————————%

function [u,Us]=myfunVector2USkew(v)
%input:輸入任意3D向量V,3 by 1
%ouput:輸出其單位反對稱矩陣 Us

n=sqrt(v(1)^2+v(2)^2+v(3)^2);
u=[v(1)/n;v(2)/n;v(3)/n];
Us=[   0  -u(3)   u(2);
    u(3)     0   -u(1);
   -u(2)   u(1)     0];

end

%————————————————————————————————————————————————————————————————————————————————————————————————%





輸入與結果:
在這裏插入圖片描述
結果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章