バックナンバーはこちら。
https://www.simulationroom999.com/blog/model-based-of-minimum-2-backnumber/
はじめに
前回から仮想HILSに於けるFMUとCANシグナルの紐づけを目的としてあCAPLの話に突入。
CAPLを記述する際はイベントとノードの意識が割と重要となる。
その点を鑑みた上でCAPLを記述することとなった。
今回は実際に作成したCAPLを確認する。
登場人物
博識フクロウのフクさん

イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1
エンジニア歴8年の太郎くん

イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1
CAPLコード

CAPLを書いてきたんで、貼っておく。
制御器側CAPL
variables
{
msTimer Timer1ms;
}
on signal Target
{
@sysvar::FMI::PID::Input::target = getSignal(Target);
}
on signal Speed
{
@sysvar::FMI::PID::Input::u = getSignal(Speed);
}
on timer Timer1ms
{
setSignal(Voltage::Voltage, @sysvar::FMI::PID::Output::y);
}
on start
{
setTimerCyclic(Timer1ms,1,1);
}
プラント側CAPL
variables
{
msTimer Timer1ms;
}
on message Voltage
{
@FMI::Motor::Input::voltage = getSignal(Voltage::Voltage);
}
on start
{
setTimerCyclic( Timer1ms, 1, 1);
}
on timer Timer1ms
{
setSignal(Sensor::Speed, @FMI::Motor::Output::speed);
setSignal(Sensor::Current,@FMI::Motor::Output::current);
}
CAPLコードを確認

これは予想以上にシンプルな感じだねー。

on startとかon timerとかon signalとかが各関数の先頭にあるけど、
これがイベントハンドラ?

そうだね。
イベントハンドラはまず先頭に「on」が付く。
そして、
シミュレーション開始なら「start」
タイマなら「timer」
シグナル更新なら「signal」
シグナル更新に関してはさらにその後ろにシグナル名を付けると、
そのシグナル更新時に該当ハンドラが呼び出される。

なるほど。

両方のon startで
setTimerCyclic
って関数呼んでるけど、これがタイマイベントを発生されるタイマを開始させてるAPIになるのかな?

正解。
今回だと1ms周期で呼び出されるタイマハンドラになる。

あとはon timerが1ms周期で呼び出されるからFMUの入出力に割り当てられた
システム変数をCANのシグナルにコピー、
またはそれの逆。
をしてるわけか。

それも正解。
CAPLのコツ的なもの

これは思ったよりも簡単そうで安心した。

まぁCAPLの使い方のコツとしては
「シンプルな構成にする」
かな。
当然複雑なこともできるのだけど、複雑なものは別途ライブラリにするとかにした方が良いだろうね。

FMUもある意味複雑な処理をライブラリにしているようなもんだんね。
CAPLは繋ぎの辻褄合わせをしてるだけだし。

そうそう。
その程度の使い方が良いだろう。

ほぼほぼ準備は整ってきたから次回は実際に動作させるところだねー。
まとめ

まとめだよ。
- 仮想HILS向けCAPLコード公開。
- イベントハンドラは関数先頭に「on」が付く。
- その後ろに以下が続く。
- start:シミュレーション開始。
- timer:タイマ。
- signal:シグナル更新。
- その後ろに以下が続く。
- CAPLのコツはシンプルに書く。
- 複雑な処理はライブラリに逃がすなどがコツ。
バックナンバーはこちら。
コメント