ミクロ交通流シミュレータSUMO(Simulation of Urban MObility)に関して勉強する機会があり,使用方法を色々と調べていたので,その備忘録として,交差点の改良を行ってみようと思います.
対象とするのは,金沢市内の田上町交差点[Google Map]です.
同交差点は,金沢市内の主要道路である,山側環状道路から,金沢大学や郊外の住宅地等に抜ける道が分岐する交差点です.
本記事では,同交差点をSUMOで再現し,さらに,平面交差から立体交差に改造してみます.
準備
OSMの修正
まずは,対象地点のOpenStreetMapを編集します.
編集方法は,OpenStreetMapへのログイン後,編集画面にて閲覧可能になるチュートリアルが分かりやすいです.
今回は下記画像のように,歩道等を追加します.
さらに,各道路の最高速度も設定しておきます.
SUMOの導入
SUMOをインストールします.
以下の記事が参考になると思います.
インストールはこちらから行ってください.
Pythonの導入
こちらからインストールしてください.
ここでの説明は割愛します.
供給の設定
道路ネットワークの取得
SUMOでは超絶便利な機能を備えたPythonコードが提供されています.
まずは,SUMOのtoolsディレクトリの直下のosmwebwizard.pyを実行します.
python Sumo\tools\osmWebWizard.py
ブラウザ上に,OpenStreetMapの選択画面が起動します.
対象とする交差点にパンして,Select Area
にチェックを入れ,道路ネットワークを取得する範囲を選択します.
さらに,Optionsで,Left Hand Traffic
にチェックを入れます.
ネットワークの種類選択を行います.
必要な道路等の種類にチェックを入れます.
今回は,Highway
とPedestrians
にチェックを入れます.
交通需要は後ほど編集するので,この段階では特に変更しません.
右上のGenerate Scenario
ボタンを押してください.
sumo-guiが起動し,ネットワークを取得した範囲が表示されます.
左上のRun
を押すと,シミュレーションが開始されます.
NetEditの起動
これだけでも十分に楽しいかもしれませんが,より現実に即した設定となるように適宜修正します.
上で作成したシミュレーションファイルは,タイムスタンプをフォルダ名として保存されています1.
シミュレーションファイル一式の中の,osm.net.xml.gzを展開します.
タスクバーの検索ボックスで,NetEdit
と検索して,NetEditアプリを起動します.
File
> OpenNetwork
から,展開したosm.net.xmlを選択します.
NetEdit上に取得した道路ネットワークが表示されます.
最高速度の修正
NetEditアプリでEdit network elements
のInspect mode
を選択した状態で,各エッジをクリックすると,各エッジの情報を確認できます.
各エッジの最高速度(speed)が正しく設定されているか確認します.
注意
SUMOの速度設定の単位は[m/s]ですので,[km/h]を3.6で割った数値になっているはずです.
今回は平面交差点と立体交差点の2パターンを作成します.
以降では,2パターンで異なる作業も出てくるので,ここまでの状態で一旦ネットワークファイルを保存します.
画面左上のSave network
から保存してください.
そのうえで,ネットワークファイルを複製して,それぞれのパターンで個別に作業していきます.
車線数と各車線間の接続の修正
NetEditでネットワークファイルを立ち上げます.
まずは,車線数を増やして,右折車線を作成します.
エッジ上の右折車線を分岐させたいあたり(たとえば,画像の赤矢印の位置)で右クリックし,Edge Options
> Split edge here
を選択します.
エッジが分割されるので,Inspect modeで車線数(numLane)を修正します.
交差点に流入する4断面全てに対して,同様の作業を行います.
つづけて,各流入-流出エッジ間の接続を修正します.
Edit network elements
のConection mode
を選択します.
交差点流入部をクリックすると,
- その流入エッジが水色
- その流入エッジから接続可能な流出エッジが緑色
- すでに結ばれている流出エッジが黄緑色
- 他の接続と競合する流出部が黄色
に着色されます.
新たに接続を作成したい場合は,緑色に着色されたエッジを左クリックし,すでに結ばれている流入-流出ペアの組み合わせを解除したい場合は,黄緑色の流出部を左クリックします.
編集を完了したら,左上のOK
をクリックします.
全ての流入車線に対して,同様の作業を行います.
新たなエッジの追加
つづいて,立体交差用の高架道路を作成します.
今回は田上町交差点の南北方向道路を高架にして,立体交差させます.
高架にする道路の分岐点付近でエッジを分割します.
Edit network elements
のEdge mode
を選択して,新たにエッジを作成するモードに入ります.
作成した高架道路の2つの分岐点(図中の青矢印の位置)を順にクリックしていき,高架道路となるエッジを新規作成します.
Edit network elements
のMove mode
を選択して,エッジの形状を変更するモードに入ります.
エッジ上の任意の地点をドラッグすると,エッジの形状を変化させることができるので,適宜形状を変更します.
新しく追加した高架道路となるエッジの最高速度(Speed)と車線数(numLane)を変更します.
信号制御の設定
Edit network elements
のTraffic light mode
を選択します.
対象交差点の信号機マークをクリックします.
信号制御タイプは様々ありますが,今回はStatic
にします.
今回は実地観測の結果を参考に,各フェーズで現示時間(dur)とどの接続にどのような通行権を与えるか(state)を設定します2.
なお,フェーズの追加は+
ボタン,フェーズの削除は✕
ボタンから行います.
各フェーズにおける各接続の通行権については,各フェーズを選択した状態で,着色された各接続を右クリックすることで,変更できます.
通行権は,以下に記載があります.
今回は以下の4種類を用います.
- r: 赤信号で,通行権なし
- y: 黄色信号で,車両が交差点から離れていれば,その車両は減速する
- g: 非優先の青信号.直進青現示のときの,右折方向に対する通行権付与に使用
- G: 優先の青信号
編集が完了したら,左上のSave
ボタンから信号プログラムを保存します.
その他の設定
詳細な説明は割愛しますが,必要に応じて以下の設定を行っても良いと思います.
- 車線変更に関する規制: 各laneの属性設定から編集可能
- 店舗駐車場等を表すポリゴンの作成
- 交差点内の停止規制: junctionのkeepclear属性を設定
- エッジ・レーンの通行優先権
以上で,供給側の設定が完了しました.
画面左上のSave network
からネットワークファイルを保存します.
需要の設定
以降は,シミュレーション内で流す車両に関する設定を行います.
走行経路の設定
走行経路を設定します.
XMLファイルの中身をテキストエディタで直接編集することもできますが3,今回はNetEditアプリを使います.
NetEditアプリでネットワークファイルを立ち上げます.
Edit traffic demand elements
のRoute mode
を選択します.
エッジを順にクリックしていき,経路を作成します.
すでに選択されたエッジは水色に,直近で選択されたエッジは黄緑色に,接続候補のエッジは緑色に着色されます.
選択を誤った場合は,画面左側のAbort route creation
ボタンやRemove last edge
ボタン,Esc
キーで選択を解除することができます.
経路上の全てのエッジの選択が完了したら,Finish route creation
ボタンで経路を確定させます.
つぎに,Inspect mode
ボタンから属性確認・編集のモードに入り,経路のidや色4を任意に設定します.
全ての経路について,以上の作業を行います.
完了したら,画面左上のSave individual files
> Save demand elements
を順に選択し,作成した経路をルートファイル(.rou.xml)として保存します.
車両の属性設定
XMLファイルをテキストエディタで直接編集して,各車両の属性を設定します5.
ではまず,先ほど保存したルートファイルを,適当なテキストエディタで開きます.
つぎのように,各経路に関する設定が記述されています.
id="~~"
が各経路のidの定義,edges="~~"
が各経路で通過するエッジid(順番に指定),color="~~"
が各経路の色の設定4です.
<?xml version="1.0" encoding="UTF-8"?>
<routes>
<!-- Routes -->
<route id="r_N2E" edges="737465020#3 737465020#4 737465020#5 54499654#2 54499654#3 54499654#4 54499654#5 54499654#6" color="220,20,60"/>
<route id="r_N2S" edges="737465020#3 737465020#4 737465020#5 1268566610#1 1268566610#2 1268566610#3 1268566610#4 1204444967" color="255,69,100"/>
<!-- 以下、r_N2W, r_E2S, r_E2W, r_E2N, r_S2W, r_S2N, r_S2E, r_W2N, r_W2E, r_W2Sも同様に定義されている -->
</routes>
このファイルに車両属性に関する設定を追記します.
今回は以下の属性を明示的に設定します.
属性名 | 説明 |
---|---|
id | 各車両タイプの名称 |
accel | 車両の加速度[m / s^2] |
decel | 車両の減速度[m / s^2] |
emergencyDecel | 車両の物理的に可能な最大限速度[m / s^2] |
sigma | 追従モデルのパラメータで,ドライバの不完全性を表現する(0が完璧な運転)[link] |
tau | 追従モデルのパラメータで,ドライバが望む最小車間距離をモデル化する[s][link] |
length | 車体長[m][link] |
minGap | 先行車との車間[m][link] |
maxSpeed | 車両の技術的な最高速度[m/s] |
desiredMaxSpeed | 希望最高速度[m/s][link].この値にspeedFacterを乗じて,最高速度とする.なお,その最高速度は,maxSpeedと道路の最高速度に次ぐ,速度上限値を与える. |
speedFactor | 車両の最高速度を計算するために,desiredMaxSpeed,または,道路の最高速度に乗じるパラメータ[link].分布を指定することもできる[link]. |
color | その車両の色4 |
vClass | 車線の走行制限のために設定する車種[link][link] |
width | 車両幅[m] |
mass | 車体重量[kg] |
laneChangeModel | 車線変更モデル[link] |
carFollowModel | 追従モデル[link].デフォルトはKraussモデル[link] |
actionStepLength | シミュレーションのタイムステップとシミュレーションにおけるドライバの反応頻度を切り離すために設定するパラメータ[s][link] |
lcStrategicLookahead | 車線変更モデルパラメータで,最適な走行車線を考える際の先読み距離[m]. |
また,交差点モデルのパラメータ[link]として,以下も明示的に設定します.
属性名 | 説明 |
---|---|
jmIgnoreKeepClearTime | ドライバが渋滞して交差点内に滞留してしまう可能性がある場合でも,交差点への進入を選択するしきい値となる累積待機時間[s][link].負値で,ドライバは常に交差点を空けるように停止する(交差点への進入を選択しない). |
jmDriveAfterRedTime | 現在から指定されたしきい値[s]以内の時間に信号が赤に変わった場合,その車両は赤信号を無視する.0に設定すると,黄色信号では進行し,赤信号では反応遅れなくブレーキをかけようとする. |
jmDriveAfterYellowTime | 現在から指定されたしきい値[s]以内の時間に信号が黄色に変わった場合,その車両は黄信号を無視する.黄色に変わった時点でブレーキをかけるには速度が速すぎる場合には,その車両は黄色信号を無視する. |
jmIgnoreFoeProb | 通行権のある車両を無視して,進行する確率(範囲[0,1]). |
jmIgnoreFoeSpeed | 本パラメータで指定した値[m/s]以下の速度で走行する通行権を有する車両を無視する. |
jmIgnoreJunctionFoeProb | すでに交差点に入っている敵車両を無視する確率(範囲[0,1])6. |
jmSigmaMinor | マイナーリンク(通行権を有しないリンク?)を通過する時の運転の不完全さ |
諸々の設定を追記したルートファイルが以下です.
<?xml version="1.0" encoding="UTF-8"?>
<routes>
<!-- Vehicle Type -->
<vType id="v_N2E"
accel="2.6" decel="4.5" emergencyDecel="9.0" sigma="0.5" tau="1.0"
length="5.0" minGap="2.5" maxSpeed="55.55" desiredMaxSpeed="33.33" speedFactor="norm(0,1)"
color="220,20,60" vClass="passenger" width="1.8" mass="1500"
carFollowModel="Krauss" laneChangeModel="LC2013" actionStepLength="0.1"
jmIgnoreKeepClearTime="-1" jmDriveAfterRedTime="-1" jmDriveAfterYellowTime="-1"
jmIgnoreFoeProb="0" jmIgnoreFoeSpeed="0" jmIgnoreJunctionFoeProb="0" jmSigmaMinor="0.5"/>
<!-- 以下、v_N2S, v_N2W, v_E2S, v_E2W, v_E2N, v_S2W, v_S2N, v_S2E, v_W2N, v_W2E, v_W2Sの車両タイプを同様に定義する -->
<!-- Routes -->
<route id="r_N2E" edges="737465020#3 737465020#4 737465020#5 54499654#2 54499654#3 54499654#4 54499654#5 54499654#6" color="220,20,60"/>
<!-- 以下、r_N2S, r_N2W, r_E2S, r_E2W, r_E2N, r_S2W, r_S2N, r_S2E, r_W2N, r_W2E, r_W2Sの経路を同様に定義する -->
</routes>
各経路の需要の設定
引き続きルートファイルに追記することで,各経路の需要を設定します.
以下のパラメータを明示的に設定します.
属性名 | 説明 |
---|---|
begin | 最初の車両が出発する時刻[s] |
end | 車両の連続発生の終わりの時刻[s] |
vehsPerHour | 1時間あたりの車両数[台/時]7 |
type | 上記で設定したvehicle typeのid |
departSpeed | 車両がネットワークに入る瞬間の速度[m/s][link] |
arrivalSpeed | 車両がネットワークを出る瞬間の速度[m/s][link] |
今回は実地での観測をもとに需要[台/時]を設定し,0秒から1800秒まで車両を連続発生させます.
また,南側断面からの右折については,前半20分間と後半10分間でvehsPerHour
を変えてみます.
諸々の設定を追記したxmlファイルが以下です.
<?xml version="1.0" encoding="UTF-8"?>
<routes>
<!-- Vehicle Type -->
<vType id="v_N2E"
accel="2.6" decel="4.5" emergencyDecel="9.0" sigma="0.5" tau="1.0"
length="5.0" minGap="2.5" maxSpeed="55.55" desiredMaxSpeed="33.33" speedFactor="norm(1.0,0.1)"
color="220,20,60" vClass="passenger" width="1.8" mass="1500"
carFollowModel="Krauss" laneChangeModel="LC2013" actionStepLength="0.1"
jmIgnoreKeepClearTime="-1" jmDriveAfterRedTime="-1" jmDriveAfterYellowTime="-1"
jmIgnoreFoeProb="0" jmIgnoreFoeSpeed="0" jmIgnoreJunctionFoeProb="0" jmSigmaMinor="0.5" lcStrategicLookahead="300"/>
<!-- 以下、v_N2S, v_N2W, v_E2S, v_E2W, v_E2N, v_S2W, v_S2N, v_S2E, v_W2N, v_W2E, v_W2Sの車両タイプを同様に定義する -->
<!-- Routes -->
<route id="r_N2E" edges="737465020#3 737465020#4 54499654#2 54499654#3 54499654#4 54499654#5 54499654#6" color="220,20,60"/>
<!-- 以下、r_N2S, r_N2W, r_E2S, r_E2W, r_E2N, r_S2W, r_S2N, r_S2E, r_W2N, r_W2E, r_W2Sの経路を同様に定義する -->
<!-- Flows -->
<flow id="f_N2E" begin="0.00" route="r_N2E" end="1800.0" type="v_N2E" vehsPerHour="300.0"/>
<flow id="f_N2S" begin="0.00" route="r_N2S" end="1800.0" type="v_N2S" vehsPerHour="1000.0" arrivalSpeed="current"/>
<!-- ここに,f_N2W,f_E2S, f_E2W, f_E2N, f_S2W, f_S2Nを同様に定義する -->
<flow id="f_S2E_1" begin="0.00" route="r_S2E" end="1200.0" type="v_S2E" vehsPerHour="400.0" departSpeed="16.67"/>
<!-- ここに,f_W2N,f_W2E, f_W2Sを同様に定義する -->
<flow id="f_S2E_2" begin="1200" route="r_S2E" end="1800.0" type="v_S2E" vehsPerHour="320.0" departSpeed="16.67"/>
</routes>
複数の経路を設定して,指定した比率でそれらの経路に交通量を分散させることもできます.
今回は,立体交差シナリオにおいて,南側断面と北側断面間の直進交通を,97%は高架上道路,3%は高架下道路を通るように設定します.
つぎのように記述します.
<?xml version="1.0" encoding="UTF-8"?>
<routes>
<!--Vehicle Type-->
<!--上記同様に車両タイプを定義する.-->
<!-- Routes -->
<route id="r_N2S_over" edges="737465020#3 E6 -E0 E8 1268566610#2.103 1268566610#3 1268566610#4 1204444967" color="255,69,100"/>
<route id="r_N2S_under" edges="737465020#3 737465020#3.86 737465020#4 737465020#5 1268566610#1 1268566610#2 1268566610#2.103 1268566610#3 1268566610#4 1204444967" color="255,69,100"/>
<routeDistribution id="r_N2S">
<route refId="r_N2S_over" probability="0.97"/>
<route refId="r_N2S_under" probability="0.03"/>
</routeDistribution>
<!--その他のルートについても上記同様に定義する.-->
<!-- Flows -->
<flow id="f_N2S" begin="0.00" route="r_N2S" end="1800.0" type="v_N2S" vehsPerHour="1000.0"/>
<!--その他のフローについても上記同様に定義する.-->
</routes>
シミュレーションの設定
シミュレーションを実行するためのファイルを作成します.
まずは,ここまでで作成したネットワークファイルやルートファイルと同じディレクトリに,拡張子を.sumocfgとした任意のファイル名の実行ファイルを作成します.
適当なテキストエディタで開き,つぎのように記述します.
実行ファイルの全体像
<?xml version="1.0" encoding="UTF-8"?>
<sumoConfiguration>
<input>
<net-file value="Tagamimachi.net.xml"/>
<route-files value="Tagamimachi.rou.xml"/>
</input>
<time>
<begin value="0"/>
<end value="2000"/>
<step-length value="0.01"/>
</time>
<output>
<fcd-output value="probe.xml"/>
</output>
</sumoConfiguration>
入力ファイルの設定
以下の部分は,入力ファイルとして,ネットワークファイルとルートファイルを指定しています.
<input>
<net-file value="Tagamimachi.net.xml"/>
<route-files value="Tagamimachi.rou.xml"/>
</input>
シミュレーション時間の設定
以下の部分は,シミュレーションの開始時刻,終了時刻,タイムステップを指定しています.
今回は1800秒まで車両を連続発生させるので,シミュレーション時間はそれよりも長い2000秒までにしておきます.
<time>
<begin value="0"/>
<end value="2000"/>
<step-length value="0.01"/>
</time>
出力の設定
以下の部分は,出力として,各車の各タイムステップごとの座標を記録したxmlファイルを得られるようにしています.
<output>
<fcd-output value="probe.xml"/>
</output>
シミュレーションの実行
テキストエディタを閉じて,実行ファイルをsumo-guiで起動します.
車両の形状の修正
画面上部のEdit Coloring Schemes
をクリックして,View Settingウィンドウを立ち上げます.
Vehicles
設定のShow Asプルダウンメニューから,raster images
を選択します.
その後,OK
をクリックして,ウィンドウを閉じます.
Delayの調整
画面上部のDelayでシミュレーションの進行速度を調整します.
これは1つのタイムステップを進むごとに待機する時間[ms]を設定するものです.
デフォルトが0ですが,この状態で実行すると,早すぎて状況が観察しづらいので,適宜調整します.
いざ実行!
画面左上のRun
から実行します.
各シナリオの288秒~432秒(信号3サイクル目)の実行の様子は下記です.
(当たり前ですが,)南北直進方向の滞留が解消されています.
また,南側から流入し,東側に流出する右折交通の滞留もやや解消されています.
おわりに
今回はミクロ交通流シミュレータSUMOの使用方法の整理も兼ねて,平面交差点の立体交差化に取り組みました.
シミュレーションなので,様々なパターンを乱打してみると面白いかもしれません.
-
私の場合は,"C:\Users\ UserName \Sumo"直下に作成されました. ↩
-
オプションで各フェーズに名前(name)をつけることもできます. ↩
-
XMLファイルを直接編集する場合には,各エッジのidを把握している必要があります. ↩
-
具体的にどういう状況を指し示しているのかはよくわかりません. ↩
-
この値を設定すると,各車は等間隔に流れ出します.別の属性を与えると,その間隔を確率的に与える設定を行うことも可能です.詳しい説明はこちら8. ↩
-
ちなみに,ランダム性を有する設定を行っても,SUMOのデフォルトではシードは固定されるそうです.詳しい説明はこちらやこちらをご覧ください. ↩