📄 invkine.m
字号:
function invkine(action)
%INVKINE Inverse kinematics of a robot arm.
% INVKINE opens a window for animation of the inverse kinematics
% problem of the two-joint robot arm system. The ellipse is the
% desired trajectory; you can change the location of the ellipse by
% clicking mouse inside it and dragging it to another location.
% The x marks in the background indicate the location of each
% training data pair.
%
% The training of ANFIS for this problem was done off-line.
% To see how the training data set was collected and how to do
% the training, see the file traininv.m. To see both the surfaces
% for forward and backward kinematics, try invsurf.m.
%
% File: invkine.m
%
% See also INVSURF, TRAININV.
% Roger Jang, 3-31-94, 10-17-94, 12-23-94
% Copyright 1994-2004 The MathWorks, Inc.
% $Revision: 1.15.2.5.2.1 $ $Date: 2005/07/17 06:06:16 $
if nargin == 0,
action = 'initialize';
end
global InvKineInsideEllipse InvKineCurrPt
global InvKineFigH InvKineFigTitle InvKineAxisH
global InvKineAnimRunning InvKineAnimStepping InvKineAnimPause
global InvKineAnimClose InvKineCount InvKineFisMat1 InvKineFisMat2
if strcmp(action, 'initialize'),
InvKineFigTitle = 'Two-Joint Planar Robot Arm: Animation';
InvKineFigH = findobj(0, 'Name', InvKineFigTitle);
InvKineCount = 1;
if isempty(InvKineFigH)
%eval([mfilename, '(''set_standard_gui'')']);
%eval([mfilename, '(''set_extra_gui'')']);
eval([mfilename, '(''set_all_gui'')']);
eval([mfilename, '(''set_anim_obj'')']);
eval([mfilename, '(''set_mouse_action'')']);
eval([mfilename, '(''load_fis_mat'')']);
eval([mfilename, '(''single_loop'')']);
% ====== change to normalized units
set(findobj(InvKineFigH,'Units','pixels'), 'Units','normal');
% ====== make all UI interruptable
set(findobj(InvKineFigH,'Interrupt','off'), 'Interrupt','on');
else
eval([mfilename, '(''set_init_cond'')']);
% set(gcf, 'color', get(gcf, 'color'));
refresh(gcf);
end
eval([mfilename, '(''set_constant'')']);
elseif strcmp(action, 'set_constant'),
InvKineAnimRunning = 0;
InvKineAnimStepping = 0;
InvKineAnimPause = 0;
InvKineAnimClose = 0;
elseif strcmp(action, 'set_all_gui'),
%elseif strcmp(action, 'set_standard_gui'),
% ====== standard UI's
% ====== % No figure, initialize everything
ui_row_n = 2; % No. of UI rows
% ###### default UI settings for SIMUINK ######
InvKineFigH = figure( ...
'Name', InvKineFigTitle, ...
'NumberTitle', 'off', ...
'DockControls', 'off');
% Set V4 default color
colordef(InvKineFigH, 'black');
set(InvKineFigH, 'color', [0 0 0], ...
'ResizeFcn', [mfilename, '(''resize'')']);
set(0, 'Currentfigure', InvKineFigH);
dCurrUnits = get(InvKineFigH, 'units');
set(InvKineFigH, 'units', 'character');
figPosChar = get(InvKineFigH, 'position');
if figPosChar(3)<110
prodRatio = 110/figPosChar(3);
figPosChar = figPosChar*prodRatio;
set(InvKineFigH,'position', figPosChar);
end
set(InvKineFigH, 'units', dCurrUnits);
figPos = get(InvKineFigH, 'position');
% ====== proportion of UI frame and axes
ui_area = 0.2;
axis_area = 1-ui_area;
% ====== animation area
axisPos = [45 (figPos(4)*ui_area)+35 figPos(3) (figPos(4)*axis_area)-35];
% weird thing: if you don't use normalized unit for
% axes, patch for ground doesn't appear
axisPos = axisPos./[figPos(3) figPos(4) figPos(3) figPos(4)];
InvKineAxisH = ...
axes('unit', 'normal', 'pos', axisPos, 'box', 'on');
% ====== background frame
coverPos = [0 0 figPos(3) figPos(4)*ui_area];
[frameH, framePos] = uiarray(coverPos, 1, 1, 0);
% ====== rows for UI controls
spacing = 5;
[H, Pos] = uiarray(framePos, ui_row_n, 1, spacing);
% ====== split lower-most rows into 2 uneven regions
delete(H(2));
[tmpH, tmpPos] = uiarray(Pos(2,:), 1, 6, 0, spacing);
% lower left frame
delete(tmpH(2:4));
lPos = tmpPos(1, :);
lPos(3) = 4*lPos(3)+3*spacing;
set(tmpH(1), 'pos', lPos);
% lower right frame
delete(tmpH(6));
rPos = tmpPos(5, :);
rPos(3) = 2*rPos(3)+spacing;
set(tmpH(5), 'pos', rPos);
set(tmpH(5), 'units', 'character')
set(tmpH(1), 'units', 'character')
set(H(1), 'units', 'character')
set(frameH, 'units', 'character')
% ====== lower-right UI's (same for all SL animation)
cb1 = [mfilename '(''info'')'];
cb2 = [mfilename '(''close'')'];
[lrH, lrPos] = uiarray(rPos, 1, 2, spacing, spacing, ...
str2mat('push', 'push'), ...
str2mat(cb1, cb2), ...
str2mat('Help', 'Close'));
infoH = lrH(1); set(infoH, 'tag', 'info');
closeH = lrH(2); set(closeH, 'tag', 'close');
% ====== lower-left UI's (same for all SL animation)
cb1 = '';
cb2 = [mfilename '(''set_init_cond'');' mfilename '(''main_loop'');'];
cb3 = '';
cb4 = '';
[llH, llPos] = uiarray(lPos, 1, 4, spacing, spacing, ...
str2mat('text', 'push', 'text', 'text'), ...
str2mat(cb1, cb2, cb3, cb4), ...
str2mat('0', 'Start Animation ...','',''));
countH = llH(1); set(countH, 'tag', 'count');
% ====== extend the width of start button
delete(llH(3:4));
startH = llH(2); set(startH, 'tag', 'start');
startPos = llPos(2,:);
startPos(3) = 3*startPos(3)+2*spacing;
set(startH, 'pos', startPos);
% ====== create stop and pause (under start)
cb1 = [mfilename '(''pause_anim'')'];
cb2 = [mfilename '(''stop_anim'')'];
cb3 = '';
[h, pos] = uiarray(startPos, 1, 3, 0,spacing,'push', ...
str2mat(cb1, cb2, cb3), ...
str2mat('Pause...', 'Stop', ''));
set(h, 'visible', 'off');
pauseH = h(1); set(pauseH, 'tag', 'pause');
stopH = h(2); set(stopH, 'tag', 'stop');
% ====== extend the width of pause button
delete(h(3));
pausePos = pos(1, :);
pausePos(3) = 2*pausePos(3)+spacing;
set(pauseH, 'pos', pausePos);
stopPos = pos(2, :);
stopPos(1) = pausePos(1)+pausePos(3)+spacing;
set(stopH, 'pos', stopPos);
% ===== create continue and step (under pause)
cb1 = [mfilename '(''continue_anim'')'];
cb2 = [mfilename '(''step_anim'')'];
[h, pos] = uiarray(pausePos, 1, 2, 0, spacing, ...
'push', ...
str2mat(cb1, cb2), ...
str2mat('Continue', 'Step'));
set(h, 'visible', 'off');
contH = h(1); set(contH, 'tag', 'continue');
stepH = h(2); set(stepH, 'tag', 'step');
%===== put UI handles into current figure's user data
tmp = [startH stopH pauseH contH stepH countH frameH H(1) tmpH(1) tmpH(5)];
set(InvKineFigH, 'userdata', tmp, 'HandleVisibility', 'on');
set(startH, 'units', 'character');
set(stopH, 'units', 'character');
set(pauseH, 'units', 'character');
set(contH, 'units', 'character');
set(stepH, 'units', 'character');
set(countH, 'units', 'character');
set(infoH, 'units', 'character');
set(closeH, 'units', 'character');
%elseif strcmp(action, 'set_extra_gui'), % extra UI's
% ====== extra UI
% ====== The upper UI controls (Specific to each animation)
cb1 = [mfilename '(''show_trail'')'];
cb2 = [mfilename '(''clear_trail'')'];
cb3 = '';
cb4 = [mfilename '(''target_pos'')'];
string1 = 'Show Trails';
string2 = 'Clear Trails';
string3 = 'Use the mouse to drag target oval inside yellow x marked area';
string4 = 'Ellipse|Mouse-Driven|';
[upH, upPos] = uiarray(Pos(1,:), 1, 4, spacing, 1*spacing, ...
str2mat('check', 'push', 'text', 'popup'), ...
str2mat(cb1, cb2, cb3, cb4), ...
str2mat(string1, string2, string3, string4));
set(upH(3), 'HorizontalAlignment', 'right');
showTrailH = upH(1); set(showTrailH, 'tag', 'show_trail');
signalH = upH(4);
% The following will be put back if we have more than one
% desired trajectory
thispos1=get(upH(2),'Position');
thispos1(1)=thispos1(1)*.7;
thispos1(3)=thispos1(3)*.8;
set(upH(2), 'Position', thispos1);
thispos=get(upH(3),'Position');
thispos(3)=thispos(3)*2.4;
thispos(1)=thispos(1)*.8;
set(upH(3), 'Position', thispos);
% delete(upH(3));
delete(upH(4));
showTrailsUnits = get(showTrailH,'units');
clearTrailsUnits = get(upH(2),'units');
helptextUnits = get(upH(3),'units');
set(showTrailH,'units','character');
set(upH(2),'units','character');
set(upH(3),'units','character');
showTrailPosChar = get(showTrailH,'position');
clearTrailPosChar = get(upH(2),'position');
helptextPosChar = get(upH(3), 'position');
if showTrailPosChar(3)<20
showTrailPosChar(3) = 20;
end
cspacing = 2;
if clearTrailPosChar(3)<18
clearTrailPosChar(3) = 18;
clearTrailPosChar(1) = ...
showTrailPosChar(1)+showTrailPosChar(3)+cspacing;
end
helptextPosChar(1) = ...
clearTrailPosChar(1)+clearTrailPosChar(3)+cspacing;
helptextPosChar(3) = ...
figPosChar(3)-(showTrailPosChar(3)+clearTrailPosChar(3)+cspacing);
set(showTrailH,'position',showTrailPosChar);
set(upH(2),'position',clearTrailPosChar);
set(upH(3),'position',helptextPosChar, 'HorizontalAlignment','right');
% set(showTrailH,'units',showTrailsUnits);
% set(upH(2),'units',clearTrailsUnits);
% set(upH(3),'units',helptextUnits);
% ====== Appending handles as the second row of userdata
tmp = [signalH showTrailH upH(2) upH(3) infoH closeH -1 -1 -1 -1];
set(InvKineFigH, 'userdata', [get(InvKineFigH, 'userdata'); tmp]);
% ====== change labels of standard UI controls
% tmp = get(InvKineFigH, 'userdata');
% set(tmp(1, 1), 'visible', 'off');
% set(tmp(1, 2:3), 'visible', 'on');
elseif strcmp(action, 'set_mouse_action'),
% action when button is first pushed down
action1 = [mfilename '(''mouse_action1'')'];
% actions after the mouse is pushed down
action2 = [mfilename '(''mouse_action2'')'];
% action when button is released
action3 = [mfilename '(''mouse_action3'')'];
% temporary storage for the recall in the down_action
set(gca,'UserData',action2);
% set action when the mouse is pushed down
down_action=[ ...
'set(gcf,''WindowButtonMotionFcn'',get(gca,''UserData''));' ...
action1];
set(gcf,'WindowButtonDownFcn',down_action);
% set action when the mouse is released
up_action=[ ...
'set(gcf,''WindowButtonMotionFcn'','' '');', action3];
set(gcf,'WindowButtonUpFcn',up_action);
elseif strcmp(action, 'set_init_cond'),
% This is called whenevern going from "stop" to "start"
InvKineCount = 1;
% set desired trajectory
r1 = 5; r2 = 3; % axes for reference ellipse
center = 11*exp(j*pi/3); % center for reference ellipse
data_n = 50;
t = linspace(0, 2*pi, data_n)-pi/2;
desired_traj = r1*cos(t) + j*r2*sin(t) + center;
tmp = get(findobj(0, 'name', InvKineFigTitle), 'userdata');
desired_trajH = tmp(3, 4);
set(desired_trajH, 'xdata', real(desired_traj));
set(desired_trajH, 'ydata', imag(desired_traj));
% set actually trajectory
actual_trajH = tmp(3, 5);
data = desired_traj(1)*ones(2,1);
set(actual_trajH, 'xdata', real(data));
set(actual_trajH, 'ydata', imag(data));
eval([mfilename, '(''clear_trail'')']);
elseif strcmp(action, 'set_anim_obj'),
l1 = 10; l2 = 7; % specifications for robot arms
r1 = 5; r2 = 3; % axes for reference ellipse
% ====== Plot locations for the training data
load invkine.mat
axis([0 l1+l2 0 l1+l2]);% ====== setting axis
tmp = line(invkine1(:, 1), invkine1(:, 2));
set(tmp, 'Marker', 'x', 'LineStyle', 'none', 'HitTest', 'off');
xlabel('X'); ylabel('Y');
axis equal;
% axis square;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -