1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SimulinkからRoadRunner上の車を動かす

1
Last updated at Posted at 2026-07-02

RoadRunnerとSimulinkを連携させる最初の一歩として今回は、

  • Simulinkで二輪モデルを動かす
  • x, y, yaw を出す
  • その結果でRoadRunner上の車両を動かす

ところまでをまとめました。

1. 導入

RoadRunnerは、道路や交差点などの静的なシーンを作り、その上で車両などの動的要素を含むシナリオを設計してシミュレーションできるツールです。

Simulinkとつなぐと、制御モデルや車両モデルの計算結果を、そのまま3Dで確認できます。

この記事では最小限の要素を紹介しますが、RoadRunnerについて詳しく知りたい場合は、以下のセミナー動画がおすすめです。

2. 今回やること

こんな感じで、RoadRunnerのコース上をSimulinkで構築した二輪モデルの車で走らせます。

Results.gif

前提はこんな二輪モデルです。

  • 重心の前後位置を変えることで、
    オーバーステア(OS) / ニュートラルステア(NS) / アンダーステア(US)
    を切り替えられる
  • 車速をスライダーで変更できる
  • NS時の旋回半径は 57.3 m

RoadRunnerに渡しているのは、車の位置と姿勢です。

環境:MATLAB R2026a
必要なToolbox:Simulink, Automated Driving Toolbox, RoadRunner, RoadRunner Scenario


3. RoadRunner環境の構築

3-1. まずは Project を作る

RoadRunnerを起動して、"New Project"からシーンを作りましょう。
Project NameもPathも任意で大丈夫です。今回はAssetsは"Base"で作ります。

※"Base+Add On"で作ると日本の標識や信号機、ビルなどのアセットがすぐ使えるよう追加されたプロジェクトが作成されます

この後の画面では、右側にある”New Scene"をクリックしてください。

3-2. 円形コースを作る

今回は NS 時の旋回半径が 57.3 m なので、それを基準にします。
左上にある円形のボタンをクリックすると、円形コースを作成できます。

右クリック&ドラッグして適当な大きさの円形コースを作り、右側に出てくるAttributesのRadiusを57.3mにしましょう。

次に車線を増やしていきます。1行目右側のほうにある「車線+」と書かれたボタンをクリックし、増やしたい車線を右クリックすると車線が増えていきます。
image.png

一番外側/内側の線をクリックすると歩道が増えてしまうので、車線を右クリックするようにしましょう。
下図の場合、矢印が指しているのが車線です。
image.png

外側/内側ともに4車線ずつ増やすとこういう道路ができます。

3-4. Scenario で車を配置する

シーンができたら Scenario Editing に切り替えて、車両アクターを置きます。
右上の"SCENE EDITING"をクリックすると、SCENARIO EDITINGに切り替えるメニューが出てきます。
※切り替える前に、File -> Save Sceneでシーンを保存しましょう。

image.png

RoadRunner Scenario では、車両はアクターとして配置され、経路やロジックを持たせてシミュレーションできます。

今回は Simulink 側で姿勢を更新するので、RoadRunner 側は「見せる側」と割り切ってOKです。
下のほうに表示されている"Library Brouser"にある"Sedan"をコースの下のほうに配置します。


4. Simulink側構成

全体像:
スクリーンショット 2026-07-02 104745.png
※ブロック名を表示しているので、構築される場合はクリックして画像を拡大してご確認ください。

4-1. 二輪モデル

赤枠の部分が二輪モデルです。
image.png

旋回半径の公式を基本的なSimulinkブロックで構成しています。
$$\rho=\left(1-\frac{m}{2l^2}\frac{l_fK_f-l_rK_r}{K_fK_r}V^2\right)\frac{l}{\delta_0}$$

  • $\rho$ : 旋回半径 [m]
  • $m$ : 車両質量 [kg]
  • $l$ : ホイールベース [m]
  • $l_f$ : 重心から前輪までの距離 [m]
  • $l_r$ : 重心から後輪までの距離 [m]
  • $V$ : 車速 [m/s]
  • $\delta_0$ : 操舵角 [rad]
  • $K_f$ : 前輪コーナリングパワー [N/rad]
  • $K_r$ : 後輪コーナリングパワー [N/rad]

パラメータはえいやで以下のように設定しました。

Kf = 30e3; % 前輪コーナリングパワー [N/rad]
Kr = 30e3; % 後輪コーナリングパワー [N/rad]

lf = 1.4; % フロントタイヤと重心の距離 [m]
l = 3.0; % ホイールベース [m]

m = 2000; % 車両重量

Ts = 0.01; % シミュレーション実行ステップ

StGr = 15; % ステアリングギア比

上にあるスライダーで速度を、ラジオボタンでフロントタイヤと重心の距離($l_f$)を変更できます。

4-2. RoadRunnerとの接続に使うブロック

SimulinkモデルとRoadRunnerの接続はこんなイメージです。

image.png

今回SimulinkとRoadRunnerの接続に使う主役はこの3つのブロックです。

モデル全体でみると上記のブロックはここにあるものです。
image.png

4-2-1. RoadRunner Scenario blockの設定

"RoadRunner Scenario"ブロックをモデルのトップ階層に配置し、ダブルクリックすると以下の設定画面が出てきます。

※"Scenario"タブのこの設定画面はMATLAB R2026a以降で実装されています。

まず"RoadRunnerの設定"ボタンをクリックし、作成したRoadRunner Projectのフォルダ(Assetsフォルダなどがある階層)を選びましょう。
インストールフォルダーのほうは、RoadRunnerがインストールされているフォルダを選んでください。

image.png

4-2-2. RoadRunner Scenario Reader/Writer blockの設定

今回は"アクターの姿勢" を使って 4x4 pose 行列とx,y,z速度を渡す前提にします。
Read/Writeブロックを以下の設定にします。

image.png

Tsは実行周期です。どのくらい細かくシミュレーションできるかはPCのスペックにも依存するので、やりたいことと自分のPCに合わせて設定してください。
私の場合は0.01(s)で設定しました。

4-2-3. Message Receive/Sendブロックの配置

RoadRunnerとSimulink間のメッセージやり取りには、Message Receive/Sendブロックを介する必要があります。

image.png

こんな感じでReaderの後にReceiveを、Writerの前にSendブロックを置きましょう。

4-3. x,y,yawの計算

全体の中だと、赤枠の部分にあたります。
image.png

中身は以下のようになっていて、二輪モデルから得られる車速 v と旋回半径 R を使って、車両の向き yaw と位置 x, y を計算しています。

image.png

まず、車両が半径 R の円弧に沿って速度 v で走行していると考えると、Yaw角の変化率(ヨーレート)は次のように表せます。
$$
\dot{\psi} = \frac{v}{R}
$$

ここで、$\psi$ は車両の向き、つまりヨー(yaw)です。
Simulinkモデルでは、vR で割った値を積分することで、yaw を求めています。

$$
\psi = yaw = \int \frac{v}{R} dt
$$

次に、車両は現在の yaw の向きに進むため、車速 vx 方向と y 方向に分解します。
$$
x_{speed} = v \cos(\psi)
$$

$$
y_{speed} = v \sin(\psi)
$$

最後に、x_speedy_speed をそれぞれ積分することで、車両の位置 x, y を求めます。

$$
x = \int x_{speed} dt
$$

$$
y = \int y_{speed} dt
$$

4-4. Pose, Velocityの計算

全体の中だと、赤枠の部分にあたります。
image.png

このブロックでは、前段で計算した車両の位置 x, y、向き yaw、速度 x_speed, y_speed を使って、RoadRunner Scenario Writer に渡すための PoseVelocity を作成しています。
中身は以下のようになっています。
image.png

4-4-1. 初期位置の設定

上記の図の水色の値 (x_init, y_init) は、RoadRunner上に配置した車両の初期位置です。
RoadRunner Scenarioで車両をクリックし、右側に出てくるメニューで"Enable Anchoring"のチェックを外すと確認できます。

Simulink側では、前段のブロックで車両の移動量として x, y を計算しています。そのため、RoadRunner上の実際の位置として使うために、初期位置を足しています。
この x, y と yaw を使って、以下のMATLAB Functionで4×4のPose行列を作成します。

4-4-2. Poseの計算

RoadRunner の actor pose は、MATLAB / Simulink とやり取りするとき 4x4 の実数 pose 行列で表されます。Pose 行列は、回転成分と平行移動成分を持つ線形変換行列です。

なので、x, y, yaw をそのまま1本ずつ送るのではなく、

  • 回転
  • 平行移動

をまとめた形にする必要があります。
2次元平面で yaw だけを使うなら、回転行列はこれです。

R =
\begin{bmatrix}
\cos(\psi_{RR}) & -\sin(\psi_{RR}) & 0 \\
\sin(\psi_{RR}) & \cos(\psi_{RR})  & 0 \\
0               & 0                & 1
\end{bmatrix}

これを使って、4x4 pose 行列を作ります。

T =
\begin{bmatrix}
R_{11} & R_{12} & R_{13} & x \\
R_{21} & R_{22} & R_{23} & y \\
R_{31} & R_{32} & R_{33} & z \\
0      & 0      & 0      & 1
\end{bmatrix}

RoadRunner の pose 行列は、上 3x3 が回転成分、右端列の最初の 3 要素が平行移動成分です。
難しく見えますが、やっていることはシンプルです。

  • 車がどこにいるか
  • 車の鼻先がどちらを向いているか

を、RoadRunner が理解できる形にまとめているだけです。
位置と姿勢を1つの行列で渡している、と理解すると整理しやすいです。

image.png

赤枠の位置にある、Poseを求めるMATLAB Functionの中身は以下です。

function currPose = generatePose(x,y,yaw)

rotm = eul2rotm([yaw-pi/2 0 0], "ZYX");
currPose = [[rotm [x y 0]']; [0 0 0 1]];

Pose行列を作成する部分では、次のように yaw から pi/2 を引いています。

rotm = eul2rotm([yaw-pi/2 0 0], "ZYX");

これは、Simulink側で計算している座標系と、RoadRunner側の座標系で、yaw = 0 のときの車両の向きが異なるためです。

Simulink側では、yaw = 0 のときに車両が +X 方向を向くものとして扱っています。
一方で、RoadRunnerの座標系では、yaw = 0 となる向きが +Y 方向です。つまり、RoadRunnerでは回転角が0のとき、車両は +Y 方向を向くものとして扱われます。
そのまま yaw を渡すと、RoadRunner上で車両の向きが90度ずれて表示されるため、90度(-pi/2)引いています。

座標系と pose matrix の説明は、公式の pose matrix ページが一番分かりやすいです。
What Is a RoadRunner Pose Matrix?

Pose行列は以下の計算で求めています。

currPose = [[rotm [x y 0]']; [0 0 0 1]];
  • rotm:車両の向きを表す回転行列
  • [x y 0]':車両の位置
  • 最後の行 [0 0 0 1]:4×4の同次変換行列にするための行

ここでは車両を平面上で動かしているため、Z方向の位置は 0 としています。

4-4-3. Velocityの作成

RoadRunnerには、車両の位置と向きだけでなく、速度も渡します。
このモデルでは、前段で計算した x_speedy_speed をMuxでまとめ、Z方向の速度として 0 を追加しています。
image.png

これにより、RoadRunner側では、Simulinkで計算した車両の速度を使ってアクターの状態を更新できます。

4-4-4. VehicleRuntimeへの反映

RoadRunner Scenario Readerから受け取った VehicleRuntime には、現在のアクターの状態が含まれています。
このブロックでは、その中の PoseVelocity を、Simulinkで計算した値に置き換えています。

image.png

  • Pose:Simulinkで計算した位置と向き
  • Velocity:Simulinkで計算した速度

こうして更新した情報をRoadRunner Scenario Writerに送ることで、Simulinkで計算した車両運動をRoadRunner上の車両アクターに反映しています。


5. まとめ

Simulinkで計算した位置と姿勢を、RoadRunnerに毎ステップ渡してRoadRunner上の車両をSimulinkの計算結果で動かしました。

やることを分解すると、以下でした。

  1. 二輪モデルで x, y, yaw,x_speed,y_speed を出す
  2. yaw を RoadRunner 用に -pi/2 補正する
  3. 補正後の x, y,yaw からpose行列を作る
  4. x_speed,y_speedからVelocityを作る
  5. Scenario Writer で RoadRunner に渡す

RoadRunner 連携は難しそうに思っていましたが、最初の壁はだいたい

  • シーンとシナリオの違い
  • Reader / Writer の役割
  • pose 行列
  • Simulink と RoadRunner の座標系の違い

このあたりのようです。

補足

今回は「定常円旋回」の軌跡を描画することを目的とした、シンプルなSimulinkモデルをベースに、RoadRunnerとの接続について記載しました。

そのため、車両運動モデルとしては定常状態を前提とした構成になっていますが、今後は状態方程式を用いて過渡応答まで扱える構成への拡張も試してみたいと思います:muscle:

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?