scilabとboost:statechartの連携(中編)

scilabとboost:statechartの連携(中編) scilab

※ 2015年1月に執筆したものを転載

scilabとboost:statechartの連携 中編です。

前回、青図を描きました。
理屈上は大丈夫そうなのですが、
実際にやってみないと分からんよねってことで、
もうちょっと具体的に設計からやってしまいたいと思います。
制御対象は「scilabの紹介」の時に使ったモータープラントをそのまま流用します。
PIDコントローラも最後にC言語版を仕込んだのでこれを使ってしまいましょう。
では、どこで状態機使うのよって話になるのだけれども、
とりあえず、PIDコントローラへ指令値を出してる手前に状態機が必要になりそうな新仕様を差し込んでしまいたいと思います。

↓新仕様

・起動時またはClear/Reset要求実施後に+100[rad]まで回せるか確認。
⇒ 1秒以内に+100[rad]に到達できなかった場合は、保留故障コード記録して次へ
・100[rad]まで回したら0[rad]に戻す。
・その後は外部指令値に従う。

ただし、以下制約を設ける
・0[rad]を目標値にする際は、突き当て防止のため、10[rad]から0.25[rad]ずつ0[rad]を目指す
・0[rad]が200ms続いた場合、全閉振動、締付によるデバイスダメージを避けるため、duty-cut(shutoff)する。

制御デバイスの動作(可動範囲)確認&保護仕様ってやつです。
指令器からの指示値をそのままバイパスするか、状況を見て書き換えてしまうかで実現させます。

これを満たせるであろうと思われる設計をざっとやってみました。

モーター制御、ステートマシン図、アクティビティ図

状態機は2段構成にしましまた。
理由は、起動時の振る舞いと、0近傍の振る舞いに同期性を見出せなかったためです。
別に1個構成にしたとしても問題があるとかは思いません。完全に好みの世界です。
私も別に日に設計したら1個にするかもしれませんし、しないかもしれないですし。

そして、この2つの状態機をboost:statechartに転写します。

無事ビルドが通った段階で、scilabから動的リンクさせます。
って言いたいですが、
ここはやはり、単体テストをしておいた方が良いでしょう。
設計ミス、コーディングミスしてる可能性は高いですし。

ちなみに、boostには簡単なユニットテストフレームワークも含まれています
ちょっとした様子見用の1発物コードなんかはこれで済ましてしまうことは多いです。
今回もきっと1発物なので、boost::unit_testで済ませてしまいます。

予想通り、コーディングミス多発ですね・・・。
設計の方は・・・大丈夫・・そう?
ぶっちゃけユニットテストでは設計の間違いは基本拾えないので良く分かりません。
何しろ設計(期待)通りの振る舞いをしているかの確認がユニットテストなわけなので。

ここまで来たら動かしてみるしかありません。
というわけscilabのCBlockから呼び出します。
結果↓

シミュレーション結果、状態遷移、起動時スイング、突き当て保護、dutycut、モーター制御、PID制御、プラントモデル、制御モデル、Scilab

なんかバッチリっぽいです。
・起動時のスイング ⇒ 問題無し。
・スイングの最後の0近傍での保護動作 ⇒ 問題無し。
・しばらく(200ms)0近傍だったらduty-cut ⇒ 問題無し
・その後は外部指令値に従う ⇒ 問題無し。
・外部指令値が0近傍を指示したら保護動作 ⇒ 問題無し。
(故障情報は外部出力してないけど、内部的には動作してるのを確認)

動いてくれてスッキリしたので、これで終わりにしてしまいたいのですが、
後、C言語化が残ってます。
これを次回。

コメント

タイトルとURLをコピーしました