Main Content

Simulink モデルでの列挙型データの使用

"列挙型データ" は決まった数の値に制約されるデータです。"列挙データ型" は、"列挙型の値" のセットを定義する MATLAB® クラスです。各列挙型の値は、ソフトウェアが生成コード内で内的に使用する "列挙型の名前""使用可能な整数" から構成されます。

Simulink® の列挙型に関する基本的な概念情報は、Simulink 列挙型を参照してください。

列挙型を使用したコード生成の詳細については、生成されたコードにおける列挙型データの使用 (Simulink Coder)を参照してください。

Simulink 列挙型の定義

Simulink モデルで使用できる列挙データ型を定義するには、次のいずれかの方法を使用します。

  • MATLAB ファイル内の classdef ブロックを使用して列挙型クラスを定義する。

  • 関数 Simulink.defineIntEnumType を使用する。型を定義するためのスクリプト ファイルは必要ありません。詳細は、関数のリファレンス ページを参照してください。

  • 関数 Simulink.importExternalCTypes を使用して、外部 C コードで定義した列挙データ型 (enum) の Simulink 表現を作成する。

Simulink 列挙型クラスを定義するワークフロー

  1. クラス定義を作成します

  2. オプションで列挙型をカスタマイズします

  3. オプションで、MATLAB ファイルに列挙型を保存します

  4. オプションで、Simulink データ ディクショナリに列挙型データを永続的に保存します。列挙型データの永続的な保存を参照してください。

Simulink 列挙型クラスの作成

Simulink 列挙型クラスを作成するには、クラス定義で以下を行います。

  • Simulink.IntEnumType のサブクラスとしてクラスを定義します。また、組み込みの整数データ型 int8uint8int16uint16int32 のいずれかをベースにして列挙型を定義することもできます。

  • 基となる整数値で列挙値を指定する enumeration ブロックを追加します。

次の例を考えます。

classdef BasicColors < Simulink.IntEnumType
  enumeration
    Red(0)
    Yellow(1)
    Blue(2) 
  end
end 

1 行目では、組み込みクラス Simulink.IntEnumType から派生する整数値に基づいた列挙型を定義します。IntEnumTypeint32 から派生するため、列挙型は整数値に基づきます。

enumeration セクションは、3 つの列挙値を指定します。

列挙値列挙名基となる整数値
Red(0)Red0
Yellow(1)Yellow1
Blue(2)Blue2

Simulink 環境で使用するために列挙型クラスを定義する際は、以下を考慮してください。

  • 列挙型クラスの名前はデータ型の名前とベース ワークスペース変数の名前の中で固有のものでなければならず、大文字と小文字が区別されます。

  • enumeration セクションの基となる整数値は、クラス内または型間で固有である必要はありません。

  • しばしば、一連の列挙値の整数値は連続して単調に増加しますが、連続させる必要も順序付ける必要もありません。

  • シミュレーションで基となる整数値は、int32 型の値になります。制限値を求めるには、MATLAB の関数 intmin および intmax を使用します。

  • コードを生成する場合、各整数値は、さまざまな制限値が与えられる可能性があるターゲット ハードウェア上で整数形式で表現される必要があります。詳細については、システム ターゲット ファイルの構成 (Simulink Coder)を参照してください。

スーパークラスの詳細については、スーパークラス値への変換を参照してください。基本値に対して 1 つを超える名前が存在する場合に列挙型クラスがどのように処理されるかについては、列挙型名のエイリアス方法を参照してください。

Simulink 列挙型のカスタマイズ

Simulink 列挙型のカスタマイズについて.  Simulink 列挙型は、クラス定義で固有の静的メソッドを実装することによってカスタマイズできます。適切な構文を使用してこれらのメソッドを定義した場合、シミュレーションの最中および生成されたコードで、クラスの動作を変更できます。

次の表に、列挙型をカスタマイズするために実装可能なメソッドを示します。

静的メソッド目的メソッドを実装しない場合の既定値カスタムの戻り値使用のコンテキスト
getDefaultValueクラスの既定の列挙型メンバーを指定します。列挙型定義で指定された最初のメンバークラスに列挙型メンバーの名前を含む文字ベクトル (列挙型のインスタンスの作成を参照)シミュレーションとコード生成
getDescription列挙型クラスの記述を指定します。''型の説明を含む文字ベクトルコード生成
getHeaderFileヘッダー ファイルの名前を指定します。メソッド getDataScope は、ファイルの重要性を判断します。''列挙型を定義するヘッダー ファイルの名前を含む文字ベクトルコード生成
getDataScope生成コードが列挙型のデータ型の定義をインポートまたはエクスポートするかどうかを指定します。メソッド getHeaderFile を使用して、型を定義するヘッダー ファイルが生成されているか含まれているかを指定します。'Auto''Auto''Exported''Imported' のいずれかコード生成
addClassNameToEnumNames生成コード内でクラス名に接頭辞を付けるかどうかを指定します。falsetrue または falseコード生成

これらのメソッドをコード生成に適用する例については、列挙データ型のカスタマイズ (Simulink Coder)を参照してください。

既定の列挙値の指定.  Simulink および関連する生成コードでは、初期値が設定されていない場合、列挙型データの基礎となる値の初期化に列挙型の既定値を使用します。たとえば、まだ実行されておらず、今後、条件付きで実行されるサブシステム内の列挙型信号には、列挙型の既定値が与えられます。安全なキャストに失敗すると、列挙値の型キャスト (Simulink Coder)で説明されているように、生成コードで列挙型の既定値が使用されます。

前述の指定と異なる指定をしない限り、列挙型の既定値が、列挙型クラス定義での最初の値になります。異なる既定値を指定するには、独自の getDefaultValue メソッドを作成して methods セクションに追加します。以下のコードでは、getDefaultValue メソッドのシェルを示します。

    function retVal = getDefaultValue()
      % GETDEFAULTVALUE Specifies the default enumeration member.
      % Return a valid member of this enumeration class to specify the default.
      % If you do not define this method, Simulink uses the first member.
      retVal = ThisClass.EnumName;
    end

このメソッドをカスタマイズするには、希望する既定値を指定する ThisClass.EnumName の値を入力します。

  • ThisClass は、メソッドが存在するクラスの名前です。

  • EnumName は、そのクラスにある定義された列挙値の名前です。

以下に例を示します。

classdef BasicColors < Simulink.IntEnumType
  enumeration
    Red(0)
    Yellow(1)
    Blue(2) 
  end
  methods (Static)
    function retVal = getDefaultValue()
      retVal = BasicColors.Blue;
    end
  end
end 

この例は、既定を BasicColors.Blue として定義しています。このメソッドが使用されないと列挙型クラス定義での最初の値は BasicColors.Red になるので、これが既定値になります。

getDefaultValue は値の名前だけではなく既定の列挙値のインスタンスを返すため、同じクラスの定義内に ThisClass の冗長な仕様が必要になります。したがって、メソッドにはインスタンスを作成する完全な仕様が必要になります。詳細については、列挙型のインスタンスの作成を参照してください。

MATLAB ファイルへの列挙型の保存

列挙型は MATLAB ファイル内で定義できます。

  • 定義ファイルの名前は、大文字小文字の区別も含めて、列挙型の名前と一致しなければなりません。たとえば、列挙型 BasicColors の定義は、BasicColors.m という名前のファイルに存在しなければなりません。それ以外の場合、MATLAB では定義を検出できません。

  • 各クラス定義は別々のファイルで定義しなければなりません。

  • 各定義ファイルは、MATLAB 検索パスに保存してください。MATLAB は必要に応じてパスで定義を検索します。

    ファイルまたはフォルダーを MATLAB 検索パスに追加するには、MATLAB のコマンド プロンプトで addpath pathname を入力します。詳細については、MATLAB 検索パスとはaddpathおよびsavepathを参照してください。

  • 列挙型を使用するために列挙型クラス定義を実行する必要はありません。前の箇条書きで示したように、唯一の必要条件は、定義ファイルが MATLAB の検索パス上にあることです。

列挙型クラスの変更と再読み込み

列挙型の定義は、定義を格納するファイルを編集および保存することによって変更することができます。クラス定義が変更されたことを MATLAB に知らせる必要はありません。ファイルを保存すると、MATLAB は変更された定義を自動的に読み込みます。ただし、以前のクラスの定義に反映するクラス インスタンス (列挙型値) が存在する場合、クラス定義の変更は完全に有効になりません。そのようなインスタンスは、ベース ワークスペースに存在するか、キャッシュされている可能性があります。

次の表では、ベース ワークスペースおよびキャッシュから列挙型のインスタンスの削除のオプションを示しています。

ベース ワークスペース内の場合キャッシュ内の場合

次のいずれかを行います。

  • 特定の旧式のインスタンスを検出し削除する。

  • clear コマンドを使用してベース ワークスペースからすべてを削除する。

  • 以前のクラスの定義が有効なうちに更新またはシミュレーションを行ったすべてのモデルを終了し、旧式のインスタンスを削除する。

  • クラスのインスタンスをキャッシュしている関数とモデルをクリアする。

同様に、Simulink.defineIntEnumType を使用して列挙型クラスを定義する場合は、インスタンスが存在していても、同じ関数を使用してクラスを再定義できます。ただし、インスタンスが存在している状態では、クラスの StorageType を変更することはできません。

列挙変更の適用の詳細は、変更済みクラスの自動更新を参照してください。

MATLAB の外部で定義された列挙型のインポート

MATLAB の外部で定義された列挙型を Simulink 環境で使用するためにインポートする場合、次の関数のうちの 1 つに対する呼び出しを使用してプログラムでそれを行うことができます。

  • Simulink.defineIntEnumType — MATLAB で使用できる列挙型を、クラス定義ファイルで定義されたかのように定義します。列挙型クラス名と値の指定に加え、各関数呼び出しでは以下を指定できます。

    • 列挙型クラスを説明する文字ベクトル。

    • 列挙値のいずれが既定値か。

    コード生成については、以下を指定できます。

    • 生成コードに対して列挙が定義されるヘッダー ファイル。

    • コード ジェネレーターが列挙型メンバーの接頭辞としてクラス名を適用するかどうか。たとえば、BasicColors_RedRed のいずれにするか。

    例として以下のクラス定義を考えます。

    classdef BasicColors < Simulink.IntEnumType
    	enumeration
    		Red(0)
    		Yellow(1)
    		Blue(2)
    	end
    	methods (Static = true)
    		function retVal = getDescription()
    			retVal = 'Basic colors...';
    		end
    		function retVal = getDefaultValue()
    			retVal = BasicColors.Blue;
    		end
    		function retVal = getHeaderFile()
    			retVal = 'mybasiccolors.h'; 
    		end
    		function retVal = addClassNameToEnumNames()
    			retVal = true;
    		end
    	end
    end

    次の関数呼び出しでは、同じクラスを MATLAB で使用するために定義します。

    Simulink.defineIntEnumType('BasicColors', ... 
         {'Red', 'Yellow', 'Blue'}, [0;1;2],...
         'Description', 'Basic colors', ...
         'DefaultValue', 'Blue', ...
         'HeaderFile', 'mybasiccolors.h', ...
         'DataScope', 'Imported', ...
         'AddClassNameToEnumNames', true);
    
  • Simulink.importExternalCTypes — 既存の C コードで定義した列挙データ型 (enum) の Simulink 表現を作成します。

モデル内の MATLAB Function ブロックが列挙型を使用する場合、外部ヘッダー ファイルの型定義をインクルードする (#include) ようにモデル コンフィギュレーション パラメーターを設定します。インポートされたバスと列挙型定義の制御を参照してください。

列挙型データの永続的な保存

列挙型の定義にクラス ファイルまたは関数 Simulink.defineIntEnumType のどちらを使用する場合でも、列挙型定義を Simulink データ ディクショナリに永続的に保存できます。ディクショナリにリンクされているモデルは列挙型を使用できます。詳細については、データ ディクショナリの列挙値を参照してください。

列挙型を使用したシミュレーション

次の列挙型クラス定義を考えます。BasicColors には列挙値 RedYellowBlue があり、既定値は Blue です。

classdef BasicColors < Simulink.IntEnumType
  enumeration
    Red(0)
    Yellow(1)
    Blue(2)
  end
  methods (Static)
    function retVal = getDefaultValue()
      retVal = BasicColors.Blue;
    end
  end
end

MATLAB がこのクラス定義を認識するようになると、Simulink モデルと Stateflow® モデルで列挙型を使用できます。Stateflow にある列挙固有の情報は、列挙データ (Stateflow)に記載されています。以下の Simulink モデルでは、上記で定義された列挙が使用されています。

モデルの出力は以下のとおりです。

Data Type Conversion ブロック OrigToInt は、出力データ型 int32 および整数丸めモード Floor を指定します。そのため、ブロックでは、Scope 表示の上の図に示される Sine Wave ブロック出力が整数のサイクル 1210121 に変換されます。Data Type Conversion ブロックの IntToColor は、これらの値を使用し、基となる整数を参照することによって列挙型 BasicColors から色を選択します。

その結果、中央のグラフに示されているように、YellowBlueYellowRedYellowBlueYellow という色のサイクルになります。Enumerated Constant ブロックの EnumConst 出力は、2 番目のグラフで直線として表示されている Yellow を出力します。Relational Operator ブロックは、定数 Yellow を色のサイクル内にあるそれぞれの値と比較します。3 番目のグラフに示されているように、Yellow が現在の色に満たない場合は 1 (true) が出力され、それ以外の場合は 0 (false) が出力されます。

比較に使用される並べ替えの順序は比較される値の整数値の数値順序で、列挙型クラス定義内で単語として現れる列挙値の順序ではありません。この例では、2 つの順序は同じですが、同じであることは求められていません。詳細については、データ型としての列挙型の指定および計算における列挙値を参照してください。

データ型としての列挙型の指定

列挙型を定義すると、他のデータ型と同じように使用できます。列挙型はインスタンスというよりもクラスです。そのため、データ型として列挙型を指定する際には、接頭辞 ? または Enum: を使用しなければなりません。接頭辞 ? は、MATLAB コマンド ウィンドウで使用しなければなりません。Simulink モデルではどちらの構文も使用可能です。Enum: は接頭辞 ? と同じ効果がありますが、グラフィカル ユーザー インターフェイスのコンテキストで内容がよりわかり易いため、Enum: をお勧めします。

コンテキストにより、Enum: に続けて列挙型の名前を入力することも、[Enum: <class name>] をメニュー ([出力データ型] ブロック パラメーターなど) から選択することも、<class name> を置き換えることもできます。

データ型アシスタントを使用するには、[モード]Enumerated に設定してから列挙型の名前を入力します。たとえば、前述のモデルで BasicColors 型の信号を出力する Data Type Conversion ブロックの IntToColor には、以下の出力信号の仕様があります。

最小および最大という概念が列挙型の目的とは関連性がないため、列挙型として定義された信号に最小値や最大値を設定することはできません。列挙型の信号の最小値と最大値を既定値の [] から変更すると、モデルを更新したときにエラーが発生します。詳細については、計算における列挙値を参照してください。

列挙データ型に関する情報の取得

関数 enumeration および Simulink.data.getEnumTypeInfo は列挙データ型に関する情報を返します。

列挙型メンバーに関する情報の取得

関数 enumeration を使用して、以下のことが行えます。

  • MATLAB コマンド ウィンドウで列挙型クラスのすべての列挙値を含む配列を返す

  • プログラムで列挙値を取得する

  • Switch Case ブロックの [Case 条件] パラメーターなど、列挙値の配列またはベクトルを受け入れる Simulink ブロック パラメーターに値を提供する

列挙型クラスに関する情報の取得

関数 Simulink.data.getEnumTypeInfo を使用して、列挙型クラスについて次のような情報を返すことができます。

  • 既定の列挙型メンバー

  • 生成コード内で型を定義するヘッダー ファイルの名前

  • 生成コード内で使用される列挙型メンバーの基となる整数値を格納するデータ型

列挙値の表示

可能な限り、Simulink は列挙値を基となる整数値ではなく名前で表示します。ただし、基となる整数は Scope ブロックおよび Floating Scope ブロックでの値の表示に影響する場合があります。

ブロック...値の表示への影響
Scope列挙型信号の表示では、列挙値の名前が Y 軸上のラベルとして表示されます。この名前は、整数値が指定する順序で、最も低い値をもつ名前が一番下に表示されます。
Floating Scope同じ列挙型の信号の表示では、Scope ブロックと同様に Y 軸上に名前が表示されます。Floating Scope ブロックで混在しているデータ型が表示されるときには、名前は表示されず、列挙値は基となる整数で表現されます。

固有の整数値をもたない列挙値

データ型としての列挙型の指定で説明されているように、列挙内の 1 つを超える値が同じ整数値をもつことができます。この場合、Scope ブロック出力の軸上または Display ブロック出力内の値は、整数値を共有する列挙型クラス定義にリストされた最初の値です。以下に例を示します。

Enumerated Constant ブロックは True を出力しますが、OnTrue の両方には同じ整数値があり、クラス定義の enumeration セクションで On が先に定義されています。したがって、Display ブロックには On が示されます。同様に、どちらの値が Scope ブロックに入力されているかは問題ではなく、Scope 軸には On のみが示され True は示されません。

列挙型のインスタンスの作成

列挙型を使用する前に、そのインスタンスを作成しなければなりません。MATLAB では、Simulink のモデル、または Stateflow のチャートで列挙型のインスタンスを作成できます。構文はすべてのコンテキストで同じです。

MATLAB での列挙型のインスタンスの作成

MATLAB で列挙型のインスタンスを作成するには、MATLAB のコマンド ウィンドウに ClassName.EnumName を入力します。ベース ワークスペースにインスタンスが作成されます。たとえば、Simulink 列挙型クラスの作成にあるように BasicColors を定義すると、以下のように入力できます。

bcy = BasicColors.Yellow

bcy = 

    Yellow

列挙型ではタブによる補完機能が有効です。たとえば、以下のように入力します。

bcy = BasicColors.<tab>

BasicColors の要素とメソッドがアルファベット順に MATLAB に表示されます。

要素またはメソッドをダブルクリックすると、<tab> キーを押したところに要素またはメソッドを挿入できます。詳細については、コードの候補と補完を参照してください。

MATLAB での列挙型のキャスト

MATLAB では、整数から列挙型へ直接キャストできます。

bcb = BasicColors(2)

bcb = 

    Blue   

列挙型から元の整数にキャストすることもできます。

>> bci = int32(bcb)

bci = 

    2   

どちらの場合も、MATLAB は該当する型の 1 行 1 列の配列にキャストの結果を返します。

キャスティングは可能ですが、列挙値、および列挙型クラスに対して定義された同等の整数が変更される場合がある場合は、列挙値の使用はロバストではありません。

Simulink (または Stateflow) での列挙型のインスタンスの作成

Simulink のモデルで列挙型のインスタンスを作成するには、ダイアログ ボックスの値として ClassName.EnumName を入力します。たとえば、以下のモデルを考えます。

列挙値 Yellow を出力する Enumerated Constant ブロック EnumConst は、その値を次のように定義します。

配列およびワークスペース変数を含む列挙値を評価する有効な MATLAB 式を入力できます。たとえば、BasicColors(1) などです。また、以前に MATLAB で bcy = BasicColors.Yellow を実行したことがある場合は、bcy を入力できます。別の例として、[BasicColors.Red, BasicColors.Yellow, BasicColors.Blue] などの配列も入力できます。

Constant ブロックを使用すると列挙値を出力できます。ただし、そのブロックでは、[出力の最小値][出力の最大値] など、列挙型に適用しないパラメーターが表示されます。

データ型としての列挙型の指定で説明されているように、Simulink.Parameter オブジェクトを列挙として作成する場合、[値] パラメーターを列挙型メンバーで指定し、[データ型] には Enum: または ? の接頭辞を付けて指定しなければなりません。

[値] パラメーターには列挙メンバーの整数値を指定することはできません。詳細については、計算における列挙値を参照してください。そのため、BasicColors.Yellow の整数値が 1 であったとしても、次の設定は失敗します。

Stateflow でも、同じ構文および同じ考慮点が適用されます。詳細については、列挙データ (Stateflow)を参照してください。

計算における列挙値

列挙型のクラスが MATLAB int32 型クラスのサブクラスであったとしても、Simulink では、意図的に列挙値が数学計算で数値として使用されないようになっています。そのため、列挙型は整数値として存在していても、数値型としては機能しません。たとえば、列挙型信号を Gain ブロックに直接入力することはできません。

Data Type Conversion ブロックを使用すると、整数型か列挙型のいずれか、あるいは 2 つの列挙型のいずれかに変換できます。つまり、Data Type Conversion ブロックを使用して列挙型信号を (列挙型信号の値の基となる整数値から構成されている) 整数型の信号に変換し、その整数型信号を Gain ブロックに入力することができます。詳細については、列挙型信号のキャストを参照してください。

Simulink の列挙型は、Relational Operator ブロックや Switch ブロックなどのブロックで、プログラムの状態を表したり、プログラム論理を制御することを目的としています。Simulink のブロックで列挙値の比較が行われる場合、比較される値の列挙型は同じでなければなりません。ブロックは、列挙型のクラス定義での順序ではなく、列挙値の基となる整数値に基づいて列挙値を比較します。

Switch ブロック、Multiport Switch ブロックのようなブロックでは複数のデータ信号を選択します。データ信号は列挙型のものであり、すべてのデータ信号は同じ列挙型である必要があります。ブロックが制御信号とデータ信号の両方を入力する際は、Switch および Multiport Switch と同様に、制御信号の型とデータ信号の型が一致していなくても構いません。

列挙型信号のキャスト

Data Type Conversion ブロックを使用すると、ブロックに入力されるすべての列挙型整数値を任意の数値型の範囲内にし、列挙型信号をその数値型の信号にキャストすることができます。キャストできない場合は、シミュレーション中にエラーが発生します。

同様に、Data Type Conversion ブロックを使用すると、ブロックに入力されるすべての値を列挙型の整数値にし、整数型の信号を列挙型信号にキャストすることができます。キャストできない場合は、シミュレーション中にエラーが発生します。

Data Type Conversion ブロックを使用して、整数データ型ではない数値信号を列挙型にキャストすることはできません。たとえば、列挙型を使用したシミュレーションで使用されているモデルでは、正弦波を列挙値に変換するために 2 つの Data Conversion ブロックが必要でした。

最初のブロックが doubleint32 にキャストし、2 番目のブロックが int32BasicColors にキャストします。実数部、虚数部のデータ型にかかわらず、複素数信号を列挙型タイプにキャストすることはできません。

列挙型ブロック パラメーターのキャスト

数値データ型のブロック パラメーターを列挙データ型にキャストすることはできません。たとえば、Enumerated Constant ブロックで [値]2 を指定し、[出力データ型]Enum: BasicColors に指定したとします。

仕様によって暗示的に double の値が列挙型にキャストされるため、エラーが発生します。このエラーは、数値が列挙型のいずれかの列挙値に算術的に対応していたとしても発生します。

列挙型のブロック パラメーターをその他のデータ型にキャストすることはできません。たとえば、Constant ブロックで [定数値]BasicColors.Blue を指定し、[出力データ型]int32 に指定したとします。

仕様によって暗示的に列挙値が数値型にキャストされるため、エラーが発生します。このエラーは、列挙値の基となる整数値が有効な int32 型であったとしても発生します。

参考

| |

関連するトピック