在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);
}