※ 2015年2月に執筆したものを転載
後編です。
前回、なんかもにゃもにゃした感じの波形になった原因の究明をします。
とりあえず、計算が間違ってると変換が間違ってるかそういう類のものではないです。
簡単に言うと時間の同期が想定よりズレている状態です。
さて、各ブロックそれぞれscilab上でどの順番で処理されるのでしょうか?
概念(数式的)としては並列(同時)に処理されることになっているのですが、実際にそのようになっているわけではなく、何かしらの規則によって処理順が決定しています。
各ブロックの依存関係によって決定しています。
つまり、該当ブロックが演算するために必要な結果をどのブロックが出してくれるかによって、演算優先度というものが発生します。
今回の場合の依存関係は、
①が依存するもの ⇒ なし
②が依存するもの ⇒ ①、④
③が依存するもの ⇒ なし
④が依存するもの ⇒ ③
となります。
この状態だと、①、③のどちらか最初。
②を実行するためには①、④が決定している必要あり、なので①を実行。
④を実行するためには③が決定している必要あり、よって、③を実行。
④を実行
最後に②を実行
おそらく、
①→③→④→②の順番で実行されます。
期待していた順番は
①→②→③→④
であり、少なくとも②と③が逆転されては困ります。
これにより、本来であれば過去の値から未来の値を推測するものが、未来の値を元に過去の値を推測するというよく分からない処理をやされることになります。
これが、前回の振動の原因となります。
解決策としては、依存関係を想定通りにすれば良いだけなので、
②と③に入出力を追加してとりあえず線で結べがOKです。
(つながってはいるがデータの受け渡しは特にしなくてOK)
これだけで少なくとも②→③の順番だけは保障できます。
これにて一見落着!
と、思いきや、
これでもなんかダメでした。
原因は・・・
前回、調子こいてタスク分割したところにありました・・・。
つまりタスク設計ミス。
前回設置したタスクは
①I/Oタスク
②状態機タスク
③制御器タスク
です。
期待する処理順は
①→②→③
です。
そして実際の処理順は
①→②→③
でした。
というわけで期待通りではあったのですが・・・。
そもそも期待する処理順が間違っていたというオチで、
もう少し処理を分割すると、
①入力
②状態機駆動
③制御器駆動
④出力
①→②→③→④
が期待する処理順で、
今回の処理順は
①→④→②→③
となってました。
これでは、前回の演算結果を出力することになります。
つまり、I/Oタスクで入出力を一気にやっていたことが問題。
というわけで改めて入力タスク、出力タスクに分解。
その結果↓
DutyCut指示や状態機からの加工指令値はソフトウェア内部に埋め込んでしまったため、波形上にはあらわれていないです。
一応、DutyCut、スイング、Soft-Landingの振る舞いは見せているのでおそらくOkと言ったところでしょうか。
まとめ
・シミュレータ間連携で少し具体的な構成で動作がみれる
・シミュレータの性質を少し把握してないと、変にはまる
・タスク設計ミスるとひどい目にあう ← New
コメント