你信任你的激光雷達嗎?

聲明:本文不是官方文檔,亦不是某種形式的斷言或結論,本文僅僅是技術討論性質的文章,無論是否用了確定性的語氣,作者都不保證內容的準確性和完整性,亦不明示或暗示此文章不是在胡說八道。(事實上,作者過去常常胡說八道並樂此不彼)。因此,所有因採用本文章涉及的方法、數據或其他任何信息,所造成的直接或間接損害,包括但不限於生命和財產損失,作者、撰寫團隊和平臺概不負責。

大部分人使用激光雷達的時候,都會選擇無條件相信激光雷達廠家,以及那個來路不明的 ROS 驅動。

多數情況下,雷達一通電,你就能在 Rviz 上看到漂亮的點雲。

我猜,很多人(包括我)心底都有一個聲音,「行了,這就可以了,不要沒事找事了」。至於雷達驅動中的各項參數,那簡直就是大象身上的蝨子,不值一提。

確實,作為開發者,我們常常被教導要抓住事物的主要矛盾,雷達的質量和精度,交給供應商來保證好了。

可問題是,我真的可以毫無保留的信任廠家和 GitHub 上長篇大論的代碼麼?

你信任你的激光雷達嗎?

更進一步,你或許不爽激光雷達的精度久已,你想自己動手進行校準。不管你動用哪種方法,有監督無監督,有標靶無標靶,各種暗黑科技。

提升雷達精度的頭號問題是,你該動哪些參數呢?

很多論文都是假定激光雷達的 Raw Data 是從原點出發,基於「多餘測量」的思想,用平差模型從外向內修正。

不過這次,我們不是要修正雷達,而是要從雷達本身,去理解雷達的校準和補償,所以,我打算從內向外來討論一下。

我們以 Velodyne 激光雷達 HDL-64E S3 的 ROS 驅動為例,來詳細瞭解一下這些參數問題。

Velodyne HDL-64E S3 是一款非常經典和優秀的激光雷達,曾是無數無人車形象的標誌性特徵。

當然,它推出有一些年頭了,不能說老態龍鍾,但是產品生命週期已經步入晚年了,有時候你需要站在更高的角度重新審視這款雷達,來複盤一下,它所代表的這一類機械旋轉式雷達,有哪些優缺點,基本校準參數是怎麼組成和相互作用的?

更近一步,這些雷達的精度和性能,被完全挖掘了麼?你所信賴的 ROS 驅動,都寫對了麼?

舉個例子:

你信任你的激光雷達嗎?

上圖是目前使用最多的雷達 ROS 驅動程序,不管你信不信這個神秘的數學模型,反正我不信,這十分令人費解。

我們之後會詳細分析,為什麼說這裡應該有問題。遺憾的是,用戶很難發現這個問題,因為,它會引起部分激光 25 米以上時,10cm 左右的測距誤差。

這原本沒有什麼,你的車上不會裝一堆高精度測距設備相互交叉驗證,但你如果有很多雷達和測距設備(大部分人沒有),大家在一起工作的時候,你就會發現不對勁。更有甚者,線與線之間,表現都感覺不太一致。

這裡就產生一個很奇怪的問題,激光雷達作為一個單純的測距設備,為什麼還要弄個內參文件,還定義那麼多個校準參數?

64 線的激光雷達,校準參數有 576 個之多(當然,有些其他型號的雷達生產改進了,於是把一部分參數填 0 了,但這些參數本身仍然存在)。

即便是對每一束激光,都有多達 9 個校準參數,這不得不使人心生疑問,為什麼要這麼多校準參數?

你信任你的激光雷達嗎?

當然,我們會一個個講,這些參數是什麼意思。

篇幅所限,我們先講幾個,餘下的,我們之後的文章接著講。

因為加工問題,激光雷達的自身的座標系,很難從雷達中心點出發。

64 線激光雷達是一個收發異軸的光學系統(其實所有的機械雷達都是),也就是說,發射出去的激光光路,和返回的激光光路,並不重合。

這主要是因為激光發射器和接收器不能做在一起導致的。現在很多方案,都是向著共軸努力,此為後話。

我們還是以經典的機械式雷達為例:

你信任你的激光雷達嗎?

打在牆上的光斑,一部分形成漫反射,有一小部分光會回到激光雷達,並被接收光學系統和接受器接收。

這個光斑的座標,本來應該以激光雷達的底部中心點為座標系原點。

然而,它做不到,它甚至不關心原點在哪裡,理論上得到的粗略目標距離,是上圖的 (D1+D2+D3+D4)/2,根據幾何光學的一般規律,D1 和 D3 是同一條直線,D2 和 D4 可不一定(因為接收器雪崩二極管粘死在背板上,無法移動)。

這引來一個好問題:雷達中心原點 O 到目標光斑 P 的距離,怎麼換算?

答案是,存在一個虛擬的邏輯點 M,我們認為激光是從 M 點發射,並在 M 點完成接收,很顯然,M 點存在於 D3 和 D4 之間,我們經過粗校準後的距離值,也就是對激光雷達的 Distance 輸出值,進行了固定補償,或者線性補償(兩點修正)之後的值,要等於這個 PM。

那如何補償呢?

激光雷達的測距精度,隨著距離的變化而變化。有幾個原因:

1. 我們這裡說的激光雷達,是指 TOF 激光雷達,TOF 測距,靠的是 TDC 電路提供計時,用光速乘以時間再除以 2 得到距離,但限於成本,TDC 一般由 FPGA 的進位鏈實現,本質上是對一個低頻的晶振信號做差值,實現高頻的計數。所以,測距的精度,強烈依賴於這個晶振的精度。而晶振隨著時間的推移,存在累計誤差;

2. 距離越遠,接收信號越弱,雷達自身的尋峰算法越難以定位到最佳接收時刻,這也造成了精度的劣化;

3. 萬能的其他原因;

於是,我們可以假定一個最簡單的情況,線性關係(實際上並不存在這樣簡單的線性關係,不過我們先這麼假定),即:D = (1+A)*d + B。

其中,d 表示測量值,A 表示線性係數,B 表示固定補償值,D 表示真值。

補償之後的 M 點,將會落在 OM 垂直於 MP 處。

寫到這裡,我們就發現第一個問題,

64 線雷達(至少是說明書)偷了一個大懶,它對 25 米以上的目標,採用固定補償,而對 25 米以下的目標,進行線性補償。(也就是兩點修正法 Two Point Calibration Methodology)

它為什麼這麼做,因為,它並不關心 25 米以上目標的精度,無人車嘛,要那麼精確幹嘛?

所以,合理地說,64 線雷達,25 米以上的精度,並不是特別高,至少不像說明書中描述的那樣高,正負 3 釐米我個人是持保留意見的。

這個兩點修正法也是個大瓜,簡直是各顯神通,我們之後再講,我們先討論 25 米以上的問題:

你信任你的激光雷達嗎?

於是,這個固定補償值 B,就是我們 xml 文件中的:distCorrection_,也是 ROS 驅動中的:corrections.dist_correction。

你信任你的激光雷達嗎?

為什麼是 25 米,確切的說是 25.04 米,這是因為雷達生產時,25.04 米外剛好設置了一個標靶,僅此而已。而且,這個 25 米的標靶,應該是他們最遠的標靶。

正確的代碼應該怎麼寫?

你信任你的激光雷達嗎?

於是,更多的疑問會產生,他們為什麼要在 xy 投影上加個尾巴:

vert_offset * sin_vert_angle?

有時候,代碼會告訴你一段塵封的歷史,就像在 shell 下輸入 cal 9 1752 查看 1752 年的 9 月日曆,你會驚奇的發現這個月只有 21 天,從 2 號起直接走到 14 號。

你信任你的激光雷達嗎?

很奇怪吧。

1582 年 2 月,因為儒略曆誤差問題,羅馬教皇格里高利十三世要求從 1582 年 10 月中減去 10 天,意大利、西班牙等天主教國家都謹尊聖諭。

但是英國因為亨利八世離婚問題跟羅馬教廷反目,成了新教國家,所以就不願意修改,直到近 200 年後的 1752 年 9 月,英國及其殖民地(包括美國)才被執行。

這樣 1752 年 9 月 2 日後面跟著的就是 1752 年 9 月 14 日。這就是為什麼 cal 會生成上面輸出的原因了。

這個雷達也是一樣,我們現在是這樣認為的:

雷達的 raw data 輸出的測量值 distance,在 25 米以上的距離,加上一個固定修正值 distCorrection_,即 distance += corrections.dist_correction 後,即 PM。

