2010-04-20

4連桿機構(筆記摘要)

連桿組(linkage)是由連桿(link)與接頭(joint)所構成的機構, 就如同齒輪系(Gear train)一樣, 主要功能為作用力的傳送 與 運動方式的轉換.


而常見的應用則是在於: 持續旋轉運動 、 往復線性運動 以及 往復搖擺運動之間的轉換.


而用途最廣泛的平面連桿組 (Planar Linkage) 所指的是連桿的運動方向垂直於接頭旋轉軸, 因此整體機構的運動範圍會限制於同一平面上.


以下是3種基本的平面連桿組機構:


   旋轉結/Revolute Joints機構


   滑件(稜柱)結/Sliding(Prismatic) Joints機構


   旋轉結與滑件結之綜合機構


4-Bar Linkage/4連桿組


平面4連桿組機構中, 不作運動的桿稱為固定桿(fixed), 而連結於固定桿之兩個側桿, 若能完全旋轉運動的稱為曲柄 (Crank), 只能往復搖擺的稱為搖桿(Rocker), 固定桿之相對應桿稱為聯結桿(Coupler).


 


Grashof Rule/葛拉索準則


若最短連桿長度為s, 最長連桿長度為l, 而其餘兩個連桿長度分別為p與q, 則若l + s < p + q條件成立時, 即為符合葛拉索準則(Grashof Rule)的4連桿機構.


而依據最短桿之位置, 又可以分成三種類型:


   曲柄搖桿機構(Crank-Rocker): 若最短桿為任一側桿, 則該最短側桿即可以完全旋轉, 而另一側桿則只能往復搖擺.
曲柄擺動時會有兩個變換方向的時機, 稱為機構的肘節位置(Toggle Position), 此時曲柄與聯結桿將分別以延伸或重疊的形式而成為一直線, 不過機構中搖桿移到這兩個肘節位置的速度不一定會相同, 此種狀況有時也稱為急回機構(Quick-Return)的特性.


   雙曲柄機構(Double-Crank/Drag-Link): 若最短桿為固定桿, 則兩個側桿皆可以完全旋轉.


   雙搖桿機構(Double-Rocker): 若最短桿為聯結桿, 則兩個側桿皆只能往復搖擺無法完全旋轉, 而且若不符葛拉索準則(Grashof Rule)的4連桿機構也同屬於雙搖擺機構.




 



  • 留言者: robotman
  • Email: tslinb@hotmail.com
  • 網址:
  • 日期: 2010-05-20 16:22:25
目前是有在"想"把比賽設計過的機型跟經驗相關機構跟程式..統合成一本書..但最大問題是..要"有時間"能坐下來打字..雖然是"藉口"..呵..不過真的要寫一本"有用"的書真得不容易..





  • 留言者: robotman
  • Email: tslinb@hotmail.com
  • 網址:
  • 日期: 2010-05-19 09:35:02
好像回到大學時期修的機構學..呵..那時課程都只是"算"..現在很想把機構學的相關課程都改由樂高來實作..呵..齒輪也就不會在那邊算pitch跟curve..算到死..
[版主回覆05/19/2010 21:31:09]樂高關於機構的參考資料多半偏向在齒輪的應用, 很少有關於連桿運動學方面的著墨, 唯一較多的大概是五十川芳仁的幾本著作, 不過還是只有圖片而沒有說明, 而市面上關於機械原理的書多半是教科書, 對於業餘的人實在太沉重了些, 還真希望有人出一本以Lego technics為主觀於機構或運動方面的書,
林老師既然有這樣的專長, 要不要也出一本書和邱老師拼場一下

2010-04-18

HiTechnic Gyro Sensor的教學文章(pbLua)



在pbLua的官方部落格中有一系列的教學文(Tutorial), 編寫的內容相當有條理且程度適中, 即使未曾使用過pbLua, 也很容易就能理解文章中範例程式的邏輯, 因此也算是具有參考價值的資源.


而其中一篇關於HiTechnic Gyro sensor的使用教學, 是以Gyro所具有的功能特性介紹起, 接著藉由四種Gyro裝置典型應用時的需求層級, 由淺入深且循序漸進的導引與講解如何達成的方法與技巧,
而這四種應用層級分別是:


1.          偵測物體是否正在轉動


2.          偵測物體正往那個方位轉動


3.          測量物體目前正在轉動的速度(角速度) 與 方位


4.          測量物體已轉動的位移角度


對於前三種應用, 很單純的只要將所讀取到感應器的回應值減掉Gyro靜止狀態時的基準值(Zero Point), 就可以得到測量當時之物體轉動的角速度, 藉以判斷出當下轉動的狀態與方位.


至於第四種應用, 則因為速度是單位時間內位移的變化率, 逆運算即是將速度乘以時間以得到位移, 所以即可以透過於固定的取樣周期來計算平均速度, 再乘以取樣週期時間長度以推算出位移角度, 然後累計每次計算的結果, 就可以估計出角度的總位移, 以下是測試時的NXC程式碼:


