Main Content

C チャート内の MATLAB 関数およびワークスペース データへのアクセス

Simulink® モデルの Stateflow® チャートには、ステート アクションと遷移アクションの構文を定義するアクション言語プロパティがあります。チャート キャンバスの左下隅にあるアイコンが、チャートのアクション言語を示します。

  • アクション言語は MATLAB®

  • アクション言語は C。

C をアクション言語として使用するチャートでは、ml 名前空間演算子または関数 ml を使用することにより、組み込みの MATLAB 関数を呼び出して MATLAB ワークスペース変数にアクセスできます。

注意:

コード生成ターゲットを作成する予定がある場合は、MATLAB 関数をターゲット環境で使用することはできないため、ml 名前空間演算子と関数 ml は使用しないでください。

ml 名前空間演算子

C チャートでは、ml 名前空間演算子は、標準的なドット (.) 表記を使用して MATLAB 変数および関数を参照します。たとえば、ステートメント a = ml.x は、MATLAB ワークスペース変数 x の値を Stateflow データ a に返します。

関数では、構文は以下のようになります。

[return_val1,return_val2,...] = ml.function_name(arg1,arg2,...)

たとえば、ステートメント [a, b, c] = ml.function(x, y) は、MATLAB 関数 function からの値を Stateflow データ ab、および c に返します。

呼び出した MATLAB 関数が引数を必要としない場合でも、前述の例のように小かっこを含める必要があります。小かっこを省略した場合は、Stateflow ソフトウェアは関数名をワークスペース変数として解釈し、該当するものが検出されない場合は、シミュレーション時にランタイム エラーを生成します。

以下の例では、xy、および z はワークスペース変数、d1d2 は Stateflow データに該当します。

  • a = ml.sin(ml.x)

    この例では、MATLAB 関数 sinx の正弦値が計算され、Stateflow データ変数 a に代入されます。ただし、x はワークスペース変数であるため、アクセスするには名前空間演算子を使用しなければなりません。このため、x ではなく ml.x が使用されます。

  • a = ml.sin(d1)

    この例では、MATLAB 関数 sind1 の正弦値が計算され、Stateflow データ変数 a に代入されます。d1 は Stateflow データであるため、直接アクセスできます。

  • ml.x = d1*d2/ml.y

    この式の結果は、x に代入されます。シミュレーションの前に x が存在していない場合は、自動的に MATLAB ワークスペース内に作成されます。

  • ml.v[5][6][7] = ml.f(ml.x[1][3],ml.y[3])

    ワークスペース変数 x および y は配列です。x[1][3] は 2 次元配列変数 x.(1,3) 要素です。y[3] は 1 次元配列変数 y の 3 番目の要素です。

    f の呼び出しで返される値は、ワークスペース配列 v の要素 (5,6,7) に代入されます。シミュレーションの前に v が存在していない場合は、自動的に MATLAB ワークスペース内に作成されます。

関数 ml

C チャートでは、関数 ml を使用して、MATLAB 関数の呼び出しを指定することができます。関数 ml 呼び出しの形式では、以下の表記法が使用されます。

ml(evalString,arg1,arg2,...);

evalString は、MATLAB ワークスペースで評価される式です。この文字列式には、書式指定子 (%g%f%d など) とともに実行される MATLAB コマンド (または各コマンドがセミコロンで区切られたコマンド セット) が含まれています。書式指定子は、evalString に他の引数 (arg1arg2 など) の形式を置き換えたものを規定します。

関数 ml で使用される書式指定子は、C 関数 printfsprintf で使用されるものと同じです。関数 ml の呼び出しは、引数 arg1, arg2,... が次のコマンド内でスカラーまたはリテラルに限定されている場合は、ml 名前空間演算子による MATLAB 関数 eval の呼び出しと同義です。

ml.eval(ml.sprintf(evalString,arg1,arg2,...))

関数 ml で使用される書式指定子は、引数のデータ型に一致しているか、引数が書式指定子で表される型に上位変換できる型でなければなりません。

Stateflow ソフトウェアは、ml 名前空間演算子からスカラー型の戻り値を想定します。この前提で引数として使用される場合に、関数 ml が呼び出されます。ml 式の戻り値サイズをチャートで推測する方法 を参照してください。

