1. 程式人生 > >淺談全國大學生智慧車競賽-攝像頭組影象處理及控制演算法

淺談全國大學生智慧車競賽-攝像頭組影象處理及控制演算法

    由於是第一次寫技術部落格,先做一下自我介紹。本人本科專業是光電資訊科學與工程(工),就讀於長春理工大學光電工程學院,研究生為華中科技大學光學工程專業。本科期間參加參加過各類比賽,其中印象最深的還是智慧車競賽。參加了十屆和十一屆的智慧車競賽,當然結果是都沒有出校賽這讓我很尷尬。做了兩屆的攝像頭,第一年跑的速度是1.8m/s第二年跑到了3m/s以上。雖然最後有一些可惜但是我希望把我自己的一些感想和遇到的問題給大家介紹一下,分享一下我的經驗,希望能夠對學弟學妹有一些幫助。

  步入主題,智慧車競賽攝像頭組主要包括幾個部分,我就以採集影象;賽道模式識別;控制演算法;PID演算法;機械結構調整等幾個方面為大家介紹我的整體思路。


  首先我先說一下我第二年用的是B車具體車型自己可以百度一下吧,在這裡我簡單介紹一下,它用的是一個大電機,速度個人認為是其他車無法比擬的,然後舵機用的是SD-5舵機,是一個數字舵機它的響應頻率很快,可以滿足我用很高的頻率去控制轉角,這樣也對於控制方面提供了方便。

  接下來談談如何調整機械部分,首先攝像頭的位置,個人把攝像頭放在了整個車的重心位置,也就是整個車的中間。舵機採用臥式結構,推薦採用臥式或立式,舵機與攝像頭之間放置的電池,為什麼將電池放在這是因為為了讓整個車的重心靠近中間,攝像頭我直接開到了電路板上,將電路板固定在底盤上,整個主控上面包含了所有的模組,節省了空間降低了重心。整車拼起來後最高的位置是舵機和輪子,個人噴了黑色噴漆感覺很帥(這個是看個人了)。

前輪調整的時候很多人很迷茫在這我給大家說一下,前輪內八,讓最小的轉彎半徑越大越好,可以得到很好地轉彎效果,又因為我的電池是靠近舵機的所以增加了轉彎時候的側滑力量,內八的程度是多少呢就是當打到最大角度的時候輪子稍微給點離心力就可以所有的面都著地,這樣就是最好的狀態,還有就是舵機的拉桿,要V字型,為什麼呢,就是為了當擺角最大的時候舵機給的推力是最大的,當擺角小的時候舵機反應不是特別靈敏(吉林大學車輛工程的一位車友告訴的方法),這樣調整完前輪後就是後輪的調整,調整到什麼狀態呢,當電機給最大佔空比的時候只要按住車瞬間電機就能停住,這樣就可以讓以後編碼器測出來的資料不會有空轉的情況(自己慢慢測試就好沒有什麼很好地方法),安裝編碼器的時候編碼器齒輪與後車輪的齒輪齧合要怎麼檢測呢,就是當你轉動編碼器齒輪時候看不出空回,如果有空回就要繼續調整直道看不出空回為止。到此為止只有一個事情要解決了,那就是B車底盤的問題,這個東西的話大家很多人是不知道的,就是買車模的時候它會給兩個小塊通常是黑色的(我當時以為這個東西是雞肋,後來才知道我太天真了。),它是用來墊前輪的底盤的(具體名詞不知道想了解可以百度),然後後輪如果拆下來可以看見輪軸與底盤連線那個位置有個類似橢圓的一個件把它倒過來裝上你會發現,咦??我的底盤低了好多。對就是這樣你的底盤調整的更低更有賽車的樣子了。至此所有的機械結構基本調整完畢。特別提醒,前後底盤的連線一定要在底盤的上部連線否則你會很不開心,會遇到各種問題,儘量做到的就是用最少的料讓前後的底盤連線的最穩定。在此不多做介紹了。

以下這種固定方法是不可取的。


舵機拉桿效果圖


整車的結構效果圖


   接下來就應該說說軟體部分了,第一個就是攝像頭影象採集問題,個人用過OV7620,藍宙捕食者3代,山外鷹眼硬體二值化(不要問我為什麼做了兩次用了三種攝像頭)。這個影象採集的問題呢,我覺得很值得一提,我首先介紹一下三種攝像頭吧,7620這款攝像頭是最經典的一種攝像頭,30幀每秒COMS感測器,個人認為用這個攝像頭做到3m/s的大神真的是太牛逼了,這個攝像頭如果想要用首先你必須有很強的影象處理能力,因為它採集速度慢,影象質量很渣,個人用它跑到的最大速度是2.2m/s。再就是藍宙捕食者3代,這個不吹不黑,個人感覺是最渣最渣的一款攝像頭,會出現各種各樣的問題,而且你不知道該怎麼去做,不推薦使用。接下來就是重頭戲山外鷹眼攝像頭,我採用的是60*80畫素,採集速度是148幀每秒,採集速度都快比線性CCD快了。它的噪聲如何呢,個人測試過沒有濾波演算法跑到了3m/s的速度,不解釋。這個攝像頭首先個人覺得需要一個比較大的廣角鏡頭,其次就是前瞻的遠處1.2M就足夠了,當然也可以用1.4m個人喜好問題和演算法問題。這個攝像頭屬於動態的閾值,閾值可以通過一個引數進行修改,這個自己多看看山外鷹眼攝像頭的介紹就知道了。然後還有一個比較頭疼的問題就是不能用山外直接給的攝像頭採集程式否則達不到148幀/s這部分只能靠自己去研究時序然後改正了,思路呢就是在初始化的時候直接初始化所有的中斷源,然後用DMA一隻採集可以實現理論上的影象處理與影象採集的並行執行。這部分是很重要的當你的採集速度達到148幀/s後車速達到3m/s你每個影象衝出去的距離也不過2.03cm,這樣相對於7620就有了一個明顯的優勢,你可以提高你的極限速度,如果7620跑3m/s你可以跑到更高。

  賽道模式識別,這部分是很多人最頭疼的部分,我也走過很多的彎路,在處理十字的時候自己看著影象看了一個月的時間最後才解決的,還有就是彎道如何識別,什麼入彎什麼出彎都是什麼情況,本人介紹的方法都是按照我以上介紹的配置才適用的,我問過很多司機師傅問他們怎麼開車,他們給的回答都很模糊,那麼我們是怎麼看的呢,我的理解就是我們看的實際上就可以理解為直線和彎道的分量,當前的影象中直線的分量是多少,只要我能夠提取出來這個分量我就能得到很好地一個模糊的數值去控制當前的電機轉速(個人認為賽道型別就是用來控制電機轉速的),那我是怎麼做到的識別出來這個分量的呢?我應用了三種方式,第一個就是採用《兩點演算法求智慧車賽道曲率》-蔣旭 吳濤 論文中的計算曲率演算法計算了賽道前部和後部的曲率,更信任前部分的曲率,然後加上有效行資料,有效行資料與賽道型別建立一個三次函式的對映關係求出其所佔的權重,這樣三個演算法算出來的數值所佔的權重不同最終就能得到一個當前賽道直線分量的權重,得到這個權重後就能通過模糊的方式控制電機了。個人採用的是三次函式對映,在過彎的時候能夠達到很好地效果,不會出現不連續的現象,這樣就能有一個很好的系統響應。具體演算法需要自己去寫了,

這是螢幕顯示的部分,當時在十字問題卡主的時候這個時候提取出來了直線的分量。

在此我貼一部分程式碼

     //找到A B C三個點   對應於  《兩點演算法求智慧車賽道曲率》-蔣旭 吳濤 論文中的 圖 1 
      Down_A_hang=left_line[0][0];//A點所在行數
      Down_A_lie=left_line[1][0];//A點所在列數
      Down_C_hang=left_line[0][(60-youxiaohang)/2];//C點所在行數
      Down_C_lie=left_line[1][(60-youxiaohang)/2];//C點所在列數
      L_AB=Down_C_hang-Down_A_hang;//求出 L_AB
      L_BC=abs(Down_C_lie-Down_A_lie);//求出 L_BC
      R_qulv=L_AB*L_AB/(2.0*L_BC)+L_BC/2.0;//計算出當前賽道的曲率半徑
      //////////
      Down_A1_hang=left_line[0][1];//A點所在行數
      Down_A1_lie=left_line[1][1];//A點所在列數
      Down_C1_hang=left_line[0][((60-youxiaohang)/2)/2+1];//C點所在行數
      Down_C1_lie=left_line[1][((60-youxiaohang)/2)/2+1];//C點所在列數
      L_AB=Down_C_hang-Down_A_hang;//求出 L_AB
      L_BC=abs(Down_C_lie-Down_A_lie);//求出 L_BC
      R_qulv=L_AB*L_AB/(2.0*L_BC)+L_BC/2.0+R_qulv;//計算出當前賽道的曲率半徑
      /////////
      Down_A2_hang=left_line[0][2];//A點所在行數
      Down_A2_lie=left_line[1][2];//A點所在列數
      Down_C2_hang=left_line[0][((60-youxiaohang)/2)/2+2];//C點所在行數
      Down_C2_lie=left_line[1][((60-youxiaohang)/2)/2+2];//C點所在列數
      L_AB=Down_C_hang-Down_A_hang;//求出 L_AB
      L_BC=abs(Down_C_lie-Down_A_lie);//求出 L_BC
      R_qulv=L_AB*L_AB/(2.0*L_BC)+L_BC/2.0+R_qulv;//計算出當前賽道的曲率半徑
      R_qulv=R_qulv/3.0;//三個點取平均

這部分是我程式碼中的一部分,當然需要你們自己去做後面的工作,如果有興趣歡迎聯絡qq:792499178.

應用此演算法後在實際實踐中將車子的速度從2.2達到了2.6m/s這時候又出現了一個新的問題就是舵機出現了抖動(抖動情況可以去看QQ空間上面寫的那個號網址

 http://mobile.qzone.qq.com/l?g=1336&appid=311&subtype=0&blog_photo=0&ciphertext=28AE2E611D3234CC4EED2BE09951BC60&uw=792499178&g_f=2000000393 
)以上是賽道型別識別模糊演算法。

  接下來就是說說控制演算法了,控制演算法的話我跟其他人應該沒什麼太大的區別舵機PD,電機PID。首先講講PID吧,PID的話就是P-比例,I-積分,D-微分,三個部分組成,這個演算法的提出是在很久以前了,具體是誰提出的自行百度吧。在這裡首先說說我電機閉環採用的是增量式PID演算法,程式碼呢在這裡給大家貼出來

s8  dspeed;
u32 speed_set;
s16 speed_set_base;
s16 Speed_Error=0;
s16 LastSpeed_Error=0;
s16 PrevSpeed_Error=0;
s32 SpeedOut=500000; //電機PWM
s32 LastSpeedOut=500000;
s32 SpeedOut1=0;
extern u8 Start_line;
extern u8 roadflag;
s32 car_speed=0;
extern u8 dispay_on;
void car_speed_control(s16 car_speed_set,u32 Moto_P,u32 Moto_I,u32 Moto_D)

   car_speed=LPTMR0_CNR;
   lptmr_counter_clean(); 
   s16 Speed_ErrorMax=50;
   s16 Speed_ErrorMin=-50;
  Speed_Error=car_speed_set-car_speed;
  if (Speed_Error>Speed_ErrorMax)Speed_Error=Speed_ErrorMax;
  else if (Speed_Error<Speed_ErrorMin)Speed_Error=Speed_ErrorMin;
  SpeedOut=LastSpeedOut+ Moto_P*(Speed_Error-LastSpeed_Error)+ Moto_I*Speed_Error+Moto_D*(Speed_Error+PrevSpeed_Error-2*LastSpeed_Error);        
    if(SpeedOut>dianji_PWM_MAX) 
  {
    SpeedOut=dianji_PWM_MAX;   
  }
  else if(SpeedOut<dianji_PWM_MIN) 
  {
    SpeedOut=dianji_PWM_MIN;
  }


  if (SpeedOut>0)
  {SpeedOut1=SpeedOut;
   FTM_PWM_Duty(FTM0,CH2,0);
   FTM_PWM_Duty(FTM0,CH0,SpeedOut1);
  }
  else
  {
    SpeedOut1=-SpeedOut;
    FTM_PWM_Duty(FTM0,CH2,SpeedOut1);
    FTM_PWM_Duty(FTM0,CH0,0);
  }
  PrevSpeed_Error = LastSpeed_Error;
  LastSpeedOut=SpeedOut;
  LastSpeed_Error=Speed_Error;  
}

這就是我用的增量式PID演算法,為什麼應用增量式PID演算法呢,其實我也不是很明白就是感覺它好吧(個人是光電工程專業的我屬於不務正業的那夥所以還請專業人士勿噴),當然也不是完全的沒有根據,大家可以百度一下位置式PID和增量式PID兩種演算法的區別,很容易比較出來哪個有優勢。在接下來就是在增量式PID的基礎上加了一個棒棒演算法,這個實際上是我沒有調好的,個人能力問題對PID演算法沒有理解到很好所以加了棒棒演算法後整個車加速的速度很快但是聲音特別大(但是個人聽起來感覺很爽,如果調好了聲音是很小的),棒棒演算法是什麼呢就是當你編碼器返回的速度與你預期速度差距很大的時候直接滿佔空比輸出,這樣可以讓你的車很快的達到目標速度(這就是對應於之前我那個機械結構的設計,在後輪調整中有提到),測試後可以在引數一般的情況下2m的距離內加速到10ms,250個脈衝的速度(採用的512線的迷你編碼器),這個根據車模不同有不同的數值,這裡的資料僅供參考。接下來就介紹一下舵機PD的引數設定了,這個引數難倒了智慧車的大部分人在這裡我就透露我的一些經驗吧,首先我採用的是P三次函式演算法,自變數是有效行,因變數是P的值,當然更建議的是自己設定P值,首先找到一個效果比較好的函式對映曲線後在用matlab進行擬合取出來相應的數值後用陣列的形式匯入到程式中,在根據除錯的情況具體情況具體分析後在微調陣列中的P值,然後D值的選取呢,當你的車速度沒有超過2.6m/s之前個人認為沒有必要用這個引數,為什麼這麼說呢,因為我在2.2m/s的時候完全不會出現抖動的情況,當速度提升後在直線時候舵機抖動厲害,這個時候就需要D的值了,這個D值作用是什麼呢?它的作用就是放大偏差,有人會說放大偏差幹什麼,個人的理解是變相的一種閉環,當速度大的時候慣性比較大拐彎不是很容易,當你需要拐的角度越大需要的力就越大,這樣就可以體現出來D值的重要性,通常D值根據拐彎的大小即賽道型別而變化個人採用的是與P值成一定的正比例關係。採用這個方式後車子的速度提升到了3m/s,從2.2m/s到3m/s一共用了2天時間。

下面我留下我的舵機P演算法

 float Kp = (CAMERA_H - info->effectiveLine)*(CAMERA_H - info->effectiveLine)/gServoPid.coefficient+gServoPid.p;
outPWM = (int32_t)(Kp*info->error + gServoPid.d*(info->error - gServoPid.error1)) + gCarParam.servoCenter;gServoPid.error1 = info->error;

具體引數自己慢慢調。有興趣的可以聯絡上面的qq,或聯絡[email protected]63.com.

  個人認為智慧車攝像頭組大體上我涉及的就只有這些了,還有一些細節問題我沒有提過,這些就需要自己去創新了,目標只有一個,但是過程我們可以有上百上千種,以上是我的方法,如果有錯誤的地方還請各位大神指正,也希望能夠幫助新手瞭解一下智慧車的一些知識。

2016.11.8    22:44

白銀浩

相關推薦

全國大學生智慧競賽-攝像頭影象處理控制演算法

    由於是第一次寫技術部落格,先做一下自我介紹。本人本科專業是光電資訊科學與工程(工),就讀於長春理工大學光電工程學院,研究生為華中科技大學光學工程專業。本科期間參加參加過各類比賽,其中印象最深的還是智慧車競賽。參加了十屆和十一屆的智慧車競賽,當然結果是都沒有出校賽這讓

恩智浦杯(飛思卡爾)全國大學生智慧競賽攝像頭簡單的影象失真矯正技術原理與實現(透視變換)

  先說一些廢話(沒耐心看可直接看分割線下面的內容):   博主是去年參加了十二屆的恩智浦杯(飛思卡爾)全國大學生智慧車競賽光電競速組,我們隊當時獲得的是區賽預賽第三、決賽第四的成績,我們區賽的光電競速組可以選拔五組進入全國總決賽,但因為我們學校另一個隊獲得了區賽決賽第三,

2018年高教社杯全國大學生數學建模競賽題目問題B 智慧RGV的動態排程策略

問題B    智慧RGV的動態排程策略 圖1是一個智慧加工系統的示意圖,由8臺計算機數控機床(Computer Number Controller,CNC)、1輛軌道式自動引導車(Rail Guide Vehicle,RGV)、1條RGV直線軌道、1條上料傳送帶、1條下料傳

2018年高教社杯全國大學生數學建模競賽題目問題B 智慧RGV的動態排程策略

問題B    智慧RGV的動態排程策略 圖1是一個智慧加工系統的示意圖,由8臺計算機數控機床(Computer Number Controller,CNC)、1輛軌道式自動引導車(Rail Guide Vehicle,RGV)、1條RGV直線軌道、1條上料傳送帶、1條下料傳

2018年高教社杯全國大學生數學建模競賽題目

簡單地說:數模競賽就是對實際問題的一種數學表述。 具體一點說:數學模型是關於部分現實世界為某種目的的一個抽象的簡化的數學結構。 更確切地說:數學模型就是對於一個特定的物件為了一個特定目標,根據特有的內在規律,做出一些必要的簡化假設,運用適當的數學工具,得到的一個數學結構。數學結構可以是數

C++的智慧指標

我們使用智慧指標來自動執行管理記憶體,避免對原始指標的使用不當而造成記憶體洩漏。   ---------------------------------------------------------------------------------------------------------

2018高教社杯全國大學生數學建模競賽

在高溫環境下工作時,人們需要穿著專用服裝以避免灼傷。專用服裝通常由三層織物材料構成,記為I、II、III層,其中I層與外界環境接觸,III層與面板之間還存在空隙,將此空隙記為IV層。 為設計專用服裝,將體內溫度控制在37ºC的假人放置在實驗室的高溫環境中,測量假人面板外側的

全國大學生數學建模競賽 B題 RGV的動態排程策略

                                                   智慧RGV的動態排程策略                                                    摘要 本文為RGV的動態排程問

2018全國大學生數學建模競賽頒獎儀式直播現場(預存)

由全國大學生數學建模競賽組委會主辦、上海賽區組委會協辦、上海交通大學承辦的2018高教社杯全國大學生數學建模競賽頒獎儀式將於12月15日在上海交通大學舉行。 屆時 中國大學生線上官方微博將對頒獎儀式進行現場直播。   直播地址:點選 2018高教社杯全國大學生數學建模競賽頒獎儀式 進

2018年全國大學生數學建模競賽獲獎名單公佈時間

還有 2天!!! 2018年11月10日20:00 請注意查收 您可以儲存此篇文章,屆時點選有下劃線紅色字型可直接到達官方網站檢視,也可關注官方微信公眾號:wwwunivscn 或掃描下方二維碼,關注獲取更多訊息 願您榜上有名!!!

