超音波感測器原理為打出一個人類聽不到的聲波,利用其反射波接收,以測得物體 的距離。於樂高的超音波感測器,具有如眼睛一般的外型,兩個圓框內裝置,一個為發 射訊號,另一個為接收訊號的裝置,使用上只要使其對準物體,其就能回饋以公分為單 位之數值,因此我們可以用ROBOTC 編寫一個簡單的避障程式。
loop:
if ( distance < 20 ) forward ( ) ; else
turn left;
end loop
這個程式是當前方20 公分有障礙物時,自走車會向右轉彎。
之前在參加TDK 盃第 11 屆全國大專院校創思設計與製作競賽時,也有拿超音波感 測器作為物體定位及行進間導引之用途,圖示,從起點開始,經過小山丘,先到定點取
特定顏色的球,此時則利用超音波感測器模擬如倒車距離警示,於即將靠牆5 公分則停 止,進行取球動作,走至卸貨區,一樣用超音波感測器測得接近牆5 公分則停止,進行 放球動作,再來就進入隧道區,因已無黑線可循跡,所以於機器人側邊亦裝上超音波感 測器,以測得沿著隧道牆之固定距離,達到機器人調整往前行走之方向,進而完成任務。
有了之前賽事的經驗,本次競賽也因機器人須定位轉向,且不能靠牆之任務挑戰及 規則,決定採用超音波感測器作為機器人轉向定位之依據,畢竟唯有正確定位才能使機 器人精確的取到貨物,不然則如迷失方向,無法完成競賽任務。以此出發點,進而探索 及研究超音波感測器原理及應用。
在” Performance Testing NXT’s Ultrasonic Range Finder”[20],作者有計劃地利用樂高 NXT 系統成功完成超音波測距儀,並成功的找出其有效測距範圍。
圖3-29試驗台:木刻,皮尺,量角器,超音波, NXT(從左至右)
正交測量(公分遞增)
誤差,準確性和線性
本實驗使用的試驗台,其中一個障礙是能夠直接在前面的感測器(正交感測器平面) 。 移動的障礙是定位在兩公分遞增至64 公分,讀數被利用內置的超聲波感測器。木材塊 被用來作為障礙,以反射超音波信號返回到感測器。
平均誤差距離的63 個樣品是一點〇七九公分和根均方誤差計算公式為一點六六二公 分。圖1 顯示了一塊數據點(黑點)的感知距離的障礙作為一個功能的實際距離的障礙。
線性方程的模擬(藍線)為: y = 0.9757 x + 1.88 。
圖3-30 感知距離的函數的實際距離。
這一點從這些統計數字,一個明確的線性關係之間存在著感測器輸出和輸入但是抵消誤 差~ 1 公分。這個錯誤可能是系統的,但未來的測試將確定是否屬於這種錯誤是不同條 件下重現。
動態範圍
雖然以前的試驗得出結論認為,該感測器的工作在正確的範圍從8 到 64 公分,確定了 動態範圍的感測器需要確定上限的精確距離讀數。在這個實驗中,被定位在木板上的距 離,造成NXT 塊顯示"???".這顯示表明,傳感器可以不遵守任何障礙在前面的。該區塊 是緩慢移動接近感測器,直到讀與會者對NXT 磚。該感測器最後測得木版在距離為 207 厘米。
作為顯示在第一個實驗中,該感測器的準確性距離不短於8 公分。此外,感測器沒有準 確性距離大於二百零七公分。因此,超音波感測器的動態範圍由8 至 207 公分。
然而依上述作者測的超音波感測器之動態範圍由8 至 207 公分,但於本研究過程需 解決之超音波感測器問題,似乎沒有作者所設定之理想環境,於超音波感測器定位過程 常因靠近機器人的貨物或無人搬運車等遮蔽物而造成超音波感測器感知到不準確之距
離數據。
於是我們使用多次偵測數據來確認準確定位距離,隬補定位錯誤之缺憾,並加入上 述超音波感測器之動態範圍由8 至 207 公分,故排除測預估偵測距離小於等於 8 公分,
並分別以單顆超音波測距及前後超音波測距離作測試。
單顆超音波測距流程
第一次測距
前進2公分
第二次測距
前進2公分
第三次測距
三次測得的值均在合理範圍 並不互相矛盾
第二次的值給第一次 第三次的值給第二次 START
三次值的平均 可拿來找到現
在位置
NO
YES
END
圖3-31 單顆超音波測距流程
前後超音波測距離流程
前超音波測距 後超音波測距
前超音波測得的距離+後超音波 測得的距離+兩超音波的距離=
全場地寬
機器人前進1公 分
目前的位置=後超音波測得的 距離+後超音波與轉動中心的距
離 START
NO
YES
END
圖3-32 前後超音波測距離流程
使用超音波感測器解決定位問題之程式區段
// sonar.c
int readSonar1() {
int val;
SensorType[S1] = sensorSONAR;
SensorType[S4] = sensorTouch; // turn off other US
int readSonar4() {
int val;
SensorType[S4] = sensorSONAR;
SensorType[S1] = sensorTouch; // turn off other US
int readUS(tSensors theSensor) {
int val;
int decSpeedCm = 30;
int pEnd = 20; // Ending power //float kSonar = 5.0;
void front2Wall(int pInit, int objCm) {
int dist;
int err, pwr;
int conf=0;
int pEndBat;
SensorType[S1] = sensorSONAR;
conf=0;
nMotorEncoder[motorB] = nMotorEncoder[motorC] = 0;
while (conf < 20) { dist = readUS(S1);
pEndBat = pEnd*7500.0/nImmediateBatteryLevel;
if (dist == objCm) {
pwr = (pInit-pEndBat)*abs(dist-objCm)/decSpeedCm + pEndBat;
}
if (dist < objCm) { pwr = (-1)*pwr;
} }
err = nMotorEncoder[motorB] - nMotorEncoder[motorC];
motor[motorB] = pwr* (7500.0/nImmediateBatteryLevel) - 2*err;
motor[motorC] = pwr* (7500.0/nImmediateBatteryLevel) + 2*err;
}
front2Wall(100, 30);
PlaySound(soundBeepBeep);
//wait1Msec(3000);
//awayWall(90, 30); 步及修正降低至最少,以爭取時間。我們以下方motorSorting.c 為馬達作配對,尋求最 佳組合。