以下の例では、x は MATLAB ワークスペース変数、d1d2 は Stateflow データに該当します。

  • a = ml("sin(x)")

    この例では、関数 ml で MATLAB 関数 sin が呼び出されて、MATLAB ワークスペースの x の正弦値が計算されます。結果は、Stateflow データ オブジェクト a に代入されます。x はワークスペース変数であり、sin(x) は MATLAB ワークスペースで評価されるため、string "sin(x)" として直接入力します。

  • sfmat_44 = ml("rand(4)")

    この例では、0 から 1 までの間の乱数から成る 4 行 4 列の正方行列が返され、Stateflow データ オブジェクト sf_mat44 に代入されます。このデータ オブジェクトは、シミュレーション前に 4 行 4 列の配列として定義しておく必要があります。それ以外の場合、実行時にサイズ不一致エラーが発生します。

  • a = ml("sin(%f)",d1)

    この例では、MATLAB 関数 sin によって MATLAB ワークスペースで d1 の正弦が評価され、その結果が Stateflow データ オブジェクト a に代入されます。d1 は Stateflow データであるため、値は形式表現 %f を使用して string 引数 "sin(%f)" に挿入されます。d1 = 1.5 の場合、MATLAB ワークスペースで評価される式は sin(1.5) です。

  • a = ml("f(%g,x,%f)",d1,d2)

    この例では、式は前述の形式説明で示した evalString に該当します。Stateflow データ d1d2 がそれぞれ書式指定子 %g%f を使用して式 "f(%g,x,%f)" に挿入されます。

ml

C チャートでは、拡張式において、Stateflow データとともに、ml 名前空間演算子と関数 ml の式を組み合わせて使用できます。以下の例では、ワークスペース変数 X の角度の sinecosine をそれぞれ二乗して加算しています。

a = ml.power(ml.sin(ml.X),2) + ml("power(cos(X),2)")

最初のオペランドでは、ml 名前空間演算子を使用して関数 sin を呼び出しています。X は MATLAB ワークスペース内に存在するため、引数は ml.X になります。2 番目のオペランドでは、関数 ml を使用しています。X はワークスペース内に存在するため、evalString 式に X として現れます。各オペランドの二乗法は MATLAB 関数 power で実行され、二乗する値および累乗値 2 の 2 つの引数を取得します。

ml 名前空間演算子や関数 ml を使用する式は、ml 名前空間演算子や関数 ml の式の引数として使用できます。以下の例では、ml 式を 3 つの異なるレベルで入れ子にしています。

a = ml.power(ml.sin(ml.X + ml("cos(Y)")),2)

ml 式を作成する際には、二項演算 に記載されている優先順位のレベルに従います。他の算術演算子と組み合わせて使用する場合は、^ 演算子を含む累乗式を小かっこで囲んでください。

Stateflow ソフトウェアは、モデルを更新またはシミュレートするアクションにおいて、式のデータ サイズ不一致をチェックします。ml 式の戻り値は実行時まで確定しないため、Stateflow ソフトウェアでは戻り値のサイズを推測しなければなりません。ml 式の戻り値サイズをチャートで推測する方法 を参照してください。

使用する ml の種類

ほとんどの場合、ml 名前空間演算子の表記法の方が簡単です。ただし、関数 ml 呼び出しを使用する場合にも、いくつかの利点があります。

  • 関数 ml を使用して、ワークスペース変数を動的に構成します。

    以下の例では、フロー チャートで新しい MATLAB 行列を 4 つ作成します。

    Flow chart that implements a for loop with four iterations.

    for ループを使用して、MATLAB ワークスペースに新しい 4 つの行列変数を作成しています。Stateflow カウンター i は、デフォルト遷移で 0 に初期化されるのに対して、上位 2 つのジャンクション間の遷移セグメントで 1 増分されます。i が 5 未満の場合は、最上位のジャンクションに戻る遷移セグメントが発生して、i の現在値で関数 ml 呼び出し ml("A%d = rand(%d)",i,i) が計算されます。i が 5 以上になった時点で、下位の 2 つのジャンクション間で遷移セグメントが発生して、実行が停止します。

    この結果は、ワークスペースのスカラー (A1) と 3 つの行列 (A2A3A4) を作成する以下の MATLAB コマンドに該当します。

    A1 = rand(1)
    A2 = rand(2)
    A3 = rand(3)
    A4 = rand(4)
  • 完全な MATLAB 表記法で関数 ml を使用します。

    以下の例に示すように、完全な MATLAB 表記法は、ml 名前空間演算子と組み合わせて使用することはできません。

    ml.A = ml.magic(4);
    B = ml("A + A'");

    この例では、ml 名前空間演算子を使用して、ワークスペース変数 A を 4 行 4 列の魔方陣に設定しています。次に、Stateflow データ BA の加算に設定され、その転置行列 A' によって対称行列が作成されています。ml 名前空間演算子では式 A' を評価できないため、関数 ml が代わりに使用されています。ただし、以下の式のように、ml 名前空間演算子を使用して MATLAB 関数 transpose を呼び出し、同等の処理を行うことは可能です。

    ml.A = ml.magic(4);
    B = ml.A + ml.transpose(ml.A)

    別の例としては、cell 配列を含む引数や、コロンを含む添字式を ml 名前空間演算子で使用することはできません。ただし、関数 ml 呼び出しでは、上記を含めることが可能です。