全國大學生資訊保安競賽writeup--拯救地球(reverse500)

描述 什麼?地球要爆炸了,據說拯救地球的程式碼就在這個程式裡。使命貌似光榮又艱鉅… tips:flag是flag{結果} 附件描述: 檔名:程式 校驗(SHA1):D78073A4C06468DFC95822A764D792C09A87F78A

飛思卡爾智慧攝像頭使用篇

飛思卡爾智慧車之攝像頭使用    今天來給大家說說攝像頭的使用,很顯然攝像頭對攝像頭組的重要性是不言而喻的,因為攝像頭是小車提取賽道資訊最關鍵的感測器了,所以只有把攝像頭使用好才能讓你的小車快速穩定的跑起來。 攝像頭我選擇的是數字攝像頭,大家可以在某寶上購買。買來之後首先要

2017年全國大學生電子設計競賽獲獎名單

2017年全國大學生電子設計競賽獲獎名單 競賽相關文件請從ftp://ftp.nuedc.com.cn/下載 序號 賽區 組別 題號參賽隊學校 學生姓名學生姓名學生姓名 獎項 1 安徽 本科組 A 安徽大學 柳岸明 陳琦 許長樂 二等獎 2 安徽 本科組 A 安徽大學 郭瑞昌 高陳媛

2017年全國大學生電子設計競賽湖南賽區獲獎名單

2017年全國大學生電子設計競賽湖南賽區獲獎名單,下載地址:http://govnew.hnedu.cn:8090/zcms/contentcore/resource/download?ID=39552 2017年全國大學生電子設計競賽湖南賽區獲獎名單 序號 學生姓名 所在學校 指導老師

2018全國大學生數學建模競賽時間試題下載

2018 高教社杯全國大學生數學建模競賽的具體時間: 9 月 13 日(週四)20 時至 9 月 16 日(週日)20 時 。屆時請勿忘記下載試題: 2018全國大學生數學建模競賽時間及試題下載 數學建模大賽 作為四大國家級大學生競賽之一,是針對遇到的問題或者具體事例,通過數學建

CUMCM:全國大學生數模競賽簡介 & 相關書籍、文章等推薦

全國大學生數模競賽評獎等級 國家獎 特等獎(1+1) 國一 2017數模競賽MATLAB創新獎(1+1) 國二 省獎(山東賽區) 省一 省二 省三 成功參賽獎 A,B獲獎比例基本相同 競賽時間推薦分配 第一天:    上午                  

2018全國大學生數學建模競賽試題下載(預存)

距離2018全國大學生數學建模競賽越來越近,此次競賽的時間為 9 月 13 日(週四)20 時至 9 月 16 日(週日)20 時,屆時請點選2018全國大學生數學建模試題下載 獲取試題資料 中國大學生線上是全國大學生數學建模競賽組委會指定的數學建模

2018全國大學生數學建模競賽比賽時間試題下載

距離一年一屆的全國大學生數學建模大賽的腳步越來越近,不僅是我們各個即將參賽的小組,對於我們同樣關注本年度競賽的心中都有著絲絲迫切與期待。 2018 高教社杯全國大學生數學建模競賽的具體時間已經確定為 9 月 13 日(週四)20 時至 9 月 16 日

2017全國大學生資訊保安競賽Reverse 填數遊戲

參考的writeup在這: 使用的程式碼為py: ''' f = open('data.txt') num = 0 a = [] for line in f: print line,line[1] if line[1] == '0': a.append('?'

APK Crack Write Up 2017年全國大學生資訊保安競賽資訊保安技能賽

首先把apk拖進JEB看一下Manifest.xml檔案,找一下主類,沒有被隱藏,找到主類程式碼反編譯:發現有個涉及到JNI函式show,於是逆向一下這個so檔案,首先通過函式名找到這個方法:進去之後反編譯拿到虛擬碼:拿到虛擬碼以後,有個技巧,點選v1,按y,然後輸入JNIE