バックナンバーはこちら。
https://www.simulationroom999.com/blog/model-based-of-minimum-2-backnumber/
はじめに
FMILibrary経由でパラメータ名文字列で変数オブジェクトの取得方法はわかった。
変数オブジェクトさえ取れてしまえば、あとはどうとでもなる。
というわけで、今回は実際の実験用ソースコードを見てみる。
登場人物
博識フクロウのフクさん
イラスト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
実験用ソースコード
実験用のソースコード書いてきたから貼る。
const char *szVarName[] = {
"HIGHT",
"HIGHT_SPEED",
"GRAVITY",
"BOUNCE_COF",
};
fmi2_import_variable_t *varHandle[sizeof(szVarName) / sizeof(szVarName[0])];
fmi2_value_reference_t vrTmp[sizeof(szVarName) / sizeof(szVarName[0])];
for (i = 0; i < sizeof(szVarName) / sizeof(szVarName[0]); i++) {
varHandle[i] = fmi2_import_get_variable_by_name(fmu, szVarName[i]);
if (varHandle[i] == NULL) {
printf("fmi2_import_get_variable_by_name failed\n");
do_exit(CTEST_RETURN_FAIL);
}
vrTmp[i] = fmi2_import_get_variable_vr(varHandle[i]);
printf("%s:valueReference is %d\n", szVarName[i], vrTmp[i]);
}
fmi2_real_t iniTmp[sizeof(vrTmp) / sizeof(vrTmp[0])];
fmistatus = fmi2_import_get_real(fmu, vrTmp, sizeof(vrTmp) / sizeof(vrTmp[0]), iniTmp);
if (fmistatus != fmi2_status_ok) {
printf("fmi2_import_set_real failed.err code=%d\n", fmistatus);
do_exit(CTEST_RETURN_FAIL);
}
printf("Initial Parameters.\n");
for (k = 0; k < sizeof(vrTmp) / sizeof(vrTmp[0]); k++) {
printf("vr:%d,iniTmp is %lf\n", vrTmp[k], iniTmp[k]);
}
iniTmp[0] = 5.0;
fmistatus = fmi2_import_set_real(fmu, vrTmp, sizeof(vrTmp) / sizeof(vrTmp[0]), iniTmp);
if (fmistatus != fmi2_status_ok) {
printf("fmi2_import_set_real failed.err code=%d\n", fmistatus);
do_exit(CTEST_RETURN_FAIL);
}
printf("Modified parameters.\n");
for (k = 0; k < sizeof(vrTmp) / sizeof(vrTmp[0]); k++) {
printf("vr:%d,iniTmp is %lf\n", vrTmp[k], iniTmp[k]);
}
実験用ソースコード解説
うーん、後半はここでやったやつだよねぇ・・・。
たしか、この時はvrTmp配列に必要なvalueReferenceを即値で格納していたから、
その即値の部分をなんとかしたってイメージかな?
そのとおり。
正解だ。
まずパラメータ名文字列を
fmi2_import_get_variable_by_name
に渡して変数オブジェクトを取得する。
その変数オブジェクトを
fmi2_import_get_variable_vr
に渡して、それぞれのvalueReferenceをvrTmp配列に格納。
それをszVarNameで指定した文字列要素分、今回だと4つの文字列に対して
for文で回しているってわけか。
そうそう。
他にも必要ななら、szVarNameに文字列渡せば一緒に取得できるって寸法だ。
なるほど。
これなら他のFMUを制御する場合でも簡単にできそうだ。
いちいちmodelDescription.xmlを見なくてもよさそうだしね。
そうだね。
そこを狙って書いたコードって感じだ。
まとめ
まとめだよ。
- パラメータ名文字列を元にFMU内パラメータ変更の実験コード提示。
- 変数オブジェクトを取得し、そこからvalueReference取得。
- valueReferenceが分かれば、FMU内パラメータは好き勝手できる。
- これにより今後、他のFMUを使う場合になっても比較的楽にパラメータアクセスができそう。
バックナンバーはこちら。
コメント