ml データ型

C チャートでは、ml 型の Stateflow データには、MATLAB 型 mxArray が内部的に設定されています。Stateflow 階層で使用可能な型のデータであれば、ml 型のデータに代入 (格納) できます。具体的な型としては、Stateflow 階層で定義されたデータ型や、ml 名前空間演算子または関数 ml で MATLAB ワークスペースから返されたデータ型が挙げられます。

ml データ型の使用ルール

ml 型の Stateflow データには、以下のルールが適用されます。

  • ml データは、Stateflow 階層の他のデータと同様に、MATLAB ワークスペースから初期化できます (MATLAB ベース ワークスペースからのデータの初期化 を参照)。

  • Stateflow 階層に格納された ml データの任意の数値スカラーや配列は、階層内の他のデータとともに、あらゆる種類の単項演算および二項演算で使用される可能性があります。

    ml データが他のデータとともに任意の数値演算に関与している場合は、ml 名前空間演算子や関数 ml から返されるデータと同様に、ml データのサイズは、使用される状況に応じて推測される必要があります。ml 式の戻り値サイズをチャートで推測する方法 を参照してください。

  • スコープの定数という設定では、ml データを定義できません。

    このオプションは、ml 型の Stateflow データに対応する [データ] プロパティ ダイアログ ボックスやモデル エクスプローラーでは無効になっています。

  • ml データを使用してシミュレーション ターゲットを作成できますが、組み込み可能コードの生成ターゲットは作成できません。

  • ml 型のデータに配列が含まれている場合は、以下のルールに従ってインデックスを追加することで、配列の要素にアクセスできます。

    1. インデックスを追加できるのは、数値要素を含む配列のみに限定されます。

    2. 数値配列には次元単位でのみインデックスを追加できます。

      つまり、単一のインデックス値でアクセスできるのは 1 次元配列のみになります。単一のインデックス値で多次元配列にはアクセスできません。

    3. 配列の各次元に対する最初のインデックス値は、0 (C 言語の配列) ではなく 1 です。

    以下の例で、mldataml 型の Stateflow データ、ws_num_array は数値をもつ 2 行 2 列の MATLAB ワークスペース配列、ws_str_array は文字ベクトル値をもつ 2 行 2 列の MATLAB ワークスペース配列です。

    mldata = ml.ws_num_array; /* OK */
    n21 = mldata[2][1]; /* OK for numerical data of type ml */
    n21 = mldata[3]; /* NOT OK for 2-by-2 array data */
    mldata = ml.ws_str_array; /* OK */
    s21 = mldata[2][1]; /* NOT OK for character vector data of type ml*/
  • ml データには C チャート外部のスコープは設定できません。つまり、ml データのスコープを [Simulink から入力] または [Simulink に出力] として定義することはできません。

ワークスペース データのプレース ホルダー

ml 名前空間演算子と関数 ml は、いずれも MATLAB ワークスペース内のデータに直接アクセスして、そのデータを C チャートに返すことができます。ただし、MATLAB ワークスペース内にデータを維持すると、Stateflow ユーザーの視点からは、ワークスペース内の他の既存データと矛盾しているように認識される場合があります。したがって、ml データ型ではチャートに ml データを維持して、C チャートの MATLAB 計算に使用できます。

たとえば、以下のステートメントでは、mldata1mldata2ml 型の Stateflow データに該当します。

mldata1 = ml.rand(3);
mldata2 = ml.transpose(mldata1);

この例では、1 行目の mldata1 は MATLAB 関数 rand の戻り値を受け取って、この場合は 3 行 3 列の乱数配列を返します。mldata1 は、配列やサイズが指定されないことに注意してください。ml 型の Stateflow データとして定義されているため、任意の MATLAB ワークスペース データや MATLAB 関数を受け取ることが可能です。

この例では、2 行目の mldata2ml 型の Stateflow データに該当し、mldata1 の行列の転置行列を受け取ります。MATLAB 関数 transpose の戻り値が代入されます。この場合、mldata1 が引数に該当します。

