轉載地址:https://mp.weixin.qq.com/s?__biz=MzI1NjkxOTMyNQ==&mid=2247484266&idx=1&sn=d6bcd4842cfb3fdf877dffb7f1867be4&chksm=ea1e1118dd69980e082ec14f9a7f8c7b8b7710ef7d5fcd3ae0a215e46bc334ebc1a99d5802d8&scene=0&pass_ticket=cKIhplBw0BjsZ7KVbkBm2c7iVlq9NKg3wcBb68%2B%2FeUvYJLWHLC9IwWdOu%2FPNeIuh#rd
前言
1. 我已將本文所述的配置文件上傳到Apollo項目的GitHub倉庫,大家直接下載使用即可。
2. 我之前已寫過一篇博客《使用Visual Studio Code編譯Apollo項目》(https://blog.csdn.net/davidhopper/article/details/79349927),這篇文章內容不夠全面,這里給出更為詳細的闡述。
Apollo項目以其優異的系統架構、完整的模塊功能、良好的開源生態及規范的代碼風格,受到眾多開發者的喜愛和好評。然而,該項目使用命令行編譯和調試,不能使用IDE開發,既不直觀,也不利於提高效率。我有點追求完美,必須想辦法讓Apollo項目能在IDE中編譯、調試。
Visual Studio Code(以下簡稱VSCode)是微軟第一款支持Linux的輕量級代碼編輯器,其功能介於編輯器與IDE之間,但更傾向於一個編輯器。優點是運行速度快,占用內存少,使用方法與Visual Stuio類似。缺點在於,與Visual Studio、QT等IDE相比,功能還不夠強大。我認為,Windows中最強大的C++ IDE為Visual Studio,Linux中最強大的C++ IDE為QT。
Apollo項目目前只支持Ubuntu系統(Mac OS系統部分支持),Windows系統中的Visual Studio自然排除在外;此外,Apollo項目使用Bazel編譯,而QT目前只支持QMake和CMake工程,因此只能忍痛割愛。在無法使用上述兩種IDE的前提下,退而求次選用VSCode。
我寫了幾個配置文件,允許使用VSCode編譯、調試Apollo項目,下面對其進行具體闡述,希望能給廣大開發者帶來一定的幫助。
{ 一 }
使用VSCode編譯Apollo項目
首先從GitHub網站(https://github.com/ApolloAuto/apollo)下載Apollo源代碼,可以使用git命令下載,也可以直接通過網頁下載壓縮包。源代碼下載完成后,將其放置到合適的目錄。使用VSCode編譯Apollo項目有一個前提,就是在你的機器上已經順利安裝了Docker。Apollo之前版本提供了一個“install_docker.sh”腳本文件,因為很多開發者反映可能出錯,Apollo項目組已將該文件移除。現在要安裝Docker就只能參考Docker官方網站(https://www.docker.com/)的幫助文檔了。
1.1編譯方法
打開“Visual Studio Code”,執行菜單命令“文件->打開文件夾”,在彈出的對話框中,選擇“Apollo”項目源文件夾,點擊“確定”,如下圖所示:
之后,執行菜單命令“任務->運行生成任務”或直接按快捷鍵“Ctrl+Shift+B”(與Visual Studio和QT的快捷鍵一致)構建工程,若之前沒有啟動過Docker,則編譯時會啟動Docker,需在底部終端窗口輸入超級用戶密碼,如下圖所示:
命令執行完畢,若在底部終端窗口出現“終端將被任務重用,按任意鍵關閉。”信息(如下圖所示),則表示構建成功。整個過程一定要保持網絡暢通,否則無法下載依賴包。
1.2配置文件解析
我在.vscode/tasks.json文件中總共配置了四個常見的任務:build the apollo project(構建Apollo項目)、run all unit tests for the apollo project(運行Apollo項目的所有單元測試)、code style check for the apollo project(Apollo項目的代碼風格檢查)、clean the apollo project(清理Apollo項目)。其中第一個任務是默認生成任務,可以直接按快捷鍵“Ctr+Shift+B”調用,其他任務可通過執行菜單命令:任務->運行任務(R)…,在彈出的窗口中,選擇對應選項即可,如下圖所示:
下面是具體的配置內容,請參考里面的注釋來調整編譯任務以滿足你的構建需求:
1 |
{ |
1.3可能存在的問題及解決方法
1.3.1 編譯時遇到“ERROR: query interrupted”錯誤
這是由於bazel內部緩存不一致造成的。
解決方法:
按任意鍵退出編譯過程,在VSCode的命令終端窗口(如果未打開,按快捷鍵“Ctrl + `”開啟)執行如下命令進入Docker環境:
1 |
bash docker/scripts/dev_into.sh |
在Docker環境中輸入如下命令,執行bazel的清理緩存任務(一定要保持網絡暢通,以便成功下載依賴包,否則該命令即使執行一萬次也不會奏效):
1 |
bazel query //... |
最后輸入exit命令退出Docker環境,按快捷鍵“Ctrl+Shift+B”,重新執行構建任務。
1.3.2 編譯時長時間停留在“Building: no action running”界面
這是由於當前系統中存在多個不同版本的Docker或者是bazel內部緩存不一致造成的。
解決方法:
按快捷鍵“Ctrl+C”鍵終止當前構建過程,在VSCode的命令終端窗口(如果未打開,按快捷鍵“Ctrl + `”開啟),使用下述方法中的任意一種,停止當前運行的Docker:
1 |
# 方法1:停止當前所有的Apollo項目Docker |
執行VSCode的菜單命令:任務->運行任務(R)…,在彈出的窗口中,選擇 “clean the apollo project”(清理Apollo項目)。待清理完畢后,按快捷鍵“Ctrl+Shift+B”,重新構建Apollo項目。
1.3.3 編譯時出現類似“Another command (pid=2466) is running. Waiting for it to complete…”的錯誤
這是由於在其他命令行終端進行編譯或是在之前編譯時按下“Ctrl+C”鍵強行終止但殘留了部分編譯進程所引起的。
解決方法:
按快捷鍵“Ctrl+C”鍵終止當前構建過程,在VSCode的命令終端窗口(如果未打開,按快捷鍵“Ctrl + `”開啟),使用如下命令終止殘留的編譯進程:
1 |
# 1.進入Docker |
按快捷鍵“Ctrl+Shift+B”,重新執行構建任務。
{ 二 }
使用VSCode本地調試Apollo項目
Apollo項目運行於Docker中,不能在宿主機(所謂宿主機就是運行Docker的主機,因為Docker服務像寄宿於主機中,故有此稱呼)中直接使用GDB調試,而必須先在Docker中借助GDBServer創建調試服務進程,再在宿主機中使用GDB連接Docker中的調試服務進程來完成。下面介紹具體操作方法:
2.1前提條件
2.1.1 編譯Apollo項目需帶調試信息
編譯Apollo項目時需使用build或build_gpu等帶調試信息的選項,而不能使用build_opt或build_opt_gpu等優化選項。
2.2.2 Docker內部已安裝GDBServer
進入Docker后,可使用如下命令查看:
1 |
gdbserver --version |
若提示類似如下信息:
1 |
GNU gdbserver (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1 |
則表示Docker內部已安裝了GDBServer(我已請Apollo項目組老師將GDBServer預裝至Docker內部,正常情況下應該能看到上述提示信息)。若提示如下信息:
1 |
bash: gdbserver: command not found |
則表示Docker內部未安裝GDBServer,可使用如下命令安裝:
1 |
sudo apt-get install gdbserver |
2.2Docker內部的操作
2.2.1 啟動Dreamview后台服務程序
進入Docker,啟動Dreamview,命令如下:
1 |
cd your_apollo_project_root_dir |
2.2.2 啟動待調試模塊
啟動待調試模塊,既可使用命令行操作,也可借助Dreamview界面完成。我肯定喜歡使用Dreamview界面操作了,下面以調試“planning”模塊為例進行說明。
打開Chrome瀏覽器,輸入網址:http://localhost:8888/,打開Dreamview界面,打開“SimControl”選項,如下圖所示:
點擊左側工具欄“Module Controler”標簽頁,選中“Routing”和“Planning”選項,如下圖所示:
點擊左側工具欄“Default Routing”標簽頁,選中“Route: Reverse Early Change Lane”或其中任意一個選項,發送“Routing Request”請求,生成全局導航路徑,如下圖所示:
2.2.3 查看“Planning”進程ID
使用如下命令,查看“Planning”進程ID:
1 |
top |
結果類似下圖,可以看到“Planning”進程ID為4147,請記住該ID。按“q”退出“top”界面。
還可使用如下命令查看:
1 |
ps aux | grep planning |
結果類似下圖,可以看到“Planning”進程ID為4147。
2.2.4 使用GDBServer附加調試“Planning”進程
接下來需要進行我們的關鍵操作了,使用GDBServer附加調試“Planning”進程,命令如下:
1 |
sudo gdbserver :1111 --attach 4147 |
上述命令中,“:1111”表示開啟端口為“1111”的調試服務進程,“4147”表示步驟2.2.3
中查到的“Planning”進程ID。若結果如下圖所示,則表示操作成功。
重新開啟一個命令終端,進入Docker后,使用如下命令可看到“gdbserver”進程已正常運行:
1 |
ps aux | grep gdbserver |
2.2.5 使用腳本文件啟動GDBServer
我寫了兩個腳本文件:scripts/start_gdb_server.sh、docker/scripts/dev_start_gdb_server.sh,其中前者用於在Docker內部啟動GDBServer,后者直接在宿主機(Docker外部)啟動GDBServer。
假設調試planning模塊,端口號為1111,scripts/start_gdb_server.sh的使用方法為:
1 |
# 進入Docker |
假設調試planning模塊,端口號為1111,docker/scripts/dev_start_gdb_server.sh的使用方法為:
1 |
# 在宿主機中(Docker外部)直接啟動gdbserver |
在2.3節我還將繼續配置VSCode文件,以便在VSCode中直接按快捷鍵“F5”就可啟動調試。
start_gdb_server.sh的內容如下:
1 |
#!/usr/bin/env bash |
dev_start_gdb_server.sh的內容如下:
1 |
#!/usr/bin/env bash |
2.3宿主機上VSCode內部的操作
在宿主機上使用VSCode打開Apollo項目(必須是你剛才構建的版本),打開需要調試的文件,在指定位置設置斷點,按“F5”鍵啟動調試。注意:由於VSCode使用腳本語言編寫,因此啟動過程會較慢,若加上網速不夠快,甚至出現一分鍾等待也有可能。調試方法和Visual Studio類似,此處不再贅述。如下圖所示:
2.4配置文件解析
我對.vscode/launch.json文件作出配置以便能在VSCode中連接Docker中的調試服務進程。此外,為了能在VSCode中直接啟動GDBServer,我在.vscode/launch.json文件中添加了一個調試前啟動任務:"preLaunchTask": "start gdbserver",該任務對應於.vscode/tasks.json文件中的一個啟動GDBServer的任務,因為GDBServer啟動后會一直阻塞命令行窗口,且無法通過在命令后面添加&的方式進行后台啟動,我只能將其配置為一個VSCode的后台運行任務。
.vscode/launch.json文件的配置內容如下:
1 |
{ |
.vscode/tasks.json文件中用於啟動GDBServer的任務配置如下:
1 |
{ |
2.5可能碰到的問題及解決方法
調試過程中,可能會碰到以下問題:
一是Docker內部待調試進程崩潰,無法在VSCode中調試(如下圖所示),解決辦法是:重啟Docker內部的調試進程;
二是網絡連接不暢,無法在VSCode中調試,解決辦法是:確保網絡暢通,並停用代理工具;
三是在VSCode內部關閉調試后,會同時將Docker內部的調試服務進程關閉,可能會出現無法直接在VSCode再次啟動調試服務里程的情形,解決辦法是:在Docker內部重啟調試服務進程,再在VSCode中按“F5”鍵啟動調試。
{ 三 }
使用VSCode遠程調試Apollo項目
研發過程中,我們還需遠程調試車內工控機上的Apollo項目,即在調試電腦上借助SSH服務連接車內工控機,啟動工控機內相關進程,然后在調試電腦上進行遠程調試。下面以調試planning模塊為例進行具體闡述:
3.1查看車內工控機IP地址
在車內工控機上,通過如下命令查看本機IP:
1 |
ifconfig |
如下圖所示,白色選中部分:192.168.3.137即為車內工控機的局域網IP地址。
3.2在調試電腦的瀏覽器中打開Dreamview並啟動待調試模塊
假設車內工控機局域網IP地址為:192.168.3.137,打開Chrome或Firefox瀏覽器,輸入如下網址:http://192.168.3.137:8888/,按照2.2.2節中的方法,啟動待調試的planning及其依賴的routing模塊。
3.3使用SSH命令遠程登錄車內工控機並啟動工控機的gdbserver服務
假設車內工控機的用戶名為:davidhopper,局域網IP地址為:192.168.3.137,使用如下命令遠程登錄車內工控機:
1 |
ssh davidhopper@192.168.3.137 |
成功進入工控機后,假設需調試planning模塊,端口號為1111,使用如下命令啟動車內工控機的gdbserver服務:
1 |
# 切換到工控機上Apollo項目根目錄 |
如下圖所示,如看到類似Listening on port 1111的提示,表示gdbserver服務順利啟動。
3.4在調試電腦上使用VSCode遠程調試工控機上的planning模塊
在調試電腦上使用VSCode打開Apollo項目,注意項目版本應與工控機上的版本一致,否則調試起來會輸出許多不一致的信息。首先,將配置文件.vscode/launch.json中的調試前加載任務行:"preLaunchTask": "start gdbserver",注釋掉,再將遠程調試服務地址修改為:"miDebuggerServerAddress": "192.168.3.137:1111",,如下圖所示:
在需要的位置設置斷點,按F5鍵啟動調試,因為是遠程連接,啟動等待的時間會更長,甚至會超過1分鍾。下圖是遠程調試界面。注意:每次在VSCode中中止調試后,需再次啟動調試時,一定要再次在命令行終端執行3.3節的操作,重啟工控機內的gdbserver服務進程。在本機調試時,因為我配置了一個preLaunchTask任務,就可省略此步驟。
自Apollo平台開放已來,我們收到了大量開發者的咨詢和反饋,越來越多開發者基於Apollo擦出了更多的火花,並願意將自己的成果貢獻出來,這充分體現了Apollo『貢獻越多,獲得越多』的開源精神。為此我們開設了『開發者說』板塊,希望開發者們能夠踴躍投稿,更好地為廣大自動駕駛開發者營造一個共享交流的平台!