生成されたコードにおける信号および状態の初期化の制御
シミュレーションとコード生成用にカスタム値で信号と離散状態を初期化するために、信号オブジェクトとブロック パラメーターを使用できます。データ初期化はアプリケーションの信頼性を増し、アプリケーションの安全性に必要です。シミュレーションとコード生成の両方のために信号を初期化することにより、モデルベース デザインの段階から段階への遷移を改善することができます。
モデル内で信号と離散状態の初期値を指定する方法に関する基本的な情報については、信号と離散状態の初期化を参照してください。
生成されたコードにおける信号および状態の初期化
コード生成用の初期化動作は、以下の例外はありますが、モデル シミュレーションのものと同じです。
RSim 実行可能プログラムは [コンフィギュレーション パラメーター] ダイアログ ボックスの [データのインポート/エクスポート] ペインを使用して、MAT ファイルから入力値を読み込むことができます。GRT と ERT 実行可能プログラムは MAT ファイルから入力値を読み込むことができません。
ブロック出力信号またはルート レベル入力/出力信号用の初期値は外部 (呼び出し) プログラムにより上書きされる可能性があります。
値が外部アプリケーションで使用されるか表示される場合は、初期値を永続的な信号に設定することが適切です。
コードを生成すると、初期化ステートメントはモデルの初期化コード内の model
.c
または model
.cpp
に配置されます。
たとえば、モデル SignalObjectInitialValue
を考えてみましょう。
openExample('SignalObjectInitialValue')
ベース ワークスペース内で信号オブジェクトを作成して初期化すると、以下に示すように、コード ジェネレーターは、信号用の初期化コードを関数 SignalObjectInitialValue_initialize
の下のファイル SignalObjectInitialValue.c
に置きます。
/* Model initialize function */ void SignalObjectInitialValue_initialize(void) { . . . /* exported global signals */ S3 = -3.0; S2 = -2.0; . . . /* exported global states */ X1 = 0.0; X2 = 0.0; /* external inputs */ S1 = -4.5; . . .
以下に、Enabled Subsystem の Unit Delay ブロックの状態 X1
と出力信号 S2
用の初期化コードを示します。
void MdlStart(void) { . . . /* InitializeConditions for UnitDelay: '<S2>/Unit Delay' */ X1 = aa1; /* Start for enable system: '<Root>/Enabled Subsystem (state X1 inside)' */ /* virtual outports code */ /* (Virtual) Outport Block: '<S2>/Out1' */ S2 = aa2; }
Enabled Subsystem の場合は、サブシステムの Outport ブロックのパラメーター [ディセーブル時の出力] が [リセット]
に設定されていると、初期値もリセット値として使用されます。以下の SignalObjectInitialValue.c
からのコードは、モデル出力関数 SignalObjectInitialValue_output
内に表示される際に、S3
用の代入ステートメントを示します。
/* Model output function */ static void SignalObjectInitialValue_output(void) { . . . /* Disable for enable system: '<Root>/Enabled Subsystem (state X1 inside)' */ /* (Virtual) Outport Block: '<S2>/Out1' */ S2 = aa2;
調整可能な初期条件の生成
信号と状態の初期条件は、調整可能なグローバル変数を作成することにより、生成されたコードで表すことができます。この変数により、メモリに格納された初期条件を使用してアプリケーションを再起動できます。
[コンフィギュレーション パラメーター]、[最適化]、[既定のパラメーター動作] を Tunable
に設定すると、初期状態はグローバル パラメーター構造体の調整可能なフィールドとして表示されます。
[既定のパラメーター動作] を Tunable
または Inlined
のどちらに設定するかに関係なく、調整可能なパラメーターを使用して信号オブジェクトの InitialValue
プロパティまたはブロックの [初期条件] パラメーターを指定できます。調整可能なパラメーターに関する基本的な情報については、生成されたコードにおける調整可能なキャリブレーション パラメーターの作成を参照してください。
この例では、調整可能なパラメーターを使用して信号および状態の初期条件を指定する方法を示します。
モデル例の確認
モデル例 SignalObjectInitialValue
を開き、生成されたブロック名を表示するよう設定します。信号 S2
はベース ワークスペースで Simulink.Signal
オブジェクトを使用します。
Simulink.Signal
オブジェクト S2
をダブルクリックし、そのプロパティを表示します。[初期値] プロパティが aa2
に設定されています。オブジェクトは変数 aa2
を使用して信号 S2
の初期条件を指定します。[ストレージ クラス] プロパティが ExportedGlobal
に設定されています。Simulink.Signal
オブジェクトを使用して信号を初期化するには、信号オブジェクトで Auto
以外のストレージ クラスを使用するか、コード マッピング エディターで対応するデータ カテゴリが Default
以外のストレージ クラス設定を使用している場合は Model default
を使用しなければなりません。
[コンフィギュレーション パラメーター] ダイアログ ボックスの [最適化] ペインで、[設定] をクリックします。変数 aa2
はストレージ クラス ExportedGlobal
を使用する調整可能なパラメーターです。
モデル内で Enabled Subsystem を開きます。Outport ブロック ダイアログ ボックスで、パラメーター [ディセーブル時の出力] を reset
に設定します。サブシステムがディセーブルになると、出力信号 S2
が初期値 aa2
にリセットされます。
Unit Delay ブロック ダイアログ ボックスを開きます。[状態属性] タブで、[状態名] ボックスを X1
に設定します。
Enable ブロック ダイアログ ボックスを開きます。パラメーター [イネーブル時の状態] を reset
に設定します。サブシステムがディセーブルの状態からイネーブルの状態に遷移すると、X1
などのそれぞれの内部ブロック状態が初期値にリセットされます。
ベース ワークスペースで、Simulink.Signal
オブジェクト X1
をダブルクリックして、そのプロパティを表示します。[初期値] プロパティが aa1
に設定されています。
Simulink.Parameter
オブジェクト aa1
をダブルクリックし、そのプロパティを表示します。[ストレージ クラス] プロパティが ExportedGlobal
に設定されています。aa1
などの調整可能なパラメーターおよび X1
などの Simulink.Signal
オブジェクトを使用して、ブロック状態に調整可能な初期条件を生成できます。
コードの生成と検査
モデル例でコードを生成します。
### Starting build procedure for: SignalObjectInitialValue ### Successful completion of build procedure for: SignalObjectInitialValue Build Summary Top model targets built: Model Action Rebuild Reason ========================================================================================================== SignalObjectInitialValue Code generated and compiled. Code generation information file does not exist. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 9.953s
コード生成レポートで、ファイル SignalObjectInitialValue.c
を表示します。コードはグローバル変数を使用してブロック状態 X1
と信号 S2
を表します。
/* Exported block states */ real_T X1; /* '<S1>/Unit Delay' */ /* Exported block signals */ real_T S1; /* '<Root>/In1' */ real_T S3; /* '<Root>/Signal Conversion' */ real_T S2; /* '<S1>/Unit Delay' */
コードはグローバル変数を使用して調整可能なパラメーター aa1
を表します。
/* Exported block parameters */ real_T aa1 = -2.5; /* Variable: aa1
モデル初期化関数は調整可能なパラメーター aa1
を使用して状態 X1
を初期化します。また、この関数は調整可能なパラメーター aa2
を使用して信号 S2
も初期化します。
/* SystemInitialize for Enabled SubSystem: '<Root>/Enabled Subsystem (state X1 inside)' */ /* InitializeConditions for UnitDelay: '<S1>/Unit Delay' */ X1 = aa1; /* SystemInitialize for UnitDelay: '<S1>/Unit Delay' incorporates: * Outport: '<S1>/Out1' */ S2 = 0.0;
モデルのステップ関数では、Enabled Subsystem がディセーブル状態からイネーブル状態に遷移すると、Unit Delay ブロック状態 X1
はその初期値にリセットされます。
if (rtb_PulseGenerator > 0) { if (!SignalObjectInitialValue_DW.EnabledSubsystemstateX1inside_M) { /* InitializeConditions for UnitDelay: '<S1>/Unit Delay' */ X1 = aa1; SignalObjectInitialValue_DW.EnabledSubsystemstateX1inside_M = true; } /* UnitDelay: '<S1>/Unit Delay' */ S2 = X1; /* Update for UnitDelay: '<S1>/Unit Delay' incorporates: * Inport: '<Root>/In1' */ X1 = S1; } else if (SignalObjectInitialValue_DW.EnabledSubsystemstateX1inside_M) { /* Disable for UnitDelay: '<S1>/Unit Delay' incorporates: * Outport: '<S1>/Out1' */ S2 = 0.0; SignalObjectInitialValue_DW.EnabledSubsystemstateX1inside_M = false; } /* End of Outputs for SubSystem: '<Root>/Enabled Subsystem (state X1 inside)' */ /* DataStoreWrite: '<Root>/Data Store Write' */ X2 = S2; /* SignalConversion: '<Root>/Signal Conversion' incorporates: * DataStoreRead: '<Root>/Data Store Read' */ S3 = X2; } /* Model initialize function */ void SignalObjectInitialValue_initialize(void) { /* Registration code */ /* initialize error status */ rtmSetErrorStatus(SignalObjectInitialValue_M, (NULL)); /* block I/O */ /* exported global signals */ S3 = -3.0; /* states (dwork) */ (void) memset((void *)&SignalObjectInitialValue_DW, 0, sizeof(DW_SignalObjectInitialValue_T)); /* exported global states */ X1 = 0.0; X2 = 0.0; /* external inputs */ S1 = -4.5; /* Start for DiscretePulseGenerator: '<Root>/Pulse Generator' */ SignalObjectInitialValue_DW.clockTickCounter = -2; /* Start for DataStoreMemory: '<Root>/Data Store Memory' */ X2 = -3.5; /* SystemInitialize for Enabled SubSystem: '<Root>/Enabled Subsystem (state X1 inside)' */ /* InitializeConditions for UnitDelay: '<S1>/Unit Delay' */ X1 = aa1; /* SystemInitialize for UnitDelay: '<S1>/Unit Delay' incorporates: * Outport: '<S1>/Out1' */ S2 = 0.0; /* End of SystemInitialize for SubSystem: '<Root>/Enabled Subsystem (state X1 inside)' */ } /* Model terminate function */ void SignalObjectInitialValue_terminate(void) { /* (no terminate code required) */ }
Enabled Subsystem がコード実行中にディセーブルになると、アルゴリズムは調整可能な初期条件 aa2
を使用して信号 S2
の値を設定します。
} else { } else if (SignalObjectInitialValue_DW.EnabledSubsystemstateX1inside_M) { /* Disable for UnitDelay: '<S1>/Unit Delay' incorporates: * Outport: '<S1>/Out1' */ S2 = 0.0; SignalObjectInitialValue_DW.EnabledSubsystemstateX1inside_M = false; }
バス信号用の調整可能な初期条件構造体の生成
MATLAB® 構造体を使用してバス内の信号要素の初期値を指定する場合、生成コードに調整可能なグローバル構造体を作成できます。
[コンフィギュレーション パラメーター]、[最適化]、[既定のパラメーター動作] を [Tunable
] に設定すると、初期条件はグローバル パラメーター構造体の調整可能なサブ構造体として表示されます。
[既定のパラメーター動作] を Tunable
または Inlined
のどちらに設定した場合でも、値が構造体である調整可能な Simulink.Parameter
オブジェクトを使用して初期条件を指定できます。パラメーター オブジェクトに Auto
以外のストレージ クラスを適用した場合、生成コード内の構造体は調整可能になります。
構造体とバス信号の間のデータ型の不一致を避けて効率的なコードを生成するためには、次のいずれかを使用します。
構造体フィールドの値を指定する型付き式。各フィールドのデータ型を対応する信号要素のデータ型と一致させます。
構造体のフィールドおよび信号の要素のデータ型を制御する
Simulink.Bus
オブジェクト。
構造体を使用したバス信号の初期化についての基本的な情報およびフィールドのデータ型の制御方法の決定については、バス要素の初期条件の指定を参照してください。
調整可能な初期条件構造体の生成
この例では、調整可能な構造体パラメーターを使用してバーチャル バス信号を初期化する方法について説明します。
モデル例を開き、生成されたブロック名を表示するよう設定します。
model = 'TunableInitStruct'; load_system(model) set_param(model,'SimulationCommand','Update',... 'HideAutomaticNames','off') open_system(model)
[モデル化] タブで [モデル データ エディター] をクリックします。
[入力端子/出力端子] タブの [Data Type] 列に、モデル内の各 Inport ブロックが異なる出力データ型を使用することが示されます。
Bus Creator ブロック ダイアログ ボックスを開きます。ブロック出力はバーチャル バスです。
[コンフィギュレーション パラメーター] ダイアログ ボックスで [最適化] ペインを開きます。コンフィギュレーション パラメーター [既定のパラメーター動作] は Tunable
に設定されています。既定では、初期条件を含むブロックのパラメーターは、生成コード内でグローバル パラメーター構造体の調整可能なフィールドとして現れます。
モデル データ エディターの [状態] タブを確認します。
Unit Delay ブロックについて、[Initial Value] を、3 つの信号要素それぞれの初期条件を指定する構造体に設定します。効率的なコードを生成するために、構造体のフィールドのデータ型を対応する信号要素のデータ型と一致させます。たとえば、[初期値] に式 struct('thermocpl',15.23,'magFlow',uint32(79),'posSwitch',false)
を設定します。
set_param([model,'/Unit Delay'],'InitialCondition',... 'struct(''thermocpl'',15.23,''magFlow'',uint32(79),''posSwitch'',false)')
モデル例からコードを生成します。
slbuild(model)
### Starting build procedure for: TunableInitStruct ### Successful completion of build procedure for: TunableInitStruct Build Summary Top model targets built: Model Action Rebuild Reason =================================================================================================== TunableInitStruct Code generated and compiled. Code generation information file does not exist. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 20.315s
コード生成レポートで、ファイル TunableInitStruct_types.h
を表示します。コードでは、struct
式で指定したデータ型を使用するフィールドをもつ構造体型を定義しています。
file = fullfile('TunableInitStruct_grt_rtw','TunableInitStruct_types.h'); coder.example.extractLines(file,'#ifndef DEFINED_TYPEDEF_FOR_struct_','}',1,1)
#ifndef DEFINED_TYPEDEF_FOR_struct_mqGi1jsItE0G7cf1bNqMu_ #define DEFINED_TYPEDEF_FOR_struct_mqGi1jsItE0G7cf1bNqMu_ typedef struct { real_T thermocpl; uint32_T magFlow; boolean_T posSwitch; } struct_mqGi1jsItE0G7cf1bNqMu;
ファイル TunableInitStruct.h
を表示します。グローバル パラメーター構造体の struct
型定義には、Unit Delay ブロックの [初期条件] パラメーターを表すサブ構造体 UnitDelay_InitialCondition
が含まれています。
file = fullfile('TunableInitStruct_grt_rtw','TunableInitStruct.h'); coder.example.extractLines(file,'struct P_TunableInitStruct_T_ {','UnitDelay_InitialCondition;',1,1)
struct P_TunableInitStruct_T_ { struct_mqGi1jsItE0G7cf1bNqMu UnitDelay_InitialCondition;
ファイル TunableInitStruct_data.c
を表示します。このソース ファイルでは、グローバル パラメーター構造体にメモリを割り当てています。サブ構造体 UnitDelay_InitialCondition
があります。
file = fullfile('TunableInitStruct_grt_rtw','TunableInitStruct_data.c'); coder.example.extractLines(file,'/* Block parameters (default storage) */','}',1,1)
/* Block parameters (default storage) */ P_TunableInitStruct_T TunableInitStruct_P = { /* Mask Parameter: UnitDelay_InitialCondition * Referenced by: * '<Root>/Unit Delay' * '<Root>/Unit Delay' * '<Root>/Unit Delay' */ { 15.23, 79U, 0 },
ファイル TunableInitStruct.c
を表示します。モデル初期化関数はサブ構造体のフィールドを使用してブロックの状態を初期化します。
file = fullfile('TunableInitStruct_grt_rtw','TunableInitStruct.c'); coder.example.extractLines(file,'* InitializeConditions for UnitDelay generated from: ''<Root>/Unit Delay'' */',... 'TunableInitStruct_P.UnitDelay_InitialCondition.posSwitch',1,1)
/* InitializeConditions for UnitDelay generated from: '<Root>/Unit Delay' */ TunableInitStruct_DW.UnitDelay_1_DSTATE = TunableInitStruct_P.UnitDelay_InitialCondition.thermocpl; /* InitializeConditions for UnitDelay generated from: '<Root>/Unit Delay' */ TunableInitStruct_DW.UnitDelay_2_DSTATE = TunableInitStruct_P.UnitDelay_InitialCondition.magFlow; /* InitializeConditions for UnitDelay generated from: '<Root>/Unit Delay' */ TunableInitStruct_DW.UnitDelay_3_DSTATE = TunableInitStruct_P.UnitDelay_InitialCondition.posSwitch;
バス オブジェクトを使用したデータ型の指定
バス オブジェクトを作成する場合は、それを使用してバス信号と調整可能な初期条件構造体のデータ型を指定できます。コード生成の前に、Simulink.Parameter
オブジェクトによって構造体のフィールドの値を信号要素のデータ型にキャストします。バス オブジェクトの作成およびモデル内での使用に関する基本的な情報については、Simulink.Bus オブジェクト データ型でのバス プロパティの指定を参照してください。
モデル例を開き、生成されたブロック名を表示するよう設定します。
model = 'InitialStructBusObject'; load_system(model) set_param(model,'SimulationCommand','Update',... 'HideAutomaticNames','off') open_system(model)
ベース ワークスペースで、Simulink.Bus
オブジェクト ComponentData
をダブルクリックします。オブジェクトは 3 つの信号要素 thermocpl
、magFlow
および posSwitch
を定義します。要素はそれぞれ異なるデータ型を使用します。
モデルでモデル データ エディターを開きます ([モデル化] タブで [モデル データ エディター] をクリック)。[入力端子/出力端子] タブで、Inport ブロック DataIn
では、出力データ型 ([データ型] 列) が Bus: ComponentData
に設定されていることが表示されます。
コマンド プロンプトで構造体パラメーター initStruct
を作成します。型なし式を使用して、フィールドの値を指定できます。可読性を高めるために、フィールド posSwitch
にブール値を指定します。
initStruct = struct(... 'thermocpl',15.23,... 'magFlow',79,... 'posSwitch',false... ); initStruct = Simulink.Parameter(initStruct);
モデル データ エディターで、[パラメーター] タブを検査します。
モデルで Unit Delay ブロックをクリックします。モデル データ エディターによって、ブロックの [Initial condition] パラメーターに対応する行が強調表示されます。
モデル データ エディターで、パラメーター値 ([値] 列) を initStruct
に設定します。
set_param([model,'/Unit Delay'],'InitialCondition','initStruct')
[追加情報の表示/更新] ボタンをクリックします。データ テーブルにパラメーター オブジェクト initStruct
が行として表示されます。
[データ型] 列を使用して、initStruct
のデータ型を Bus: ComponentData
に設定します。
initStruct.DataType = 'Bus: ComponentData';
[ビューの変更] ドロップダウン リストを Code
に設定します。
[ストレージ クラス] 列を使用して、ストレージ クラス ExportedGlobal
を initStruct
に適用します。
initStruct.StorageClass = 'ExportedGlobal';
モデル例からコードを生成します。
slbuild(model)
### Starting build procedure for: InitialStructBusObject ### Successful completion of build procedure for: InitialStructBusObject Build Summary Top model targets built: Model Action Rebuild Reason ======================================================================================================== InitialStructBusObject Code generated and compiled. Code generation information file does not exist. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 12.315s
コード生成レポートで、ファイル InitialStructBusObject_types.h
を表示します。コードは、バス オブジェクトでデータ型を使用するフィールドをもつ構造体型 ComponentData
を作成します。
file = fullfile('InitialStructBusObject_grt_rtw','InitialStructBusObject_types.h'); coder.example.extractLines(file,'#ifndef DEFINED_TYPEDEF_FOR_ComponentData_','}',1,1)
#ifndef DEFINED_TYPEDEF_FOR_ComponentData_ #define DEFINED_TYPEDEF_FOR_ComponentData_ typedef struct { real_T thermocpl; uint32_T magFlow; boolean_T posSwitch; } ComponentData;
ファイル InitialStructBusObject.c
を表示します。コードではグローバル変数を作成して調整可能なパラメーター オブジェクト initStruct
を表します。
file = fullfile('InitialStructBusObject_grt_rtw','InitialStructBusObject.c'); coder.example.extractLines(file,'/* Exported block parameters */','Variable: initStruct',1,1)
/* Exported block parameters */ ComponentData initStruct = { 15.23, 79U, 0 } ; /* Variable: initStruct
モデル初期化関数は構造体フィールドを使用してブロック状態を初期化します。
coder.example.extractLines(file,'/* InitializeConditions for UnitDelay generated from: ''<Root>/Unit Delay'' */',... '= initStruct.posSwitch;',1,1)
/* InitializeConditions for UnitDelay generated from: '<Root>/Unit Delay' */ InitialStructBusObject_DW.UnitDelay_1_DSTATE = initStruct.thermocpl; /* InitializeConditions for UnitDelay generated from: '<Root>/Unit Delay' */ InitialStructBusObject_DW.UnitDelay_2_DSTATE = initStruct.magFlow; /* InitializeConditions for UnitDelay generated from: '<Root>/Unit Delay' */ InitialStructBusObject_DW.UnitDelay_3_DSTATE = initStruct.posSwitch;
信号要素のデータ型を変更するには、バス オブジェクトで新しい型を指定します。モデル内の信号要素は新しい型を使用します。シミュレーションおよびコード生成の前に、パラメーター オブジェクト initStruct
は対応する構造体のフィールドを新しい型にキャストします。