Apollo環境下的調試
在安裝完Apollo的環境之後如何使用Apollo系統進行調試運行是瞭解該系統的基礎,網上以及官方說明文檔也有,主要是下載Apollo提供的數據包,看看數據效果,本文主要是針對代碼調試自己需要了解的模塊,這裏主要以規劃控制模塊爲例,其他模塊與之類似。本文主要對規劃中的全局路徑規劃(Routing)模塊、決策規劃(Planning)模塊的運行過程進行說明,並介紹瞭如何在planning中添加障礙物,以及planning中對障礙物的決策進行說明。
1.啓動Apollo的環境
調試Apollo的環境需要先啓動Apollo的運行環境,對Apollo安裝有不懂的可以參考Apollo無人駕駛平臺的離線搭建與使用。啓動Apollo環境過程如下:
// 切換到docker目錄下
~$ cd apollo-3.0.0/docker/scripts/
// start(可能需要聯網,然後將--local去掉)
~$ ./dev_start.sh --local
// 進入
~$ ./dev_into.sh
//run system
~$ ./scripts/bootstrap.sh start
2.選擇車輛和地圖的配置參數
在瀏覽器中打開 http://localhost:8888 進入界面,車輛型號選擇 MkzExample,Apollo給了三個區域的高精度地圖,地圖可以任意選擇一個,這裏選擇 Sunnyvale Loop,並在Tasks裏面選擇 simcontrol,即可進入仿真模擬控制,如下圖所示:
3.啓動模塊進程
在選擇好配置參數啓動仿真模擬後,在ModuleControl中選擇你需要調試的模塊如下圖所示:
由於這是模擬環境下啓動的,沒有雷達攝像頭等硬件設備,因此很難直接在這個模擬平臺上調試感知的參數,當然如果有攝像頭激光雷達的數據包也可以使用感知模塊。感知與預測模塊得到的障礙物數據是給planning中使用的,當然如果需要測試planning中對障礙物的決策情況,還是可以手動添加的障礙物,會在後續文檔進行介紹。因此,這裏就很多情景中,無人車的軌跡跟隨的場景進行模擬,這裏啓動routing(全局規劃),planning(決策規劃),control(控制模塊的進程),啓動完成後,可以進入routing Editing發送請求,如下圖,第一張圖表示Apollo給出的一張地圖,其地圖的詳細數據存儲在base_map.xml中,設置請求即在如下地圖中設置起點-途經點-終點,如下第二張圖所示:
可以在整張地圖上,拖動點擊鼠標可以在地圖上任意選擇兩個點,然後選擇send routing request可以發送請求,routing模塊就會在地圖中搜索出可行的路徑,planning模塊將指導車進行決策和局部規劃,進而指導車進行運動,其效果如下:
圖中可瞭解到,紅線就是routing規劃的,藍色的亮線爲planning規劃的。
4. 手動添加障礙物
在Apollo系統的代碼中因爲沒有感知和預測的數據,所以除了高精度地圖中的一些標誌,是沒有其他車輛和障礙物的約束,要想了解在planning模塊中對障礙物的決策過程,可以在程序中添加障礙物,planning中將預測得到的結果添加到frame中得到障礙物的軌跡,因此可以按照預測的結果直接添加到frame函數中,具體過程如下:
在這個目錄下按照這個文件格式添加障礙物
"modules/planning/common/testdata/sample_prediction.pb.txt"
其數據格式如下:
header {
timestamp_sec: 1487029724.22
module_name: "prediction"
sequence_num: 9338
}
prediction_obstacle {
perception_obstacle {
id: 2161
position {
x: 585868.39
y: 4139982.16
z: 0
}
theta: 0.0249947936189
velocity {
x: 0
y: 0
z: 0
}
length: 0.357469637533
width: 1.513933358
height: 0.514804840088
polygon_point {
x: 97.2893624333
y: 347.796489884
z: -31.6976950117
}
polygon_point {
x: 97.2902582356
y: 347.923750521
z: -31.6948381206
}
polygon_point {
x: 97.3307050201
y: 348.052103216
z: -31.6921948431
}
polygon_point {
x: 97.5875120205
y: 348.394845337
z: -31.6860325399
}
polygon_point {
x: 97.6613368321
y: 346.921045429
z: -31.7196251173
}
polygon_point {
x: 97.33956867
y: 346.945560842
z: -31.7171360436
}
polygon_point {
x: 97.3009911378
y: 347.136420518
z: -31.7126110052
}
tracking_time: 0
type: UNKNOWN
timestamp: 0
}
}
Header是數據頭包括時間戳、標籤名、序列號等,prediction_obstacle是具體的數據,包括障礙物的id、位置(該位置可以設置到地圖中,是全局座標)、航向角、速度,以及障礙物的尺寸(長寬高),polygon_point用來描述障礙物的的形狀,這裏採用多邊形來進行描述,type表示障礙物的類型,與感知的標籤有關,當然如果是unknown,planning會根據尺寸和爲位置進行判斷,考慮前車或者其他的交通進行決策,具體過程見planning的tasks中,這裏沒有加障礙物預測的軌跡,如有需要可自行添加。
然後在frame.cc中在 **Frame::CreateReferenceLineInfo()**函數中這行
bool has_valid_reference_line = false ;前添加如下代碼:
//添加一個靜態的障礙物
PredictionObstacles prediction_obstacle;
common::util::GetProtoFromFile(
"modules/planning/common/testdata/sample_prediction.pb.txt",
&prediction_obstacle);
auto obstacles = Obstacle::CreateObstacles(prediction_obstacle);
//AddObstacle(*obstacles1);
for (auto& obstacle : obstacles) {
AddObstacle(*obstacle);
}
這裏在車前設置一個障礙物,車認爲是靜止的前車,然後進行決策,採取stop,其效果如下所示: