Main Content

このページは前リリースの情報です。該当の英語のページはこのリリースで削除されています。

バリアント モデルを使用して C のプリプロセッサ条件を使用するコードを生成する

この例では、プリプロセッサの条件によって、どのコードが組み込み実行ファイルのリンク先になるかを制御するために、コードを生成するバリアント モデルの利用方法を説明します。

バリアント モデルの概要

Model ブロックを使用すると、ある Simulink® モデル ("子モデル") を別の Simulink® モデル ("親モデル") から参照できます。Variant Subsystem ブロックは、さまざまな "バリアント" をもつことができます。バリアントには、Variant Subsystem ブロックにより選択される一連の Model ブロックを含めることができます。Model ブロックで参照されるモデルは、指定されたノミナルの機能に基づき、バリエーションを提供します。

Variant Subsystem ブロックでは一度に 1 つのバリアントのみアクティブになります。Variant Subsystem ブロックのダイアログ ボックスを使用して、アクティブなバリアントを選択できます。または、アクティブなバリアントの選択をパラメーター化したり、MATLAB® のベース ワークスペースの変数およびオブジェクトの値に依存させたりすることもできます。コードを生成する場合、すべてのバリアントのコードを生成し、コードのコンパイル時までアクティブなバリアントの選択を行わないようにできます。

バリアント モデルの指定

モデル例 PreprocessorConditionalsUsingVariantModel を開くと、[モデル プロパティ]、[コールバック] ダイアログ ボックスで定義されている "PostLoadFcn" が実行されます。これにより、ベース ワークスペースに Variant Subsystem ブロックの制御変数が入力されます。

open_system('PreprocessorConditionalsUsingVariantModel')

Left Controller 変数サブシステムには、2 つの子 Model ブロック LinearNonlinear が含まれます。Left Controller/Linear 子モデルは、Simulink.Variant オブジェクト LINEARtrue に評価されると実行され、Left Controller/Nonlinear 子モデルは、Simulink.Variant オブジェクト NONLINEARtrue に評価されると実行されます。

Simulink.Variant オブジェクトを Left Controller サブシステムに対して指定するには、Left Controller サブシステムを右クリックし、Subsystem Parameters を選択します。これで、Left Controller Variant Subsystem ブロックのダイアログ ボックスが開きます。

Left Controller Subsystem ブロックのダイアログ ボックスでは、ベース ワークスペースから LINEARNONLINEAR の 2 つの Simulink.Variant オブジェクトを使用して Linear Model ブロックと Nonlinear Model ブロック間の関連付けを作成します。これらのオブジェクトには、ブール値として評価され、アクティブなバリアント モデル (Linear または Nonlinear) を決定するために使用される式である、Condition という名のプロパティがあります。条件は Subsystem ブロックのダイアログ ボックスにも表示されます。この例では、LINEARNONLINEAR の条件は、それぞれ 'VSSMODE == 0''VSSMODE == 1' です。

この例では、Simulink.Variant オブジェクトはベース ワークスペース内に作成されます。

LINEAR = Simulink.Variant;
LINEAR.Condition = 'VSSMODE==0';
NONLINEAR = Simulink.Variant;
NONLINEAR.Condition = 'VSSMODE==1';

バリアント制御変数の指定

バリアント オブジェクトを使用することによって、モデル全体で任意の複雑な条件を再利用できます。複数の Variant Subsystem ブロックで同じ Simulink.Variant オブジェクトを使用すると、バリアント モデルのアクティブ化を 1 つのセットとしてまとめて切り替えることができます。このセットは MATLAB 環境の VSSMODE の値を変更するとシミュレーションの前に切り替えることができます。また、次の節で説明するように、生成コードのコンパイル時に切り替えることができます。この例では、Left ControllerRight Controller は同じバリアント オブジェクトを参照しているため、これらを同時に切り替えられます。

非線形コントローラー モデルはヒステリシスを実装しますが、線形コントローラー モデルは単純なローパス フィルターとして動作します。左側のチャネルのサブシステムを開きます。右側のチャネルのモデルも同様です。

生成されたコードは、バリアント制御変数 VSSMODE にユーザー定義マクロとしてアクセスします。この例では、variants_importedmacros.hVSSMODE を提供します。MATLAB 環境では、Simulink.Parameter オブジェクトを使用して VSSMODE を指定します。プリプロセッサ条件を含むコードを生成する場合、値は無視されます。ただし、値はシミュレーションに使用されます。レガシ ヘッダー ファイルは、生成コードのコンパイル時に使用するマクロの値を指定します。これは最終的に、組み込み実行ファイルの指定された 2 つのバリアントのどちらかをアクティブ化します。

バリアント制御変数は次のいずれかのストレージ クラスと共に Simulink.Parameter オブジェクトとして定義できます。

  • ヘッダー ファイルが指定された Define または ImportedDefine

  • CompilerFlag

  • SystemConstant (AUTOSAR)

  • 指定されたヘッダー ファイル内でデータをマクロとして定義するユーザー定義のカスタム ストレージ クラス

VSSMODE = Simulink.Parameter;
VSSMODE.Value = 1;
VSSMODE.DataType = 'int32';
VSSMODE.CoderInfo.StorageClass = 'Custom';
VSSMODE.CoderInfo.CustomStorageClass = 'ImportedDefine';
VSSMODE.CoderInfo.CustomAttributes.HeaderFile = 'variants_importedmacros.h';

複数のバリアントをもつモデルのシミュレーション

VSSMODE の値を 1 に設定しているため、このモデルはシミュレーション時に非線形コントローラーを使用します。

sim('PreprocessorConditionalsUsingVariantModel')
youtnl = yout;

VSSMODE の値を 0 に変更すると、このモデルはシミュレーション時に線形コントローラーを使用します。

VSSMODE.Value = int32(0);
sim('PreprocessorConditionalsUsingVariantModel')
youtl = yout;

次のようにして、線形コントローラーおよび非線形コントローラーの応答をプロットして比較できます。

figure('Tag','CloseMe');
plot(tout, youtnl.signals(1).values, 'r-', tout, youtl.signals(1).values, 'b-')
title('Response of Left Channel Linear and Nonlinear Controllers');
ylabel('Response');
xlabel('Time (seconds)');
legend('nonlinear','linear')
axis([0 100 -0.8 0.8]);

C プリプロセッサの条件の使用

このモデルの例は C プリプロセッサの条件を生成するように設定されています。モデルのコードを生成するには、ツールストリップの [C コード] タブで、[ビルド] を選択します。

プリプロセッサの条件のコード生成を有効にするには、次の条件が整っていることを確認してください。

  • [コンフィギュレーション パラメーター] ダイアログ ボックスの [コード生成]、[システム ターゲット ファイル] で Embedded Coder® ターゲットを選択します。

  • Variant Subsystem の [ブロック パラメーター] ダイアログ ボックスで、[バリアントのアクティベーションのタイミング] パラメーターを [code compile] に設定します。

この例で生成されたコードには、Simulink.Variant オブジェクト LINEARNONLINEAR への参照およびこれらのバリアントに対応するマクロの定義が含まれます。これらの定義は、外部ヘッダー ファイル variants_importedmacros.h によって提供される、VSSMODE の値に依存します。アクティブなバリアントは、マクロ (#define) LINEAR および NONLINEAR でプリプロセッサの条件 (#if) を使用することにより決定されます。

マクロ LINEAR および NONLINEAR は生成される PreprocessorConditionalsUsingVariantModel_types.h ヘッダー ファイルで定義されます。

  |#ifndef LINEAR|
  |#define LINEAR      (VSSMODE == 0)|
  |#endif|
  |#ifndef NONLINEAR|
  |#define NONLINEAR   (VSSMODE == 1)|
  |#endif|

生成コードではバリアントに関連するコードが C プリプロセッサの条件によってガードされます。たとえば PreprocessorConditionalsUsingVariantModel.c では各バリアントのステップ関数および初期化関数の呼び出しが条件付きでコンパイルされます。

モデル、Figure および例のワークスペース変数を閉じます。

bdclose('PreprocessorConditionalsUsingVariantModel')
close(findobj(0,'Tag','CloseMe'));
clear LINEAR NONLINEAR VSSMODE
clear tout yout youtl youtnl