2007年5月30日 星期三

作業十一

我本週有上課。

我將本作業的三個小題合併成一個大程式,因為老師沒有在題目內明講偏置量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)




ework9



-------------------------------------------------------------------------------------------------
另行說明部份:
我在那裡用了不太直觀的寫法。假設偏差量是e,然後我想要把凸輪順時針轉動theta角,這時候不能先用pincam把圖畫出來再把圖轉theta角!理由將配合以下兩圖說明:
上面是錯誤的轉法:假設凸輪是上面的橢圓形,從動件為紅線,左圖是一開始的樣子。我想得到凸輪順時針轉了theta角(上圖theta為45度,程式內是1度)後的圖形,然後我就直接把整張凸輪的圖都轉了theta角後,再把從動件放上去,結果就會發生上圖所畫出來的有誤差的情況。

這張是正確的轉法:因為我不能直接轉theta角,所以我必須繼續把圖旋轉,直到錯誤的那張圖的誤差量等於零,總共必須旋轉phi角。

注意!若偏差量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) ;

1 則留言:

不留白老人 提到...

你的分析很不錯,只可惜你沒宣告axiis equal,所型成的圖有點扁扁的。修正後,應該可以得到很好的結果