前述の例で Stateflow ml データの代わりに MATLAB ワークスペース データ (wsdata1wsdata2) を使用して、生成された行列を保持する場合は、以下のように表記法の相違があることに注意してください。

ml.wsdata1 = ml.rand(3);
ml.wsdata2 = ml.transpose(ml.wsdata1);

この場合、ml 名前空間演算子を介して各ワークスペース データにアクセスしなければなりません。

ml 式の戻り値サイズをチャートで推測する方法

C チャートでは、ml 名前空間演算子と関数 ml を使用する Stateflow 式は、実行時に MATLAB ワークスペースで評価されます。これは、以下の式タイプから返されるデータの実際のサイズが実行時にはじめて確定することを意味します。

  • ml 名前空間演算子または関数 ml 呼び出しを使用している MATLAB ワークスペース データまたは関数

    たとえば、式 ml.varml.func()、または ml(evalString, arg1, arg2,...) (ここで、var は MATLAB ワークスペース変数で、func は MATLAB 関数) からの戻り値のサイズは、実行時まで未確定です。

  • Stateflow データの型 ml

  • ml 型の Stateflow データを返すグラフィカル 関数

これらの式をアクションで使用すると、Stateflow のコード生成において一時データが作成され、式全体を評価する際の中間の戻り値が保持されます。これらの戻り値のサイズは実行時まで未確定であるため、Stateflow ソフトウェアではコンテキスト ルールを使用して一時データの作成用にサイズを推測しなければなりません。

実行時に、いずれかのコマンドの実際の戻り値と、戻り値を格納する一時変数の推測サイズが異なる場合は、サイズ不一致のエラーが発生します。実行時のエラーを回避するには、以下のガイドラインを使用して、MATLAB コマンドまたは ml データを含むアクションを作成します。

ガイドライン

式に含まれる MATLAB コマンドやデータの戻り値サイズは、同等の式の戻り値サイズと一致している必要があります。

ml.func() * (x + ml.y) において、x が 3 行 2 列の行列の場合、ml.func()ml.y も 3 行 2 列の行列になると想定されます。いずれかの式で異なるサイズの値 (スカラー値以外) が返された場合は、実行時にエラーが発生します。

スカラーを返す式では、エラーは発生しません。

MATLAB コマンドではスカラー拡張が実行されるため、拡張式では行列とスカラーを組み合わせることが可能です。

ml.x + y で、y が 3 行 2 列の行列であり、ml.x がスカラーを返す場合は、結果の値は、ml.x のスカラー値を y の各メンバーに加算することで、サイズ y (3 行 2 列) の行列を生成します。

これと同じルールが減算 (-)、乗算 (*)、除算 (/)、およびその他の 2 項演算 にも適用されます。

MATLAB コマンドまたは ml 型の Stateflow データは、以下に示すように、式で独立したレベルのメンバーにすることができます。その戻り値サイズは、解決する必要があります。

引数

各関数の引数の式は拡張式に該当し、MATLAB コマンドまたは ml 型の Stateflow データの戻り値サイズを確定しなければなりません。

z + func(x + ml.y) では、ml.y は関数の引数レベルで使用されるため、ml.y のサイズは z のサイズと関連がありません。ただし、func(x + ml.y) の戻り値サイズは z のサイズと一致していなければなりません。これは、両者が同じ式レベルであることに起因します。

配列インデックス

配列インデックスの式は、式の独立したレベルであり、そのサイズはスカラーである必要があります。

x + array[y] では、y のサイズは x のサイズと関連がありません。これは、yx は式のレベルが異なることに起因します。また、y はスカラーである必要があります。

インデックスが追加された配列要素アクセスの戻り値サイズは、スカラーである必要があります。

x[1][1] で、x が 3 行 2 列の配列である場合は、スカラーとして評価しなければなりません。

ml 名前空間演算子を介して呼び出される MATLAB 関数の入力引数として式で使用される、MATLAB コマンドまたはデータの要素のサイズが解決されます。この解決は、式自体の同等の式のルール (前述のルール 1) に基づいて行われます。これは、サイズ定義として使用できるプロトタイプが存在しないことに起因します。

関数呼び出し ml.func(x + ml.y) において、x が 3 行 2 列の配列の場合、ml.y は 3 行 2 列の配列またはスカラーを返さなければなりません。

グラフィカル関数の引数として使用される、MATLAB コマンドまたはデータの要素のサイズは、関数のプロトタイプに基づいて解決されます。

グラフィカル関数 gfunc が、プロトタイプ gfunc(arg1) をもち、arg1 が 2 行 3 列の Stateflow データ配列である場合は、呼び出し側の式 gfunc(ml.y + x) において、実行時に ml.yx の両方が 2 行 3 列の配列 (またはスカラー) になる必要があります。

