自駕車模擬。
利用深度學習 RBF 模型,讓自駕車根據過往的行駛資料來分析與學習,車輛在下一個時刻應該要轉多少角度,並在最後順利走出道路。
且在此深度學習程式中,我沒有使用任何深度學習框架 ex: scikit-learn, PyTorch, TensorFlow 等,所有的運算皆是我用程式寫出來的,包含 K-Means, 倒傳遞的參數更新, 更新方法,都是寫程式來進行運算;也因為如此,這個專案讓我更熟悉深度學習的基本原理,而不是僅會套用現有框架,而不知隱藏在其中的數學意義。
圓形是車子
左上角顯示是前右左3個距離的方向
紅色區域是終點
軌道檔案在 "data/軌道座標點.txt"
第一行為車體中心起始的(x,y,φdegree)
二,三行標示出終點區域位置
第二行為區域左上角(x,y)
第三行為區域右下角(x,y)
第四行以後為軌道邊界節點(x,y)
直到最後一行
最後一行與第四行數值相同
形成一個封閉的跑道
軌道於起點線右下角為(-6,-3);左下角為(6,-3)
起點線為(-6,0) -> (6,0)
檔案有兩種 "data/train4dAll.txt", "data/train4dAll.txt"
- train4dAll.txt 格式: 前方距離、右方距離、左方距離、方向盤得出角度(右轉為正)
- train6dAll.txt 格式: X 座標、Y 座標、前方距離、右方距離、左方距離、方向盤得出角度(右轉為正)
我分成 車子與牆壁距離計算 和 RBF Model 兩部分說明
目的:這裡描述模擬車的**方程式
方程式如下
x: 車子所在的 x 座標
y: 車子所在的 y 座標
theta: 車子要轉的角度(θ)
empty: 車子與水平線的夾角(ϕ)
目的:計算車子的三個方向到牆壁的距離
vehicle_x: 車子所在的 x 座標
vehicle_y: 車子所在的 y 座標
empty: 車子與水平線的夾角
這裡會計算車子和前、右、左三個方向的距離
計算方式分成五個步驟
-
def find_vehicle_front_all_wall_point(line)
車子這三個方向的直線可以算出一個直線方程式,將方程式和所有牆壁的方程式會算出很多交點。 -
def find_point_on_wall(points)
但這些交點並不是真的都在那些牆壁上(有些是在那些牆壁的延長線上),因此這個步驟要去判斷這些點是不是都在真的牆壁上。 -
def find_correct_direction(points, vehicle_x, vehicle_y, empty)
接著要分析車子現在方向是朝向上面還是朝向下面,以及是朝向正右方(水平夾角=0),或是朝向正左方(水平夾角=180)。 -
def find_closest_point(points, vehicle_x, vehicle_y)
這個方向仍然可能有多個交點,因此要找離車子最近的那一個,這個交點即是正確的那個交點。 -
def cal_dist(point, vehicle_x, vehicle_y)
將這個交點和車子的中心去算距離,回傳算出來的距離以及交點。
沒有使用任何深度學習的框架 ex: pytorch, tensorflow 等
這裡我自己實做一個 RBF Model,包括模型的訓練方式、模型的參數參數更新等
這裡就不說明原理,只說明我怎麼做的
我們的輸出只會有一個,因為是要預測 "方向盤要轉多少角度",是屬於 regression 的任務
RBF 共分成兩個步驟,第一步要先分群,第二步才是真的訓練模型
分群的方式我採用的是 K-means
目的:將資料分成 k 群,算出每一群的中心點與標準差。
X: 所有的資料點
k: 分成 k 群
max_iters: 最大迭代次數
-
RBFNN.train(lr, n_epochs)
目的:訓練 RBF 模型
learning rate: 0.0001
n_epochs: 500
基底函數: (高斯分布)
利用 LMS演算法來更新模型參數 -
RBFNN.predict(X_pred)
目的: 輸入要預測的資料,並輸出預測的角度
X_pred: 被預測的資料(前、右、左三個方向的距離)
output: 預測的角度(θ)
使用上方訓練完的 RBF 模型的參數,來預測我們輸入的資料。
自動車可以順利地到達終點,且不論是在起跑線上的哪一點皆可。
- 右轉
當偵測到右邊的距離突然變大,則車子會開始進行右轉彎。
- 左轉
當偵測到左邊的距離突然變大,則車子會開始進行左轉彎。
當車子偵測到有某一邊的數值突然變大時,則會開始朝那個方向進行轉彎。全部觀察下來,車子會朝距離大的那個方向進行轉彎,而距離相對小的時候會進行比較小幅度的轉彎,距離大的時候會進行相對較大幅度的轉彎。
下圖是三種距離與角度的對照圖
橫軸分別是前方、右方、左方距離,縱軸是角度(θ)
紅色點是我的模型跑出來的結果,藍色點是原始的訓練資料
由圖片可以看出,不論是哪一個方向,相對於助教的資料,我的資料都沒有辦法產生大角度的輸出 (最多大概就到 25 度),也就代表訓練出來的自動車沒有辦法做大角度的轉彎 (實測出來也是如此)。 會造成這樣的原因,我的猜想是因為大角度的資料比較少,這樣導致在第一步做 K-means 的時候,和大角度相關的資料中心點個數就會比較少,也因此後續訓練的時候,很容易就被平均掉了,所以如果要避免產生這種現象,應該要多增加資料量。
不過即使沒有大角度的資料,我的自動車一樣可以順利地到達終點,而它就會比較早開始轉彎,轉彎的幅度也會比較小。