📄 juggler.m
字号:
[upH, upPos] = uiarray(Pos(1,:), 1, 4, spacing, 2*spacing, ...
str2mat('check', 'push', 'text', 'popup'), ...
str2mat(cb1, cb2, cb3, cb4), ...
str2mat(string1, string2, string3, string4));
set(upH(3), 'HorizontalAlignment', 'right');
controllerH = upH(4);
showTrailH = upH(1); set(showTrailH, 'tag', 'show_trail');
set(controllerH, 'value', 2);
% ====== Appending handles as the second row of userdata
tmp = [controllerH showTrailH -1 -1 -1 -1 -1 -1 -1 -1];
set(JugFigH, 'userdata', [get(JugFigH, 'userdata'); tmp]);
% ====== change labels of standard UI controls
% ud = get(JugFigH, 'userdata');
% set(ud(1, 1), 'visible', 'off');
% set(ud(1, 2:3), 'visible', 'on');
elseif strcmp(action, 'set_init_cond'),
JugCount = 1;
theta = 0;
ProjAngle = pi/3;
v_magnitude = 4.5;
x_prev = xMin + JugBallRadius;
y_prev = JugBallRadius;
v_prev = v_magnitude*exp(j*ProjAngle);
ud = get(findobj(0, 'name', JugFigTitle), 'userdata');
ud(3, 8) = x_prev;
ud(3, 9) = y_prev;
ud(3, 10) = v_prev;
set(JugFigH, 'userdata', ud);
DesiredPos = (xMin+xMax)/2;
% ====== set refH
refH = ud(3, 3);
ref = get(refH, 'userdata');
new_ref = ref + DesiredPos;
set(refH, 'xdata', real(new_ref), 'ydata', imag(new_ref));
% ====== set plate
plateH = ud(3, 2);
plate = get(plateH, 'userdata');
new_plate = plate*exp(j*theta);
set(plateH, 'xdata', real(new_plate), 'ydata', imag(new_plate));
% ====== set arrow
arrowH = ud(3, 4);
center = ud(3, 7);
arrow = get(arrowH, 'userdata');
new_arrow = arrow*exp(sqrt(-1)*theta) + center;
set(arrowH, 'xdata', real(new_arrow), 'ydata', imag(new_arrow));
% ====== redraw
eval([mfilename, '(0,0,0,0,''clear_trail'')']);
elseif strcmp(action, 'set_anim_obj'),
% ====== Setting up the axis
xMin = -2.0; xMax = -xMin;
y_min = -0.3; y_max = -xMin;
axis([xMin xMax y_min y_max]);
axis equal;
% ====== Setting up the ground
%colormap(gray); % To assign correct patch color
%patch([xMin xMax xMax xMin], ...
% [-y_max/8 -y_max/8 0 0], [10 10 55 55]);
h = line([xMin xMax], [0 0]);
set(h, 'color', 'b');
% ====== Setting up the ball
JugBallRadius = 0.1;
ball = JugBallRadius*exp(j*linspace(0, 2*pi, 21));
%colormap(cool);
%ballH = patch(real(ball), imag(ball), 64*ones(size(ball)));
ballH = line(real(ball)+xMin + JugBallRadius, imag(ball)+JugBallRadius);
set(ballH, 'color', 'c', 'clipping', 'off', 'erasemode','xor');
set(ballH, 'userdata', ball);
% ====== Setting up the plate
plate_leng = (xMax-xMin)/10;
plate = plate_leng*[-0.5 0.5]' + j*[0 0]';
plateH = line(real(plate), imag(plate));
set(plateH, 'color', 'y', 'erasemode', 'xor', 'linewidth', 5);
set(plateH, 'userdata', plate);
% ====== Setting up the base
%baseH = line(real(plate), imag(plate));
%set(baseH, 'color', 'r', 'erasemode', 'xor', 'linewidth', 5);
%set(baseH, 'erase', 'xor', 'userdata', plate);
%set(baseH, 'clipping', 'off');
% ====== Setting the reference triangle
ref = JugBallRadius*[-1 1 0 -1]' + j*2*JugBallRadius*[0 0 1 0]' - 2*j*JugBallRadius;
refH = line(real(ref), imag(ref));
set(refH, 'color', 'r', 'linewidth', 2);
set(refH, 'erase', 'xor', 'clipping', 'off');
set(refH, 'userdata', ref);
% ====== Setting steering arrow
sy_min = 1.50; % min. of y of loc. of steering device
sy_max = 2.00; % max. of y of loc. of steering device
s_JugBallRadius = (sy_max - sy_min)/sqrt(2);
sx_min = 1.5;
center = sx_min + j*((sy_max - sy_min)/2 + sy_min);
tmp = s_JugBallRadius*exp(sqrt(-1)*linspace(-pi/4, pi/4, 100));
arc = [0 tmp 0 s_JugBallRadius] + center;
arrow_baseH = line(real(arc), imag(arc));
dummyLine=line(real(center), real(center), 'color', 'black');
set(arrow_baseH, 'clipping', 'off');
arrow_x = [0 1 nan 0.9 1 0.9];
arrow_y = [0 0 nan 0.1 0 -0.1];
arrow = s_JugBallRadius*(arrow_x + sqrt(-1)*arrow_y);
curr_arrow = arrow + center;
arrowH = line(real(curr_arrow), imag(curr_arrow));
set(arrowH, 'color', 'red', 'erasemode', 'xor');
set(arrowH, 'clipping', 'off', 'userdata', arrow);
set(arrowH, 'userdata', arrow);
% ====== set 'userdata'
ud = [ballH plateH refH arrowH arrow_baseH -1 center -1 -1 -1];
% ud(6) is for JugFisMat flag, ud(8:10) is for x, y and v
set(JugFigH, 'userdata', [get(JugFigH, 'userdata'); ud]);
elseif strcmp(action, 'set_mouse_action'),
ud = get(JugFigH, 'userdata');
which_controller = get(ud(2, 1), 'value');
if which_controller == 1, % human controller
% ====== move refH to center
DesiredPos = (xMin+xMax)/2;
refH = ud(3, 3);
ref = get(refH, 'userdata');
new_ref = ref + DesiredPos;
set(refH, 'xdata', real(new_ref), 'ydata', imag(new_ref));
% ====== show steering arrow
set(ud(3,4:5), 'visible', 'on');
% ====== action when button is first pushed down
action1 = [mfilename '(0,0,0,0,''mouse_action_steering'')'];
% ====== actions after the mouse is pushed down
action2 = action1;
% ====== action when button is released
action3 = action1;
else % automatic controller
% ====== hide steering arrow
set(ud(3,4:5), 'visible', 'off');
% ====== action when button is first pushed down
action1 = [mfilename '(0,0,0,0,''mouse_action_ref'')'];
% ====== actions after the mouse is pushed down
action2 = '';
% ====== action when button is released
action3 = '';
end
% ====== 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, 'main_loop'),
JugAnimRunning = 1;
% ====== get animation objects
tmp = get(JugFigH, 'userdata');
% ====== change visibility of GUI's
set(tmp(1, 1), 'visible', 'off');
set(tmp(1, 4:5), 'visible', 'off');
set(tmp(1, 2:3), 'visible', 'on');
% ====== looping
while 1 & ~JugAnimClose
if ~JugAnimRunning | JugAnimPause,
break;
end
eval([mfilename, '(0, 0, 0, 0, ''single_loop'')']);
end
% ====== shut down
if JugAnimClose,
delete(JugFigH);
end
elseif strcmp(action, 'load_fis_mat'),
ud = get(JugFigH, 'userdata');
if ud(3, 6) < 0, % FIS not been built
JugFisMat = readfis('juggler');
ud(3, 6) = 1;
set(JugFigH, 'userdata', ud);
end
name='juggler';
figNum=findobj(allchild(0), 'name', ['Rule Viewer: ' name]);
if isempty(figNum)
ruleview(JugFisMat);
figNum=findobj(allchild(0), 'name', ['Rule Viewer: ' name]);
pstn=get(figNum, 'Position');
set(figNum, 'Position', pstn+[.35 -.3 0 0]);
figure(JugFigH);
else
figure(figNum);
end
elseif strcmp(action, 'mouse_action_steering')
% Action for mouse when steered by human
tmp = get(gca, 'currentpoint');
tmp_x = tmp(1, 1); tmp_y = tmp(1, 2);
ud = get(gcf, 'userdata');
center = ud(3, 7);
theta = angle(tmp_x + sqrt(-1)*tmp_y - center);,
theta = min(max(theta, -pi/4), pi/4);
plateH = ud(3, 2);
arrowH = ud(3, 4);
arrow = get(arrowH, 'userdata');
plate = get(plateH, 'userdata');
new_arrow = arrow*exp(sqrt(-1)*theta) + center;
set(arrowH, 'xdata', real(new_arrow), 'ydata', imag(new_arrow));
new_plate = plate*exp(j*theta);
set(plateH, 'xdata', xNextHit + real(new_plate), ...
'ydata', imag(new_plate));
elseif strcmp(action, 'mouse_action_ref')
curr_info = get(gca, 'CurrentPoint');
mouse_pos = curr_info(1,1);
bound = [xMin+1.5*JugBallRadius xMax-1.5*JugBallRadius];
DesiredPos = min(max(mouse_pos, bound(1)), bound(2));
ud = get(JugFigH, 'userdata');
refH = ud(3, 3);
new_ref = get(refH, 'userdata') + DesiredPos;
set(refH, 'xdata', real(new_ref), 'ydata', imag(new_ref));
elseif strcmp(action, 'ideal_controller'), % Ideal controller
% ====== find where the ball hits the ground
vy = imag(v_prev);
t_hit = (vy + (vy*vy+2*g*(y_prev-JugBallRadius))^0.5)/g;
x_hit = real(v_prev)*t_hit + x_prev;
v_hit = real(v_prev) + j*(imag(v_prev) - g*t_hit);
% ====== get animation objects
% Note that sin(2*theta) = k has two solution theta1 and theta2,
% and theta1 + theta2 = pi/2;
tmp = g*(DesiredPos - x_hit)/abs(v_hit)^2;
tmp = min(max(tmp, -1), 1);
tmp_angle = asin(tmp);
% tmp_angle is equal to two times the next_project_angle
% tmp_angle must be in [0, 2*pi] in order to make the next
% project angle between [0, pi].
% For every tmp_angle, we can find another solution.
if tmp_angle >= 0,
solution1 = tmp_angle;
solution2 = pi - tmp_angle;
else
solution1 = pi - tmp_angle;
solution2 = 2*pi + tmp_angle;
end
% To make next_proj_angle as close as possible to pi/2
if abs(solution1-pi) < abs(solution2-pi),
next_proj_angle = solution1/2;
else
next_proj_angle = solution2/2;
end
o1 = (next_proj_angle - ProjAngle)/2;
elseif strcmp(action, 'fuzzy_controller'), % fuzzy controller
% ====== find where the ball hits the ground
vy = imag(v_prev);
t_hit = (vy + (vy*vy+2*g*(y_prev-JugBallRadius))^0.5)/g;
x_hit = real(v_prev)*t_hit + x_prev;
v_hit = real(v_prev) + j*(imag(v_prev) - g*t_hit);
% ====== get animation objects
ud = get(JugFigH, 'userdata');
o1 = evalfis([x_hit - DesiredPos ProjAngle], JugFisMat);
% ====== rule viewer
xx=allchild(0);
figN=[];
for i=1:length(xx)
name=get(xx(i), 'name');
if length(name)>11 & strcmp(name(1:12), 'Rule Viewer:');
figN=xx(i);
break;
end
end
if ~isempty(figN)
set(figN, 'HandleVis', 'on');
ruleview('#simulink', [x_hit - DesiredPos ProjAngle], figN);
set(figN, 'HandleVis', 'callback');
end
elseif strcmp(action, 'state_feedback_controller'), % SF controller
% ====== find where the ball hits the ground
vy = imag(v_prev);
t_hit = (vy + (vy*vy+2*g*(y_prev-JugBallRadius))^0.5)/g;
x_hit = real(v_prev)*t_hit + x_prev;
v_hit = real(v_prev) + j*(imag(v_prev) - g*t_hit);
% ====== get animation objects
ud = get(JugFigH, 'userdata');
% coef is obtained from showsurf.m
coef = [0.12493010239152 -0.50000000017091 0.78539816478460]';
state = [x_hit-DesiredPos ProjAngle 1];
out = state*coef;
elseif strcmp(action, 'stop_anim'),
ud = get(JugFigH, 'userdata');
set(ud(1, 1), 'visible', 'on');
set(ud(1, 2:5), 'visible', 'off');
JugAnimRunning = 0;
JugAnimPause = 0;
elseif strcmp(action, 'pause_anim'),
ud = get(JugFigH, 'userdata');
set(ud(1, 3), 'visible', 'off');
set(ud(1, 4:5), 'visible', 'on');
JugAnimRunning = 0;
JugAnimClose = 0;
JugAnimPause = 1;
elseif strcmp(action, 'step_anim'),
JugAnimStepping = 1;
eval([mfilename, '(0, 0, 0, 0, ''single_loop'')']);
elseif strcmp(action, 'continue_anim'),
ud = get(JugFigH, 'userdata');
set(ud(1, 3), 'visible', 'on');
set(ud(1, 4:5), 'visible', 'off');
JugAnimRunning = 1;
JugAnimPause = 0;
JugAnimClose = 0;
JugAnimStepping = 0;
eval([mfilename, '(0,0,0,0,''set_constant'')']);
eval([mfilename, '(0,0,0,0,''main_loop'')']);
elseif strcmp(action, 'info'),
helpwin(mfilename);
% title = get(JugFigH, 'Name');
% content = ...
% [' '
% ' Animation of the ball juggling system. The small '
% ' triangle indicates the desired ball position. '
% ' You can choose either human or fuzzy control to '
% ' control this system. If it is controlled by human, '
% ' click the steering arrow at the upper right corner '
% ' to change the tilted angle of the hitting board. '
% ' If it is controlled by fuzzy controller, use mouse '
% ' to change the location of the triangle. (If fuzzy '
% ' controller is selected, the position of the small '
% ' triangle will also be updated randomly every '
% ' 200 step counts.) '
% ' '
% ' File: juggler.m '];
% fhelpfun(title, content);
elseif strcmp(action, 'close'),
if JugAnimRunning == 1,
JugAnimClose = 1; % close via main_loop
else % close when animation is stopped or paused
ud = get(JugFigH, 'userdata');
delete(JugFigH);
end
% ###### additional UI controls
elseif strcmp(action, 'show_trail'),
ud = get(JugFigH, 'userdata');
showTrailH = ud(2, 2);
objectH = ud(3, 1:4);
dispmode = get(showTrailH, 'value');
if dispmode == 0, % xor
set(objectH, 'erasemode', 'xor');
% set(JugFigH, 'color', get(JugFigH, 'color'));
refresh(JugFigH);
else
set(objectH, 'erasemode', 'none');
end
elseif strcmp(action, 'clear_trail'),
refresh(JugFigH);
% set(JugFigH, 'color', get(JugFigH, 'color'));
else
fprintf('Action string = %s\n', action);
error('Unknown action string!');
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -