Day 12 看見 BSM、CAM 與 DENM 如何描述車輛狀態及道路事件。
但如果要研究一台車接近十字路口時的位置、速度與路徑,我們不能每次都把真實車輛開上道路測試。
更安全也更容易重現的方法,是先在電腦裡建立一座城市:
道路與路口
→ 放入車輛與車流
→ 讓車輛依交通規則移動
→ 取得每個時間點的位置與速度
→ 交給後續 V2X 通訊模擬使用
這就是 **SUMO(Simulation of Urban MObility,城市交通模擬)**在本系列中的角色。
今天先不急著手動畫出完整十字路口,我們要先看懂 SUMO 的組成、常見檔案及執行流程,最後用工具自動產生一座小城市並讓車輛跑起來。
讀完這篇文章,你應該能夠:
sumo、sumo-gui、netedit 與 netconvert 的角色.net.xml、.rou.xml 與 .sumocfg 的用途SUMO 是一套開源、可跨平台使用的交通模擬工具,由德國航空太空中心 DLR 與開源社群持續開發,目前也是 Eclipse Foundation 的專案。
它可以模擬道路車輛、大眾運輸、行人與單車等不同交通參與者,也提供建立路網、產生需求、執行模擬及分析輸出的工具。
其中最重要的關鍵字是 microscopic(微觀)。
微觀交通模擬會把每一台車當成獨立實體,車輛具有自己的 ID、出發時間、路線與速度,也會受到前車、車道、路口和號誌影響。
相對地,巨觀模型可能用流量與密度描述一段道路,不一定追蹤每一台車。
巨觀交通模型
→ 這段道路目前每小時通過多少車?平均速度是多少?
SUMO 的微觀模型
→ veh0 現在在哪條 Lane?速度多少?前方是哪一台車?
V2X 研究需要知道個別車輛的位置、速度及移動軌跡,所以微觀模型很適合提供 mobility 資料。
![]()
圖 1:SUMO GUI 可以用不同視角觀察道路、車輛與模擬時間;畫面為 SUMO 1.6.0,現在的介面可能略有不同
圖片來源:Oabanse Wikimedia Commons,CC BY-SA 4.0
SUMO 會處理交通與移動,例如車輛何時出發、走哪條路、目前速度多少,以及是否停在紅燈前。
它不會自行模擬無線電波、頻道競爭、封包延遲、封包遺失或 V2X 安全簽章。
兩種模擬器的分工可以先記成:
| 模擬器 | 主要處理的問題 | 本系列使用位置 |
|---|---|---|
| SUMO | 道路、車流、交通規則與車輛移動 | Day 13~Day 14 |
| OMNeT++ | 節點、通訊協定、訊息與封包事件 | Day 15 |
| SUMO + OMNeT++ | 車輛移動如何影響 V2X 通訊 | Day 16~Day 17 |
所以「兩台車在 SUMO 裡互相靠近」不代表它們已經交換 V2X 封包。
後面還要把 SUMO 的車輛位置交給網路模擬器,才能建立移動節點並模擬訊息傳送。
初學時可以把 SUMO 場景拆成四塊:
Network
+ Traffic Demand
+ Simulation Configuration
→ SUMO/SUMO GUI
→ Simulation Output
| 部分 | 回答的問題 | 常見內容 |
|---|---|---|
| Network | 城市的道路長什麼樣? | Junction、Edge、Lane、Connection、Traffic Light |
| Traffic Demand | 哪些交通參與者要移動? | Vehicle Type、Route、Vehicle、Trip、Flow |
| Configuration | 要載入哪些檔案與模擬多久? | Network、Route、Begin Time、End Time、Output 設定 |
| Output | 模擬過程與結果是什麼? | 車輛軌跡、行程時間、速度、排放與道路統計 |
缺少 Network,車輛沒有路可以走。
缺少 Traffic Demand,畫面可能只有道路,卻沒有任何車輛出現。
Configuration 則把各項輸入與模擬設定集中起來,讓命令列與 GUI 可以載入同一個場景。
SUMO 的道路網路不只是一張背景地圖。
它必須包含車輛實際可以行駛的拓樸、方向、車道連接與路權關係。
Junction 可以代表路口,也可能只是道路幾何、車道數或其他屬性改變的位置。
每個 Junction 都有 ID 與座標,SUMO 也會依設定處理路口優先權、號誌及內部連接。
Edge 通常連接兩個 Junction,而且具有方向。
如果一條現實道路允許雙向行駛,在 SUMO 中通常需要兩條方向相反的 Edge,不能把一條 Edge 自動理解成雙向道路。
一條 Edge 可以包含一條或多條 Lane。
Lane 具有允許速度、長度與可使用的車種,也會透過 Connection 接到下一條 Edge 的特定 Lane。
可以把三者關係想成:
Junction A
→ Edge A_to_B
├── Lane 0
└── Lane 1
→ Junction B
Edge 是 Route 使用的道路區段,Lane 則是車輛在模擬中實際占用的位置。
道路建立後,還要定義交通需求。
Vehicle Type 常寫成 vType,可以設定車長、最大速度、加速度、減速度與跟車模型參數。
它描述一類車輛的共同特性,不代表某一台實際車輛。
Route 是一串具有連續關係的 Edge ID。
<route id="east_to_west" edges="east_in center west_out"/>
如果相鄰 Edge 沒有合法 Connection,Route 即使看起來方向正確,也可能無法使用。
Vehicle 會引用 Vehicle Type 與 Route,再指定自己的 ID 及出發時間。
<vehicle id="veh0" type="passenger" route="east_to_west" depart="0"/>
若要建立大量車流,逐台寫出 Vehicle 並不方便。
Flow 可以描述一段時間內的車輛產生規則,例如固定間隔、車輛數量或交通流率。
Day 14 會實際比較 Vehicle 與 Flow,建立第一批通過十字路口的車輛。
SUMO 檔案大多使用 XML,但副檔名會提示檔案角色。
| 檔案 | 主要用途 | 常見建立方式 |
|---|---|---|
scenario.net.xml |
完整道路網路 | 由 netedit 建立,或由 netconvert 轉換其他輸入 |
scenario.rou.xml |
Route、Vehicle Type、Vehicle 與 Flow | 手動撰寫、使用 netedit 或由工具產生 |
scenario.sumocfg |
集中指定網路、交通需求、時間與輸出 | 手動建立或由工具產生 |
.net.xml 是 SUMO 可以直接載入的完整 Network。
複雜網路通常不建議直接用文字編輯器修改,因為其中還包含 Lane、Connection、Junction Logic 與 Internal Edge 等衍生資料。
若要以文字方式描述基礎路網,可以先準備 Node、Edge、Connection 等 Plain XML,再交給 netconvert 產生 .net.xml。
SUMO 不是只有一個執行檔,而是一組彼此配合的工具。
| 程式 | 用途 |
|---|---|
sumo |
在命令列執行交通模擬,適合批次實驗與自動化 |
sumo-gui |
執行相同模擬並提供圖形介面,適合觀察與除錯 |
netedit |
以圖形介面建立及修改 Network、Demand 與其他物件 |
netconvert |
將 Plain XML、OpenStreetMap 或其他來源轉成 SUMO Network |
netgenerate |
產生格狀、蜘蛛網狀或隨機的抽象路網 |
duarouter |
依 Trip 與路網計算可行 Route |
randomTrips.py |
產生隨機 Trip,常用於快速建立交通需求 |
初學者最容易把 sumo-gui 當成場景編輯器。
實際上 sumo-gui 主要用來執行及觀察模擬,建立或修改場景通常要使用 netedit、XML 與其他產生工具。
本文以 Debian/Ubuntu 類 Linux 環境為例。
官方文件提供的套件安裝方式是:
sudo apt update
sudo apt install sumo sumo-tools sumo-doc
安裝完成後先確認版本:
sumo --version
sumo-gui --version
netedit --version
不同作業系統與套件來源可能提供不同版本。
記錄實驗時不要只寫「使用 SUMO」,還要保存實際版本、作業系統、場景檔案與隨機種子,後續才能重現結果。
若使用 Kali Linux,也可以透過 APT 查詢套件,但版本仍要以實際安裝結果為準。
本系列不要求在 NetHunter 手機上執行 SUMO GUI,交通模擬使用一般 Linux 電腦或 VM 會更方便。
sumo 與 sumo-gui 有什麼差別?兩者可以載入相同的 .sumocfg。
sumo -c scenario.sumocfg
sumo-gui -c scenario.sumocfg
sumo 適合大量重複實驗,不需要繪製畫面,執行速度通常也比較適合批次處理。
sumo-gui 可以播放、暫停與逐步執行,也能查看車輛、Edge、Lane 及號誌的目前狀態。
GUI 上看起來「車輛有在移動」只是第一層檢查。
正式分析仍應輸出可比較的資料,例如車輛軌跡、速度、行程時間與事件紀錄,不能只用螢幕截圖判斷研究結果。
Day 12 的 BSM 與 CAM 會描述位置、速度、Heading 及其他動態資料。
SUMO 可以提供模擬中的車輛狀態,例如:
simulationTime = 12.0 s
vehicleId = veh0
edgeId = east_in
laneId = east_in_0
position = 84.5 m
speed = 13.2 m/s
heading = 270°
這段資料只是概念示意,不是 SUMO 的固定輸出格式。
之後透過 TraCI 或模擬器整合層,可以讀取車輛狀態並更新 OMNeT++ 中的移動節點。
接著 V2X 應用才會把其中一部分資料編成 BSM、CAM 或研究用訊息。
SUMO 中的車輛狀態
→ Mobility 資料
→ OMNeT++ 中的 Vehicle Node
→ V2X Message
→ 其他節點接收與判斷
這裡要保留一條重要邊界:
SUMO 裡的模擬位置,是我們用來建立實驗情境的 ground truth;V2X 封包裡宣告的位置,則是接收端看到的資料。
正常節點可以讓兩者一致。
到了 Day 21 與 Day 30,惡意節點可能宣告錯誤位置,而 SUMO 仍保留車輛真正的模擬位置,這樣才能比較「真實移動」與「對外宣告」之間的差異。
SUMO 本身不是攻擊工具,但模擬資料會直接影響研究結論。
如果路網、車流、隨機種子或時間設定沒有保存,同一個攻擊情境可能無法再次產生相同結果。
若 Ground Truth 被錯誤修改,IDS 的偵測率與攻擊影響也可能失去比較基準。
因此後續實驗至少要保存:
這些資料不只是研究筆記,也會成為 Day 30 TARA 案例中的分析證據。
今天不手動畫道路,也不逐台編寫 Route。
我們會使用 netgenerate 自動產生 3×3 格狀路網,再用 randomTrips.py 建立車流,目標是先跑通 SUMO 最基本的工作流程。
確認環境
→ 產生 Network
→ 產生 Traffic Demand
→ 建立 Configuration
→ 執行模擬
→ 匯出 Ground Truth 軌跡
在 Kali VM 開啟 Terminal,執行:
sudo apt update
sudo apt install -y sumo sumo-tools sumo-doc
sumo --version
sumo-gui --version
netgenerate --version
不同套件來源提供的版本可能不同,因此截圖時要保留完整版本資訊。

圖 2:在 Kali VM 確認 SUMO 與路網產生工具的版本
mkdir -p sumo-day13
cd sumo-day13
今天產生的路網、車流、設定與輸出都放在這個目錄,避免和後續實驗混在一起。
netgenerate --grid \
--grid.number 3 \
--grid.length 100 \
--default.lanenumber 1 \
--output-file day13.net.xml
這個指令會建立橫向與縱向各三個 Junction 的格狀 Network,相鄰 Junction 相距 100 公尺,每個方向使用一條 Lane。

圖 3:使用 netgenerate 建立格狀路網檔案
畫面中的 SUMO_HOME is not set properly 是 XML 驗證環境的警告,這次路網仍然成功建立,下一步設定 SUMO_HOME 後就能讓工具找到正確資源。
先確認檔案已建立,再用 GUI 載入路網:
ls -lh day13.net.xml
sumo-gui -n day13.net.xml
這時畫面只有路網而沒有車輛是正常的,因為我們還沒建立 Traffic Demand。

圖 4:使用 netgenerate 產生的 3×3 格狀路網
關閉 GUI 後回到 Terminal,繼續下一步。
Kali 透過 APT 安裝時,SUMO 工具通常位於 /usr/share/sumo/tools。
先設定 SUMO_HOME 並確認腳本存在:
export SUMO_HOME=/usr/share/sumo
test -f "$SUMO_HOME/tools/randomTrips.py" && echo "randomTrips.py found"
若沒有顯示 randomTrips.py found,可以用以下指令確認套件安裝的位置:
dpkg -L sumo-tools | grep '/randomTrips.py$'
找到實際路徑後,再調整 SUMO_HOME。
接著產生 0 到 120 秒的交通需求,每 2 秒嘗試加入一個 Trip:
python3 "$SUMO_HOME/tools/randomTrips.py" \
-n day13.net.xml \
-o day13.trips.xml \
-r day13.rou.xml \
-b 0 \
-e 120 \
-p 2 \
--seed 13
--seed 13 會固定隨機種子,讓同樣的輸入能產生相同交通需求。
day13.trips.xml 保存起點、終點與出發時間,day13.rou.xml 則保存經過路網計算後可供 SUMO 使用的 Route。
使用文字編輯器建立 day13.sumocfg:
nano day13.sumocfg
貼上以下內容後儲存:
<configuration>
<input>
<net-file value="day13.net.xml"/>
<route-files value="day13.rou.xml"/>
</input>
<time>
<begin value="0"/>
<end value="120"/>
</time>
</configuration>
這份 Configuration 把 Network 與 Route File 放在一起,也把模擬時間限制為 0 到 120 秒。
sumo -c day13.sumocfg
如果指令正常結束而且沒有顯示 Error,代表路網、路線與設定檔可以一起載入。
若出現找不到檔案的訊息,先執行 pwd 與 ls,確認四個檔案位於同一個目錄:
day13.net.xml
day13.trips.xml
day13.rou.xml
day13.sumocfg
sumo-gui -c day13.sumocfg
開啟後按下播放按鈕。
如果車輛移動太快,可以把介面上方的 Delay 調高,再用滑鼠滾輪放大路口。
建議等模擬時間超過 10 秒。

