MATLAB机器人可视化运动仿真

MATLAB机器人可视化运动仿真

摘要
本文在前文SolidWorks转.urdf格式机器人模型导入Matlab中提到的方法基础上,对导入Matlab环境中的机器人模型进行可视化运动仿真,主要运用MATLAB App Designer进行操作界面的简单设计,实现对机器人基于关节运动和TCP运动的手动操作可视化运动仿真。

一 MATLAB App Designer

MATLAB App Designer是Matlab2016b以上版本新出的UI设计软件,详细教程见:https://www.mathworks.com/products/matlab/app-designer.html
其是基于面向对象的编程模式,使用简单方便。

二 关节运动

主要思想是:利用滚动滑条(或键盘输入)设置各关节值,然后用show(app.robot,app.q);不断刷新画面,起到运动仿真的效果。并且通过机器人正运动学实时刷新TCP坐标并显示。部分代码片段如下:

%画面刷新函数
function fShowRobot(app)            	
    app.q=[app.q1 app.q2 app.q3 app.q4 app.q5 app.q6];                   
    show(app.robot,app.q);                  
    axis([-2,2,-2,2,-3,1]);            
    fCurrentTcpPosition(app);        
end  
%当前TCP坐标值显示                      
function fCurrentTcpPosition(app)                 
    Current_T=app.robot.getTransform(app.q,'Link6');    %正运动学            
    app.XEditField.Value=Current_T(1,4);            
    app.YEditField.Value=Current_T(2,4);            
    app.ZEditField.Value=Current_T(3,4);            
    R=tform2eul(Current_T, 'ZYX');            
    app.PXEditField.Value=R(1);              
    app.PYEditField.Value=R(2);             
    app.PZEditField.Value=R(3);                         
    app.XSpinner.Value=app.XEditField.Value;            
    app.YSpinner.Value=app.YEditField.Value;            
    app.ZSpinner.Value=app.ZEditField.Value;            
    app.PXSpinner.Value=app.PXEditField.Value;            
    app.PYSpinner.Value=app.PYEditField.Value;            
    app.PZSpinner.Value=app.PZEditField.Value;                   
end

可视化仿真效果
在这里插入图片描述

三 TCP运动

主要思想是通过手动输入(或微调)TCP位姿坐标【包含位置坐标(x,y,z)和Roll-Pitch-Yaw 角度】,然后通过机器人逆运动学逆解求出关节坐标,最后如二中一样不断刷新机器人显示画面以达到可视化运动仿真的效果。部分代码段如下:


%逆运动学
function fIK(app)           
    if (app.XSpinner.Value<3 && app.XSpinner.Value>-3) &&...            
    (app.YSpinner.Value<3 && app.YSpinner.Value>-3) &&...                
    (app.ZSpinner.Value<3 && app.ZSpinner.Value>-3)                 
         app.TargetPos(1,4)=app.XSpinner.Value;              
         app.TargetPos(2,4)=app.YSpinner.Value;                
         app.TargetPos(3,4)=app.ZSpinner.Value;             
     end             
     rr=eul2tform([app.PXSpinner.Value app.PYSpinner.Value 
     app.PZSpinner.Value],'ZYX');             
     app.TargetPos(1:3,1:3)=rr(1:3,1:3);             
     ik = robotics.InverseKinematics('RigidBodyTree', app.robot);%新建逆解器
     [app.q,app.info]=ik('Link6',app.TargetPos,ones(1,6),app.robot.homeConfiguration);%ones(1,6)代表各关节误差,robot.homeConfiguration代表迭代初始值
end

% Button pushed function: SendPositionButton        
function SendPositionButtonPushed(app, event)            
    fIK(app);                        
    app.q1=app.q(1);            
    app.q1ValEditField.Value=app.q(1)/pi*360;            
    app.J1Slider.Value=app.q(1)/pi*360;            
    app.q2=app.q(2);            
    app.q2ValEditField.Value=app.q(2)/pi*360;            
    app.J2Slider.Value=app.q(2)/pi*360;            
    app.q3=app.q(3);            
    app.q3ValEditField.Value=app.q(3)/pi*360;            
    app.J3Slider.Value=app.q(3)/pi*360;            
    app.q4=app.q(4);            
    app.q4ValEditField.Value=app.q(4)/pi*360;            
    app.J4Slider.Value=app.q(4)/pi*360;            
    app.q5=app.q(5);            
    app.q5ValEditField.Value=app.q(5)/pi*360;            
    app.J5Slider.Value=app.q(5)/pi*360;            
    app.q6=app.q(6);            
    app.q6ValEditField.Value=app.q(6)/pi*360;            
    app.J6Slider.Value=app.q(6)/pi*360;                        
    fShowRobot(app);       
end

% Value changed function: StepPrecisionDropDown        
function StepPrecisionDropDownValueChanged(app, event)            
    if app.StepPrecisionDropDown.Value=="1"                
        app.XSpinner.Step=1;                
        app.YSpinner.Step=1;                
        app.ZSpinner.Step=1;               
        app.PXSpinner.Step=1;                
        app.PYSpinner.Step=1;                
        app.PZSpinner.Step=1;            
    elseif app.StepPrecisionDropDown.Value=="0.1"                
        app.XSpinner.Step=0.1;                
        app.YSpinner.Step=0.1;                
        app.ZSpinner.Step=0.1;                
        app.PXSpinner.Step=0.1;                
        app.PYSpinner.Step=0.1;                
        app.PZSpinner.Step=0.1;            
    elseif app.StepPrecisionDropDown.Value=="0.01"                
        app.XSpinner.Step=0.01;                
        app.YSpinner.Step=0.01;                
        app.ZSpinner.Step=0.01;                
        app.PXSpinner.Step=0.01;                
        app.PYSpinner.Step=0.01;                
        app.PZSpinner.Step=0.01;            
    elseif app.StepPrecisionDropDown.Value=="0.001"                
        app.XSpinner.Step=0.001;                
        app.YSpinner.Step=0.001;                
        app.ZSpinner.Step=0.001;                
        app.PXSpinner.Step=0.001;                
        app.PYSpinner.Step=0.001;                
        app.PZSpinner.Step=0.001;            
    end        
end   

可视化仿真效果
在这里插入图片描述备注:逆解速度较慢,故用TCP运动时会出现卡顿不连贯的现象。

后记:笔者才疏学浅,如有错误,望指出。

clear all v=0; %%目标速度 v_sensor=0;%%传感器速度 t=1; %%扫描周期 xradarpositon=0; %%传感器坐标 yradarpositon=0; %% ppred=zeros(4,4); Pzz=zeros(2,2); Pxx=zeros(4,2); xpred=zeros(4,1); ypred=zeros(2,1); sumx=0; sumy=0; sumxekf=0; sumyekf=0; %%%统计的初值 L=4; alpha=1; kalpha=0; belta=2; ramda=3-L; azimutherror=0.015; %%方位均方误差 rangeerror=100; %%距离均方误差 processnoise=1; %%过程噪声均方差 tao=[t^3/3 t^2/2 0 0; t^2/2 t 0 0; 0 0 t^3/3 t^2/2; 0 0 t^2/2 t]; %% the input matrix of process G=[t^2/2 0 t 0 0 t^2/2 0 t ]; a=35*pi/180; a_v=5/100; a_sensor=45*pi/180; x(1)=8000; %%初始位置 y(1)=12000; for i=1:200 x(i+1)=x(i)+v*cos(a)*t; y(i+1)=y(i)+v*sin(a)*t; end for i=1:200 xradarpositon=0; yradarpositon=0; Zmeasure(1,i)=atan((y(i)-yradarpositon)/(x(i)-xradarpositon))+random('Normal',0,azimutherror,1,1); Zmeasure(2,i)=sqrt((y(i)-yradarpositon)^2+(x(i)-xradarpositon)^2)+random('Normal',0,rangeerror,1,1); xx(i)=Zmeasure(2,i)*cos(Zmeasure(1,i));%%观测值 yy(i)=Zmeasure(2,i)*sin(Zmeasure(1,i)); measureerror=[azimutherror^2 0;0 rangeerror^2]; processerror=tao*processnoise; vNoise = size(processerror,1); wNoise = size(measureerror,1); A=[1 t 0 0; 0 1 0 0; 0 0 1 t; 0 0 0 1]; Anoise=size(A,1); for j=1:2*L+1 Wm(j)=1/(2*(L+ramda)); Wc(j)=1/(2*(L+ramda)); end Wm(1)=ramda/(L+ramda); Wc(1)=ramda/(L+ramda);%+1-alpha^2+belta; %%%权值 if i==1 xerror=rangeerror^2*cos(Zmeasure(1,i))^2+Zmeasure(2,i)^2*azimutherror^2*sin(Zmeasure(1,i))^2; yerror=rangeerror^2*sin(Zmeasure(1,i))^2+Zmeasure(2,i)^2*azimutherror^2*cos(Zmeasure(1,i))^2; xyerror=(rangeerror^2-Zmeasure(2,i)^2*azimutherror^2)*sin(Zmeasure(1,i))*cos(Zmeasure(1,i)); P=[xerror xerror/t xyerror xyerror/t; xerror/t 2*xerror/(t^2) xyerror/t 2*xyerror/(t^2); xyerror xyerror/t yerror yerror/t; xyerror/t 2*xyerror/(t^2) yerror/t 2*yerror/(t^2)]; xestimate=[Zmeasure(2,i)*cos(Zmeasure(1,i)) 0 Zmeasure(2,i)*sin(Zmeasure(1,i)) 0 ]'; end cho=(chol(P*(L+ramda)))';% for j=1:L xgamaP1(:,j)=xestimate+cho(:,j); xgamaP2(:,j)=xestimate-cho(:,j); end Xsigma=[xestimate xgamaP1 xgamaP2]; F=A; Xsigmapre=F*Xsigma; xpred=zeros(Anoise,1); for j=1:2*L+1 xpred=xpred+Wm(j)*Xsigmapre(:,j); end Noise1=Anoise; ppred=zeros(Noise1,Noise1); for j=1:2*L+1 ppred=ppred+Wc(j)*(Xsigmapre(:,j)-xpred)*(Xsigmapre(:,j)-xpred)'; end ppred=ppred+processerror; chor=(chol((L+ramda)*ppred))'; for j=1:L XaugsigmaP1(:,j)=xpred+chor(:,j); XaugsigmaP2(:,j)=xpred-chor(:,j); end Xaugsigma=[xpred XaugsigmaP1 XaugsigmaP2 ]; for j=1:2*L+1 Ysigmapre(1,j)=atan(Xaugsigma(3,j)/Xaugsigma(1,j)) ; Ysigmapre(2,j)=sqrt((Xaugsigma(1,j))^2+(Xaugsigma(3,j))^2); end ypred=zeros(2,1); for j=1:2*L+1 ypred=ypred+Wm(j)*Ysigmapre(:,j); end Pzz=zeros(2,2); for j=1:2*L+1 Pzz=Pzz+Wc(j)*(Ysigmapre(:,j)-ypred)*(Ysigmapre(:,j)-ypred)'; end Pzz=Pzz+measureerror; Pxy=zeros(Anoise,2);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值