你信任你的激光雷達嗎?

然而,以前並不是這樣的。我們先放一放,上文中,激光收發平面是指什麼?

我們詳細解釋一下,雷達從前向後看:

你信任你的激光雷達嗎?

我們對比一下照片:

你信任你的激光雷達嗎?

(有透鏡的一側,我們稱之為「前面」)

下圖反過來,是從後向前看,我們把激光編號和接收器編號標上,

你信任你的激光雷達嗎?

激光編號和接收器編號的一一對應關係:

你信任你的激光雷達嗎?

這裡,我們回答了上文的問題:「每對激光收發器中,收和發的裝置,都在同一個平面上」。

換句話說,激光發射路徑的俯仰角(vertical angle)是-10.15 度,那麼,激光反射路徑的豎直角,也是-10.15 度。這在工廠加工時,就被如此排列。

我們接著講校準參數,先從最好理解的 vertCorrection 開始:

你信任你的激光雷達嗎?

激光光斑在最後需要呈現笛卡爾座標系的座標,要基於底部中心點,在下圖中:θ1 和θ2 是激光俯仰角,這個數據,就是 XML 文件中的「vertCorrection_」。

另外:雷達內部設計尺寸如下:

你信任你的激光雷達嗎?

所以,除了 vertCorrection_,還有一個 vertOffsetCorrection_:

你信任你的激光雷達嗎?

它是可以被計算出來的,以上圖 UpperBlock 為例:

vertOffsetCorrection_ =7.1905 x tan(- θ1) + 20.6573 cm

(θ1 為啥是負的呢,因為θ1 是個負角度,當然這個公式對θ1 是正角度時,同樣適用)

Lower Block 中,是這樣:

vertOffsetCorrection_ = 6.2139x tan(- θ2) + 13.415 cm

這樣的話,我們就把 xml 文件中的兩個量,聯繫起來了:

你信任你的激光雷達嗎?

我們可以用一個 xml 文件中的數據驗證下:

21.734091 = 7.1905 x tan(8.5167751)+ 20.6573

發現奧秘了吧。

現在回過頭來,講一講,他們為什麼要在 ROS 驅動的 xy 投影上加個尾巴?

float xy_distance = distance * cos_vert_angle - vert_offset * sin_vert_angle;

vert_offset * sin_vert_angle 的幾何意義,是下圖中的 O’N,其中 PN 垂直於 O’N。

你信任你的激光雷達嗎?

以前他們認為:經過固定值修正的 distance,更接近這個 NP,所以在 XY 平面的投影,需要增加一點數值,vert_offset * sin_vert_angle 只是一個估計的距離值,並不是嚴格的幾何關係,嚴格的幾何關係應該是:

float xy_distance = distance * cos_vert_angle - vert_offset * sin_vert_angle* cos_vert_angle

但是,很快,他們就意識到這是有問題的,因為 vert_offset * sin_vert_angle 也幾乎等於一個固定值,這樣表達是沒有任何意義的。

所以,在說明書上,還留下了這個痕跡:

你信任你的激光雷達嗎?

作為對比,我們看一下 Velodyne 官方的 Veloview 是怎麼寫的,顯然 Veloview 就沒有加這個尾巴:

你信任你的激光雷達嗎?

很可惜,ROS 驅動的作者沒有改過來,所以,全世界但凡使用 ROS 驅動 Velodyne 64 線的用戶,大家一直就這麼沿用了這個疑似有問題的代碼。

單單是這個地方,就會引來全量程最大 10cm 左右的測距誤差。不可思議吧!

不過,這個雷達好像進入生命週期的末尾了,驅動也穩定很久了,所以也沒有必要再建議他們動 master 分支,本文主要的目的不在於批判這款雷達,而在於和大家一起探討校準參數的問題,所以為這點小事耽誤大神們的寶貴時間是完全不值得的。

(未完待續。下一篇,我們會接著講解其他的校準參數,不要走開哦!)

P.S.汽車之心開始招募專欄作者了,只要你樂於分享,是智能網聯、自動駕駛、智能座艙、動力電池等領域的從業者或觀察者,歡迎掃描上方二維碼或添加微信 autobitxyz 瞭解詳情。在這裡,我們一起鼓搗些智能汽車領域的燒腦知識。


分享到:


相關文章: