Code Cams Matlab
Code Cams Matlab
global S
%{
Cam Simulator
To launch, simply type cams in the MATLAB command window with this in the current
directory. Alternatively, you can choose Debug -> Run from this editor window,
or press F5.
Helpful Notes:
- The first edit box column is to contain the motion type(s). Each row of it
should have one of the preset motions written inside it (SHM, CYC, etc...).
- The second edit box is to specify the duration of each of the motion types.
Each row should contain a duration in degrees for the corresponding respective
motion type.
- The third edit box contains the respective displacemens for the motion types.
- The durations (second box) have to add up to 360 degrees. Also, while not
necessary in the typical sense, the displacements should generally add up to 0.
- To understand more, see one of the pre-set examples found at File -> Load.
- As for the axis limits, the first is offline at the current time. The second
changes the axis for the second plot (Velocity) and the third for the third plot
(Acceleration).
- The number under 'Res' changes the number of points for drawing the cam profile.
It is the top critereon for the load time above it.
- You can change the speed of rotation (Fast, Slow, Pause) during animation.
- Any comments should be sent to <[email protected]>. Don't hesitate to send!
- Recommended resolution is 1280 by 800 pixels.
- Works only on MATLAB 7.4 (R2007a) and above.
%}
%% Main Figure and Menus
figure('units','normalized',...
'position',[.1 .1 .8 .75],...
'color','w',...
'numbertitle','off',...
'menubar','none',...
'name','Cam Simulator')
m1=uimenu('Label','File');
m2=uimenu('Label','More');
% when you click on a menu the code go to its corresponding callback function
uimenu(m1,'Label','Save Model','Callback',@savv);
uimenu(m1,'Label','Load Model','Callback',@ladd,'Separator','on');
uimenu(m1,'Label','Quit','Callback',@xq,'Separator','on');
uimenu(m2,'Label','About','Callback',@bott);
%% File -> quit
function xq(varargin)
close(gcf)
end
%% File -> Save
function savv(varargin)
% make a small figure with a button, text and edit
figure('units','normalized','position',[0.1 .6 .2
.2],'color','w','numbertitle','off','menubar','none','name','Save')
uicontrol('style','text','units','normalized','position',[.05 .7 .9
.2],'string','Save Model As','backgroundcolor','w',...
'fontsize',15,'fontweight','b','fontname','arial','horizontalalignment','left')
se=uicontrol('style','edit','units','normalized','position',[.05 .525 .7
.2],'string','','backgroundcolor','w',...
'fontsize',15,'fontweight','b','fontname','arial','horizontalalignment','left');
uicontrol('style','pushbutton','units','normalized','position',[.1 .25 .5
.2],'string','Save','backgroundcolor','w',...
'fontsize',15,'fontweight','b','fontname','arial','horizontalalignment','left','ca
llback',@savvy)
save(['Models\',ns,'.mat'],'Types','Disps','Durations','rb','kk')
else
kk=2; %#ok
rd=(get(t2,'string')); %#ok
e=(get(t4,'string')); %#ok
kc=(get(t6,'string')); %#ok
save(['Models\',ns,'.mat'],'Types','Disps' ,'Durations'
,'rb','rd','e','kc','kk')
end
end
end
%% File -> Load
function ladd(varargin)
'fontsize',11,'fontweight','b','fontname','arial','horizontalalignment','left')
uicontrol('style','text','units','normalized','position',[.05+.9/2+.1-.1 .7
.9/2 .2],'string','Available Models','backgroundcolor','w',...
'fontsize',11,'fontweight','b','fontname','arial','horizontalalignment','left')
se=uicontrol('style','edit','units','normalized','position',[.05 .525 .7/2
.2],'string','','backgroundcolor','w',...
'fontsize',15,'fontweight','b','fontname','arial','horizontalalignment','left');
uicontrol('style','pushbutton','units','normalized','position',[.1 .25 .5/2
.2],'string','Load','backgroundcolor','w',...
'fontsize',15,'fontweight','b','fontname','arial','horizontalalignment','left','ca
llback',@laddy)
% get all files in the folder 'Models' that end with '.mat'
pW=dir('Models\*.mat');
pl=uicontrol('style','listbox','max',2,'units','normalized','position',[.05+.9/2
.1 .9/2 .7],'string',hol,'backgroundcolor','w',...
'fontsize',11,'fontweight','b','fontname','arial','horizontalalignment','left','ca
llback',@yah);
% every time you click a name in the listbox the name is displayed in
% the edit box as per the following function
function yah(varargin)
sh=get(pl,'value'); % get value of chosen element in the listbox
sg=(get(pl,'string'));
sj=sg(sh,:); % get the string respective to that value
set(se,'string',sj) % put said string in edit box
end
% what happens when you press the 'Load' button in the Load figure window
function laddy(varargin)
ns=get(se,'string'); % get the name in the edit box
ns(ns==' ')=[]; % delete spaces that strvcat produced at the end of
names
close(gcf) % close the Load figure window
% load the variable kk from name (used to see how many variables are
to
% be loaded, since flat face follower has less characteristics to
load)
load(['Models\',ns,'.mat'],'kk')
'fontsize',11,'fontweight','b','fontname','arial','horizontalalignment','left');
uicontrol('style','text','units','normalized','position',[.05 .65 .6
.2],'string','Husam Aldahiyat 28/12/2008','backgroundcolor','w',...
'fontsize',11,'fontweight','b','fontname','arial','horizontalalignment','left');
end
%% Main Figure uicontrols (edits, text, etc...)
% some texts
uicontrol('style','text','units','normalized','position',[.025 .9 .08
.05],'backgroundcolor','w','max',2,...
'fontsize',12,'fontname','calibri','string','Motion Type')
uicontrol('style','text','units','normalized','position',[.125 .9 .08
.075],'backgroundcolor','w','max',2,...
'fontsize',12,'fontname','calibri','string','Motion Duration')
uicontrol('style','text','units','normalized','position',[.225 .875 .085
.075],'backgroundcolor','w','max',2,...
'fontsize',11,'fontname','calibri','string','Displacement')
% this is the black axis that acts as a seperator
axes('position',[.35 0 .025
1],'color','k','xcolor','w','ycolor','w','zcolor','w','xtick',100,'ytick',100)
% the little squares above 'Res'. they act as a loading bar
hl(1)=uicontrol('style','text','units','normalized','position',[.335 .95 .005
.0075],'backgroundcolor','r');
hl(2)=uicontrol('style','text','units','normalized','position',[.335 .94 .005
.0075],'backgroundcolor','r');
hl(3)=uicontrol('style','text','units','normalized','position',[.335 .93 .005
.0075],'backgroundcolor','r');
hl(4)=uicontrol('style','text','units','normalized','position',[.335 .92 .005
.0075],'backgroundcolor','r');
hl(5)=uicontrol('style','text','units','normalized','position',[.335 .91 .005
.0075],'backgroundcolor','r');
hl(6)=uicontrol('style','text','units','normalized','position',[.335 .9 .005
.0075],'backgroundcolor','r');
hl(7)=uicontrol('style','text','units','normalized','position',[.335 .89 .005
.0075],'backgroundcolor','r');
hl(8)=uicontrol('style','text','units','normalized','position',[.335 .88 .005
.0075],'backgroundcolor','r');
hl(9)=uicontrol('style','text','units','normalized','position',[.335 .87 .005
.0075],'backgroundcolor','r');
hl(10)=uicontrol('style','text','units','normalized','position',[.335 .86 .005
.0075],'backgroundcolor','r');
% dummy text, used only to store certain values so that they would be retrieved
% later by another function
dummy1=uicontrol('style','text','visible','off','max',2);
dummy2=uicontrol('style','text','visible','off','max',2);
dummy3=uicontrol('style','text','visible','off','max',2);
% some more stuff
uicontrol('style','text','units','normalized','position',[.31 .82 .035
.025],'string','Res','backgroundcolor','w');
rR=uicontrol('style','edit','units','normalized','position',[.31 .79 .035
.025],'string','100','backgroundcolor','w');
MT=uicontrol('style','edit','units','normalized','position',[.025 .6 .08
.3],'backgroundcolor','w','max',2,...
'fontsize',14,'fontname','calibri');
MD=uicontrol('style','edit','units','normalized','position',[.125 .6 .08
.3],'backgroundcolor','w','max',2,...
'fontsize',14,'fontname','calibri');
MA=uicontrol('style','edit','units','normalized','position',[.225 .6 .08
.3],'backgroundcolor','w','max',2,...
'fontsize',14,'fontname','calibri');
uicontrol('style','text','units','normalized','position',[.025 .5 .2
.05],'backgroundcolor','w',...
'fontsize',12,'fontname','calibri','string','SHM: Simple Harmonic
Motion','horizontalalignment','left');
uicontrol('style','text','units','normalized','position',[.025 .45 .3
.05],'backgroundcolor','w',...
'fontsize',12,'fontname','calibri','string','DWL: Dwell CSV: Constant
Velocity','horizontalalignment','left');
uicontrol('style','text','units','normalized','position',[.025 .4 .2
.05],'backgroundcolor','w',...
'fontsize',12,'fontname','calibri','string','PAR: Parabolic
Motion','horizontalalignment','left');
uicontrol('style','text','units','normalized','position',[.025 .35 .2
.05],'backgroundcolor','w',...
'fontsize',12,'fontname','calibri','string','CYC: Cycloidal
Motion','horizontalalignment','left');
uicontrol('style','text','units','normalized','position',[.025 .3 .15
.05],'backgroundcolor','w',...
'fontsize',10,'fontname','calibri','string','Base Circle Radius:
','horizontalalignment','left');
BC=uicontrol('style','edit','units','normalized','position',[.145 .32 .03
.035],'backgroundcolor','w',...
'fontsize',10,'fontname','calibri','string',' ','horizontalalignment','center');
% 'Go' pushbutton
BB=uicontrol('style','pushbutton','units','normalized','position',[.225 .025 .08
.05],'backgroundcolor','w',...
'fontsize',14,'fontname','calibri','string','Go','callback',@go);
D3=uicontrol('style','pushbutton','units','normalized','position',[.225 .4 .08
.05],'backgroundcolor','w',...
'fontsize',14,'fontname','calibri','string','3D','callback',@go3,'visible','off');
% choose follower type radio group
hr=uibuttongroup('Units','normalized',...
'Position',[.025 .25 .3 .05],'SelectionChangeFcn',@CGMT);
hb1=uicontrol('Style','Radiobutton','String','Flat Face
Follower','Units','normalized',...
'Position',[0 0 1/2 1],'Parent',hr,'backgroundcolor',[1 1 1],'foregroundcolor',[0 0 0]);
hb2=uicontrol('Style','Radiobutton','String','Translating Roller
Follower','Units','normalized',...
'Position',[1/2 0 1/2 1],'Parent',hr,'backgroundcolor',[1 1 1],'foregroundcolor',[0 0
0]);
% speed of animation radio group
hr2=uibuttongroup('Units','normalized',...
'Position',[.175 .1 .15 .05]);
hbs=uicontrol('Style','Radiobutton','String','Fast','Units','normalized',...
'Position',[0 0 1/3 1],'Parent',hr2,'backgroundcolor',[1 1 1],'foregroundcolor',[0 0 0]);
hbk=uicontrol('Style','Radiobutton','String','Slow','Units','normalized',...
'Position',[1/3 0 1/3 1],'Parent',hr2,'backgroundcolor',[1 1 1],'foregroundcolor',[0 0
0]);
uicontrol('Style','Radiobutton','String','Pause','Units','normalized',...
'Position',[2/3 0 1/3 1],'Parent',hr2,'backgroundcolor',[1 1 1],'foregroundcolor',[0 0
0]);
% texts that are set on/off depending on follower type
t1=uicontrol('style','text','units','normalized','position',[.025 .18 .15
.05],'backgroundcolor','w',...
'fontsize',10,'fontname','calibri','string','Roller Radius:
','horizontalalignment','left');
t2=uicontrol('style','edit','units','normalized','position',[.125 .2 .03
.035],'backgroundcolor','w',...
'fontsize',10,'fontname','calibri','string',' ','horizontalalignment','center');
t3=uicontrol('style','text','units','normalized','position',[.025 .14 .15
.05],'backgroundcolor','w',...
'fontsize',10,'fontname','calibri','string','Offset:
','horizontalalignment','left');
t4=uicontrol('style','edit','units','normalized','position',[.125 .16 .03
.035],'backgroundcolor','w',...
'fontsize',10,'fontname','calibri','string',' ','horizontalalignment','center');
t5=uicontrol('style','text','units','normalized','position',[.025 .1 .15
.05],'backgroundcolor','w',...
'fontsize',10,'fontname','calibri','string','Inside/Ouside(~):
','horizontalalignment','left');
t6=uicontrol('style','edit','units','normalized','position',[.125 .12 .03
.035],'backgroundcolor','w',...
'fontsize',10,'fontname','calibri','string','0','horizontalalignment','center');
% text and edits at the lower left corner of the main figure window
uicontrol('style','text','units','normalized','position',[.025 .065 .15
.05],'backgroundcolor','w',...
'fontsize',10,'fontname','calibri','string','Axis Limits:
','horizontalalignment','left');
uicontrol('style','text','units','normalized','position',[.025 -.005 .15
.05],'backgroundcolor','w',...
'fontsize',10,'fontname','calibri','string','[y1
y2]','horizontalalignment','left','fontweight','b');
uicontrol('style','edit','units','normalized','position',[.025 .05 .05
.035],'backgroundcolor','w',...
'fontsize',10,'fontname','calibri','string','','horizontalalignment','center','cal
lback',@ca1,'enable','off');
al2=uicontrol('style','edit','units','normalized','position',[.08 .05 .05
.035],'backgroundcolor','w',...
'fontsize',10,'fontname','calibri','string','','horizontalalignment','center','cal
lback',@ca2);
al3=uicontrol('style','edit','units','normalized','position',[.13 .05 .05
.035],'backgroundcolor','w',...
'fontsize',10,'fontname','calibri','string','','horizontalalignment','center','cal
lback',@ca3);
% create the four axes and hide them for now
a1=axes('position',[.4 .65 .55/3 .3]); % Displacement
a2=axes('position',[.4+.55/3+.025 .65 .55/3 .3]); % Velocity
a3=axes('position',[.4+.55/3*2+.05 .65 .55/3 .3]); % Acceleration
a4=axes('position',[.4 .025 .55 .55]); % cam profile axes
set(findobj('type','axes','-not','color','k'),'visible','off') % hide them
% evaluate this function which sets certain uicontrols' visiblity on/off
CGMT
%% Change Axis Limits
function ca2(varargin)
an1=str2num(get(al2,'string')); %#ok % get limits from edit box
set(a2,'ylim',an1(1:2)); % set these limits for the corresponding axes
end
function ca3(varargin)
an1=str2num(get(al3,'string')); %#ok
set(a3,'ylim',an1(1:2));
end
%{
function ca1(varargin)
an1=str2num(get(al1,'string'));
set(a1,'ylim',an1(1:2));
end
%}
%% Change Follower Type
function CGMT(varargin)
if get(hr,'selectedobject')==hb1 % flat face
set(t1,'visible','off') % rf text
set(t2,'visible','off') % rf edit
set(t3,'visible','off') % offset text
set(t4,'visible','off') % offset edit
set(t5,'visible','off') % inside/outside text
set(t6,'visible','off') % inside/outside edit
else
set(t1,'visible','on')
set(t2,'visible','on')
set(t3,'visible','on')
set(t4,'visible','on')
set(t5,'visible','on')
set(t6,'visible','on')
end
end
%% Motion Program Functions
% Dwell
function [s,si,ti]=DWL(si,ti,a)
s=sym(si); % create motion equation
ezplot(s,[ti,ti+a]) % plot motion equation
ti=ti+a;
end
% Simple Harmonic Motion
function [s,si,ti]=SHM(si,ti,h,a)
s=si+h/2*(1-cos(pi/a*(sym('x')-ti)));
si=subs(s,a+ti);
ezplot(s,[ti,ti+a])
ti=ti+a;
end
% Parabolic Motion
function [s1,s2,si,ti]=PAR(si,ti,h,a)
s1=si+2*h/a^2*(sym('x')-ti)^2;
s2=si+h*(-1+4*(sym('x')-ti)/a-2*(sym('x')-ti)^2/a^2);
si=subs(s2,ti+a);
ezplot(s1,[ti,ti+a/2])
hold on
ezplot(s2,[ti+a/2,ti+a])
xlim([ti ti+a])
ti=ti+a;
end
% Cycloidal Motion
function [s,si,ti]=CYC(si,ti,h,a)
s=si+h*((sym('x')-ti)/a-1/2/pi*sin(2*pi*(sym('x')-ti)/a));
si=subs(s,ti+a);
ezplot(s,[ti,ti+a])
ti=ti+a;
end
% Constant Velocity
function [s,si,ti]=CV(si,ti,h,a)
s=si+h/a*((sym('x')-ti));
si=subs(s,ti+a);
ezplot(s,[ti,ti+a])
ti=ti+a;
end
%% The 'Go' Button
function go(varargin)
% reveal axes
set(findobj('type','axes'),'visible','on')
si=0; % initial displacement is zero
ti=0; % initial theta is zero
S=[]; % motion equation(s) matrix
T=ti; % theta timeline-esque vector
% set displacement axes as current one (i.e. all subsequent plots will
% be done on it)
axes(a1)
cla
hold on
%% Displacement Diagram
% the following loop obtains for us the motion equation(s) for the
% follower as well as plots the displacement diagram
switch Types(lp1,:)
case 'DWL'
[s,si,ti]=DWL(si,ti,Durations(lp1));
S=[S;s]; % stack latest motion equation
end
for klp=1:length(S)
% get displacements of follower at each of the critical values of
theta
JJ(klp)=subs(S(klp),T(klp+1));
end
%% Acceleration Diagram
axes(a3)
cla
hold on
drawnow() % give user something to look at while he waits for the rest of
the
% computations
%% Cam Profile
reR=str2double(get(rR,'string')); % get number of points used to plot
x=zeros(1,reR+1); % x points of profile
y=zeros(1,reR+1); % y points of profile
pa=zeros(1,reR+1); % pressure angles. there is a different pressure angle
for each theta,
% where it is the angle between the vertical line of
motion and the normal
% to the tangent of the two contact surfaces
if strcmp(get(t6,'string'),'1') % inside
koin=-1;
else % outside
koin=1;
end
end
% just to make sure, set all loading block colours to green
set(hl,'backgroundcolor','g')
% h=plot(x,y);
ppp=line([min(x)+(max(x)-min(x))/4,max(x)-(max(x)-
min(x))/4],[ch ch]);
else
% the follower circle, varargin{1} is the horizontal offest
(e)
ppp=circle([-varargin{1} ch+(rb+varargin{2})*cos(beta)-
rb],varargin{2},100);
title(['\phi = ',num2str(pa/pi*180,3)])
end
if exist('hag','var')
delete(hag)
end
hag=ang([0 0],rb/2,[0 -p2],'w.'); % draw an arc from 0 to theta
degrees
set(ppp,'linewidth',3,'color','b')
delete(ppp)
if ~who
delete(lll)
delete(ooo)
end
end
end
%% '3D' Button
function go3(varargin)
x=str2num(get(dummy1,'string')); %#ok
y=str2num(get(dummy2,'string')); %#ok
T=str2num(get(dummy3,'string')); %#ok
rb=str2double(get(BC,'string'));
if get(hr,'selectedobject')==hb1
e=0;
hok=1;
rd=0;
else
e=str2double(get(t4,'string'));
hok=0;
rd=str2double(get(t2,'string'));
end
Durations=str2num(get(MD,'string')).*pi/180; %#ok
Disps=[str2num(get(MA,'string'));1e-9;-1e-9];%#ok
z1=sum(-abs(Disps));
z2=sum(abs(Disps));
dg(x,y,S,T,e,rb,z1,z2,hok,rd)
end
end
%% Angle Function
% function that draws an arc based on it centre, radius and angle span.
% burrows from the function CIRCLE
function h = ang(centre,radius,span,style)
theta = linspace(span(1),span(2),100);
rho = ones(1,100) * radius;
[x,y] = pol2cart(theta,rho);
x = x + centre(1);
y = y + centre(2);
x=x(end);
y=y(end);
h = plot(x,y,style);
end
%% Circle Function
% function that draws a circle based on its centre and radius. I didn't make it;
% it was created by Zhenhai Wang on the MATLAB File Exchange
function H=circle(center,radius,NOP,style)
if (nargin==3)
style='b-';
end
THETA=linspace(0,2*pi,NOP);
RHO=ones(1,NOP)*radius;
[X,Y] = pol2cart(THETA,RHO);
X=X+center(1);
Y=Y+center(2);
H=plot(X,Y,style);
axis square
end
%% 3D Animation
function dg(x,y,S,T,e,rb,z1,z3,hok,rd)
S
T
figure
hold on
set(gcf,'color','w','numbertitle','off','menubar','none','name','3D (Demo)')
set(gca,'xcolor','w','ycolor','w','zcolor','w')
z=zeros(size(x));
z2=ones(size(x));
view(3)
f1=fill3(x,z,y,[.5 .5 .5],'edgecolor',[.7 .7
.7],'FaceVertexAlphaData',0.9,'FaceAlpha','flat');
f2=fill3(x,z2,y,[.5 .5 .5],'edgecolor',[.5 .5 .5]);
% [gg,hh,jj]=cylinder(repmat(rb,1,100));
% jj=[-flipud(jj);jj];
% jj=jj*6;
% for p=1:size(jj,1)/2
% jj(p,:)=[];
% end
% hhh=surf(gg,jj,hh);
kk=[f1;f2];
p2=0;
while true
rotate(kk,[0 1 0],5,[0 1 0])
p2=p2+5/180*pi;
if p2>2*pi
p2=p2-2*pi;
end
axis([(z1-rb) z3+rb -5 5 z1 z3].*2)
for p=1:length(T)-1
if p2<=T(p+1)
a=p;
break
end
end
ch=subs(S(a),p2)+rb;
if hok
a=[min(x)+(max(x)-min(x))/4 0 0;
max(x)-(max(x)-min(x))/4 0 0;
max(x)-(max(x)-min(x))/4 1 0;
min(x)+(max(x)-min(x))/4 1 0;
min(x)+(max(x)-min(x))/4 0 z3/2;
max(x)-(max(x)-min(x))/4 0 z3/2;
max(x)-(max(x)-min(x))/4 1 z3/2;
min(x)+(max(x)-min(x))/4 1 z3/2];
else
a=[0 0 0;
1 0 0;
1 1 0;
0 1 0;
0 0 z3/2;
1 0 z3/2;
1 1 z3/2;
0 1 z3/2];
a(:,1)=a(:,1)*.3;
end
a(:,1)=a(:,1)+e;
a(:,2)=a(:,2)*.3;
a(:,3)=a(:,3)+(ch)+rd;
b=[1 2 6 5;2 3 7 6;3 4 8 7;4 1 5 8;1 2 3 4;5 6 7 8];
ppp=patch('vertices',a,'faces',b,'edgecolor','r','facecolor','k','linewidth',2,'Fa
ceVertexAlphaData',0.5);
rotate3d on
pause(.001)
delete(ppp)
end
end
%% EOF