Matlab/Simulinkでシミュレータ環境を作るコツ
はじめに
この記事はMicro Mouse Advent Calendar 2020の1日目の記事になります。
このAdventCalendar(ADC)について
今年はCovid-19により、例年ですと、ちょうど全日本が実施される頃合いですが、今年は特別対応、オンラインでの開催になりました。
12/4に公式HPより「詳細告知・課題公開」の予定です。マイクロマウス2020 – All Japan Micromouse Contest 2020
さて、学生団体のように活動が規制されていない社会人たちはきっと、進化を続けていることでしょう!!!ということで、例年に漏れず、このADCを作りました。
というのは建前で、だいたいこれが理由です。
今年のadvent calendar
— らっち (@hiiragium1) 2020年11月28日
誰か作って誰か書いて
僕読みたいから
らっちくん。枠なら余裕があるよ。
本題
マイクロマウス大会のスポンサー「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でグラフを描画していましたが、simulinkのFrom Spradsheet
を使用すると便利です。
1列目にtime_indexとして時系列情報を書き込む(行番号でOK)必要があるのですが、それ以外は特に制約なく利用できます。
「適用」を推すとブロックから各出力が表示されますので、あとはscopeなどで描画して確認します。
まとめ
「Matlab/SimulinkでMBDをやるんだ!」といっても、それ以前にソフト作りのしやすくするために、スクリプトを整えなくては宝の持ち腐れです。(そういう系の共有がMatlab/Simulinkは商用ユーザばかりでなさすぎる気がする)
やってることが、shell芸につながるアレコレだったり、自動化系じゃないかって?(本職でjenkinsおじさんしているので仕方ない)