第十六屆全國大學生智能汽車比賽是我大學參加的第一個有意義的比賽,讓我在學校實驗室SCA打開了進入大學的大門,無數次的包夜和學習讓我靜下了心,很榮幸參加過這樣一次的競賽,收獲頗豐。簡單的做一個總結,算是畫上大二一學年的句號,希望對你們有幫助。
本文僅自己看法,并不是權威結論。若有錯誤或不足之處,還請多多包涵。
攝像頭算法控制我分為二類:圖像處理和車體控制
第一類:圖像處理
1.1 攝像頭如何使用(小白篇)?
我比賽用的總鉆風130°攝像頭,拿到攝像頭后,使用例程可以在IPS屏幕上看到一個灰度圖像(原始圖像)。這個原始圖像我們一般都要進行處理,也可以不處理。我來介紹一下常用的三種處理方法.(1)圖像二值化。(2)圖像灰度。(3)邊緣檢測算法。
我用的是簡單好用的圖像二值化,所以我拿二值化進行講解。我先簡單介紹一下二值化圖像,在原始圖像的基礎上,把他分為黑和白(即賽道是白,其它是黑)。
灰度圖像有256個像素點 即0-255。0-255是什么意思,個人理解即顏色的深淺。0是黑,255是白。0-255是介于黑至白之間。對于一個灰度圖像中,圖像中每一個點都是在0-255之間,每一個點都有一個值.受光照影響,不同位置,不同時間,不同關照,每一個點的值都會不同。
所以我們要對這個值進行區分黑白,要進行處理。處理的方法就是:大津法(還有其他方法不唯一,大津法用的人比較多)
大津法就是對你的灰度圖像進行處理后得到一個閾值。輸入進去一個二位數組圖像,然后會返回給你一個閾值,然后你就用這個閾值進行二值化(即大于閾值為白(黑),小于閾值為黑(白)。即你就可以得到一個二值化圖像。
1.2 掃線
關于攝像頭循跡,一般都是按照獲取賽道中線,根據賽道中線來進行循跡的。如何獲得賽道中線,我來簡單介紹一下。在2.1中我們知道中線是按照左右邊線獲得的,而左右邊線我們則需要在圖像中進行處理獲得,這個過程就是掃線。
在二值化圖像的基礎上進行掃線處理,以圖像60行120列為例,從上到下為0-60行,我們取第60行中點(圖像下面相比上面較穩定,所以我們從下面開始),也就第60行第60列為起始點往兩邊進行掃線。
一般來說,我們的車是放在賽道中間,即起始點為白點,然后我們往兩邊判斷一直到黑點,我們記錄下黑點坐標放進左右邊線的數組里,若沒有掃到黑點則記錄圖像數組邊界值放進左右邊線數組里。
這樣每一行都這樣重復就可以獲取左右邊線數組。簡單的掃線就這么結束了。(后面還會補充掃線進階篇,你也可以根據簡單的掃線,自己想一想代碼如何升級)
1.3 中線
我們是根據賽道中線進行循跡,所以中線的處理也非常重要。
中線 = (左邊線+右邊線)/2?
中線 = 左邊線+X
中線 = 右邊線-X
X的值,根據實際情況來定。
1.4?圖像的直道和彎道
所有元素處理過后都是直道和彎道,這部分的處理也決定了你車體速度的上限。不僅是你PID的調參還有你圖像的處理。
先說簡單的,根據中線的值來確定直道和彎道,在不同情況下,調用不同的PID參數。(等元素處理都寫完,回來在寫這個進階篇)
1.5?元素處理
1.5.1 十字、環島、三岔路口
這三個元素我是同一個處理方法。三個問題:
(1)拐點問題(左右看看,上下看看)
所有拐點我都分為下拐點和上拐點。
下拐點:十字下面兩個拐點,環島入環和出環拐點,三叉下面兩個拐點
下拐點都是在邊線上,在一定范圍內遍歷數組尋找最大值或最小值。
上拐點:十字上面兩個拐點,三叉路口上拐點。
上拐點(抽象講解)圖像數組 范圍內 從左到右,從下往上掃點(白變黑的跳變點),掃到把行坐標放入一維數組內,然后范圍內搜索較大(小)值(一次就好)。
(2)補線問題
兩點確定一條直線,確定斜率,就確定兩點中的每一個點,然后讓這條直線上所有白點變成黑點,在重新掃線,就可以了。(說著其實都很簡單,其實也不難,自己多動動手0.0)
(3)狀態問題
1)十字
這是即將進入十字的布線狀態,在看到兩邊丟線且中間大量空白時,進入十字狀態,然后開始算出上下四個拐點,上拐點連接下拐點就可以如圖所示了。
不管你是即將進入十字還是十字中,還是即將出十字,都需要這么一個補線狀態,所以,我們用簡單的if來控制十字狀態。
當下拐點消失時,我們固定下拐點值,直接連接上拐點。我簡單來說一下我的代碼怎么寫的。
if( 左邊線丟線&右邊線丟線) ? (條件判斷的有點粗糙,后面詳細說一下) ? ? { ? ? if(中間大量白點) ? ? ?{ ? ? ? 進入十字標志 ? ?} ? ? ? } if( 進入十字標志) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? { ? ? 搜索左上拐點(沒搜到給定值) ? ? ? 搜索左下拐點 ?(沒搜到給定值) ? 連接左上和左下兩拐點 ? ? ? 搜索右上拐點(沒搜到給定值) ? ? ? 搜索右下拐點 ?(沒搜到給定值) ? 連接右上和右下兩拐點 ? ? ? if(兩邊不丟線,結束十字標志) ? { ? ? } ? ? ? ? } ? ? ?
2)環島?
?
?
環島的補線差不多就4個狀態(還有一個出環切內的補線)但是我分為7個狀態。用的switch語句來控制個個狀態,一但進入環島第一個狀態后面,在環島結束前都不會誤判,非常好用。
if(左邊丟線 || 右邊丟線) ?// ?進入元素識別狀態 { ?左環島判斷 ?if(左邊丟線||右邊不丟線) ?// 可能是環島或者彎道或者車庫 ?{ ? ?if(右邊邊線是條直線) ?// 排除彎道 ? ?{ ? ? ?給予左環島標志; ? ? ?進入左環島狀態1; ? ?} ?} roadabout_dispose(); ?//環島處理函數 } roadabout_dispose() { if(左環島標志位) { ?switch(左環島狀態) ? { ? ? case 1: ? ? ? ?if(左邊即將不丟線) ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? 進入左環島狀態2; ? ? ? ? } ? ? break; ? ? case 2: ? ? ? ?if(左下邊為圓環) ? ? ? ? { ? ? ? ? ? 進入左環島狀態3; ? ? ? ? } ? ? break; ? ? case 3: ? ? ? ?if(左邊第二次丟線,找拐點補線進入環島) ? ? ? ? { ? ? ? ? ? 進入左環島狀態4; ? ? ? ? } ? ? break; ? ? case 4: ? ? ? ?if(進入環島,環島內) ? ? ? ? { ? ? ? ? ? 進入左環島狀態5; ? ? ? ? } ? ? break; ? ? case 5: ? ? ? ?if(即將出環島,找拐點補線出環島) ? ? ? ? { ? ? ? ? ? 進入左環島狀態6; ? ? ? ? } ? ? break; ? ? case 6: ? ? ? ?if(右邊即將不丟線,車身擺正) ? ? ? ? { ? ? ? ? ? 進入左環島狀態7; ? ? ? ? } ? ? break; ? ? case 7: ? ? ? ?if(左邊即將不丟線) ? ? ? ? { ? ? ? ? ? 進入左環島狀態8; ? ? ? ? } ? ? break; ? ? case 8: ? ? ? ?if(完全出環島) ? ? ? ? { ? ? ? ? ? 清除左環島狀態; ? ? ? ? ? 清除左環島標志位; ? ? ? ? } ? ? break; ? } ? ? ?if(左環島狀態1||左環島狀態2) ?{ ? 找到左下拐點; ? 找到左上拐點; ? 補線; ?} ?if(左環島狀態4) ?{ ? 找到左上拐點; ? 定點補線; ?} ?if(左環島狀態6) ?{ ? 找到右下拐點; ? 定點補線; ?} ?if(左環島狀態7) ?{ ? 定點補線切內環; ?} ?if(左環島狀態8) ?{ ? 左邊定點補線,防抖; ?} } }
3)三岔路口
作為十六屆的新元素,起初覺得很簡單,拉一條線就能過,后來錯了,其實很有講究和難度,并未有想象出來那么簡單,衍生出來很多難搞的問題,要仔細對待。三岔路口最好的特征點,就是兩個Y拐點和一個V拐點。
在你看到三岔路口時,并沒有丟線狀態,所以你在直道上就要判斷Y拐點是否存在。有時三岔接彎道時,車體無法“完全”正 ,肉眼可能覺得車體正的(但是我們稱這種為斜入)只能看到一個Y拐點。
所以三岔路口要分為正入,左斜,右斜,三種判斷。簡單說一下怎么寫的三岔,因為三岔路口我寫的不是很好,2.8以上會誤判不是很好。
if(中間上面出現黑點) { 判斷Y拐點是否存在; 2個Y拐點為正入; 左邊存在為左斜; 右邊存在為右斜; 判斷V拐點是否存在; V拐點存在或Y拐點存在進入三岔路口標志位1; 進入三岔路口狀態1; } 然后根據3種情況和狀態 進入下一階段和拐點補線操作。 可以模仿環島偽代碼來寫。 僅供參考。
借鑒一下思路即可。
1.5.2 坡道
坡道個人建議用紅外測距,還是比較準的。即簡單也準確。
1.5.3 車庫
https://blog.csdn.net/qq_51679917/article/details/121874542
第二類:車體控制
車體控制主要是舵機和電機以及配合圖像處理進行循跡。俗話說的好:圖像處理的好,開環也能跑。說到控制那不得不說幾個環的事,簡單說一下最基本的兩個環(1)轉向環 (2)速度環
2.1 轉向環
我用的是C車模,S3010舵機。轉向要能進行左轉和右轉,所以我們要在圖像上區分左和右。
例如:我的圖像是 60×120( 60行,120列)我利用(左邊線+右邊線)/2=中線 這時候你就取一行或多行 賽道中線-圖像中線=error。得到error來區分左右,正常來說你把車體放在賽道中間,error會是0。
車體往左邊偏為正,車體往右邊偏為負。(反之也可以)這樣我們就區分了左和右,車體就可以進行轉彎了。
但我們發現轉彎可能過大或者過小,沒法理想的轉彎,這時候我們要用PID算法進行調節,新手建議位置式PID(非常夠用)。
個人建議起步用位置式PID中的純P調節。調到2米時用PD調節,跳到2米8時換模糊PID。
這時候你把error放入位置式PID中,Ki和Kd給0,調節Kp,輸出Steer。然后用舵機中值加減Steer得到的控制值來控制舵機靈敏的轉向。
這樣舵機就可以根據在賽道的不同位置來進行靈活的轉向了,這就是一個簡單的轉向環。
編輯:黃飛
?
評論
查看更多