mcpField
M
matlab-cosimulate-sumo-simulink

matlab-cosimulate-sumo-simulink

github.com/matlabテスト・品質1.2k51 回インストール1 日前に更新
リポジトリ

matlab-cosimulate-sumo-simulink について

Automated Driving Toolbox Interface for Eclipse SUMOを使い、Eclipse SUMOとSimulinkの同期交通コシミュレーションを構築するスキルです。車両状態の取得、制御、動的な追加・削除を扱います。

主な機能

  1. 01SUMO ServerとClientブロックの設定
  2. 02SUMOとSimulinkのシミュレーション同期
  3. 03車両状態とシミュレーション情報の取得
  4. 04車両の速度と位置の制御
  5. 05車両の動的な追加と削除

活用シーン

  1. 01ADASまたはADコントローラーのテスト
  2. 02Simulinkで車両の位置と速度を取得
  3. 03コントローラーからSUMO車両を操作
  4. 04ルートファイルなしで背景交通を生成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/matlab/matlab-agentic-toolkit --skill matlab-cosimulate-sumo-simulink

インストール後、Claude Code で/matlab-cosimulate-sumo-simulinkを入力して読み込まれたか確認します。

同梱ファイルmanifest.yaml

詳細

SUMO と Simulink の協調シミュレーションを構築する

Automated Driving Toolbox Interface for Eclipse SUMO Traffic Simulator の SumoInterfaceLibrary ブロックを使用して、Eclipse SUMO と同期した協調シミュレーションを実行する Simulink モデルを作成します。

使用する場面

  • Eclipse SUMO に接続する Simulink モデルを構築する
  • ADAS/AD コントローラーのテスト用に交通の協調シミュレーションを設定する
  • SUMO から Simulink に車両の状態(位置、速度)を読み込む
  • Simulink コントローラーから SUMO 内の自車両を制御する
  • シミュレーション中に車両を動的に生成または削除する
  • ルートファイルを作成せずにランダムな背景交通を生成する

使用しない場面

  • Simulink を使わない SUMO 単独のシミュレーション(SUMO の CLI または Python TraCI を直接使用してください)
  • 車両ダイナミクスのモデリング(Vehicle Dynamics Blockset を使用してください)
  • Driving Scenario Designer によるシナリオ設計(異なるワークフローです)

前提条件

  1. SUMO_HOME 環境変数を設定して Eclipse SUMO をインストールしていること
  2. 「Automated Driving Toolbox Interface for Eclipse SUMO Traffic Simulator」サポートパッケージをインストールしていること
  3. Windows:SUMO_HOME の末尾に区切り文字を追加すること — Server ブロックのランチャーは、区切り文字を補わずに SUMO_HOME + "bin\..." を連結します。SUMO_HOME の末尾に \ または / がないと、SUMO が正しくインストールされていても、すべての sim() が「Failed to launch Eclipse SUMO simulator」エラーで失敗します。モデルを作成またはシミュレーションする前に、必ず次を実行してください。
if ~endsWith(getenv('SUMO_HOME'), filesep)
    setenv('SUMO_HOME', [getenv('SUMO_HOME') filesep]);
end
  1. 確認:getenv('SUMO_HOME') が区切り文字で終わる有効なパスを返す必要があります。

推奨する構築方法

mcp__matlab__model_edit(SATK)が利用可能な場合は、生の add_block/add_line よりも優先して使用してください。各編集後に自動レイアウトが適用され、重なりのない整った配線が作成されます。また、同じ呼び出し内で ref を使って新しく追加したブロックを参照できます。以下のパターンはそのまま適用できます。1 つの JSON ペイロード内で add_block/connect/configure 操作として表現してください。SATK が利用できない場合、またはスキーマで表現できない操作(例:sfroot を使った MATLAB Function の Script の設定)に限り、add_block/add_line を使用してください。

注:新規作成した Enabled Subsystem の既定の In1/Out1 を削除した後に EnablePort を配線する場合、model_edit は Enable ポートを解決できません。回避策として、add_line(model, 'Source/1', 'SubsystemName/Enable', 'autorouting','smart') を使用してください。

ワークフロー

冪等なビルド用テンプレート
modelName = 'sumo_cosim';
workDir = fileparts(mfilename('fullpath'));
% SUMO_HOME workaround (Windows)
sh = getenv('SUMO_HOME');
if ~endsWith(sh, filesep), setenv('SUMO_HOME', [sh filesep]); end
% Idempotent rebuild
if bdIsLoaded(modelName), close_system(modelName, 0); end
slxPath = fullfile(workDir, [modelName '.slx']);
if isfile(slxPath), delete(slxPath); end
new_system(modelName);
open_system(modelName);
set_param(modelName, 'StopTime','100', 'SolverType','Fixed-step', 'FixedStep','0.1');
% ... build model ...
save_system(modelName, slxPath);
1. SUMO シナリオファイルを準備する

ユーザーに既存の .sumocfg を尋ねてください。新しいファイルを生成するのは、明示的に依頼された場合に限ります。簡易ネットワークには netgenerate を使用してください。

sumoHome = getenv('SUMO_HOME');
cmd = sprintf('"%s" --grid --grid.number 2 --grid.length 200 --output-file "%s"', ...
    fullfile(sumoHome,'bin','netgenerate'), fullfile(pwd,'network.net.xml'));
system(cmd);

最小限の .sumocfg(EnableRandomTraffic を使用する場合、route-files は省略可能です):

<configuration>
    <input><net-file value="network.net.xml"/></input>
    <time><begin value="0"/><end value="100"/><step-length value="0.1"/></time>
</configuration>

ルートファイルの規則:すべての <vehicle>、<person>、<personFlow> エントリは、depart 時刻(フローの場合は begin)の順に並べる必要があります。順序が正しくないエントリは、警告なしで無視されます。Actor ブロックで使用するルートは、<flow> に埋め込まず、単独の <route> 要素にしてください。

OpenDRIVE のインポート:netconvert --opendrive-files file.xodr -o network.net.xml を使用してください。注:SUMO は netOffset を適用します(.net.xml の <location> 要素に表示されます)。すべての SUMO 座標は、OpenDRIVE 座標に netOffset を加えた値です。

2. Server と Client を作成する
add_block('SumoInterfaceLibrary/Server', [modelName '/SUMO Server']);
set_param([modelName '/SUMO Server'], 'ServerFile',fullfile(pwd,'cosim.sumocfg'), ...
    'ServerPort','8813', 'ServerNumClients','1', 'EnablePacing','on', ...
    'PacingRate','1', 'SampleTime','0.1');
add_block('SumoInterfaceLibrary/Client', [modelName '/SUMO Client']);
set_param([modelName '/SUMO Client'], 'ClientAddress','127.0.0.1', ...
    'ClientPort','8813', 'ClientOrder','1', 'SampleTime','0.1');

重要:ClientPort は ServerPort と同じ値にしてください。FixedStep は SUMO の step-length と一致させてください。ペーシング(EnablePacing='on')を有効にして、GUI が 2 秒で一気に表示されるのを防いでください。

3~6. リーダー、ライター、Actor を追加し、保存して実行する

以下の「ブロックリファレンス」および「パターン」セクションを参照してください。モデルをプログラムから変更した場合は、必ず sim(modelName) の前に save_system(modelName) を実行してください。

ブロックリファレンス

サーバーブロック
パラメーター用途デフォルト
ServerFile.sumocfg へのパス—
ServerPortTraCI ポート'8813'
ServerNumClientsクライアント数'1'
EnableRandomTrafficルートファイルなしで車両を生成'off'
RandomTrafficランダム交通が有効な場合の車両数'0'
EnablePacingリアルタイムのペーシング(デモに推奨)'off'
PacingRateペーシング倍率'1'
SampleTimeステップ間隔'-1'

注: SUMO のデフォルトは time-to-teleport=300s です。300 秒を超えて停止した車両はテレポートされます。バス停で意図的に自車を停止させる場合、予期しない動作になることがあります。

クライアントブロック
パラメーター用途デフォルト
ClientAddressサーバー IP'127.0.0.1'
ClientPortServerPort と一致させる必要があります'8813'
ClientOrderクライアントの優先度'1'
リーダーブロック — 車両トピック

対象の車両が存在しない場合、すべての車両トピックのリーダーとライターはクラッシュします。 車両が t=0 より後に出現する場合は、有効なサブシステムで制御してください。Safe Vehicle State Access を参照してください。

トピック入力出力
Speed車両 ID速度(スカラー)
Position車両 ID位置 [x, y]
Position3D車両 ID位置 [x, y, z]
Acceleration車両 ID加速度
Angle車両 ID進行方向(度、0=北、時計回り)

車両 ID の入力には String Constant ブロックを使用してください。他のリーダーの出力は使用しないでください。

リーダーブロック — シミュレーショントピック(入力ポートなし)
トピック出力
ID list車両 ID 文字列
ID countスカラー数
Arrived list目的地に到着した ID
Departed listネットワークに進入した ID
ライターブロック — 車両トピック

対象の車両が存在しない場合、ライターはクラッシュします。リーダーと同じ障害が発生します。出現が遅れる車両は、有効なサブシステムで制御してください。

トピック入力ポート備考
Speed車両 ID、速度希望速度を設定します。SUMO の追従制御では、先行車に応じて引き続きブレーキがかかります
Position(RouteFlag オフ)車両 ID、X、Y、角度—
Position(RouteFlag オン)車両 ID、Edge ID、Lane Index、X、Y、角度、Keep Route下記の型の表を参照
Min gap車両 ID、間隔—
Speed mode車両 ID、モード—

Writer(Vehicle/Position, RouteFlag=on) のポート型 — 型が一致しない場合、エラーは通知されずに失敗します。

ポート信号型
1車両 IDstring
2Edge IDstring
3Lane Indexint32
4Xdouble
5Ydouble
6角度double(度)
7Keep Routeuint8(uint8(1) を使用)

警告: Writer(Vehicle/Position) は衝突チェックを行いません。他の車両の近くにテレポートさせると、車両が積み重なることがあります。生成する車両は近くの交通とは別の車線に配置してください。

ライターブロック — 可視化トピック

GUITopic パラメーターとともに TopicCategory='Visualization' を使用してください。可視化コマンドの設定は保持されます。SUMO が Schema/Track/Zoom を受信すると、その設定を保持します。必ずワンショットの有効なサブシステムで囲んでください。毎ステップ実行したままにしないでください。

GUITopic入力ポート有効な値
Track VehicleView Id、Vehicle Id—
Zoom factorView Id、Zoom—
SchemaView Id、Schema"standard"、"real world"、"fast standard"、"fast real world"

すべての可視化トピックでは、ポート 1 に View Id の入力が必要です。SUMO GUI のデフォルトのビュー名は "View #0" です。必ずこの文字列をそのまま使用してください。

% Track Vehicle example (one-shot): camera follows ego
add_block('SumoInterfaceLibrary/Writer', [subsysPath '/Track Writer'], ...
    'TopicCategory','Visualization', 'GUITopic','Track Vehicle', 'SampleTime','0.1');
add_block('simulink/String/String Constant', [subsysPath '/View Id'], ...
    'String','"View #0"');  % Default SUMO GUI view — always "View #0"
add_block('simulink/String/String Constant', [subsysPath '/Vehicle Id'], ...
    'String','"ego_vehicle"');
add_line(subsysPath, 'View Id/1', 'Track Writer/1');
add_line(subsysPath, 'Vehicle Id/1', 'Track Writer/2');
% Wrap in one-shot Enabled Subsystem (Constant(0)->IC(1)->Enable)
% Schema example (one-shot): switch GUI to "real world"
add_block('SumoInterfaceLibrary/Writer', [modelName '/Set Schema'], ...
    'TopicCategory','Visualization', 'GUITopic','Schema', 'SampleTime','0.1');
add_block('simulink/String/String Constant', [modelName '/View Id'], ...
    'String','"View #0"');  % Default SUMO GUI view — always "View #0"
add_block('simulink/String/String Constant', [modelName '/Schema Name'], ...
    'String','"real world"');
% Wrap in one-shot Enabled Subsystem (Constant(0)->IC(1)->Enable)
Actor ブロック
パラメーター用途
VehicleState'Add' または 'Remove'
SpawnMethod'Lane'(こちらを使用)または 'Position'(動作しません — 既知の問題を参照)
departLane'random'、'free'、'allowed'、'first'、'best'
departSpeed'max'(推奨)、'random'、'desired'、'speedLimit'
enableRouteID'on'/'off'
routeID.rou.xml のルート ID(enableRouteID='on' が必要)
typeID車両タイプ ID(デフォルト:'DEFAULT_VEHTYPE')

Actor ブロックは必ず Enabled Subsystems 内に配置してください。Spawn サブシステムには Priority='1' を設定し、Readers(Priority='10')より先に実行されるようにしてください。

パターン

単発トリガー
トリガーパターン
t=0 のときのみスポーンConstant(0) -> IC(Value=1) -> Enabled Subsystem
シミュレーション時間 T にスポーンClock -> MATLAB Function (persistent fired) -> Enabled Subsystem
T 以降、継続的に実行(例:速度ライター)Clock -> Compare To Constant (>=T) -> Enabled Subsystem
条件が真になったときにスポーンClock/センサー -> MATLAB Function (persistent fired) で条件をチェック

時間ベースの単発処理(t=1.2 にスポーン):

% MATLAB Function code:
% function pulse = fcn(t)
% %#codegen
% persistent fired
% if isempty(fired), fired = false; end
% if (t >= 1.2) && ~fired, pulse = 1.0; fired = true;
% else, pulse = 0.0; end
% end
自車両の制御(ルートファイル方式 — 推奨)

Reader が t=0 から動作するよう、.rou.xml で depart="0" を指定して自車両を定義します。

<routes>
    <vType id="ego_type" accel="2.6" decel="4.5" sigma="0" length="5" maxSpeed="25"/>
    <route id="ego_route" edges="B1B2 B2B3 B3B4 B4B1 B1B2 B2B3 B3B4 B4B1"/>
    <vehicle id="ego_veh" type="ego_type" route="ego_route" depart="0"
             departLane="free" departSpeed="max"/>
</routes>

Simulink が Writer(Vehicle/Speed) で縦方向の制御を行う場合、自車両のルートに <stop> 節を含めないでください。SUMO の停止指令が Speed Writer を上書きします。

遅延スポーン車両向けのゲート付き Writer(Vehicle/Speed)
% Latched enable: HIGH from t >= spawnTime onwards
% Clock -> Compare To Constant (relop='>=', const=spawnTime) -> Enable
% Inside Enabled Subsystem:
%   String Constant("veh_1") -> Writer(Vehicle/Speed) port 1
%   Constant(desiredSpeed)   -> Writer(Vehicle/Speed) port 2

ワンショットではなく Compare To Constant >= spawnTime(HIGH のまま維持)を使用してください。車両が存在する間、速度を継続的に適用する必要があります。

車両ごとに異なるルート(動的スポーン)
<routes>
    <route id="ego_route"   edges="A0A1 A1A2 A2B2 B2C2 C2C1 C1C0"/>
    <route id="veh_1_route" edges="A1B1 B1B2 B2C2 C2C1 C1C0 C0B0"/>
    <route id="veh_2_route" edges="B0B1 B1A1 A1A2 A2B2 B2C2 C2C1"/>
</routes>
% Per Actor block: set_param(actorPath, 'routeID', sprintf('veh_%d_route', k));
スポーン後にテレポート(位置指定の回避策)

SpawnMethod='Position' は動作しないため(既知の問題を参照)、次の 2 ステップのパターンを使用します。

Step N:   Actor(Add, SpawnMethod='Lane', routeID=...) -> vehicle at edge start
Step N+1: Writer(Vehicle/Position, RouteFlag=on) with (VehId, EdgeId, int32(LaneIdx),
          X, Y, Angle, uint8(1)) -> vehicle teleports to (X,Y)

Spawn と Move の間に 1 ステップの遅延が必須です。イネーブル信号に Unit Delay を使用してください。Actor の発火から 1 ステップ後まで、SUMO 側には車両が存在しません。

移動する基準点の近くで定期的に一括スポーン
Clock -> PulseGen (persistent, fires every 5s, increments batch id)
       -> SpawnBatch (Enabled SS, Priority=1): N IDGen -> N Actor(Add)
       -> [Unit Delay z^-1]
       -> MoveBatch (Enabled SS, Priority=10): N Writer(Vehicle/Position)
Reader(Vehicle/Position) on ego feeds PosGen so batch lands at egoPos + offset.
文字列出力を持つ MATLAB Function

動的に生成される車両 ID(例:"dyn_" + string(batch) + "_1")の場合:

chart = sf.find('-isa','Stateflow.EMChart','Path',chartPath);
chart.ChartUpdate = 'DISCRETE';
chart.SampleTime = '0.1';
outData = chart.find('-isa','Stateflow.Data','Scope','Output');
outData.DataType = 'string';
outData.Props.Array.Size = '1';
安全な車両状態へのアクセス

Vehicle トピックの Reader と Writer はすべて、各ステップで Vehicle Id を参照します。車両が存在しない場合、クラッシュします。これは Reader(Vehicle/...)、Writer(Vehicle/...)、および Writer(Visualization/Track Vehicle) に適用されます。

t=0 より後にスポーンする車両は、Enabled Subsystem 内でゲートしてください。

% Clock -> Compare To Constant (>= spawnTime) -> Enabled Subsystem
% Inside: String Constant + Reader/Writer blocks

depart="0" を指定して .rou.xml で定義した自車両には、ゲートは不要です。

ランダム交通のクイックスタート
set_param([modelName '/SUMO Server'], 'EnableRandomTraffic','on', 'RandomTraffic','10');

