パワエレ系のモデルをSimulinkで動かすときに気をつけてること

# これはなに？
パワエレ系のモデルをSimulinkやSimscapeで動かすときに個人的に気をつけてることをまとめてみました！
これが最強な方法！かは正直わからん！でも役に立つかもしれないので書いていくぜ!


## みんなはPWMどうやってつくってますか～？
この記事を見てくれている大小のお友達～
PWM波形をモデル上で表現したいですか～？

・・・・

ウンウン！したいよね！わかる。

じゃあやってみようか！

## やってみた

おっここにいい感じのサンプルがあるじゃねぇか。

https://github.com/mathworks/adc-synchronized-with-pwm

なるほどこういう感じのハーフブリッジをSimscape Electricalで定義してるのね。それを動かして。。。。？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331637/32c6fcd7-18dd-e9d1-49d8-bc6f2441707f.png)


おお！グラフの一番下にPWM作るときのキャリアと基準信号が重ねて表示されてるね！
こういう感じのキャリアでPWMだして電流制御してるのね！？
しかもキャリアに同期してADCしとるのか！なるほどね！うんうん！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331637/671a0fcc-9660-a8dc-54ed-442aa0421615.png)

早速GitHubからデータ持ってきて動かしてみるぜ！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331637/fb4cd5f2-a837-12f0-de78-59f997de0346.png)
・・・・あれ。
TimerCounter・・・・がキャリア波形だよな・・・
なんなんこれ、真っ平らやん・・・全然動いてない気がするんだけど・・・？

えっこれ本当に同じモデル？

## どうしてこうなるんだろう

わざとソルバの設定を変えたからです。

### 可変ステップソルバってなにやってんの
そもそもこの可変ステップソルバっつーやつはどういうふうに動いてるかというと、
「シミュレーション実効途中にシミュレーションタイムステップ変えやがる」
のだ。

https://jp.mathworks.com/help/simulink/ug/variable-step-solvers-in-simulink-1.html#f11-37717


「はぁああ！？？勝手に変えるなよ！？」と思うが、
むしろ勝手に変えてくれたほうがいいこともある。
シミュレーションステップが細かすぎるとそれはシミュレーション時間がすんごいかかるということだ。
これは時間という概念に基づく自然の摂理でありどうにもならない。
一方でシミュレーションステップを荒くすると、連続で動作する実際の物理現象等の乖離がでかくなってくるので
シミュレーションの誤差は増大してしまう。


・・・・そこで
「じゃあ、この”誤差”をどこまでなら許せるという許容値をきめといて、それを超えない限りシミュレーションステップを荒くすれば良いのでは？」
というコンセプトが可変ステップソルバっていうふうに考えている。あくまでこれは概念的なコンセプトであり細かいところは違うかもしれないけど大体はこんな感じでいいだろう。

ただ、Simulinkのソルバ設定にも誤差とか書いてるので、あながち大外れはしてないのだと思っている。
![Snag_76f241.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331637/abfcd3af-6267-4af3-fc56-75f736083e9a.png)

この相対誤差と相対誤差、ここでかかれた規定誤差範囲内であればステップを荒くしてくれてる。
ステップ幅の最大値と最小値も規定できる。

つまり、誤差範囲という目的変数に基づいてステップ幅を常に最適化してくれるので、
言い方悪いが「無駄に」タイムステップこまかく切っていた固定ステップソルバと違って、
誤差と計算時間を両立できる可能性があるというものだ。

### 今回どうなってるか
注目したいのが「誤差」だ。
シミュレーションソルバは意志を持たないため、シミュレーションの中に存在するすべての値をすべからく同じ誤差という基準でチェックし、誤差範囲に収まっていると判断したらどんどんステップ幅をぶっ飛ばす。

一方キャリア波形はそういう「数値計算の誤差」って基準で評価されるわけではないのが
ちょっとこまったところだ。
一見ある値を言ったり来たりしているだけなので値としては
規定誤差を超えない限り無限にタイムステップとばしてもいいように見える。
ただ、これは値の精度というより、基準値、リファレンスとの比較をする際の誤差がPWM精度において重要であるためちょっと汎用ソルバーとして「数値計算の誤差」だけで判断されると困るわけだ。

なので多分、先程の結果が得られたのだと思う。多分。なかなか私でもソルバーが細かくみるとどうなってんのかまではわかりようがないが、おそらくそうだ。

# どうすりゃいいの
PWMの分解能をどれだけにしたいという意志があれば、最大ステップ幅を設定するのが一つの手だろう。
誤差に依存せず時間幅に縛りを与えるのだ。

ただ、最大ステップサイズを小さい時間幅に設定しすぎると
正直固定ステップソルバと何も変わらんくなる。普通に遅い。可変ステップソルバ使ってる意味がない。
「最悪ここぐらいまで荒くしていい」という値にするべきだろう。


また、ソルバを変更することで改善される可能性もある。

どのケースでもおすすめ！という形は一概には紹介することは難しいが、MathWorksヘルプドキュメントに書いている「陰的ソルバー」という中から選ぶのがいいと思う。

このヘルプにあるStiffな問題というのは具体的になにかというのを定義するのは難しいが、MATLAB Answerにも解説がある。

■ヘルプドキュメント

https://jp.mathworks.com/help/simulink/ug/variable-step-solvers-in-simulink-1.html#bsc6i5t

■MATLAB Answers

https://jp.mathworks.com/matlabcentral/answers/787844-

コンバータ系のアプリケーションでよくあるStiffな例はPFC(力率改善回路）だ。

■PFC回路（ローム様Webページ）

https://techweb.rohm.co.jp/product/power-device/si/si-basic/7389/

これは系統周波数である50Hz,60Hzの比較的ゆっくりな周期の動きと、コンバータがスイッチングする100kHz前後のスイッチ切り替えの動きが一つのモデルに混在することになる。このようにタイムレンジの幅が広い要素が1つのモデルに混在するモデルはPFC以外のアプリケーションであっても「Stiffなモデル」といって陰的ソルバーの利用が推奨される。

さて、モデルに対して最適なソルバ設定を議論すると永遠に話が終わらないので、Buckコンバーターを例にして設定を色々やってみた結果を示して本記事は終わろうと思う。

## ode15s + 最大ステップ幅 "Auto"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331637/2b0040da-76d7-6528-691c-48ba7e4c18c0.png)

これがさっきやってみただめなケース。
完全にぶっ飛んでやがる。

ode15sはパワエレシミュレーションする際におすすめされるようなソルバであるが、
それでもちゃんとステップ幅設定していないとこうなる。

## ode15s + 最大ステップ幅　"PWM分解能１％”
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331637/75e079a2-7158-6a3b-3965-d3c12bae1639.png)

こちらはステップ幅を設定したケース。
まぁいい感じだ。これだと少なくとも1%は細かく切るけど、
その時間より短い時間で急激な変化が来た場合はオートマチックにステップ幅をより細かくしてくれる。
過渡応答の影響などみのがしたくないときに便利だとおもう。でもキャリア歪んでいるせいで多分キャリアの谷の時点でADCしないといけないタイミングがずれていたり細かいところで見ると変なところがある。

これは結果的に電流値が変化しないからこの粗さでOKだったのだとおもうが・・・・

## プラントのモデリングをかえてみる

いままで、プラントのモデルはPWMキャリアとAD変換の部分をSimulinkでかいていたが、
PWMキャリアとAD変換部分もSimscapeでかいてみる。

プラントのところにバリアントってのがあってプラントのタイプを切り替えられるようだ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331637/72cac792-4cc3-4bfb-2c6d-5058769914b2.png)

中身は最初と最後だけSimulinkで後は全部Simscapeの基本ブロックでADCとPWM処理をしている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331637/2c7b5768-ff03-59b0-40d6-ded8266c7ffe.png)

これで動かすとシミュレーション時間はややかかるが
ode15s+最大ステップ幅Auto　でもいい感じに動いた。
![2023-12-16_19-51-15.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331637/a101e318-523b-cc61-f3ae-18170a8c91c1.gif)

これが今のところ一番いい感じに見える。


# 結局何が一番いいのって気持ちになるんだけど

重ねて申し上げるが　すまん。わからない。というのが私個人の正直な回答です。
このあたり目的にもよるのでそれに合わせてモデル構築者が考えないといけないところかもしれない。

その分自由度があるので、カスタマイズ性があるといえるのじゃないかなと思っています。

# まとめ
ソルバ、むずかしいがこういう比較があるとわかりやすいとおもうので参考にしてくれると嬉しいです！

ちなみに去年も似たようにいろいろ試した記事をかいてるのでこいつも併せてみてくれると嬉しいです！

https://qiita.com/griffin921/items/3b0778148674f0780ab5