我將本作業的三個小題合併成一個大程式,因為老師沒有在題目內明講偏置量e為多少,故我的程式設計成可自行輸入偏差量;由於返程的運動形式為自訂,故我的程式設計成去程及返程的運動形式都可以自行輸入。以下為程式碼以及解釋:
-------------------------------------------------------------------------------------------------
function homework9(r0,s,e,L,range,pattern,cw)
% 把本作業的三個小題整合在一個程式內,分別以三個figure呈現出來。
% uses plot_dwell.m
% uses pincam.m
% Inputs:
% cth:angle of cam, degrees
% r0:radius of base circle
% e:offset
% s:stroke
% L:length of pin
% cw:rotation direction of cam(-counterclockwise,+clockwise
% pattern = denote the type of motion used(a 3 element-row matrix)
% 1:uniform 2:parabolic 3:simple harmonic 4: cycloidal
% 5:polynomial motion
% example [4 3]
% range =the degrees the specific motion starts, eg.[90 180 240]
% 我一律設定所有圖表都是每度畫一次,使用者不得自行更改。
ctheta=0:1:359;
% r0必小於e,否則會有凸輪轉到一半從動件跟凸輪失去接觸的情況。
if r0<=e
error('Please try another set of r0 & e, since r0 cannot be smaller than e!')
end
%%%%%%%%%%%%%%%%%%%%%%%%%%% 第一小題 %%%%%%%%%%%%%%%%%%%%%%%%%%%
% 以下是將老師的plot_dwell稍做修改後得到:
figure(1); % 第一小題,使用figure1。
clf;
[y,yy,yyy]=dwell(ctheta,range,pattern);
plot(ctheta,y*s,'b-',ctheta,yy*s,'k-',ctheta,yyy*s,'r-'); % 我僅把此行的handle拿掉,其他都跟原程式碼一樣。
legend('Displacement','Velocity','Acceleration',3)
xlabel('Elapsed Angle, degrees')
grid
%%%%%%%%%%%%%%%%%%%%%%%%%%%% 第二小題 %%%%%%%%%%%%%%%%%%%%%%%%%%%
% 以下是將老師的pincam修改後得到:
figure(2); % 第二小題,使用figure2。
clf;
th=ctheta*pi/180;
s0=sqrt(r0*r0-e*e);
for i=1:length(ctheta)
t=th(i)*cw;
A=[cos(t) -sin(t);sin(t) cos(t)];
[ym,yy,yyy]=dwell(ctheta(i),range,pattern);
x0=s0+ym*s;
Sx=[0 x0 x0+L;e e e];
X=A\Sx;
x(i)=X(1,2);y(i)=X(2,2);
% 每十度畫一次從動件的延伸和從洞件。
% 若是每一度都畫一次,圖形會密到看不出來。
r= mod(i,10); % 計數器i可以被10整除時就畫一次。
if r == 0
line(X(1,1:2),X(2,1:2)); % 畫從動件的延伸
line(X(1,2:3),X(2,2:3),'linewidth',3,'color','red'); % 畫從動件
end
end
hold on;
plot(0,0,'ro',x,y,'k-') % 畫工作曲線
axis([-(r0+s+L+5) (r0+s+L+5) -(r0+s+L+5) (r0+s+L+5)])
%%%%%%%%%%%%%%%%%%%%%%%%%%%% 第三小題 %%%%%%%%%%%%%%%%%%%%%%%%%%%
% 以下是將第二小題的程式再進行修改後所得到:
figure(3); % 第三小題,使用figure3。
clf;
% 分成有沒有偏移量e來處理
if e==0 % 無偏移量e
while 1 % 讓動畫可以無限循環
for i=1:length(ctheta)
clf; % 製作動畫所必須的更新畫面。
% 將所有點繞原點旋轉1度後畫工作曲線。
x = x.*cosd(1) - y.*sind(cw) ;
y = x.*sind(cw) + y.*cosd(1) ;
plot(0,0,'ro',x,y,'k-');
hold on;
% 畫從動件的延伸以及從動件。
plot([x(i) x(i)+L],[0 0],'red','LineWidth',3);
plot([0 x(i)],[0 0],'blue');
axis([-(r0+s+L+5) (r0+s+L+5) -(r0+s+L+5) (r0+s+L+5)]);
pause(0.01);
end
end
else % 有偏移量e
while 1 % 讓動畫可以無限循環
for i=1:length(ctheta)
clf; % 製作動畫所必須的更新畫面。
% 當cw=-1,也就是順時針旋轉時:
% i等於360時x(i+1)會讀到第361項,需修正為第1項。
if i == 360 && cw==-1
i = 0;
end
% 當cw=-1,也就是順時針旋轉時:
% i等於1時x(i-1)會讀到第0項,需修正為第360項。
if i == 1 && cw==1
i = 360;
end
% 雖然在這裡有可能會改到計數器i,但是經過測試後發現:計數器本身並不會因為i被暫時改變而計算錯!
% 例:i=1且cw=1時i被改為360,但for迴圈下次再跑進來的時候i會是2而不是361!
% 以下寫法特殊,另行說明。
R2 = ( (x(i-cw))^2 + (y(i-cw))^2 )^0.5 ;
phi = asind(y(i-cw)/R2) - asind(e/R2) ;
x = x.*cosd(phi) - y.*sind(-phi) ;
y = x.*sind(-phi) + y.*cosd(phi) ;
plot(0,0,'ro',x,y,'k-');
hold on;
% 以上寫法特殊,另行說明。
% 畫從動件的延伸線所切出的包絡圓。
p=linspace(0,2*pi,360)';
pp=e*(sin(p)+j*cos(p));
plot(pp);
% 畫從動件的延伸以及從動件。
plot([x(i-cw) x(i-cw)+L],[e e],'red','LineWidth',3);
plot([x(i-cw) 0],[e e],'blue');
axis([-(r0+s+L+5) (r0+s+L+5) -(r0+s+L+5) (r0+s+L+5)]);
pause(0.01);
end
end
end
-------------------------------------------------------------------------------------------------
homework9(15,5,5,10,[100 200 260],[2 5],-1)
(選擇偏置量=5、返程運動型式=5)
另行說明部份:
-------------------------------------------------------------------------------------------------
我在那裡用了不太直觀的寫法。假設偏差量是e,然後我想要把凸輪順時針轉動theta角,這時候不能先用pincam把圖畫出來再把圖轉theta角!理由將配合以下兩圖說明:
上面是錯誤的轉法:假設凸輪是上面的橢圓形,從動件為紅線,左圖是一開始的樣子。我想得到凸輪順時針轉了theta角(上圖theta為45度,程式內是1度)後的圖形,然後我就直接把整張凸輪的圖都轉了theta角後,再把從動件放上去,結果就會發生上圖所畫出來的有誤差的情況。
注意!若偏差量e為0,則不會有此問題。這也是為什麼e==0那部份的程式碼較簡單的原因!
phi角與theta角的關係如下:
R2 = ( (x(i-cw))^2 + (y(i-cw))^2 )^0.5 ;
phi = asind(y(i-cw)/R2) - asind(e/R2) ;