電子工作にモデルベース開発(Model Based Development: MBD)を適用してみた【コントローラモデル編】

# はじめに

モデルベース開発(Model Based Developmentの頭文字をとって以下、MBDと略)は、航空宇宙分野や自動車業界で近年、急速に普及している製品開発手法です。
その名前の響きと適用産業分野(製品)から、なんだかとっても崇高でムズカシイものだと思ってしまうかも知れませんが、今回は**プラレールの魔改造**(速度コントロール)にMBDを取り入れてみて、電子工作を通してMBDのうま味について解説していきたいと思います。


# 実際の成果物
こんなものを作ってみました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">甥のプラレールを奪って魔改造を施す計画。まだまだ詰めの部分はあるけど、なんとかクリスマスに間に合いそう！<br>いやしかし、ムダにホンモノの電車っぽいコントローラ挙動にしてしまったから、小学生にはちと操作ムズいか・・・？ <a href="https://t.co/yN2zZaEtXH">pic.twitter.com/yN2zZaEtXH</a></p>&mdash; わたなべ (@mana_544) <a href="https://twitter.com/mana_544/status/1206195741858729984?ref_src=twsrc%5Etfw">December 15, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

5段階(力行2、力行1、惰行、ブレーキ1、ブレーキ2)の加減速度コントロールにより、速度(モータ印加電圧)を調整しています。
今回は、この速度コントロールプログラムをMBD(コントローラモデル)で作りました。

# MBDとは？
MBDとは、マイコンを搭載した製品開発において、 **実機で評価をする前に「モデル」を作ってシミュレーションで事前検討をする** という、開発手法のことを言います。[^2]

これだけだとなんのこっちゃ？だと思いますので、もう少し詳しく説明します。
まず、マイコンを搭載した製品を構成する“要素”をブロックで表すと、ふつうはこんな感じになります。
![マイコンを搭載した製品を構成する“要素”](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448922/5d3cb55e-ea0e-1c78-fceb-c26f121998c3.png)

そして、この構成で「モノを作ろう！」となったときに、作り方(開発方法)としては「実機(試作機)にマイコンを載せ、ソフトを書き込んで**実際に動かして実験・評価する**」というのが一般的ですが、このやり方にはいくつかの問題(宿命)があります。

### 【問題1】プログラムの動作確認をしたいだけなのに、回路(ハード)を用意しないといけない
これは当然といえば当然なのですが、プログラムのロジックがちゃんと意図した仕様通りになるかどうかを見たいときだけでも、わざわざブレッドボードにマイコンその他の周辺回路をぷすぷす挿さなければなりません(ソフトだけで動かせない)。実機を使ってのフィードバックコントロールだったらなおのことだけれど、そうではないシーケンス的な(オープンループ)プログラムであったとしても、実物にいちいち書き込まないとプログラム検証すらできないというのは地味にメンドい。

### 【問題2】何かエラーが起きた時の原因特定(デバッグ)がツラい
これはマイコンを使った電子工作をやられた方ならば誰しも経験があるかと思いますが、何かエラーが起きた時にマイコンプログラム(ソフトウェア)が悪いのか、あるは回路や部品(ハードウェア)が悪いのかを切り分けるのだけでも一苦労です。

### 【問題3】実機の試験はお金と危険が伴う
趣味の電子工作レベルだとあまりピンとこないかもしれませんが、パワーエレクトロニクス(重電)、自動車、飛行機、ロケットなど、ものすごく巨大なエネルギーを扱う製品の開発には、とても危険が伴います。また、試験機自体も大型になったり、使う燃料代もバカにはできなかったり、試験中いつ起こるかわからない危険な状態を回避するための施設(設備)を作ったりで、とにかく実機の試験はお金がめちゃくちゃかかるのです。

こんなかんじでつらつらと問題をあげてみましたが、これらの問題について **実機を動かす(作る)前に、“モデル”でシミュレーションして評価しようぜ！** というのが、基本的なMBDの発想になります。

# MBDの「モデル」の種類
ここで、MBDで登場する「モデル」という概念には、大きく分けて以下2種類あります。

1. コントローラモデル
1. プラントモデル

**「コントローラモデル」**は、対象物を動かすコントローラ(マイコン)に書き込むプログラムそのものをモデルとして作ること。**「プラントモデル」**は、対象物そのものをモデルとして作ることを言います。
![“コントローラモデル”と“プラントモデル”の分け](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448922/df18c660-625b-9379-8c0b-ec9d1b6a7d62.png)

「コントローラモデル」「プラントモデル」両方とも作れば、さきほどの3つの問題にすべてアプローチできますが、実は「コントローラモデル」を作るだけでも問題1と問題2の一部(プログラムのどこが悪いのか)は十分に検証可能です。したがって、電子工作においては**「コントローラモデル」だけ作るのでも十分なうま味が得られます**ので、今回は実際に「コントローラモデル」を作ってMBDのうま味について解説していきたいと思います。

プラントモデル編は・・・なんか良い題材が見つかったらやります。 [^1] 


* 2020/02/03 追記  
プラントモデル編も書きました。併せてご覧下さい。  
[電子工作にモデルベース開発(Model Based Development: MBD)を適用してみた【プラントモデル編】](https://qiita.com/mana_544/items/71c0024c3229dd9bacc6)


# プラレールのスピードコントロールシステム
こんな感じのシステムを考えました。
![システム概要構成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448922/1e340960-9536-db0e-332d-43d66ae16064.png)


* マイコンはArduino(厳密にはArduino Pro Mini)
    * Inputはマスコンから送られてた電圧
    * Outputはモータードライバーへの制御電圧
* 無線モジュールは[TWELITE](https://mono-wireless.com/jp/products/TWE-LITE/index.html) をそのまま書き換えずに利用(なんて便利なんだ！)
* マスコンがわりのコントローラ
    * 5段階ロータリーSWで再現(力行2段階、惰行、減速2段階)
    * 分圧回路で電源電圧(3V)を5段階にして、無線モジュール経由でArduino(Analog Input)に投げる

ですので、作りたいプログラム(コントローラモデル)はこんな感じです。
![コントローラモデル概要構成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448922/4a9e7527-5451-388e-9e8f-bb6633093129.png)

* ロータリーSW電圧から加減速モード(Power2, Power1, Neutral, Brake1, Brake2)の決定
* 加減速モードに応じたモーター印加電圧(加減速度)の決定
* 停車からの加速は、静止摩擦に打ち勝つためにオフセット電圧＋インパルス的な補正電圧を与える

各信号は下記のような感じのイメージを想定しています。
![信号タイミングチャートポンチ絵](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448922/57cdffec-2962-34ea-ea33-7f45219af3a4.png)


このようにスピード(モーター印加電圧)を調整するようなプログラムをモデルで書いていきます。


# モデル構築ツール
さて、コントローラモデルを書くツールですが、MBD業界ではもっぱら**MATLAB/Simulink**がデファクトスタンダードです。というか、コントローラモデルにおいては事実上これ一択です。[^7]
[Webサイト](https://jp.mathworks.com/products/simulink.html)を見てみても、個人を寄せ付けないビジネス向け商用ツール独特のオーラがみなぎっていて、さぞかし個人で買うには高いんでしょう？**・・・とお思いの方、ご安心ください。** 個人(趣味)用途のライセンスなら[4回ぐらい飲み会をガマンすれば手が届く値段](https://jp.mathworks.com/products/matlab-home.html)で買えます。[^3]
電子工作でArduinoスケッチを書き込んで、実際に動かしてみたらうまく動かなくて、「う～ん、やっぱ●クトロニクスのロジアナがないとなぁ・・・」なんて言ってる人は、まずはMATLAB/Simulinkを買って机上シミュレーションすることを検討してみる価値はあると思います。

# プログラムロジックをモデルとして構築していく
さっそく、Simulinkでスピードコントロールプログラム(モデル)を書いていきます。下記はプラレールコントロールモデルの全体図です。
![コントローラモデル全体](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448922/67db4f33-500a-ebaa-d842-45bde0223d38.png)


C言語を始めとするテキストベースのプログラミング言語しかやったことのない人にとっては、Simulinkのようなビジュアルプログラミングはとっつきにくいかと思いますが、そこは、、、がんばってください(投げやり)。
ここでは、さらに「モーター印加電圧算出」ブロック内のロジック部分の例を示します。
![モーター印加電圧算出ブロック](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448922/bdf0d34b-a34c-ad0d-4028-123c71e7fce8.png)

こんな感じて、「if-else」的なロジカル要素をSimulinkブロックで描いていくのですが、Simulinkはいろいろなブロックがあるので、それこそいろんな書き方でロジックの表現ができてしまいます。
たとえば、“if-elseの条件構文”一つとっても、Simulinkだと[こんな感じで複数パターンで表現できてしまいます。](https://jp.mathworks.com/help/simulink/mdl_gd/maab/db_0114simulinkpatternsforifthenelseifconstructs.html)
これは表現にとっても柔軟性がある一方で、それが却ってモデル可読性を損なうことがありますので、自分の中で「こう書くんだ」というルール(ガイドライン)を定めるといいです。といっても、やっていかないとわからないと思いますので、やってみてください(投げやり)。[^8]


# シミュレーションをしてみる
モデル(プログラムロジック)を構築したら、MBD最大のうま味、シミュレーションをしてみましょう。
今回はプラントモデルを構築していないので、インプットとして「ロータリースイッチのポジション(電圧)」をソースブロック(SignalBuilder)で模擬して作り、「モーターへの指示印加電圧(スピード)」をScopeブロックで見てみることにします。[^4]
<img width="560" alt="シミュレーション結果" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448922/021edb18-f521-c72c-0163-6fa5a59c1c79.png">

おっけーい、発進補正がうまく動いたぜ！:ok_hand:
最初に描いたイメージ図タイミングチャートと同じ挙動になることが確認できましたね！

このように、**シミュレーションを回して検証確認して、ロジック(プログラム)のおかしな挙動はすぐさまモデルを修正できる** これこそがMBDのうま味で、電子工作にも十分威力を発揮できます！

# モデル→Arduinoスケッチ(プログラム)への変換とArduinoへの書き込み
シミュレーションで期待通りのプログラム挙動が確認できたら、このモデルをArduinoへ書き込みたいのですが、[Simulink Support Package for Arduino](https://jp.mathworks.com/hardware-support/arduino-simulink.html)というアドオン(無料)を追加してインストール&初期設定していれば、ボタン一発で「モデルからArduinoスケッチへの変換 [^5] 」「コンパイル&ビルド」「Arduinoへの転送」をやってくれます。[^9]

**モデルでシミュレーションしてプログラムの挙動はバッチリ**なので [^6] 、これでマイコンに書き込んで動かなかったらハードが原因の可能性が高いということがすぐにわかって安心ですね！
このプラレールも案の定動かなくて、原因ははんだづけが甘くてGNDが浮いてたというオチもつけときます。

# さいごに
MBDのうま味、伝わりましたでしょうか？
今回は “モデルベース開発” というちょっととっつきづらいモノに対して、電子工作に適用することでなんとかうま味を身近に感じて頂けるように記事を書きました。ですので、中身の技術的な部分(プラレール自体の改造内容)については、大幅カットしてしまいました。
プラレールに盛り込んだ機能としては、スピードコントロール以外にも

* モーター印加電圧値を無線で送り返して手元(コントローラ)の速度計に表示
* プラレール側のバッテリー電圧が低下したらLEDでお知らせする
* 特定のコマンド入力をすると、バックモードに入る(ハードを固めた後にバックのことを思いついてしまったので、SWなどのハードを追加せずにプログラムだけでなんとかした)

あたりを盛り込んでいますので、要望があればプラレール魔改造の内容についても書こうと思います。


[^2]: MBDは「Model Based **Development** (モデルベース**開発**)」と「Model Based **Design** (モデルベース**設計**)」という2つの表記ゆれが見られます。この記事では「モデルベース開発」に統一しましたが、どちらでも意味はほぼ同じように使われています。(「モデルベース設計」のほうがコントローラモデリングに重きを置いて、制御設計手法にフォーカスしたニュアンス、「モデルベース開発」のほうがプラントモデリングにも重きを置いて、開発全体を含んだニュアンスといったところでしょうか) また、MBDと似たような概念に「MDD」「MBSE」「MBC」というものもありますが、これらはMBDとは似て非なるものです。MDD(Model Driven Development: モデル駆動開発)は、ソフトウェア要件や仕様などを従来の自然言語ベースのドキュメント(WordやExcel)からモデル化(UML)して表現しましょうというもので、MBSE(Model Based Systems Engineering: モデルベースシステムズエンジニアリング)は、MDDやMBDの概念をさらに抽象化して「製品の企画(作りたいモノ・コトを“システム”として捉え、何を作りたくて、どう作るか？をモデル(SysML)化)」にまで発展させたもので、MBC(Model Based Calibration: モデルベース適合)は、マイコンプログラムの適合値(実験から決める定数)を、実験計画法などの最適化手法で計測対象点を絞り込み、統計モデルを作って最適な制御点を見つける(適合する)手法のことをいいます。

[^1]: 今回のプラレール速度コントロールは、センサを搭載しておらず、フィードバック制御系のロジックを入れていません。なので、今回の題材ではプラントモデルも使ったMBDのうま味を語るにはちと役不足という面もあります。プラントモデル編をどうせやるんだったら、昨今MBD業界で流行り(?)の「物理モデリング&マルチドメインシミュレーション(Dymola, Amesim, MapleSim, Simscapeあたり)」を取り入れたCo-Simあたりを考えていますが、なかなかお手軽電子工作レベルでマルチドメインのものって無いしなー。

[^3]: 今回この記事で紹介した内容は、MATLABとSimulinkの2つあればOKです。ほかにもタイヘン魅力的なToolboxが並んでいますが、その沼にハマると飲み会4回じゃ済まなくなります。

[^4]: これを「オープンループシミュレーション」といったりします。コントローラモデルのみの構築だと必然的にオープンループシミュレーションになります。ですから、PIDなどのフィードバック制御プログラム設計には使えません。対してプラントモデルもつくると、コントローラモデルと相互に作用し合う「(クローズド)ループシミュレーション」をすることができます。このクローズドループシミュレーションにはさらに、モデルをどうやってシミュレートするかに応じて更に細分化されて呼ばれていたりします。例えば、コントローラーモデルをSimulinkモデルのままシミュレーションするか(MILS: Model in the Loop Simulation)、Simulinkモデルからマイコン(ターゲットハードウェア)に書き込んで、マイコンとプラントモデル(リアルタイム処理できる専用の装置)とつなげてシミュレーションするか(HILS: Hardware in the Loop Simulation)などがあります。また、プラントモデルを作らずに、実機とコントローラモデル(Simulinkモデルを動かすことができる専用の装置)を直接つないで、Simulinkモデルそのままで実機を動かす(RCP: Rapid Control Prototyping)なんてものもあり、実際の開発現場はニーズに応じてさまざまな手法が存在します。

[^5]: Simulinkモデル(コントローラモデル)からマイコンに合わせてソースコードを自動的に生成してくれる技術を「自動コード生成(Automatic Code Generation)」といい、MBD(コントローラモデル)の中核技術となります。本当はMATLAB CoderとSimulink Coder(場合によってはEmbedded Coder)というToolbox(いずれもHomeライセンスでは利用不可)がないと自動コード生成できませんが、ArduinoとRaspberry Pi については、MATLABとSimulinkだけで自動コード生成が利用できます。

[^6]: 「バッチリ」なんて書きましたが、この “モデルの挙動と生成するソースコードの挙動をバッチリ一致させる” ことが自動コード生成技術のいちばんムズいトコロであり、ものすごい技術が詰まってる部分でもあります。

[^7]: この理由については、筆者の推測ですが「自動コード生成(Automatic Code Generation)」技術が、他ツールの追従を許さないレベルまで達していることが大きいと思います。(TargetLinkなど強力なサードパーティツールも相まって、コントローラモデリングツールにおけるMATLAB/Simulinkのプレゼンスを高めています)

[^8]: Simulinkのコントローラモデルの書き方にはいろいろな流派(ガイドライン)が存在します。特に、ワタシが身を置いている世界(自動車の量産開発)は、コード品質(自動コード生成の解釈性・トレーサビリティ・処理負荷など)を保つためにツールベンダーのガイドライン、自社ルール、ECUサプライヤールールなどがいろいろからまり、細かいレベルでものすごい制約になっています。まー趣味の電子工作レベルではそんなに気にする必要は無いと思います。自分が読みやすく作れればそれでOKです。いちおう参考までに[MathWorksが提供しているモデリングガイドライン](https://jp.mathworks.com/help/simulink/modeling-guidelines.html)を貼っておきます。

[^9]: [MathWorksの公式ドキュメントにLチカの例](https://jp.mathworks.com/help/supportpkg/arduino/ref/communicating-with-arduino-hardware.html)とか載っていて、これをやればひととおりSimulinkの設定からArduinoへの書き込みはできるようになります。