|
之前在網(wǎng)上搜無人機(jī)避障在發(fā)現(xiàn)了“PlayUAV匯聚開源力量”上看到“多旋翼通用避障開源項(xiàng)目”(http://www.playuav.com/article/242),這個作者是湖南工業(yè)大學(xué)的20歲小伙子,昵稱叫“七煙”,現(xiàn)在是“多旋翼避障系統(tǒng)開發(fā)”QQ群的群主。
在這個帖子里看到他所引用的由魏宇科提出的“用Arduino擴(kuò)展無人飛行器”的新思路,魏宇科在百度上就能搜到,是第九屆全國高職高專“發(fā)明杯”大學(xué)生創(chuàng)新創(chuàng)業(yè)大賽一等獎的獲得者,他這篇帖子是在“ARDUINO中文社區(qū)”,題為“用Arduino擴(kuò)展無人飛行器+普及無人機(jī)知識,不會算法的人必看”(http://www.arduino.cn/thread-11353-1-1.html),魏宇科的QQ群是“Arduino擴(kuò)展無人機(jī)”。
我這里之所以寫這個帖子,主要是看到很多人對此也感興趣,但在應(yīng)用和參考上,很多都是照搬照抄,囫圇吞棗式的進(jìn)行,存在的一些問題也是繼續(xù)在使用。為此,從我的角度對兩位的工作做一些錦上添花的補(bǔ)充和進(jìn)一步的優(yōu)化等工作。此外,他們的工作是在Atmega2560上做的,我這里簡化了,在Atmega328p上做了一些工作,很多東西我并沒有做完整,只是為了說明問題,做了局部的工作。
他們兩位的一些作品和工作,你們可參考相關(guān)的帖子,或到這兩個群里看看相關(guān)的群文件。
首先來對兩位之前的工作談?wù)勛约旱囊恍┛捶ǎ?br />
1. 魏宇科的“Arduino擴(kuò)展無人機(jī)”
1.1 優(yōu)點(diǎn)
在接收機(jī)和飛控之間插入的方式很好,這使得避障與飛控程序無關(guān),從而降低了開發(fā)難度,門檻比較低,在這里不僅可以實(shí)現(xiàn)避障,只要有想法就可在這里實(shí)現(xiàn)你想要的其他一些功能,大家可以自由設(shè)想,并努力實(shí)現(xiàn)。
1.2 不足
(1)遙控信號解碼
魏宇科的遙控信號解碼采用下述方式
INAIL = pulseIn(AIL1, 1);
INELE = pulseIn(ELE2, 1);
INTHR = pulseIn(THR3, 1);
INRUD = pulseIn(RUD4, 1);
程序效率比較低,實(shí)時性不是很好,這一點(diǎn),“七煙”做了改進(jìn),采用了中斷方式。
(2)遙控信號輸出的校準(zhǔn)與修正比較繁瑣,輸出精度比較低,這個問題,我做了一些改進(jìn)。
2. “七煙”的避障工作
2.1 優(yōu)點(diǎn)
提出了一個實(shí)用、具體的工作;用中斷獲取接收機(jī)的AIL和ELE信號,提高了解讀遙控信號的實(shí)時性。
2.2 不足
(1)AIL.write(OUTAIL)與ELE.write(OUTELE)這兩個輸出,在 loop() 內(nèi),而且是在超聲波函數(shù)與避障函數(shù)之后,那么前面所用的中斷方式獲取的AIL和ELE信號其實(shí)時性的優(yōu)勢就大打折扣了;
(2)HC-SR04正常的、比較好的、合格的模塊,說明書中要求超聲測量的重復(fù)周期要大于60ms,超聲測量程序使用的是 pulseIn 函數(shù),而且四個超聲測距是順序執(zhí)行的,理想情況下,所用的時間需要 240ms 以上,而遙控信號的周期略大于 20ms,這樣就嚴(yán)重的影響了避障的響應(yīng)時間;
(3)在沒有障礙物的情況下,上述所說的重復(fù)周期要求很長,我實(shí)測了一款,從發(fā)射到檢測完成的時間為 216.972ms,這是一個超聲波測量所需要的時間,要是4個超聲波,加在一起的時間在無障礙的情況下就要 867.888ms 了,這個時間近 1 秒了,這樣遙控相應(yīng)時間以及避障的響應(yīng)時間都存在很大的隱患。
我發(fā)現(xiàn)的這些不足,在我的工作中做了一些優(yōu)化和改進(jìn)。
3. 改進(jìn)與優(yōu)化
3.1 遙控器中斷方式解碼,與實(shí)時輸出
在void setup()中設(shè)置中斷,見下面的“*****”部分,這個在“七煙”的工作中已經(jīng)實(shí)現(xiàn)了。
void setup() {
Serial.begin(115200);
pinMode(Echo, INPUT); //超聲波測距
pinMode(Trig, OUTPUT);
digitalWrite(Trig, LOW);
pinMode(RC1_In, INPUT); //遙控器 1 通道輸入
attachInterrupt(0, RC1_Int, CHANGE); //*****
rco1.attach(4);
}
下面中斷處理函數(shù)與“七煙”的基本相同,但我加了一句,還是“*****”部分。
void RC1_Int() { //遙控器 1 通道解碼
if (digitalRead(RC1_In) == HIGH)
time0 = micros(); // store the current micros() value
else
t_rc1 = micros() - time0;
if(Ob_ST == 0) rco1.writeMicroseconds(t_rc1); //*****
}
新增加的部分表示在沒有要處理的情況下(通過設(shè)置一個標(biāo)識Ob_ST判斷),遙控器解碼后立即輸出這個通道的遙控信號給飛控,在這里輸出,而不是在主循環(huán)loop里等其他處理函數(shù)處理完成后再輸出,這樣實(shí)時性就幾乎與遙控器直接操作完全相同了,僅延時最大2ms的時間,遙控信號更新率仍保持在20ms左右。
而且輸出使用“writeMicroseconds()”函數(shù),參數(shù)變量是us,比魏宇科所用的“write()”函數(shù)精度高多了,而且不用校準(zhǔn)和修正了,因?yàn)楸3至嗽瓉淼倪b控輸出信號精度和范圍不變,如果非要校準(zhǔn)的話也很簡單,將實(shí)測值直接給下列語句即可。
OUTAIL = map(rc1_val, rc1_min, rc1_max, 1000, 2000);
其中,rc1_min是遙控器該通道輸出的最小值;rc1_max是遙控器該通道輸出的最大值。將遙控器的輸出規(guī)范到1000us到2000us之間。
3.2 超聲波測距的改進(jìn)
超聲波測距以前他們直接采用下列語句:
Dist = pulseIn(Echo, HIGH);
這樣的話,在沒有障礙時,超聲波下次測量時必須要等200多ms以上,為此我簡單的加了一個超時限制,譬如超時值為15000us,語句如下:
Dist = pulseIn(Echo, HIGH, 15000);
給出一個單超聲波避障的例程如下。
SR04避障.zip
(889 Bytes, 下載次數(shù): 12)
2016-4-11 15:56 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
避障擴(kuò)展板原理圖:
164943jjxnh0s10o12qzl0.jpg (182.17 KB, 下載次數(shù): 160)
下載附件
2016-4-11 18:02 上傳
這里的程序只做了接近距離的比例避障,大家可以考慮加速接近速度項(xiàng),這樣就成了類似PD算法了。
進(jìn)一步的擴(kuò)展方法可以使用原理圖中的RC1對接收機(jī)的PPM信號進(jìn)行解碼,這樣就可實(shí)現(xiàn) 8 通道接收信號的中斷實(shí)時處理,也可以做更多、更豐富的擴(kuò)展功能了。
如果有人感興趣的話,我將繼續(xù)說上面還未說到的一些問題,且聽下回分解吧!!!
|
|