向上發展FORTH技術
曾慶潭 Ching-Tang Tseng
ilikeforth@gmail.com
Hamilton, New Zealand
25 October 2011
本文特別為了慶祝台灣光復節而寫
我在今年九月份中華民國 Forth 語言協會的月會中,發表了一篇『行星齒輪組動態模擬程式』的現場展示與演講,公開的程式是贈送給與會者的禮物。
由於題目太大,當時,無法在短時間內講完這個程式所有的含意,月會現場,只能大致說明程式的基本精神。對於不熟悉機械工程的聽眾,現場觀賞完畢動態展示後,可能仍難以體會程式執行時,顯示的表面機械意義。
現在重談這個主題,有一點勉強。因為,已經贈送出去的禮物,似乎也不該一送再送,否則豈不成了二手禮物?但是,我在離台返紐前,親眼目睹中華民國台灣現今 Forth 界的最高高手──陳爽大師兄,一連耗費幾個晚上,專程為我精進修改這個一年多前寫出來的程式,能不感動?現在,不想在網上公開這個程式都不行,那會太辜負了爽兄的好意。
因此,特別挑選台灣光復節,仔細交代這個程式的全盤精神,並為其留下永久的文字記錄,本文可以為台灣帶來向上發展 Forth 技術的一條小路,它才是我當初設計這個程式時的初衷。文末的討論,會涉及未來的多 CPU 系統之平行處理觀念性想法,是有希望在近期內發展出來的理論性探討,這樣的討論,沒實現前都是空談,讀者若不想看,我絕不勉強。
我不是在寫論文,所以文章的內容可以不按牌理出牌,而以方便講解為主。刊出網文也沒有浪費紙張的問題,所以可以不管刊出的圖示是否會太佔空間的問題。全文只考慮以各方面適當的專業術語,清楚、通順的表達我個人的想法。
1. 執行『行星齒輪組動態模擬程式』後的範例停格顯示圖
圖1
如圖1所示,這是一個會按照機械運動原理旋轉起來的動態顯示圖,程式使用了兩個視窗,上圖用掉一個視窗。運轉的同時, Forth 主系統的視窗照常運作。當使用者操作滑鼠於上圖中的三個不同齒輪組區域,點選一下之後,主視窗會顯示經過運算才得到的轉速比,上圖中的實際相對轉速與轉向,也會立即配合操作而馬上動態顯示合理的結果。在齒輪區域外點選,則令轉動立即反向。運轉時壓下鍵盤上的任何鍵,就能得到瞬間停格圖。這裡面有好幾套可以同時運作的現象,但沒有用到 Forth 自身的多工。
歡迎熟悉機械運動原理的專家,從我的創作中找問題,或來信討論,但請勿吹毛求疵到非要我把齒輪的齒畫出來不可。等到有一天, Forth 多 CPU 的系統能夠方便的使用之後,我自然就會再度實現這種創作。那些應該顯示卻不見了的齒,就當它是我在發展程式期間,不小心轉錯方向而被打掉磨平了的結果,如果您不好好學會這種機械運動的原理,亂組合這種齒輪,那些齒是真的會被打掉的。
公開的程式必須在我所設計的 ABC Forth 數學計算系統中才能執行,我試過了,從 XP 的 V4.2 ,到 XP 的 V6.14 ,再到 W7 的 V6.14 ,三套 ABC Forth 系統都能順利的執行,請記住!已經幾年不改的程式,擁有還能再跑好幾年的特性,直到 64 位元的電腦被淘汰前,都能不必修改而執行。這個題材,用來教育我們的下一代,再好不過。現任教師,請不要以此物無利可圖而抗拒採用,下一代不是別人的下一代,他們就是您與我的下一代,我則何必曰利?
2. 我所設計的原始程式
:
\ Planetary Gear set
\ 行星齒輪組動態旋轉模擬程式
\ 作者:曾慶潭 於紐西蘭
\ 版權所有,標示版權,便歡迎使用。
\ Copyright 2010-08-08 Ching-Tang Tseng, Hamilton, NZ
\ Permission is granted by the author to use this software for any application
\ provided this copyright notice is preserved.
120 VALUE SUNR \ (1)太陽齒輪半徑或齒數
40 VALUE PLANETR \ (2)行星齒輪半徑或齒數
40 VALUE DELAY \ (3)畫完停頓時間,以毫秒計
SUNR PLANETR 2 * + VALUE RINGIR \ 環形齒輪內半徑或齒數
RINGIR 40 + VALUE RINGOR \ 環形齒輪外半徑
4 3 MATRIX XF
4 3 MATRIX YF
4 ARRAY R
4 ARRAY W \ 用來暫存轉動之角度位置
4 ARRAY DW \ 每次寸動旋轉步進之角度變量
3 ARRAY BIAS \ 三組旋轉標示點固定之偏差角度
REAL FPI/180
REAL RATIO
INTEGER I
INTEGER J
INTEGER AA
\ 藉助於FORTH標準指令VALUE之使用方式,可以比較方便的將參數傳遞給繪圖系統。
\ 注意:硬用ABC FORTH系統中宣告而成之整數變數,將使程式原理複雜。
0 VALUE A1X 0 VALUE A2X 0 VALUE A3X
0 VALUE A1Y 0 VALUE A2Y 0 VALUE A3Y
0 VALUE B1X 0 VALUE B2X 0 VALUE B3X
0 VALUE B1Y 0 VALUE B2Y 0 VALUE B3Y
0 VALUE C1X 0 VALUE C2X 0 VALUE C3X
0 VALUE C1Y 0 VALUE C2Y 0 VALUE C3Y
0 VALUE D1X 0 VALUE D2X 0 VALUE D3X
0 VALUE D1Y 0 VALUE D2Y 0 VALUE D3Y
\ 固定參數
: INIT1
{{ FPI/180 = FPI / 180 }}
{{ BIAS ( 1 ) = 0 }} {{ BIAS ( 2 ) = 120 }} {{ BIAS ( 3 ) = -120 }}
{{ W ( 1 ) = 0 }} {{ W ( 2 ) = 0 }} {{ W ( 3 ) = 0 }} {{ W ( 4 ) = W ( 3 ) }}
{{ R ( 1 ) = I>R ( SUNR ) }}
{{ R ( 2 ) = I>R ( SUNR ) + I>R ( PLANETR ) }}
{{ R ( 3 ) = I>R ( RINGIR ) }}
{{ R ( 4 ) = I>R ( RINGIR ) + 40 }}
;
\ (4)與齒輪轉速及轉向相關之變數,由設定DW之值來達到目的。
\ 轉向由正負號決定,負值(-)逆時鐘方向旋轉(CCW),正值(+)順時鐘方向旋轉(CW)。
\ 轉速由數值之大小來決定,0值不旋轉,值越大,旋轉得越快。
\ 此處預設為練習計算相對旋轉速度之用,亂設定就亂旋轉。
\ 此範例表示沒有固定齒輪,太陽齒輪為主動,其他齒輪為被動,三組均可自由轉動。
: INIT2
{{ DW ( 1 ) = 5 }}
{{ DW ( 2 ) = R ( 1 ) / ( R ( 1 ) + R ( 3 ) ) }}
{{ DW ( 3 ) = NEGATE ( R ( 1 ) ) / R ( 3 ) }}
{{ DW ( 4 ) = DW ( 3 ) }}
;
: INIT INIT1 INIT2 ;
: INCH-ALONG BASIC
10 FOR I = 1 TO 4
15 LET { W ( I ) = W ( I ) + DW ( I ) }
20 IF { W ( I ) > 360 } THEN 40
30 GOTO 60
40 LET { W ( I ) = W ( I ) - 360 }
50 GOTO 90
60 IF { W ( I ) < 0 } THEN 80
70 GOTO 90
80 LET { W ( I ) = W ( I ) + 360 }
90 NEXT I
100 END
;
: (XYF) BASIC
10 FOR I = 1 TO 4
20 FOR J = 1 TO 3
30 LET { XF ( I J ) = 250 + R ( I ) * COS ( ( W ( I ) + BIAS ( J ) ) * FPI/180 ) }
40 LET { YF ( I J ) = 250 + R ( I ) * SIN ( ( W ( I ) + BIAS ( J ) ) * FPI/180 ) }
50 NEXT J
60 NEXT I
70 END
;
: [XYI]
[[ AA = INT ( XF ( 1 1 ) ) ]] AA TO A1X
[[ AA = INT ( XF ( 1 2 ) ) ]] AA TO A2X
[[ AA = INT ( XF ( 1 3 ) ) ]] AA TO A3X
[[ AA = INT ( YF ( 1 1 ) ) ]] AA TO A1Y
[[ AA = INT ( YF ( 1 2 ) ) ]] AA TO A2Y
[[ AA = INT ( YF ( 1 3 ) ) ]] AA TO A3Y
[[ AA = INT ( XF ( 2 1 ) ) ]] AA TO B1X
[[ AA = INT ( XF ( 2 2 ) ) ]] AA TO B2X
[[ AA = INT ( XF ( 2 3 ) ) ]] AA TO B3X
[[ AA = INT ( YF ( 2 1 ) ) ]] AA TO B1Y
[[ AA = INT ( YF ( 2 2 ) ) ]] AA TO B2Y
[[ AA = INT ( YF ( 2 3 ) ) ]] AA TO B3Y
[[ AA = INT ( XF ( 3 1 ) ) ]] AA TO C1X
[[ AA = INT ( XF ( 3 2 ) ) ]] AA TO C2X
[[ AA = INT ( XF ( 3 3 ) ) ]] AA TO C3X
[[ AA = INT ( YF ( 3 1 ) ) ]] AA TO C1Y
[[ AA = INT ( YF ( 3 2 ) ) ]] AA TO C2Y
[[ AA = INT ( YF ( 3 3 ) ) ]] AA TO C3Y
[[ AA = INT ( XF ( 4 1 ) ) ]] AA TO D1X
[[ AA = INT ( XF ( 4 2 ) ) ]] AA TO D2X
[[ AA = INT ( XF ( 4 3 ) ) ]] AA TO D3X
[[ AA = INT ( YF ( 4 1 ) ) ]] AA TO D1Y
[[ AA = INT ( YF ( 4 2 ) ) ]] AA TO D2Y
[[ AA = INT ( YF ( 4 3 ) ) ]] AA TO D3Y
;
: [XY] BASIC
10 RUN (XYF)
20 RUN [XYI]
30 RUN INCH-ALONG
40 END
;
0 VALUE XM \ 儲存Mouse的座標位置
0 VALUE YM
:OBJECT SPR-GEARS
<SUPER WINDOW
:M ON_INIT: ON_INIT: SUPER ;M
:M STARTPOS: 500 100 ;M
:M STARTSIZE: 500 500 ;M
:M WINDOWTITLE: Z" 行星齒輪組動態展示圖 作者:曾慶潭2010-08-08於紐西蘭" ;M
:M ON_DONE: ON_DONE: SUPER ;M
\ :M WINDOWTITLE: Z" Planetary Gear set Author: Chint-Tang Tseng" ;M
\ 這個指令用到視窗航舵(Handle of the WiNDow),故必須放在這裡。
: SAVEMOUSE
HWND GET-MOUSE-XY TO YM TO XM ;
:M ON_PAINT:
INIT
BEGIN
SAVEMOUSE
[XY]
BLACK LINECOLOR: DC
A1X A1Y MOVETO: DC
250 250 LINETO: DC
A2X A2Y LINETO: DC
250 250 MOVETO: DC
A3X A3Y LINETO: DC
B1X B1Y MOVETO: DC
B2X B2Y LINETO: DC
B3X B3Y LINETO: DC
B1X B1Y LINETO: DC
B1X B1Y PLANETR CIRCLE: DC
B2X B2Y PLANETR CIRCLE: DC
B3X B3Y PLANETR CIRCLE: DC
C1X C1Y MOVETO: DC
D1X D1Y LINETO: DC
C2X C2Y MOVETO: DC
D2X D2Y LINETO: DC
C3X C3Y MOVETO: DC
D3X D3Y LINETO: DC
250 250 SUNR CIRCLE: DC \ 重繪三組被破壞之圓圈
250 250 RINGIR CIRCLE: DC
250 250 RINGOR CIRCLE: DC
DELAY MS
KEY? 0=
WHILE
WHITE LINECOLOR: DC
A1X A1Y MOVETO: DC
250 250 LINETO: DC
A2X A2Y LINETO: DC
250 250 MOVETO: DC
A3X A3Y LINETO: DC
B1X B1Y MOVETO: DC
B2X B2Y LINETO: DC
B3X B3Y LINETO: DC
B1X B1Y LINETO: DC
B1X B1Y PLANETR CIRCLE: DC
B2X B2Y PLANETR CIRCLE: DC
B3X B3Y PLANETR CIRCLE: DC
C1X C1Y MOVETO: DC
D1X D1Y LINETO: DC
C2X C2Y MOVETO: DC
D2X D2Y LINETO: DC
C3X C3Y MOVETO: DC
D3X D3Y LINETO: DC
REPEAT
;M
;OBJECT
\ 操作滑鼠控制出各種方式之旋轉
REAL XR
REAL YR
REAL XYR \ 儲存Mouse座標的半徑值
: SUN-GEAR-FIXED
{{ DW ( 1 ) = 0 }} {{ DW ( 2 ) = 1 }}
{{ DW ( 3 ) = ( R ( 1 ) + R ( 3 ) ) / R ( 3 ) }}
{{ DW ( 4 ) = DW ( 3 ) }}
CR ." 行星齒輪架為主動輸入,環形齒輪為被動輸出時,轉速比為: "
CR ." 1 : " {{ RATIO = ( R ( 1 ) + R ( 3 ) ) / R ( 3 ) }} RATIO F.
CR ." 環形齒輪為主動輸入,行星齒輪架為被動輸出時,轉速比為: "
CR ." 1 : " {{ RATIO = R ( 3 ) / ( R ( 1 ) + R ( 3 ) ) }} RATIO F. ;
: PLANETARY-GEARSET-FIXED
{{ DW ( 1 ) = 5 }} {{ DW ( 2 ) = 0 }}
{{ DW ( 3 ) = NEGATE ( R ( 1 ) / R ( 3 ) ) }}
{{ DW ( 4 ) = DW ( 3 ) }}
CR ." 太陽齒輪為主動輸入,環形齒輪為被動輸出時,轉速比為: "
CR ." 1 : " {{ RATIO = NEGATE ( R ( 1 ) / R ( 3 ) ) }} RATIO F.
CR ." 環形齒輪為主動輸入,太陽齒輪為被動輸出時,轉速比為: "
CR ." 1 : " {{ RATIO = NEGATE ( R ( 3 ) / R ( 1 ) ) }} RATIO F. ;
: RING-GEAR-FIXED
{{ DW ( 1 ) = 5 }}
{{ DW ( 2 ) = R ( 1 ) / ( R ( 1 ) + R ( 3 ) ) }}
{{ DW ( 3 ) = 0 }} {{ DW ( 4 ) = DW ( 3 ) }}
CR ." 太陽齒輪為主動輸入,行星齒輪架為被動輸出時,轉速比為: "
CR ." 1 : " {{ RATIO = R ( 1 ) / ( R ( 1 ) + R ( 3 ) ) }} RATIO F.
CR ." 行星齒輪架為主動輸入,太陽齒輪為被動輸出時,轉速比為: "
CR ." 1 : " {{ RATIO = ( R ( 1 ) + R ( 3 ) ) / R ( 1 ) }} RATIO F. ;
:NONAME BASIC
10 LET { XR = I>R ( XM ) - 250 }
20 LET { YR = I>R ( YM ) - 250 }
30 LET { XYR = SQRT ( ( XR * XR ) + ( YR * YR ) ) }
40 IF { XYR <= R ( 1 ) } THEN 90
50 IF { ( XYR > R ( 1 ) ) AND ( XYR < R ( 3 ) ) } THEN 110
60 IF { ( XYR >= R ( 3 ) ) AND ( XYR <= R ( 4 ) ) } THEN 130
70 IF { XYR > R ( 4 ) } THEN 150
80 GOTO 180
90 RUN SUN-GEAR-FIXED
100 GOTO 180
110 RUN PLANETARY-GEARSET-FIXED
120 GOTO 180
130 RUN RING-GEAR-FIXED
140 GOTO 180
150 FOR I = 1 TO 4
160 LET { DW ( I ) = NEGATE ( DW ( I ) ) }
170 NEXT I
180 END
; SETCLICKFUNC: SPR-GEARS
: MAIN
CR ." 太陽齒輪半徑為: " SUNR . ." ,行星齒輪半徑為: " PLANETR .
CR ." 因此,環形齒輪的半徑為: " RINGIR .
." ,而行星齒輪架的等效半徑為: " RINGIR SUNR + .
START: SPR-GEARS ;
MAIN
3. 陳爽精進修改後的程式
:
:
anew 行星齒輪組.F
\ Planetary Gear set
\ 行星齒輪組動態旋轉模擬程式
\ 作者:曾慶潭 於紐西蘭
\ 版權所有,標示版權,便歡迎使用。
\ Copyright 2010-08-08 Ching-Tang Tseng, Hamilton, NZ
\ Permission is granted by the author to use this software for any application
\ provided this copyright notice is preserved.
needs timer-window \ 動畫改用 timer 驅動 ** 陳爽 2011/9/22
120 VALUE SUNR \ (1)太陽齒輪半徑或齒數
40 VALUE PLANETR \ (2)行星齒輪半徑或齒數
40 VALUE DELAY \ (3)畫完停頓時間,以毫秒計
SUNR PLANETR 2 * + VALUE RINGIR \ 環形齒輪內半徑或齒數
RINGIR 40 + VALUE RINGOR \ 環形齒輪外半徑
4 3 (MATRIX) XI \ 將原 XF 實數陣列 改用 XI 整數陣列 ** 陳爽 2011/9/22
4 3 (MATRIX) YI \ 將原 YF 實數陣列 改用 YI 整數陣列 ** 陳爽 2011/9/22
4 ARRAY R
4 ARRAY W \ 用來暫存轉動之角度位置
4 ARRAY DW \ 每次寸動旋轉步進之角度變量
3 ARRAY BIAS \ 三組旋轉標示點固定之偏差角度
REAL FPI/180
REAL RATIO
REAL FF
INTEGER I
INTEGER J
\ 固定參數
: INIT1
{{ FPI/180 = FPI / 180 }}
{{ BIAS ( 1 ) = 0 }} {{ BIAS ( 2 ) = 120 }} {{ BIAS ( 3 ) = -120 }}
{{ W ( 1 ) = 0 }} {{ W ( 2 ) = 0 }} {{ W ( 3 ) = 0 }} {{ W ( 4 ) = 0 }}
{{ R ( 1 ) = I>R ( SUNR ) }}
{{ R ( 2 ) = I>R ( SUNR ) + I>R ( PLANETR ) }}
{{ R ( 3 ) = I>R ( RINGIR ) }}
{{ R ( 4 ) = I>R ( RINGOR ) }}
;
\ (4)與齒輪轉速及轉向相關之變數,由設定DW之值來達到目的。
\ 轉向由正負號決定,負值(-)逆時鐘方向旋轉(CCW),正值(+)順時鐘方向旋轉(CW)。
\ 轉速由數值之大小來決定,0值不旋轉,值越大,旋轉得越快。
\ 此處預設為練習計算相對旋轉速度之用,亂設定就亂旋轉。
\ 此範例表示沒有固定齒輪,太陽齒輪為主動,其他齒輪為被動,三組均可自由轉動。
: INIT2
{{ DW ( 1 ) = 5 }}
{{ DW ( 2 ) = R ( 1 ) / ( R ( 1 ) + R ( 3 ) ) }}
{{ DW ( 3 ) = NEGATE ( R ( 1 ) ) / R ( 3 ) }}
{{ DW ( 4 ) = DW ( 3 ) }}
;
: INIT INIT1 INIT2 ;
: INCH-ALONG BASIC
10 FOR I = 1 TO 4
20 LET { W ( I ) = W ( I ) + DW ( I ) }
30 IF { W ( I ) > 360 } THEN 60
40 IF { W ( I ) < 0 } THEN 80
50 GOTO 90
60 LET { W ( I ) = W ( I ) - 360 }
70 GOTO 90
80 LET { W ( I ) = W ( I ) + 360 }
90 NEXT I
95 END
;
: <XYF> BASIC
10 FOR I = 1 TO 4
20 FOR J = 1 TO 3
30 LET { FF = 250 + R ( I ) * COS ( ( W ( I ) + BIAS ( J ) ) * FPI/180 ) }
35 LET XI ( I J ) = INT ( FF ) \ 原實數陣列 XF 改為整數陣列 XI ** 陳爽 2011/9/22
40 LET { FF = 250 + R ( I ) * SIN ( ( W ( I ) + BIAS ( J ) ) * FPI/180 ) }
45 LET YI ( I J ) = INT ( FF ) \ 原實數陣列 YF 改為整數陣列 YI ** 陳爽 2011/9/22
50 NEXT J
60 NEXT I
70 END
;
: [XY] BASIC
10 RUN <xyf>
30 RUN INCH-ALONG
40 END
;
0 VALUE XM 0 VALUE YM \ 儲存 Mouse 的座標位置
:OBJECT SPR-GEARS <super timer-window \ 原 window 改為 timer-window ** 陳爽 2011/9/22
:M ON_INIT: ON_INIT: SUPER INIT ;M
:M STARTPOS: 500 100 ;M
:M STARTSIZE: 500 500 ;M
:M WINDOWTITLE: Z" 行星齒輪組動態展示圖 作者:曾慶潭2010-08-08於紐西蘭" ;M
:M ON_DONE: ON_DONE: SUPER ;M
\ :M WINDOWTITLE: Z" Planetary Gear set Author: Chint-Tang Tseng" ;M
: SAVEMOUSE HWND GET-MOUSE-XY TO YM TO XM ;
:M On_Timer: \ 設定 timer 自動更新計算繪圖 ** 陳爽 2011/9/22
[XY] SAVEMOUSE Paint: self ;M
:M ON_PAINT: \ 簡化原重覆計算迴路, 只繪圖 ** 陳爽 2011/9/22
BLACK LINECOLOR: DC
[[ XI ( 1 1 ) ]] @ [[ YI ( 1 1 ) ]] @ MOVETO: DC
250 250 LINETO: DC
[[ XI ( 1 2 ) ]] @ [[ YI ( 1 2 ) ]] @ LINETO: DC
250 250 MOVETO: DC
[[ XI ( 1 3 ) ]] @ [[ YI ( 1 3 ) ]] @ LINETO: DC
[[ XI ( 2 1 ) ]] @ [[ YI ( 2 1 ) ]] @ MOVETO: DC
[[ XI ( 2 2 ) ]] @ [[ YI ( 2 2 ) ]] @ LINETO: DC
[[ XI ( 2 3 ) ]] @ [[ YI ( 2 3 ) ]] @ LINETO: DC
[[ XI ( 2 1 ) ]] @ [[ YI ( 2 1 ) ]] @ LINETO: DC
[[ XI ( 2 1 ) ]] @ [[ YI ( 2 1 ) ]] @ PLANETR CIRCLE: DC
[[ XI ( 2 2 ) ]] @ [[ YI ( 2 2 ) ]] @ PLANETR CIRCLE: DC
[[ XI ( 2 3 ) ]] @ [[ YI ( 2 3 ) ]] @ PLANETR CIRCLE: DC
[[ XI ( 3 1 ) ]] @ [[ YI ( 3 1 ) ]] @ MOVETO: DC
[[ XI ( 4 1 ) ]] @ [[ YI ( 4 1 ) ]] @ LINETO: DC
[[ XI ( 3 2 ) ]] @ [[ YI ( 3 2 ) ]] @ MOVETO: DC
[[ XI ( 4 2 ) ]] @ [[ YI ( 4 2 ) ]] @ LINETO: DC
[[ XI ( 3 3 ) ]] @ [[ YI ( 3 3 ) ]] @ MOVETO: DC
[[ XI ( 4 3 ) ]] @ [[ YI ( 4 3 ) ]] @ LINETO: DC
250 250 SUNR CIRCLE: DC \ 重繪三組被破壞之圓圈
250 250 RINGIR CIRCLE: DC
250 250 RINGOR CIRCLE: DC
[ classes ] \ 暫時可如此過關, 因前述 BASIC 語法未將原 order 還原 ** 陳爽 2011/9/22
;M
;OBJECT
cr .( SPR-GEARS )
START: SPR-GEARS
130 createTimer: SPR-GEARS
: g 130 createTimer: SPR-GEARS ; \ 啟動 timer (設定間隔 130 ms) ** 陳爽 2011/9/22
: h killTimer: SPR-GEARS ; \ 停止 timer ** 陳爽 2011/9/22
\ 操作滑鼠控制出各種方式之旋轉
REAL XR
REAL YR
REAL XYR \ 儲存 Mouse 座標的半徑值
: SUN-GEAR-FIXED
{{ DW ( 1 ) = 0 }} {{ DW ( 2 ) = 1 }}
{{ DW ( 3 ) = ( R ( 1 ) + R ( 3 ) ) / R ( 3 ) }}
{{ DW ( 4 ) = DW ( 3 ) }}
CR ." 行星齒輪架為主動輸入,環形齒輪為被動輸出時,轉速比為: "
CR ." 1 : " {{ RATIO = ( R ( 1 ) + R ( 3 ) ) / R ( 3 ) }} RATIO F.
CR ." 環形齒輪為主動輸入,行星齒輪架為被動輸出時,轉速比為: "
CR ." 1 : " {{ RATIO = R ( 3 ) / ( R ( 1 ) + R ( 3 ) ) }} RATIO F. ;
: PLANETARY-GEARSET-FIXED
{{ DW ( 1 ) = 5 }} {{ DW ( 2 ) = 0 }}
{{ DW ( 3 ) = NEGATE ( R ( 1 ) / R ( 3 ) ) }}
{{ DW ( 4 ) = DW ( 3 ) }}
CR ." 太陽齒輪為主動輸入,環形齒輪為被動輸出時,轉速比為: "
CR ." 1 : " {{ RATIO = NEGATE ( R ( 1 ) / R ( 3 ) ) }} RATIO F.
CR ." 環形齒輪為主動輸入,太陽齒輪為被動輸出時,轉速比為: "
CR ." 1 : " {{ RATIO = NEGATE ( R ( 3 ) / R ( 1 ) ) }} RATIO F. ;
: RING-GEAR-FIXED
{{ DW ( 1 ) = 5 }}
{{ DW ( 2 ) = R ( 1 ) / ( R ( 1 ) + R ( 3 ) ) }}
{{ DW ( 3 ) = 0 }} {{ DW ( 4 ) = DW ( 3 ) }}
CR ." 太陽齒輪為主動輸入,行星齒輪架為被動輸出時,轉速比為: "
CR ." 1 : " {{ RATIO = R ( 1 ) / ( R ( 1 ) + R ( 3 ) ) }} RATIO F.
CR ." 行星齒輪架為主動輸入,太陽齒輪為被動輸出時,轉速比為: "
CR ." 1 : " {{ RATIO = ( R ( 1 ) + R ( 3 ) ) / R ( 1 ) }} RATIO F. ;
:NONAME BASIC
10 LET { XR = I>R ( XM ) - 250 }
20 LET { YR = I>R ( YM ) - 250 }
30 LET { XYR = SQRT ( ( XR * XR ) + ( YR * YR ) ) }
40 IF { XYR <= R ( 1 ) } THEN 90
50 IF { ( XYR > R ( 1 ) ) AND ( XYR < R ( 3 ) ) } THEN 110
60 IF { ( XYR >= R ( 3 ) ) AND ( XYR <= R ( 4 ) ) } THEN 130
70 IF { XYR > R ( 4 ) } THEN 150
80 GOTO 180
90 RUN SUN-GEAR-FIXED
100 GOTO 180
110 RUN PLANETARY-GEARSET-FIXED
120 GOTO 180
130 RUN RING-GEAR-FIXED
140 GOTO 180
150 FOR I = 1 TO 4
160 LET { DW ( I ) = NEGATE ( DW ( I ) ) }
170 NEXT I
180 END
; SETCLICKFUNC: SPR-GEARS
: MAIN
CR ." 太陽齒輪半徑為: " SUNR . ." ,行星齒輪半徑為: " PLANETR .
CR ." 因此,環形齒輪的半徑為: " RINGIR .
." ,而行星齒輪架的等效半徑為: " RINGIR SUNR + .
START: SPR-GEARS g ;
MAIN
4. 原理
許多機械工業的產品,用到行星齒輪組作為設備元件,例如:汽車的自動變速箱。從網路 Google 搜索引擎來探尋,鍵入『Planetary gear set』則可以得到幾千幾百篇相關資料。我們很容易從網文中找到它的各種實體齒輪照片,能動態展示運轉現象的影像則不多。而且,我今天還見過網頁上刊載亂畫、亂轉的動態影像,只是會動,轉速與轉向則完全不合理。
行星齒輪組具有廣泛的功能,雖然在機械傳動的應用上,主要是用於動力轉向輪軸上,做為差速器使用,及用來圓滑改變機械傳動的轉速與變換傳輸扭力。但若考慮到將其應用於最近興起的特殊節能車與油電混合車設計時,它就另有功效,具有結合不同輸入或輸出動力於單一結構的特殊功效。
基本的行星齒輪組結構,由位於中央的太陽齒輪、居間的行星齒輪配上固定的支架、及位於最外圍的環形齒輪三者所構成。正式的運轉,是三者中固定其中單一種齒輪,而讓另外的兩種齒輪自由運轉,來達到變速與改變扭力的目的。一般而言,通常都以數套行星齒輪組,依次配合在一起,設計進單一個齒輪箱內,以達到範圍更為廣泛的變化目的。
就算是機械專家,通常對這種機械運轉起來時的轉速與轉向,不能很直接且正確的進行描述,因此,就產生了不少幫助記憶的圖表或口訣,用來描述這種機械的運動方式。我在初次接觸這種機械時,也很難正確的想像其運轉方式,設計程式時,依然必須藉助於書本的幫助,才能確定程式設計無誤。
相關文獻上都不提行星齒輪是由誰?何時?發明的,甚至於有書本記載,中國古時候黃帝軒轅氏(西元前 2689 年至西元前 2597 年,距今約 4600 年了),打敗蚩尤所使用的指南車,就是使用行星齒輪的運轉原理設計而成。我對這些說法不表意見,但是經由我自己設計的萬用程式,很快就能了解,行星齒輪的運轉原理,可以從軸端安裝了彈子盤(Bearing,學名為軸承)的結構推演出來。
只要古人有機會以肉眼觀察軸端安裝了小滾桿彈子盤的轉軸在運轉,為了保持小滾桿轉動時不會散掉,必須加裝滾桿保持器(Retainer),觀察保持器與轉軸之間的旋轉關係,就會顯現出相當於這種行星齒輪的運轉狀況,於是,行星齒輪就能夠很自然的被發現出來。因此,我們不需要特別去研究,行星齒輪到底是誰發明的?
基本上,我所設計的程式,只須更改太陽齒輪與行星齒輪的半徑,就能立即獲得新的顯示結果。行星齒輪的半徑被設定成相對的很小時,就能見到這種軸承效果,如圖2所示。而且,您還能見到無齒的圖形描述方式,更像實際的軸端彈子盤。
反過來的描述圖,也能立即獲得,都是只須改變兩個數字,就能從我的程式輕易獲得,如圖3所示。因此,這一套動態模擬系統是萬用的,適用於各種情況。
圖2
圖3
圖2與圖3能夠如此輕易的產生,係我對此一系統進行過仔細分析後,才得到的結果。我效法 Forth 程式語言發明人莫查理(Charles H. Moore)先生發明 Forth CPU 的同樣方法,仔細分析問題後,將因子簡化到最精簡程度,才設計程式。因此,得到了只須根據兩個數字,就能設計出整個系統的結論。
設計程式前,我手繪分析此問題的圖形,得知欲繪出展示圖時,只須根據12個關鍵點,然後採用兩點間繪出一直線的指令,與根據一個點及半徑繪出一個圓的指令,就能快速繪出全圖。問題被精簡到最簡程度時,電腦所需執行的程式,就不會太多或太耗時。因此,能讓我們有機會產製像演電影一般的動態展示圖。
讓展示圖形具有動態感的技巧也很簡單,宣告使用黑線讓電腦繪完一次全圖後,停一小段時間,讓觀者能產生視覺暫留的效果。然後,再讓電腦使用見不到的白線宣告,就在原處重繪一遍,原圖就消失了。緊接著,根據電腦快速計算,得到下一步寸動(Inch-along)之後的新位置,也就是該有之新的12個關鍵點,重覆執行上述程序,就可完成動態展示圖。
這 12 個關鍵點,以及繪圖時僅需使用的兩個繪圖指令,可以從圖4的紅圈標示點顯現出來。讀者請自行觀察後體會。
圖4
我也仔細分析過計算這個系統中的轉速比時,根本可以不必去考慮行星齒輪的個別轉速,反倒是行星齒輪架的轉速,才會是繪製動態展示圖時該有的關鍵數據。分析各組齒輪的轉速比時,必須把行星齒輪架,考慮成具有一個等效的旋轉半徑,這個半徑就等於太陽齒輪半徑與環形齒輪內徑之和。因此,再度把問題簡化到計算轉速比時,只須顧慮太陽齒輪的半徑,與環形齒輪的內徑,兩者,便可算出各種轉速變化關係,程式更形簡化了。
如果讀者對於程式中計算轉速比的算法有疑問,請自行上網參考別的專家之論述。此處則是我自己歸納分析後,所得到的最精簡結果,您也可以根據程式執行後印出來的數字,驗證於您自己遭遇到問題後,根據書本中提供的其它公式,計算得到之結果,來核對我設計的程式,對或者是不對?
事實上,探討這種裝置的應用時,行星齒輪架的轉速,確實比行星齒輪本身的轉速要有意義,因為,行星齒輪是恆被架子框住來運轉的。
裝置中用來固定三組齒輪所需要的煞車帶,是不需要繪出圖來表示的。我藉助於設計出電腦滑鼠點選功能的操作,來固定指定的齒輪,就能達到完全一樣的效果。
5. 程式特殊狀況說明
繪圖程式的設計方法非常簡單,近期內即將出版之我的新書中,詳細講解了最基本的設計方法,我鼓勵全世界的中國人去買這本書,書中以非常奇特的方式,描述了許多電腦界所罕見的觀念。
只用兩組繪圖指令就能繪完全圖。換句話說,程式的執行,耗用了大部份的時間,去計算出12個關鍵點的座標。計算時,要用到浮點數及幾何函數,因此,如果不用 ABC Forth 數學計算系統來協助設計,只用傳統的 Forth 程式語言來設計,必會遭遇很大的困難。上述程式中以浮點計算式算出座標,再經過變換成對應整數的相關程式,都是直接列示的數學式子,懂得幾何就懂得這些程式。
一年多前,我在將計算結果傳送進繪圖程式時,遭遇到了困難,因為繪圖程式的原始創作者是麥安卓(Andrew McKewan)先生,他以物件導向(Object oriented)的觀念,創作了新的繪圖程式寫法。而我所設計的 ABC Forth 數學計算程式寫法,與這種設計不相容,嚴格說來是二者互不相容。彼此都由基礎 Forth 系統發展而成,於是,最後,我只好採取一個基礎 Forth 系統中,大家都可以共同使用的變常數 VALUE 宣告的格式,來解決數據傳遞的問題,結果就設計出了上述的原始程式。
陳爽在仔細研究過我的程式後,發現了上述狀況,深覺這樣的程式安排很不恰當,於是我們兩人討論後進行改寫,就改出了以類似 [[ XI ( 2 2 ) ]] @ 的方式取得 ABC Forth 整數變數內容的方式,來取消原來大量使用 VALUE 的原始程式設計方法。另外,在這種使用方式結束後,要增用一列立即執行式的宣告
[ CLASSES ]
以便讓系統在編譯此程式時,能因正確的字彙搜尋路徑,找得到隨後就要編納進系統的 『;M 』指令,達到了我們期望中的目的。
這一段發展過程,展示了陳爽熟悉 Forth 系統的功力,是一段很好的技術研究方式,值得記錄下來供大家參考。
陳爽對利用軟體定時器(Timer)控制動態顯示圖的技巧熟悉,於是又加上了以定時器設計程式的新格式。它的功效等同於宣告將軟體定時器使用於這個繪圖程式之後,繪圖程式便會依照設定的時間間隔,每次均重新繪出一個寸動變換位置後的新視窗,程式能啟、能停,指令的使用方法,就如程式所示。
程式的其它部份,也有幾個值得參考的設計範例,尤其是滑鼠的應用方式,程序完整,從取得滑鼠座標位置的方法,到讓點選位置產生指定功效的設計,均已明確的顯示在程式之中。
精進修改程式之後,我們都並未滿足於這樣的研究結果,我回到紐西蘭,便再度研究試驗出將 ABC Forth 程式格式,融進物件導向程式格式的正式方法,順便透過此文公諸於大眾,大家以後就能依樣使用。
我只須公布一個最簡實例,看完程式,大家立刻就能明白,程式格式的互相融入方法。
\ 視窗繪圖01
\ 作者:曾慶潭 於紐西蘭,版權所有,標示版權,便歡迎使用。
\ Copyright 2011-06-01 Ching-Tang Tseng, Hamilton, NZ
\ Permission is granted by the author to use this software for any application
\ provided this copyright notice is preserved.
INTEGER A
INTEGER B
INTEGER C
INTEGER D
: INIT
[[ A = 0 ]] [[ B = 250 ]] [[ C = 500 ]] [[ D = 250 ]] ;
:OBJECT GRAPH01
<super WINDOW
:M STARTPOS: 100 100 ;M
:M STARTSIZE: 500 500 ;M
:M WINDOWTITLE: Z" 星(Star) 作者:曾慶潭2010-06-01於紐西蘭 " ;M
:M ON_PAINT:
INIT
BLACK LINECOLOR: DC
BASIC
10 RUN A 250 MOVETO: DC
20 RUN 250 B LINETO: DC
30 RUN C 250 LINETO: DC
40 RUN 250 D LINETO: DC
50 RUN A 250 LINETO: DC
60 LET A = A + 10
70 LET B = B + 5
80 LET C = C - 10
90 LET D = D - 5
100 IF C >= 0 THEN -10
110 END
[ CLASSES ]
;M
;OBJECT
: MAIN START: GRAPH01 ;
MAIN
執行結果,可得到圖5。
圖5
這是一個新改寫完成的程式,當初,我在設計這個繪圖程式時,根本不知道我的 ABC Forth 程式能夠這樣使用,但此性能原本即已存在,這樣用,雖然是回到紐西蘭後才產生的新發現,事實上,沒有陳爽的那一列傳統 Forth 程式技巧
[ CLASSES ]
新發現就不容易被發現得出來,大家還是感謝陳爽的協助吧。
我在陳爽家中共同研究了幾個晚上的 Forth ,見到他仔細研讀過我的『ABC FORTH數學計算系統使用說明』,並以彩色筆從頭到尾畫完了重點,深受感動,於是告訴他,可以免費再致贈一本新書給他。您知道他如何回答嗎?他說:『那我畫過的重點豈不全都不見了?』天啊!他是目前全台灣FORTH界最高的高手啊!
上列這個新公佈的小程式,應該是回敬給陳爽大師兄最好的禮物,他最能看懂我的設計,『行星齒輪組動態模擬程式』也因此還能再進一步精進改寫,但我不做了,我想改談當初我設計這個程式時的原始初衷。
6. 討論
我為什麼要發展『行星齒輪組動態模擬程式』?
不是為了想表演技術,是為了替可能很快就會出現的多 CPU Forth 系統找試驗性題目。
我曾在叛逃美國的張憲義手下工作過一段時日,那時,他領導的工作小組中,有發展電腦軟體模擬系統的研究工作,因此,見識過一些模擬系統的研發問題,那是30幾年前的往事。
當時,電腦的軟硬體都沒那麼進步,模擬系統的研究,幾乎只能算是停留在基本的理論性研究階段而已。我最記得的模擬軟體要求,就是設法將所有多項式的數學計算式子,都編寫成一連串 ( a * X + b ) 格式的程式,然後,就能交給平行處理的電腦,進行連貫性的計算,以便快速得到一系列平行輸出的計算結果。
模擬系統最需要快速得到大量的計算結果,這是模擬系統的基本要求。
回頭看看我所設計的『行星齒輪組動態模擬程式』,主要的程式內容,就是不斷的進行一序列的數學計算,它適合用來考驗能夠平行處理的多 CPU Forth 系統,這就是我設計這個程式時的真正初衷,讓我自己可以見到耗用了許多時間在數學計算上的實際程式。
也許讀者立刻會感到我的想法非常幼稚,支湯姆(Tom Zimmer)先生創作的 Win32Forth 系統,原本就是一個根本跑得不夠快的系統,拿它當基礎,當然得不到理想的輸出結果。沒錯,它是跑得非常慢,上述的程式幾乎只能讓我得到每分鐘僅有一轉的動態展示結果,真正汽車上的引擎轉速,在慢車運轉時,都還得有每分鐘 800 轉的轉速,我到底想模擬出甚麼東西呢?這一節討論,就論述這方面的問題。
三年前也是回台參加 Forth 月會時,見識過鄒鳴峰小老弟,展示他使用 CUDA 跑平行處理程式,使用了四個 CPU 。程式給我的感覺,是系統以迴路方式,執行一個畫面的影像處理時,只將平行處理安排成處理互不相干的四個區域影像,來達到平行處理的快速效果,沒有其它特出的系統性意義。
我先行建立起一個自己設計、可以執行無誤而獲得結果的動態模擬程式,然後經常回顧這個程式的內容,用它來思考程式應該如何被編譯?才能成為最好的平行處理程式碼。至於程式設計的漂不漂亮?能不能獲得甚麼好處?不是考慮的重點,甚至於根本就沒打算將它寫進新書中當教材。因為它遠離了一般群眾學習上的基本需求。
我也經常從網上閱讀一些多CPU的最新發展訊息,知道上個月底,綠色陣列(GreenArrays)公司,已經推出了莫查理先生設計的陣列式 144 個 CPU 評估板(Evaluation board),此版為一種原型發展測試用實體裝置。他們推出產品之後,也苦於新人的難以進入使用狀況,必須像我寫新書那樣,趕著寫出新資料,教大家如何憑少到只用3個鍵片(3-key pad)的操作方式來編寫程式,與如何將程式編譯載入系統。
綠色陣列公司的創舉很可貴,我們應該給予高度的肯定。但是,這一個月,我也看到了非 Forth 領域,多 CPU 的技術發展報導訊息,據說 IBM 公司已經與 3M 公司合作,取得了一種特殊的膠水技術,能將多 CPU 的結構黏製成 100 層摩天大樓的樣子,而且可能在 2013 年推出這種結構的多 CPU 裝置,並正式應用在行動手機上。這些訊息告訴了我,多 CPU 的硬體實體發展,還有後續的進展,不是到此為止。
如果將莫查理先生於綠色陣列公司發展出來的 144 個陣列式 CPU ,配上 IBM 公司的膠水技術,將陣列式結構也黏製成摩天大樓,情況就會不一樣了,它將被稱為『144大樓』。摩天大樓的3維式結構,能提供多條CPU間的高速資料通道,陣列式安排的多 CPU 結構只有一條,兩者相比,就好像是一片平房與一座摩天大樓的對應關係,性能差異,可以立見。這些硬體科技的實現,事實上離我們都不遠,在我們有生之年,絕對可以見得到。
我沒有蓋摩天大樓式多CPU的技術,甚至於硬要在我家後院蓋一間小木屋的經濟付出,都會造成我們家庭生活上的緊張。但是,我可以先於別人,先行自我培養出經營一座摩天大樓,讓其發揮效果的能力。
思考多 CPU 的程式碼應有之編譯問題時,我經常回顧我自己設計的破(Poor)程式,如果根據 144 大樓的結構,我好像應該設計一個名為中階指令專用的程式計數器,仿照 Forth 系統中原有的專業術語,它就叫作 MP(Middle word Pointer)。傳統 Forth 中的幾個重要系統變數,它們原始的意義,是這樣的:
W控管低階定義而成指令的執行。
IP控管高階定義而成指令的執行。
UP控管多工定義而成程式的執行。
它們的實質功能,全都像實際 CPU 內的程式計數器 PC(Program Counter),專門用來指出程式被執行到了那一個點,而且必須按規矩自動增量。
我想要的 MP 之所以被稱為中階,是因為系統若將程式中的指令,拆放給 144 大樓中的部份 CPU 執行之後,需要一個中階小主管,暫時可以想像成它就是一名二房東。例如:上述程式中的 (XYF) 指令,本身需要一個 MP 來控管 12 個點的各自計算,它代表需要借用 144 大樓中的 13 層樓,因為 (XYF) 指令自己當個二房東,也需要一層樓。於是,要快速執行出 (XYF) 指令時,系統就去爭取13層樓的使用權, MP 因此而僅在這13層樓間打轉,二房東沒事就去逐樓收房租、發通告,又因為只是二房東,收到的房租,除了自己控管的部份之外,是要上繳大房東的。
這樣的中階程式計數器概念,就能讓我在設計多 CPU 系統編譯程式時,在指令結構中,多增用一欄記憶單元,用來儲存這個指令可以用到多少個 CPU ?此欄暫時就稱它為編制欄吧,它儲存的內容代表執行這個指令時,可由編制出多少個 CPU ,同時執行平行處理而得到結果。
同樣的道理,處理 [XYI] 也需要 13 層樓的使用權,也是一個二房東。兩個二房東要聽命於大房東 [XY] 安排它們串行處理,大房東 [XY] 還有第三個名叫山本寸動(Inch-along)的日本人二房東,它專門經營轉滿一圈 360 度後就會自動歸0的旋轉門,從旋轉門企業經營的內容來看,一次要租 5 層樓。如此一來,將大房東也要租住一層樓而納入考慮, 144 大樓一下子就租出去 13 + 13 + 5 + 1 = 32 層樓了, 144 大樓生意真好,它最歡迎上述幾個房東型式的顧客來租樓使用了。
多 CPU 的編譯器(Compiler),在編譯指令時,需要一些規則,例如:遇到矩陣內各個單元的計算程式時,就鑑別計算是否互不相干?鑑別方法也很簡單,就根據矩陣指標作為識別單元的依據,然後鑑別等號右邊被編譯的內容,有無用到其它同一陣列內的單元?若全無,則表全不相干,於是就根據矩陣指標的總量,上例中是 3 * 4 = 12,再加上自己本身 1 個,總共是 13 ,編進編制欄內。
編譯的規矩當然不僅只是上述這麼簡單,還有其他鑑別出一個指令可以放什麼數值進編制欄的規矩,例如上述程式中專供滑鼠操作用的『:NONAME』指令,它的執行內容都是一些格式相當,彼此也互不相干的程式,也能被分配到幾個 CPU 去分工,卻未必一定要平行而處理。 144 大樓式的 CPU ,由於莫查理先生設計得足夠精簡,佔用空間很少,同一層樓的 CPU 旁,就還能安放出許多的自用記憶體。未必一定要平行處理的互不相干、同格式、小型程式,因此也能交給 144 大樓各樓去執行。
可以想像,如果碰上了前後高度相依的串行程式,編譯系統也得將這些逐步執行的每一列程式,安排成一串樓上、樓下依序相通的租樓方式來執行了。有幾列就得租幾樓,該填進編制欄內的數字是多少?只要清算這一模組程式參數欄的內容,有幾個獨立單元?就能獲得。
Forth 傳統程式已經高度模組化, ABC Forth 程式的寫法,也鼓勵大家盡量使用超短型的模組化格式來寫程式。模組與模組之間可以確定是絕對不相干的程式,因此,那種一時看不出內容,能不能被編譯成高度平行處理的程式?其編制欄的內容就填1,碰上了,只好僅租用 144 大樓的單一樓層來解決問題。
除此之外,必然還有許多多 CPU 程式編譯方法需要考慮的問題可以探討。能被易於編譯成平行處理的程式,也應該有一些基本的程式書寫語法要求。這些規矩,都很值得在144大樓尚未建成上市之前,就開始著手研究,但是,就是需要先準備好類似本文所用的動態模擬程式,才有可以研究的對象。
上述研究方法,是基於一個大前題,才得以如此進行。 144 大樓的每一層樓,都得具有基本 Forth 的核心程式才行。此前我們用來執行 Forth 程式的核心(Kernel)程式,是經由普通 CPU 設計出 Forth 虛擬機(Virtual Machine)而成,如果 144 大樓還用一般 CPU 來建造,那麼,每一層樓都還得有各自的一套 Forth 虛擬機器才行,這樣的發展當然不切實際。
144 大樓裡面,已經不再需要傳統 Forth 系統內的低階指令程式計數器 W 了,它直接使用 Forth 原生碼(Native code)的程式計數器 PC 。因此,思考平行處理的程式編譯問題時,必須從(非『重』)新思考,想法才能不受約束。總而言之, 144 大樓必須採用綠色陣列公司的創作,上述的討論才有意義,因為這是一種天生全硬體 Forth 核心式的 CPU 。
大師兄協助我精進的程式中,採用的一個軟體定時器設計,不是採用 Forth 程式語言完成的設計,它不能上 144 大樓,只好請他在樓下訪客貴賓室內休息了,遇到這種狀況,我們只好另換以 Forth 設計的軟體定時器。
這個月中旬,十月十七日,莫查理先生在他的個人部落格網文中記述,他已開始為這種系統,設計專用的編輯器(Editor)及編譯器(Compiler)。請注意!他設計出來的編譯器,將會是一個標標準準的平行處理程式編譯器,當然與我在本節中討論的觀念完全無關,我們拭目以待。
莫查理先生是設計所有 Forth 相關物品的『真高手』,我是『曾低手』,但是『曾低手』經常會向『真高手』仔細學習。仔細搞通『真高手』 30 幾年前設計的『Tiny BASIC compiler』,『曾低手』就能設計出現在的『ABC FORTH』。
台灣要不要向上發展這種 Forth 技術?隨便您。
目前,一分鐘才轉一轉的動態模擬結果,經過 144 大樓的處理,可能可以處理出每分鐘十萬轉的轉速。
也許您又會問了,轉那麼快要幹什麼?
我則對於回答這種問題,有點不耐煩了。
我告訴您,每分鐘十萬轉,是氣體離心分離機,能夠輕易分離出造原子彈的材料 U235 濃縮原料之基本要求轉速。
----------------------------------
:
許多機械工業的產品,用到行星齒輪組作為設備元件,例如:汽車的自動變速箱。從網路 Google 搜索引擎來探尋,鍵入『Planetary gear set』則可以得到幾千幾百篇相關資料。我們很容易從網文中找到它的各種實體齒輪照片,能動態展示運轉現象的影像則不多。而且,我今天還見過網頁上刊載亂畫、亂轉的動態影像,只是會動,轉速與轉向則完全不合理。
行星齒輪組具有廣泛的功能,雖然在機械傳動的應用上,主要是用於動力轉向輪軸上,做為差速器使用,及用來圓滑改變機械傳動的轉速與變換傳輸扭力。但若考慮到將其應用於最近興起的特殊節能車與油電混合車設計時,它就另有功效,具有結合不同輸入或輸出動力於單一結構的特殊功效。
基本的行星齒輪組結構,由位於中央的太陽齒輪、居間的行星齒輪配上固定的支架、及位於最外圍的環形齒輪三者所構成。正式的運轉,是三者中固定其中單一種齒輪,而讓另外的兩種齒輪自由運轉,來達到變速與改變扭力的目的。一般而言,通常都以數套行星齒輪組,依次配合在一起,設計進單一個齒輪箱內,以達到範圍更為廣泛的變化目的。
就算是機械專家,通常對這種機械運轉起來時的轉速與轉向,不能很直接且正確的進行描述,因此,就產生了不少幫助記憶的圖表或口訣,用來描述這種機械的運動方式。我在初次接觸這種機械時,也很難正確的想像其運轉方式,設計程式時,依然必須藉助於書本的幫助,才能確定程式設計無誤。
相關文獻上都不提行星齒輪是由誰?何時?發明的,甚至於有書本記載,中國古時候黃帝軒轅氏(西元前 2689 年至西元前 2597 年,距今約 4600 年了),打敗蚩尤所使用的指南車,就是使用行星齒輪的運轉原理設計而成。我對這些說法不表意見,但是經由我自己設計的萬用程式,很快就能了解,行星齒輪的運轉原理,可以從軸端安裝了彈子盤(Bearing,學名為軸承)的結構推演出來。
只要古人有機會以肉眼觀察軸端安裝了小滾桿彈子盤的轉軸在運轉,為了保持小滾桿轉動時不會散掉,必須加裝滾桿保持器(Retainer),觀察保持器與轉軸之間的旋轉關係,就會顯現出相當於這種行星齒輪的運轉狀況,於是,行星齒輪就能夠很自然的被發現出來。因此,我們不需要特別去研究,行星齒輪到底是誰發明的?
基本上,我所設計的程式,只須更改太陽齒輪與行星齒輪的半徑,就能立即獲得新的顯示結果。行星齒輪的半徑被設定成相對的很小時,就能見到這種軸承效果,如圖2所示。而且,您還能見到無齒的圖形描述方式,更像實際的軸端彈子盤。
反過來的描述圖,也能立即獲得,都是只須改變兩個數字,就能從我的程式輕易獲得,如圖3所示。因此,這一套動態模擬系統是萬用的,適用於各種情況。
圖2
圖3
圖2與圖3能夠如此輕易的產生,係我對此一系統進行過仔細分析後,才得到的結果。我效法 Forth 程式語言發明人莫查理(Charles H. Moore)先生發明 Forth CPU 的同樣方法,仔細分析問題後,將因子簡化到最精簡程度,才設計程式。因此,得到了只須根據兩個數字,就能設計出整個系統的結論。
設計程式前,我手繪分析此問題的圖形,得知欲繪出展示圖時,只須根據12個關鍵點,然後採用兩點間繪出一直線的指令,與根據一個點及半徑繪出一個圓的指令,就能快速繪出全圖。問題被精簡到最簡程度時,電腦所需執行的程式,就不會太多或太耗時。因此,能讓我們有機會產製像演電影一般的動態展示圖。
讓展示圖形具有動態感的技巧也很簡單,宣告使用黑線讓電腦繪完一次全圖後,停一小段時間,讓觀者能產生視覺暫留的效果。然後,再讓電腦使用見不到的白線宣告,就在原處重繪一遍,原圖就消失了。緊接著,根據電腦快速計算,得到下一步寸動(Inch-along)之後的新位置,也就是該有之新的12個關鍵點,重覆執行上述程序,就可完成動態展示圖。
這 12 個關鍵點,以及繪圖時僅需使用的兩個繪圖指令,可以從圖4的紅圈標示點顯現出來。讀者請自行觀察後體會。
圖4
我也仔細分析過計算這個系統中的轉速比時,根本可以不必去考慮行星齒輪的個別轉速,反倒是行星齒輪架的轉速,才會是繪製動態展示圖時該有的關鍵數據。分析各組齒輪的轉速比時,必須把行星齒輪架,考慮成具有一個等效的旋轉半徑,這個半徑就等於太陽齒輪半徑與環形齒輪內徑之和。因此,再度把問題簡化到計算轉速比時,只須顧慮太陽齒輪的半徑,與環形齒輪的內徑,兩者,便可算出各種轉速變化關係,程式更形簡化了。
如果讀者對於程式中計算轉速比的算法有疑問,請自行上網參考別的專家之論述。此處則是我自己歸納分析後,所得到的最精簡結果,您也可以根據程式執行後印出來的數字,驗證於您自己遭遇到問題後,根據書本中提供的其它公式,計算得到之結果,來核對我設計的程式,對或者是不對?
事實上,探討這種裝置的應用時,行星齒輪架的轉速,確實比行星齒輪本身的轉速要有意義,因為,行星齒輪是恆被架子框住來運轉的。
裝置中用來固定三組齒輪所需要的煞車帶,是不需要繪出圖來表示的。我藉助於設計出電腦滑鼠點選功能的操作,來固定指定的齒輪,就能達到完全一樣的效果。
5. 程式特殊狀況說明
繪圖程式的設計方法非常簡單,近期內即將出版之我的新書中,詳細講解了最基本的設計方法,我鼓勵全世界的中國人去買這本書,書中以非常奇特的方式,描述了許多電腦界所罕見的觀念。
只用兩組繪圖指令就能繪完全圖。換句話說,程式的執行,耗用了大部份的時間,去計算出12個關鍵點的座標。計算時,要用到浮點數及幾何函數,因此,如果不用 ABC Forth 數學計算系統來協助設計,只用傳統的 Forth 程式語言來設計,必會遭遇很大的困難。上述程式中以浮點計算式算出座標,再經過變換成對應整數的相關程式,都是直接列示的數學式子,懂得幾何就懂得這些程式。
一年多前,我在將計算結果傳送進繪圖程式時,遭遇到了困難,因為繪圖程式的原始創作者是麥安卓(Andrew McKewan)先生,他以物件導向(Object oriented)的觀念,創作了新的繪圖程式寫法。而我所設計的 ABC Forth 數學計算程式寫法,與這種設計不相容,嚴格說來是二者互不相容。彼此都由基礎 Forth 系統發展而成,於是,最後,我只好採取一個基礎 Forth 系統中,大家都可以共同使用的變常數 VALUE 宣告的格式,來解決數據傳遞的問題,結果就設計出了上述的原始程式。
陳爽在仔細研究過我的程式後,發現了上述狀況,深覺這樣的程式安排很不恰當,於是我們兩人討論後進行改寫,就改出了以類似 [[ XI ( 2 2 ) ]] @ 的方式取得 ABC Forth 整數變數內容的方式,來取消原來大量使用 VALUE 的原始程式設計方法。另外,在這種使用方式結束後,要增用一列立即執行式的宣告
[ CLASSES ]
以便讓系統在編譯此程式時,能因正確的字彙搜尋路徑,找得到隨後就要編納進系統的 『;M 』指令,達到了我們期望中的目的。
這一段發展過程,展示了陳爽熟悉 Forth 系統的功力,是一段很好的技術研究方式,值得記錄下來供大家參考。
陳爽對利用軟體定時器(Timer)控制動態顯示圖的技巧熟悉,於是又加上了以定時器設計程式的新格式。它的功效等同於宣告將軟體定時器使用於這個繪圖程式之後,繪圖程式便會依照設定的時間間隔,每次均重新繪出一個寸動變換位置後的新視窗,程式能啟、能停,指令的使用方法,就如程式所示。
程式的其它部份,也有幾個值得參考的設計範例,尤其是滑鼠的應用方式,程序完整,從取得滑鼠座標位置的方法,到讓點選位置產生指定功效的設計,均已明確的顯示在程式之中。
精進修改程式之後,我們都並未滿足於這樣的研究結果,我回到紐西蘭,便再度研究試驗出將 ABC Forth 程式格式,融進物件導向程式格式的正式方法,順便透過此文公諸於大眾,大家以後就能依樣使用。
我只須公布一個最簡實例,看完程式,大家立刻就能明白,程式格式的互相融入方法。
\ 視窗繪圖01
\ 作者:曾慶潭 於紐西蘭,版權所有,標示版權,便歡迎使用。
\ Copyright 2011-06-01 Ching-Tang Tseng, Hamilton, NZ
\ Permission is granted by the author to use this software for any application
\ provided this copyright notice is preserved.
INTEGER A
INTEGER B
INTEGER C
INTEGER D
: INIT
[[ A = 0 ]] [[ B = 250 ]] [[ C = 500 ]] [[ D = 250 ]] ;
:OBJECT GRAPH01
<super WINDOW
:M STARTPOS: 100 100 ;M
:M STARTSIZE: 500 500 ;M
:M WINDOWTITLE: Z" 星(Star) 作者:曾慶潭2010-06-01於紐西蘭 " ;M
:M ON_PAINT:
INIT
BLACK LINECOLOR: DC
BASIC
10 RUN A 250 MOVETO: DC
20 RUN 250 B LINETO: DC
30 RUN C 250 LINETO: DC
40 RUN 250 D LINETO: DC
50 RUN A 250 LINETO: DC
60 LET A = A + 10
70 LET B = B + 5
80 LET C = C - 10
90 LET D = D - 5
100 IF C >= 0 THEN -10
110 END
[ CLASSES ]
;M
;OBJECT
: MAIN START: GRAPH01 ;
MAIN
執行結果,可得到圖5。
圖5
這是一個新改寫完成的程式,當初,我在設計這個繪圖程式時,根本不知道我的 ABC Forth 程式能夠這樣使用,但此性能原本即已存在,這樣用,雖然是回到紐西蘭後才產生的新發現,事實上,沒有陳爽的那一列傳統 Forth 程式技巧
[ CLASSES ]
新發現就不容易被發現得出來,大家還是感謝陳爽的協助吧。
我在陳爽家中共同研究了幾個晚上的 Forth ,見到他仔細研讀過我的『ABC FORTH數學計算系統使用說明』,並以彩色筆從頭到尾畫完了重點,深受感動,於是告訴他,可以免費再致贈一本新書給他。您知道他如何回答嗎?他說:『那我畫過的重點豈不全都不見了?』天啊!他是目前全台灣FORTH界最高的高手啊!
上列這個新公佈的小程式,應該是回敬給陳爽大師兄最好的禮物,他最能看懂我的設計,『行星齒輪組動態模擬程式』也因此還能再進一步精進改寫,但我不做了,我想改談當初我設計這個程式時的原始初衷。
6. 討論
我為什麼要發展『行星齒輪組動態模擬程式』?
不是為了想表演技術,是為了替可能很快就會出現的多 CPU Forth 系統找試驗性題目。
我曾在叛逃美國的張憲義手下工作過一段時日,那時,他領導的工作小組中,有發展電腦軟體模擬系統的研究工作,因此,見識過一些模擬系統的研發問題,那是30幾年前的往事。
當時,電腦的軟硬體都沒那麼進步,模擬系統的研究,幾乎只能算是停留在基本的理論性研究階段而已。我最記得的模擬軟體要求,就是設法將所有多項式的數學計算式子,都編寫成一連串 ( a * X + b ) 格式的程式,然後,就能交給平行處理的電腦,進行連貫性的計算,以便快速得到一系列平行輸出的計算結果。
模擬系統最需要快速得到大量的計算結果,這是模擬系統的基本要求。
回頭看看我所設計的『行星齒輪組動態模擬程式』,主要的程式內容,就是不斷的進行一序列的數學計算,它適合用來考驗能夠平行處理的多 CPU Forth 系統,這就是我設計這個程式時的真正初衷,讓我自己可以見到耗用了許多時間在數學計算上的實際程式。
也許讀者立刻會感到我的想法非常幼稚,支湯姆(Tom Zimmer)先生創作的 Win32Forth 系統,原本就是一個根本跑得不夠快的系統,拿它當基礎,當然得不到理想的輸出結果。沒錯,它是跑得非常慢,上述的程式幾乎只能讓我得到每分鐘僅有一轉的動態展示結果,真正汽車上的引擎轉速,在慢車運轉時,都還得有每分鐘 800 轉的轉速,我到底想模擬出甚麼東西呢?這一節討論,就論述這方面的問題。
三年前也是回台參加 Forth 月會時,見識過鄒鳴峰小老弟,展示他使用 CUDA 跑平行處理程式,使用了四個 CPU 。程式給我的感覺,是系統以迴路方式,執行一個畫面的影像處理時,只將平行處理安排成處理互不相干的四個區域影像,來達到平行處理的快速效果,沒有其它特出的系統性意義。
我先行建立起一個自己設計、可以執行無誤而獲得結果的動態模擬程式,然後經常回顧這個程式的內容,用它來思考程式應該如何被編譯?才能成為最好的平行處理程式碼。至於程式設計的漂不漂亮?能不能獲得甚麼好處?不是考慮的重點,甚至於根本就沒打算將它寫進新書中當教材。因為它遠離了一般群眾學習上的基本需求。
我也經常從網上閱讀一些多CPU的最新發展訊息,知道上個月底,綠色陣列(GreenArrays)公司,已經推出了莫查理先生設計的陣列式 144 個 CPU 評估板(Evaluation board),此版為一種原型發展測試用實體裝置。他們推出產品之後,也苦於新人的難以進入使用狀況,必須像我寫新書那樣,趕著寫出新資料,教大家如何憑少到只用3個鍵片(3-key pad)的操作方式來編寫程式,與如何將程式編譯載入系統。
綠色陣列公司的創舉很可貴,我們應該給予高度的肯定。但是,這一個月,我也看到了非 Forth 領域,多 CPU 的技術發展報導訊息,據說 IBM 公司已經與 3M 公司合作,取得了一種特殊的膠水技術,能將多 CPU 的結構黏製成 100 層摩天大樓的樣子,而且可能在 2013 年推出這種結構的多 CPU 裝置,並正式應用在行動手機上。這些訊息告訴了我,多 CPU 的硬體實體發展,還有後續的進展,不是到此為止。
如果將莫查理先生於綠色陣列公司發展出來的 144 個陣列式 CPU ,配上 IBM 公司的膠水技術,將陣列式結構也黏製成摩天大樓,情況就會不一樣了,它將被稱為『144大樓』。摩天大樓的3維式結構,能提供多條CPU間的高速資料通道,陣列式安排的多 CPU 結構只有一條,兩者相比,就好像是一片平房與一座摩天大樓的對應關係,性能差異,可以立見。這些硬體科技的實現,事實上離我們都不遠,在我們有生之年,絕對可以見得到。
我沒有蓋摩天大樓式多CPU的技術,甚至於硬要在我家後院蓋一間小木屋的經濟付出,都會造成我們家庭生活上的緊張。但是,我可以先於別人,先行自我培養出經營一座摩天大樓,讓其發揮效果的能力。
思考多 CPU 的程式碼應有之編譯問題時,我經常回顧我自己設計的破(Poor)程式,如果根據 144 大樓的結構,我好像應該設計一個名為中階指令專用的程式計數器,仿照 Forth 系統中原有的專業術語,它就叫作 MP(Middle word Pointer)。傳統 Forth 中的幾個重要系統變數,它們原始的意義,是這樣的:
W控管低階定義而成指令的執行。
IP控管高階定義而成指令的執行。
UP控管多工定義而成程式的執行。
它們的實質功能,全都像實際 CPU 內的程式計數器 PC(Program Counter),專門用來指出程式被執行到了那一個點,而且必須按規矩自動增量。
我想要的 MP 之所以被稱為中階,是因為系統若將程式中的指令,拆放給 144 大樓中的部份 CPU 執行之後,需要一個中階小主管,暫時可以想像成它就是一名二房東。例如:上述程式中的 (XYF) 指令,本身需要一個 MP 來控管 12 個點的各自計算,它代表需要借用 144 大樓中的 13 層樓,因為 (XYF) 指令自己當個二房東,也需要一層樓。於是,要快速執行出 (XYF) 指令時,系統就去爭取13層樓的使用權, MP 因此而僅在這13層樓間打轉,二房東沒事就去逐樓收房租、發通告,又因為只是二房東,收到的房租,除了自己控管的部份之外,是要上繳大房東的。
這樣的中階程式計數器概念,就能讓我在設計多 CPU 系統編譯程式時,在指令結構中,多增用一欄記憶單元,用來儲存這個指令可以用到多少個 CPU ?此欄暫時就稱它為編制欄吧,它儲存的內容代表執行這個指令時,可由編制出多少個 CPU ,同時執行平行處理而得到結果。
同樣的道理,處理 [XYI] 也需要 13 層樓的使用權,也是一個二房東。兩個二房東要聽命於大房東 [XY] 安排它們串行處理,大房東 [XY] 還有第三個名叫山本寸動(Inch-along)的日本人二房東,它專門經營轉滿一圈 360 度後就會自動歸0的旋轉門,從旋轉門企業經營的內容來看,一次要租 5 層樓。如此一來,將大房東也要租住一層樓而納入考慮, 144 大樓一下子就租出去 13 + 13 + 5 + 1 = 32 層樓了, 144 大樓生意真好,它最歡迎上述幾個房東型式的顧客來租樓使用了。
多 CPU 的編譯器(Compiler),在編譯指令時,需要一些規則,例如:遇到矩陣內各個單元的計算程式時,就鑑別計算是否互不相干?鑑別方法也很簡單,就根據矩陣指標作為識別單元的依據,然後鑑別等號右邊被編譯的內容,有無用到其它同一陣列內的單元?若全無,則表全不相干,於是就根據矩陣指標的總量,上例中是 3 * 4 = 12,再加上自己本身 1 個,總共是 13 ,編進編制欄內。
編譯的規矩當然不僅只是上述這麼簡單,還有其他鑑別出一個指令可以放什麼數值進編制欄的規矩,例如上述程式中專供滑鼠操作用的『:NONAME』指令,它的執行內容都是一些格式相當,彼此也互不相干的程式,也能被分配到幾個 CPU 去分工,卻未必一定要平行而處理。 144 大樓式的 CPU ,由於莫查理先生設計得足夠精簡,佔用空間很少,同一層樓的 CPU 旁,就還能安放出許多的自用記憶體。未必一定要平行處理的互不相干、同格式、小型程式,因此也能交給 144 大樓各樓去執行。
可以想像,如果碰上了前後高度相依的串行程式,編譯系統也得將這些逐步執行的每一列程式,安排成一串樓上、樓下依序相通的租樓方式來執行了。有幾列就得租幾樓,該填進編制欄內的數字是多少?只要清算這一模組程式參數欄的內容,有幾個獨立單元?就能獲得。
Forth 傳統程式已經高度模組化, ABC Forth 程式的寫法,也鼓勵大家盡量使用超短型的模組化格式來寫程式。模組與模組之間可以確定是絕對不相干的程式,因此,那種一時看不出內容,能不能被編譯成高度平行處理的程式?其編制欄的內容就填1,碰上了,只好僅租用 144 大樓的單一樓層來解決問題。
除此之外,必然還有許多多 CPU 程式編譯方法需要考慮的問題可以探討。能被易於編譯成平行處理的程式,也應該有一些基本的程式書寫語法要求。這些規矩,都很值得在144大樓尚未建成上市之前,就開始著手研究,但是,就是需要先準備好類似本文所用的動態模擬程式,才有可以研究的對象。
上述研究方法,是基於一個大前題,才得以如此進行。 144 大樓的每一層樓,都得具有基本 Forth 的核心程式才行。此前我們用來執行 Forth 程式的核心(Kernel)程式,是經由普通 CPU 設計出 Forth 虛擬機(Virtual Machine)而成,如果 144 大樓還用一般 CPU 來建造,那麼,每一層樓都還得有各自的一套 Forth 虛擬機器才行,這樣的發展當然不切實際。
144 大樓裡面,已經不再需要傳統 Forth 系統內的低階指令程式計數器 W 了,它直接使用 Forth 原生碼(Native code)的程式計數器 PC 。因此,思考平行處理的程式編譯問題時,必須從(非『重』)新思考,想法才能不受約束。總而言之, 144 大樓必須採用綠色陣列公司的創作,上述的討論才有意義,因為這是一種天生全硬體 Forth 核心式的 CPU 。
大師兄協助我精進的程式中,採用的一個軟體定時器設計,不是採用 Forth 程式語言完成的設計,它不能上 144 大樓,只好請他在樓下訪客貴賓室內休息了,遇到這種狀況,我們只好另換以 Forth 設計的軟體定時器。
這個月中旬,十月十七日,莫查理先生在他的個人部落格網文中記述,他已開始為這種系統,設計專用的編輯器(Editor)及編譯器(Compiler)。請注意!他設計出來的編譯器,將會是一個標標準準的平行處理程式編譯器,當然與我在本節中討論的觀念完全無關,我們拭目以待。
莫查理先生是設計所有 Forth 相關物品的『真高手』,我是『曾低手』,但是『曾低手』經常會向『真高手』仔細學習。仔細搞通『真高手』 30 幾年前設計的『Tiny BASIC compiler』,『曾低手』就能設計出現在的『ABC FORTH』。
台灣要不要向上發展這種 Forth 技術?隨便您。
目前,一分鐘才轉一轉的動態模擬結果,經過 144 大樓的處理,可能可以處理出每分鐘十萬轉的轉速。
也許您又會問了,轉那麼快要幹什麼?
我則對於回答這種問題,有點不耐煩了。
我告訴您,每分鐘十萬轉,是氣體離心分離機,能夠輕易分離出造原子彈的材料 U235 濃縮原料之基本要求轉速。
----------------------------------
:
\ 最後的發展,演進說明都在程式內,有興趣就請自行參考。(2013/11/8) \ 2013-12-29 加註指令堆疊變化說明,都不用堆疊也應標示。 \ Planetary Gearset \ 行星齒輪組動態旋轉模擬程式 \ 作者:曾慶潭 於紐西蘭 \ 版權所有,標示版權,便歡迎使用。 \ Copyright 2010-08-08 Ching-Tang Tseng, Hamilton, NZ \ Permission is granted by the author to use this software for any application \ provided this copyright notice is preserved. \ 適用於ABC FORTH V648以後之版本(2013-11-8) 120 VALUE SunR \ (1)太陽齒輪半徑或齒數 40 VALUE PlanetR \ (2)行星齒輪半徑或齒數 40 VALUE Delay \ (3)畫完停頓時間,以毫秒計 SunR PlanetR 2 * + VALUE RingIR \ 環形齒輪內半徑或齒數 RingIR 40 + VALUE RingOR \ 環形齒輪外半徑 4 3 (MATRIX) XI 4 3 (MATRIX) YI 4 ARRAY R 4 ARRAY W \ 用來暫存轉動之角度位置 4 ARRAY DW \ 每次寸動旋轉步進之角度變量 3 ARRAY Bias \ 三組旋轉標示點固定之偏差角度 \ 簡化同性質多個變數的宣告方式 5 REALS Fpi/180 Ratio XFF YFF PFF 2 INTEGERS I J \ 固定參數 : Init1 ( -- ) {{ Fpi/180 = FPI / 180 }} {{ Bias ( 1 ) = 0 }} {{ Bias ( 2 ) = 120 }} {{ Bias ( 3 ) = -120 }} {{ W ( 1 ) = 0 }} {{ W ( 2 ) = 0 }} {{ W ( 3 ) = 0 }} {{ W ( 4 ) = W ( 3 ) }} {{ R ( 1 ) = I>R ( SunR ) }} {{ R ( 2 ) = I>R ( SunR ) + I>R ( PlanetR ) }} {{ R ( 3 ) = I>R ( RingIR ) }} {{ R ( 4 ) = I>R ( RingIR ) + 40 }} ; \ (4)與齒輪轉速及轉向相關之變數,由設定DW之值來達到目的。 \ 轉向由正負號決定,負值(-)逆時鐘方向旋轉(CCW),正值(+)順時鐘方向旋轉(CW)。 \ 轉速由數值之大小來決定,0值不旋轉,值越大,旋轉得越快。 \ 此處預設為練習計算相對旋轉速度之用,亂設定就亂旋轉。 \ 此範例表示沒有固定齒輪,太陽齒輪為主動,其他齒輪為被動,三組均可自由轉動。 : Init2 ( -- ) {{ DW ( 1 ) = 5 }} {{ DW ( 2 ) = R ( 1 ) / ( R ( 1 ) + R ( 3 ) ) }} {{ DW ( 3 ) = NEGATE ( R ( 1 ) ) / R ( 3 ) }} {{ DW ( 4 ) = DW ( 3 ) }} ; : Init ( -- ) Init1 Init2 ; : Inch-Along ( -- ) BASIC 10 FOR I = 1 TO 4 20 LET { W ( I ) = W ( I ) + DW ( I ) } 30 IF { W ( I ) > 360 } THEN 40 40 GOTO 70 50 LET { W ( I ) = W ( I ) - 360 } 60 GOTO 100 70 IF { W ( I ) < 0 } THEN 80 80 GOTO 100 90 LET { W ( I ) = W ( I ) + 360 } 100 NEXT I 110 END ; \ 以::取代必須連續多次使用之標號與LET,亦即:( :: ) = (LET ) : XYF>XYI ( -- ) BASIC 10 FOR I = 1 TO 4 20 FOR J = 1 TO 3 30 LET { PFF = ( W ( I ) + Bias ( J ) ) * Fpi/180 } :: { XFF = 250 + R ( I ) * COS ( PFF ) } :: XI ( I J ) = INT ( XFF ) :: { YFF = 250 + R ( I ) * SIN ( PFF ) } :: YI ( I J ) = INT ( YFF ) 40 NEXT J 50 NEXT I 60 END ; 12 INTEGERS A1X A2X A3X A1Y A2Y A3Y B1X B2X B3X B1Y B2Y B3Y 12 INTEGERS C1X C2X C3X C1Y C2Y C3Y D1X D2X D3X D1Y D2Y D3Y : XYI>ABCD[XY] ( -- ) [[ A1X = XI ( 1 1 ) ]] [[ A2X = XI ( 1 2 ) ]] [[ A3X = XI ( 1 3 ) ]] [[ A1Y = YI ( 1 1 ) ]] [[ A2Y = YI ( 1 2 ) ]] [[ A3Y = YI ( 1 3 ) ]] [[ B1X = XI ( 2 1 ) ]] [[ B2X = XI ( 2 2 ) ]] [[ B3X = XI ( 2 3 ) ]] [[ B1Y = YI ( 2 1 ) ]] [[ B2Y = YI ( 2 2 ) ]] [[ B3Y = YI ( 2 3 ) ]] [[ C1X = XI ( 3 1 ) ]] [[ C2X = XI ( 3 2 ) ]] [[ C3X = XI ( 3 3 ) ]] [[ C1Y = YI ( 3 1 ) ]] [[ C2Y = YI ( 3 2 ) ]] [[ C3Y = YI ( 3 3 ) ]] [[ D1X = XI ( 4 1 ) ]] [[ D2X = XI ( 4 2 ) ]] [[ D3X = XI ( 4 3 ) ]] [[ D1Y = YI ( 4 1 ) ]] [[ D2Y = YI ( 4 2 ) ]] [[ D3Y = YI ( 4 3 ) ]] ; \ 以=>取代必須連續多次使用之標號與RUN,亦即:( => ) = ( RUN ) : ABCD[XY] ( -- ) BASIC 10 RUN Inch-Along => XYF>XYI => XYI>ABCD[XY] 20 END ; \ 儲存Mouse的座標位置 2 VALUES XM YM \ 物件規格式程式起始點,注意!說明敘述不可以直接放在:OBJECT後面。 :OBJECT SPR-Gears <SUPER WINDOW \ 新開視窗物件之框架宣告程式 :M ON_INIT: ON_INIT: SUPER ;M :M STARTPOS: 500 100 ;M :M STARTSIZE: 500 500 ;M :M WINDOWTITLE: Z" 行星齒輪組動態展示圖 作者:曾慶潭2010-08-08於紐西蘭" ;M \ :M WINDOWTITLE: Z" Planetary Gearset Author:Chint-Tang Tseng" ;M :M ON_DONE: ON_DONE: SUPER ;M \ 下列程式,等同於是被設計在此一SPR-Gears物件之內的專門類別性(class)指令。 \ 這種指令只在此物件所屬程式範圍內有效,物件以外的程式不能叫用。 \ 這個指令用到視窗航舵(Handle of the WiNDow),故必須放在這裡。 : SaveMouse ( -- ) HWND GET-MOUSE-XY TO YM TO XM ; : 繪出全圖 ( -- ) A1X A1Y MOVETO: DC 250 250 LINETO: DC A2X A2Y LINETO: DC 250 250 MOVETO: DC A3X A3Y LINETO: DC B1X B1Y MOVETO: DC B2X B2Y LINETO: DC B3X B3Y LINETO: DC B1X B1Y LINETO: DC B1X B1Y PlanetR CIRCLE: DC B2X B2Y PlanetR CIRCLE: DC B3X B3Y PlanetR CIRCLE: DC C1X C1Y MOVETO: DC D1X D1Y LINETO: DC C2X C2Y MOVETO: DC D2X D2Y LINETO: DC C3X C3Y MOVETO: DC D3X D3Y LINETO: DC ; : 以黑線繪圖 ( -- ) Black LINECOLOR: DC 繪出全圖 ; : 以白線繪圖 ( -- ) White LINECOLOR: DC 繪出全圖 ; : 重繪三組被破壞之圓 ( -- ) 250 250 SunR CIRCLE: DC 250 250 RingIR CIRCLE: DC 250 250 RingOR CIRCLE: DC ; \ 此一區段內的程式,才是主要執行繪圖的實際程式。 :M ON_PAINT: Init BEGIN \ 此SaveMouse指令無法以BASIC格式的RUN指令來叫用!!! SaveMouse ABCD[XY] 以黑線繪圖 重繪三組被破壞之圓 Delay MS \ 碰觸鍵盤為正常結束,以滑鼠強行關閉視窗為不正常結束。 KEY? 0= WHILE 以白線繪圖 REPEAT ;M ;OBJECT \ 物件規格式程式結束點 \ 以下程式供作用來操作滑鼠控制出各種方式之旋轉時使用。 \ 儲存Mouse座標的半徑值 3 REALS XR YR XYR : Sun-Gear-Fixed ( -- ) {{ DW ( 1 ) = 0 }} {{ DW ( 2 ) = 1 }} {{ DW ( 3 ) = ( R ( 1 ) + R ( 3 ) ) / R ( 3 ) }} {{ DW ( 4 ) = DW ( 3 ) }} CR ." 行星齒輪架為主動輸入,環形齒輪為被動輸出時,轉速比為: " CR ." 1 : " {{ Ratio = ( R ( 1 ) + R ( 3 ) ) / R ( 3 ) }} Ratio F. CR ." 環形齒輪為主動輸入,行星齒輪架為被動輸出時,轉速比為: " CR ." 1 : " {{ Ratio = R ( 3 ) / ( R ( 1 ) + R ( 3 ) ) }} Ratio F. ; : Planetary-GearSet-Fixed ( -- ) {{ DW ( 1 ) = 5 }} {{ DW ( 2 ) = 0 }} {{ DW ( 3 ) = NEGATE ( R ( 1 ) / R ( 3 ) ) }} {{ DW ( 4 ) = DW ( 3 ) }} CR ." 太陽齒輪為主動輸入,環形齒輪為被動輸出時,轉速比為: " CR ." 1 : " {{ Ratio = NEGATE ( R ( 1 ) / R ( 3 ) ) }} Ratio F. CR ." 環形齒輪為主動輸入,太陽齒輪為被動輸出時,轉速比為: " CR ." 1 : " {{ Ratio = NEGATE ( R ( 3 ) / R ( 1 ) ) }} Ratio F. ; : Ring-Gear-Fixed ( -- ) {{ DW ( 1 ) = 5 }} {{ DW ( 2 ) = R ( 1 ) / ( R ( 1 ) + R ( 3 ) ) }} {{ DW ( 3 ) = 0 }} {{ DW ( 4 ) = DW ( 3 ) }} CR ." 太陽齒輪為主動輸入,行星齒輪架為被動輸出時,轉速比為: " CR ." 1 : " {{ Ratio = R ( 1 ) / ( R ( 1 ) + R ( 3 ) ) }} Ratio F. CR ." 行星齒輪架為主動輸入,太陽齒輪為被動輸出時,轉速比為: " CR ." 1 : " {{ Ratio = ( R ( 1 ) + R ( 3 ) ) / R ( 1 ) }} Ratio F. ; :NONAME ( -- ) BASIC 10 LET { XR = I>R ( XM ) - 250 } :: { YR = I>R ( YM ) - 250 } :: { XYR = SQRT ( ( XR * XR ) + ( YR * YR ) ) } 40 IF { XYR <= R ( 1 ) } THEN 90 50 IF { ( XYR > R ( 1 ) ) AND ( XYR < R ( 3 ) ) } THEN 110 60 IF { ( XYR >= R ( 3 ) ) AND ( XYR <= R ( 4 ) ) } THEN 130 70 IF { XYR > R ( 4 ) } THEN 150 80 GOTO 180 90 RUN Sun-Gear-Fixed 100 GOTO 180 110 RUN Planetary-GearSet-Fixed 120 GOTO 180 130 RUN Ring-Gear-Fixed 140 GOTO 180 150 FOR I = 1 TO 4 160 LET { DW ( I ) = NEGATE ( DW ( I ) ) } 170 NEXT I 180 END ; SetClickFunc: SPR-Gears : MAIN ( -- ) CR ." 太陽齒輪半徑為: " SunR . ." ,行星齒輪半徑為: " PlanetR . CR ." 因此,環形齒輪的內半徑為: " RingIR . ." ,而行星齒輪架的等效半徑為: " RingIR SunR + . CR START: SPR-Gears ; MAIN \S \ 執行MAIN,再以滑鼠點選三個齒輪區域後的輸出範例: 太陽齒輪半徑為: 120 ,行星齒輪半徑為: 40 因此,環形齒輪的內半徑為: 200 ,而行星齒輪架的等效半徑為: 320 太陽齒輪為主動輸入,行星齒輪架為被動輸出時,轉速比為: 1 : .375000000000 行星齒輪架為主動輸入,太陽齒輪為被動輸出時,轉速比為: 1 : 2.66666666667 太陽齒輪為主動輸入,環形齒輪為被動輸出時,轉速比為: 1 : -.600000000000 環形齒輪為主動輸入,太陽齒輪為被動輸出時,轉速比為: 1 : -1.66666666667 行星齒輪架為主動輸入,環形齒輪為被動輸出時,轉速比為: 1 : 1.60000000000 環形齒輪為主動輸入,行星齒輪架為被動輸出時,轉速比為: 1 : .625000000000
附註 : 20241023 重新整理後貼出。