圖 5:載入交通需求並執行模擬後,車輛開始在格狀路網中移動
關閉 GUI 後,用命令列重新執行模擬並輸出 FCD 資料:
sumo -c day13.sumocfg --fcd-output day13-fcd.xml
head -n 20 day13-fcd.xml
FCD 是 Floating Car Data 的縮寫。
輸出會依時間列出模擬中的車輛位置、速度、角度與 Lane 等資料,之後可作為 V2X 節點移動的 Ground Truth。

圖 6:完成模擬後輸出 day13-fcd.xml 車輛軌跡檔案
完成後,~/sumo-day13 應該至少包含:
| 檔案 | 檢查重點 |
|---|---|
day13.net.xml |
可以在 SUMO GUI 看見 3×3 格狀路網 |
day13.trips.xml |
包含不同出發時間與起訖 Edge 的 Trip |
day13.rou.xml |
包含工具計算後可行的 Route 與 Vehicle |
day13.sumocfg |
正確引用 Network 與 Route File |
day13-fcd.xml |
包含 timestep 與車輛位置、速度等資料 |
只載入 day13.net.xml 時,GUI 會顯示道路但沒有車輛。
載入 day13.sumocfg 並開始播放後,車輛才會依交通需求陸續出發,這正好呈現 Network、Traffic Demand 與 Configuration 的分工。
如果按下播放後仍看不到車輛,可以依序檢查:
day13.rou.xml 是否存在且不是空檔案day13.sumocfg 是否引用正確檔名今天使用工具快速生成場景,目的是確認整條流程可以運作。
Day 14 會改成手動建立道路與十字路口,再親自定義 Route、Vehicle 與 Flow,理解每個元素如何影響交通行為。
.net.xml 保存完整道路網路,.rou.xml 保存交通需求,.sumocfg 集中指定模擬設定sumo 適合批次執行,sumo-gui 適合觀察,netedit 用來建立與修改場景netgenerate 可以快速建立抽象路網,randomTrips.py 可以依固定種子產生可重現的交通需求今天我們先看懂 SUMO 的工具、檔案與資料流。
Day 14 將不再依靠自動產生工具,而是從道路與路口開始手動建立交通場景,加入 Route、Vehicle 與 Flow,再觀察參數如何改變車流。