関数 ml の呼び出しでは、スカラーまたは文字ベクトル リテラルの引数のみを指定できます。MATLAB コマンドまたはデータは、関数 ml の引数を指定する目的で使用された場合は、スカラー値を返す必要があります。

a = ml("sin(x)") では、関数 ml が MATLAB 関数 sin を呼び出して、MATLAB ワークスペースの x の正弦値を計算します。その結果は、Stateflow データ変数 a に格納されます。

代入では、右辺の式のサイズが左辺の式のサイズと一致しなければなりません。ただし、1 つ例外があります。左辺の式が単一の MATLAB 変数 (ml.x など) または ml 型の Stateflow データである場合は、左辺の式と右辺の式のサイズはともに右辺の式によって決まります。

s = ml.func(x) において、x が 3 行 2 列の行列であり、s がスカラー Stateflow データである場合は、ml.func(x) は左辺の式 s と一致するようにスカラーを返さなければなりません。ただし、式 ml.y = x + s で、x が 3 行 2 列のデータ配列であり、s がスカラーである場合は、右辺の式 x+s (3 行 2 列の配列) と一致するように、左辺の式のワークスペース変数 y は 3 行 2 列の配列のサイズで代入されます。

代入では、左辺の Stateflow 列ベクトルは、右辺のサイズが同じ MATLAB の行または列ベクトルと互換性があります。

行次元 1 で定義する行列は、行ベクトルとみなされます。1 次元または列次元 1 で定義する行列は、列ベクトルとみなされます。

s = ml.func() において、ml.func() が 1 行 3 列の行列を返し、s がサイズ 3 のベクトルである場合、代入は有効です。

前述のルールに基づいて、拡張式における MATLAB コマンドまたはデータ要素の戻り値サイズを解決できない場合は、スカラー値を返すと想定されます。

ml.x = ml.y + ml.z では、前述のルールを使用しても、ml.xml.y および ml.z に共通のサイズを推測できません。この場合、ml.yml.z はともにスカラー値を返すと想定されます。実行時に ml.yml.z が一致するサイズを返した場合でも、両者が非スカラー値を返した場合は、サイズ不一致のエラーが発生します。

前述のルールは、拡張式のメンバーに該当する MATLAB コマンドまたは ml 型の Stateflow データのサイズを解決する目的で使用され、メンバーとして数値が想定される場合にのみ適用されます。数値以外が返される場合、実行時エラーが発生します。

メモ

拡張式のメンバーに該当する MATLAB コマンドまたは ml 型のデータは、数値式で使用される場合は、数値 (スカラーまたは配列) のみに限定されます。

x + ml.str で、ml.str が文字ベクトル ワークスペース変数である場合、ml.str が数値型でないことを通知する実行時エラーが発生します。

特殊な事例では、サイズのチェックが実行されずに、拡張式に含まれる MATLAB コマンドまたはデータの式のサイズが解決されます。以下の式を使用する場合は、実行時にサイズ チェックの必要がありません。

  • ml.var

  • ml.func()

  • ml(evalString, arg1, arg2,...)

  • Stateflow データの型 ml

  • ml 型の Stateflow データを返すグラフィカル関数

これらの事例では、双方のサイズ不一致は考慮されず、代入ステートメントの左辺または関数の引数に対して、戻り値の代入が実行されます。

  • 左辺が MATLAB ワークスペース変数である代入

    たとえば、式 ml.x = ml.y では、ml.y は任意のサイズおよび型 (構造体、cell 配列、文字ベクトルなど) の MATLAB ワークスペース変数です。

  • 左辺が ml 型のデータである代入

    たとえば、式 m_x = ml.func() では、m_xml 型の Stateflow データです。

  • MATLAB 関数の入力引数

    たとえば、式 ml.func(m_x, ml.x, gfunc()) において、m_xml 型の Stateflow データで、ml.x は任意のサイズおよび型の MATLAB ワークスペース変数であり、gfunc()ml 型の Stateflow データを返す Stateflow グラフィカル関数です。入力型のサイズ チェックが行われない場合でも、渡されたデータが、想定される型でない場合、関数呼び出し ml.func() に起因するエラーが発生します。

  • プロトタイプ ステートメントで ml 型の Stateflow データとして指定されたグラフィカル関数の引数

    メモ

    前述の事例の入力が非 MATLAB 数値の Stateflow データで置き換えられた場合は、ml 型への変換が実行されます。