<route-files> は不要です。ランダム車両の名前は SpawnedVehicle_1、SpawnedVehicle_2 のようになります。

既知の問題(サポートパッケージのバグ)

問題影響回避策
SUMO_HOME の末尾に区切り文字がない → 起動失敗(Windows)P0 ブロッカーsetenv('SUMO_HOME', [getenv('SUMO_HOME') filesep])
SpawnMethod='Position' は内部の moveToXY で誤った RouteFlag を渡す車両が指定位置ではなく、エッジの始点に配置されるスポーン後にテレポートするパターンを使用(Actor + Unit Delay + Writer(Vehicle/Position))

よくある間違い

間違い失敗する理由修正方法
車両がまだ存在しない状態で Reader/Writer を使用するmdlOutputs で S-function がクラッシュしますEnabled Subsystem 内で実行を制御します。自車両には depart="0" を使用します
Reader の出力を Reader の入力に接続するID List は可変長であり、Vehicle reader には単一の文字列が必要ですVehicle Id には String Constant を使用します
ClientPort != ServerPortクライアントが接続できません両方を一致させます(デフォルトは '8813')
可変ステップソルバーSUMO ではロックステップが必要です固定ステップを使用し、step-length と一致させます
Actor が繰り返し起動する「Vehicle already exists」ワンショットロジックを備えた Enabled Subsystem を使用します
遅延スポーン車両の Writer(Vehicle/Speed) が実行制御されていないt=0 でクラッシュしますClock >= spawnTime の条件で実行を制御します
Visualization Writer が毎ステップ実行されるシミュレーション時間を浪費し、車両が存在しない場合はクラッシュしますワンショットの Enabled Subsystem を使用します
ルートエントリーが depart 時刻順に並んでいない警告なしに破棄されますすべてのエントリーを depart/begin 順に並べます
<flow> 内にルートを埋め込むActor がルートを見つけられません独立した <route> 要素を定義します
自車両のルートに <stop> があり、Speed Writer も使用するSUMO の stop が Writer より優先されます<stop> を削除し、Simulink の速度プロファイルを使用します
Clock ブロックが複数ある配線が煩雑になり、すべて同じ時刻を出力しますClock を 1 つだけ使用し、すべてのコンシューマーに分岐させます
Writer の Lane Index または Keep Route に double を使用する型の不一致により拒否されますint32(laneIdx)、uint8(keepRoute) を使用します
占有されている車線にテレポートする車両が積み重なり、動けなくなります周囲の交通とは別の車線にテレポートします
sim の前に save_system を実行しない「Unapplied changes」マスクエラーが発生しますプログラムによる変更後は必ず保存します
自車両の depart="2" と t=0 の Reader を併用する車両が未定義のため、無効なデータやクラッシュが発生します自車両の depart="0" を設定します
FixedStep=1.0 で小数時刻にスポーンするソルバーが目標時刻に到達しませんFixedStep、step-length、すべての SampleTime を一致させます

規則

  • 常に、ステップサイズを SUMO の step-length およびすべてのブロックの SampleTime に合わせた固定ステップソルバーを使用します
  • プログラムによる変更後は、sim(modelName) の前に必ず save_system(modelName) を実行します
  • 常に ClientPort と ServerPort を一致させます
  • モデルルートで Clock を 1 つだけ使用し、すべての比較器/パルスジェネレーターに分岐させます
  • Actor ブロックよりも、.rou.xml で depart="0" を指定して自車両を定義する方法を優先します
  • シミュレーション途中で車両が削除されないよう、自車両に長いルートまたは循環ルートを設定します
  • 動きながらスポーンさせる車両には、実用上のデフォルトとして departSpeed='max' を使用します
  • Writer(Speed) は希望速度を設定します。車間距離の維持は SUMO が追従走行によって処理します
  • デモではペーシング(EnablePacing='on')を有効にして、GUI が瞬時に進んでしまわないようにします
  • Visualization writer(Track、Schema、Zoom)は、ワンショットの Enabled Subsystem で囲みます。これらの設定は保持されます
  • Actor ブロックは必ず Enabled/Triggered Subsystem 内に配置します
  • 動的にスポーンする車両には、それぞれ一意の ID と有効な独立ルートが必要です
  • Simulink で使用する前に SUMO CLI で .sumocfg を検証します:system(sprintf('"%s" -c "%s" --end 0.1', sumoExe, cfgFile))
  • mcp__matlab__model_edit を使用する際、Enable ポートの配線には add_line を代わりに使用します

著作権 2026 The MathWorks, Inc.


コメント