currTick = CurrentTick();


currSpeed = SensorRaw(GYRO_PORT) * BIAS_SCALE * BIAS_WEIGHT - biasSpeed;


sampleTick = currTick;


lastSpeed  = currSpeed;


do


{


  currTick  = CurrentTick();


  if  ((currTick - sampleTick) >= TRAVEL_SAMPLE_TICK)


  {


     currSpeed = SensorRaw(GYRO_PORT) * BIAS_SCALE * BIAS_WEIGHT -
                  biasSpeed;


     relTravel  + = (currTick - sampleTick) * (currSpeed + lastSpeed)/2;//位移計算


     lastSpeed  = currSpeed;


     sampleTick = currTick;


   }   


  } until (ButtonPressed(BTNCENTER, true));


 


最後所得到的結果雖然未必足夠精確, 不過拿來作為對Gyro sensor特性的教學說明, 還算是不錯的範例.


在實務上, 專業的導航系統確實也使用了第四種應用的概念來提供對GPS的輔助功能, 因為, 通常GPS會受到地理與天候等環境的影響, 並無法確保隨時隨地都能接收到衛星訊號來進行定位, 例如當天候不佳或處於都會區的大樓夾縫中以致衛星訊號收訊不良時, 這時候就需要透過Acceleration 與 Gyro sensor的輔助, 對於前者可以推算出移動距離, 而後者可以推算方位偏向角度, 若在加上Compass來校正, 就可以達成慣性導航系統(Inertial Navigation System, INS)的功能.


而以上所提到的Acceleration’ Gyro’ Compass等三種sensor剛好HiTechnic都有賣, 所以是否有機會結合這些裝置做出慣性導航系統? 個人覺得可能想太多了, 首先, 要將Acceleration sensor所讀到的線性加速度值轉換成位移距離, 就必須對時間做兩次積分, 所以累積的誤差會失真的很嚴重, 再者它是一個I2C裝置, 回應速度對於要成為導航系統而言實在不夠快, 也許, 如果有廠商能開發出All-in-One的裝置, 將三種功能作在一起, 並兼具位移推算的功能, 也許就真的有機會讓NXT具有慣性導航的功能.


改善Gyro基準值的準確度


最後, 在本篇教學文中最重要的內容就是如何改善Gyro基準值(Zero Point)的準確度, 因為, Gyro sensor的測量值會受到外在溫度的影響, 所以須要在每次使用前的熱機過程中先測量出靜止狀態下穩定的基準值, 一般的做法就是持續讀取數次之後再求出平均值, 不過, 再以前面所提的四種應用層級來考量, 前三種應用對於基準值的參考時機是獨立的, 並不會有誤差累積的情況, 而第四種應用, 則因為每次取樣時都會參考基準值來計算位移, 所以若基準值不夠準確, 累積的誤差會讓結果失真, 因此, 在這篇文章中就提到了兩個改善的方法:


l   首先以人為的方式擴大所讀取到感應器回應值的精確位數, 這裡會將每次的讀取值乘以一個常數64, 因此, 當進行平均值計算時就不會因為整數運算的關係被捨棄太多的準確位數.


l   接著會透過加權平均的概念, 來抑制取樣過程中突發的Noise影響基準值計算的準確度, 意即降低每一次取樣影響計算結果的敏感性,
作法的概念是這樣
:
假設要針對流動中的水流測量出平均的生菌數, 為了避免突發的情況影響穩定的結果, 所以, 我們可以事先準備好一個一公升的容器, 然後裝滿純水(生菌數為0), 接著在固定的取樣週期時, 先從水桶中取出25ml的水之後, 再加入等量要測量之水流的水, 如此當取樣次數夠多時, 則水桶中平均的生菌數就會趨於穩定, 而同樣的概念若應用到基準值的計算過程, 就可以讓結果隨著取樣次數的增加而呈現平順的變動, 最後同樣會趨於穩定, 而得到了所需求的基準值了.


以下是NXC的程式碼範例:


long Get_Bias()


 {


    long biasVal, newVal, oldBias=0;


    long xtick=0, sampleTick=0, dispTick=0;   


    do


    {


       xtick = CurrentTick();


       if ((xtick - sampleTick) >= BIAS_SAMPLE_TICK)


       {


          newVal = SensorRaw(GYRO_PORT) * BIAS_SCALE;


          biasVal= biasVal - (biasVal/BIAS_WEIGHT) + newVal;


          sampleTick = xtick;


       }


       if ((xtick - dispTick) >= BIAS_WATCH_TICK)


       {


          NumOut(0, LCD_LINE3, biasVal);


          TextOut(0, LCD_LINE4, "            " );


          NumOut(0, LCD_LINE4, biasVal-oldBias);


          NumOut(0, LCD_LINE5, biasVal / (BIAS_SCALE * BIAS_WEIGHT));


          dispTick = xtick;


          oldBias = biasVal;


       }


    } until (ButtonPressed(BTNRIGHT, true));


    return (biasVal);


 }