Matlab/Simulinkでシミュレータ環境を作るコツ

はじめに

この記事はMicro Mouse Advent Calendar 2020の1日目の記事になります。

このAdventCalendar(ADC)について

今年はCovid-19により、例年ですと、ちょうど全日本が実施される頃合いですが、今年は特別対応、オンラインでの開催になりました。

12/4に公式HPより「詳細告知・課題公開」の予定です。マイクロマウス2020 – All Japan Micromouse Contest 2020

さて、学生団体のように活動が規制されていない社会人たちはきっと、進化を続けていることでしょう!!!ということで、例年に漏れず、このADCを作りました。

というのは建前で、だいたいこれが理由です。

らっちくん。枠なら余裕があるよ。

本題

マイクロマウス大会のスポンサー「mathworks社」が大会出場者向けに無償提供しているソフトウェア「Matlab/Simulink」でシミュレーションを作る際のコツや使える関数などを紹介します。

Cのヘッダファイルからバスに読み込む(Simulink.importExternalCTypes)

Simulinkでバス(構造体のようなもの)を使用する際、自作バスを定義するのが面倒です。
そこで紹介するが、Simulink.importExternalCTypesです。この関数はC/C++のヘッダファイルに記載した構造体をバスとして読み込み、Simulinkで使用することができます。

以下のコードをシミュレーション前にinitファイルとして1度実行し、バス構成をワークスペースに登録しておきます。

Simulink.importExternalCTypes('../include/bus.h'); 

コード生成後は生成されたファイルと、上記のbus.hをC/C++ワークスペースにコピーしてビルドすればOKです。(インターフェースに構造体を使用したい場合など、この方法が個人的ベストプラクティスです)

enumを読み込むと、~~.mというファイルが自動生成されますが、enumの中身を変更した際は一度mファイル側を削除しないと、エラーが出たりしますが、overwriteのオプションを使用すればエラーを無視し、上書きします。

mファイルのパス情報を取得(mfilename、fileparts)

simulinkでビルドした際や、コード生成をした際は、matlabの現在のディレクトリに対し、ファイルを生成する仕様があります。(これどうにかしてほしい)

自動ビルドなどを行う際、mファイルなどに記載したコードを実行しようにも、mファイルの配置先からみた相対ファイル情報を得た方が、git管理をするときなど便利です。

mfilenameでは現在実行中のmファイルのパスを、以下のように、引数に'fullpath'と入れることで、取得できます。

script_file_full_path = mfilename('fullpath')

これだと、ファイル名まで取得できてしまうので、filepartsを使用します。 filepartsでは、引数に指定したファイルのパス、名前、拡張子を取得できます。

[filepath, name, ext] = fileparts(script_file_full_path );

コード生成コマンド(slbuild)

slbuildは引数に指定したSimulinkファイルをコンフィギュレーションファイルに沿ってビルド(コード生成)します。
ただし、先述のように、現在のディレクトリに対して、ファイルを生成します。(gitユーザには至極迷惑)
そのため、先に紹介したmfilenameやfilepartsを使用し、テンポラリーで作成したbuildフォルダに移動してから実行しましょう。.gitignoreでbuild/を追記しておけば、ビルドファイルによるgitのワークスペースの汚染は防げます。

初期値とunit_delayしたデータを切り替える

1ステップ目の初期状態と、シミュレーション結果を切り替えたい。そんな場合に、clockブロックを使用しています。
clock>0ならシミュレーション結果の座標を使用しています。

csv読み込み

私のマウスでは走行ログをCSV形式でprintfしてダンプしてます。
以前まではexcelでグラフを描画していましたが、simulinkFrom Spradsheetを使用すると便利です。
1列目にtime_indexとして時系列情報を書き込む(行番号でOK)必要があるのですが、それ以外は特に制約なく利用できます。

f:id:nao1288stusj:20201130212640p:plain

「適用」を推すとブロックから各出力が表示されますので、あとはscopeなどで描画して確認します。 f:id:nao1288stusj:20201130212834p:plain

まとめ

Matlab/SimulinkでMBDをやるんだ!」といっても、それ以前にソフト作りのしやすくするために、スクリプトを整えなくては宝の持ち腐れです。(そういう系の共有がMatlab/Simulinkは商用ユーザばかりでなさすぎる気がする)

やってることが、shell芸につながるアレコレだったり、自動化系じゃないかって?(本職でjenkinsおじさんしているので仕方ない)

おわりに

明日の担当は「ジャッジー君」です。(あ。twitterフォローしてない。これではトスができない。)