Main Content

カスタム マッピングされる外部入力をもつマッピング モードの使用

この例では、Simulink マッピング モードに類似したカスタム マッピング アルゴリズムを実装する方法を示します。関数 getSlRootInportMap および getRootInportMap を使用して、カスタム マッピングを実装します。

この例では、getRootInportMap コマンドおよびルート Inport マッパー ツールのカスタム マッピング機能に精通していることを前提としています。これらの概念に精通していない場合、ドキュメンテーションを読み、getRootInportMap とカスタム マッピングに関連する例を確認してください。

ワークフロー

この例では、組み込みの Simulink マッピング モードを使って、できるだけ多くのマッピングを実行する方法を示します。次に、信号を割り当てることができなかったルート Inport にフラグを設定します。次に、アルゴリズムはカスタム マッピングを使って、フラグが設定されたマッピングをオーバーライドし、残りの信号をマッピングします。このようなソリューションを実装するには、getSlRootInportMap を使用してカスタム マッピング関数を作成します。

この例では、次の 2 種類の信号に関する入力リストを使用します。

  • Simulink ブロック名マッピング モードを使ってマッピングできる信号。

  • Simulink ブロック名マッピング モードを使ってマッピングできない信号。これらの信号は、カスタム マッピング モードを使ってマッピングしなければなりません。

次のシナリオを想定します。

  • 信号グループを、Simulink モデルへの入力として使用します。

  • 信号には、変数名がルートレベル Inport のブロック名と一致するような名前が付けられます。

  • この命名規則を使用する各信号は、許容誤差内に収まっています。

  • 名前に 'x' という文字が付加された各信号は、許容誤差外と見なされます。

この例では、Simulink ブロック名のマッピング方法と類似するマッピング モードを使用します。

ルートレベル Inport ブロック名を次に示します。

  • Throttle

  • Brake

信号変数名を次に示します。

  • Throttlex

  • Brake

このシナリオで、入力をルートレベル Inport ブロックにマッピングするには、ルート Inport マッパー ツール用のカスタム マッピング関数が必要です。この例では、カスタム マッピング関数 AlmostBlockName を使用します。

この例の場合、slexAutotransRootInportsExample モデルを使って、カスタム マッピング関数を検証します。

カスタム マッピング関数の宣言

関数名、入力および出力を宣言します。そのためには、次のコード スニペットを MATLAB ファイルにコピーして貼り付け、AlmostBlockName.m という名前でファイルに保存します。

function inputMap = AlmostBlockName( modelName, signalNames, signals )

Simulink BlockName マッピングの取得

次に、すべての信号をマッピングします。そのためには、最初に Simulink ブロック名マッピング モードを使って、許容誤差内のすべての信号をマッピングし、その後、許容誤差外の信号をマッピングします。

Simulink マッピング モードのいずれかを使って許容誤差内の信号をモデルにマッピングするには、関数 getSlRootInportMap を使用します。この関数は、inputMap と logical 値のベクトルを返します。各 logical 値は、inputMap から信号へのマッピングが成功したか失敗したかを示します。ブロック名を使ってマッピングするには、関数宣言の直後に、次のコード行を挿入します。

inputMap = getRootInportMap('empty');
if ~bdIsLoaded(modelName)
   load_system(modelName);
end
[inputMap, hasASignal] = getSlRootInportMap('Model', modelName, ...
        'MappingMode','BlockName',...
        'signalName',signalNames, 'signalValue', signals);

不足している入力信号の検出

前の手順では、ブロック名マッピング モードを使って、マッピングを作成しました。許容誤差内の信号に関連付けられていない、空の inputMapinputMap(s) を考慮しなければなりません。関数 getSlRootInportMap は、出力変数 hasASignal を使って、これらの信号にフラグを設定しました。このためには、以下のことを行います。

  1. 変数 inputMap をチェックします。

  2. 変数 inputMap が空でない場合、inputMap ベクトルのどの要素が信号に割り当てられなかったかを判別します。そのためには、次に示すように、hasASignal ベクトル上で logical ~ を使用します。これで emptyIndex ベクトルに、logical ベクトルが含まれました。true は inputMap には信号がマッピングされていないことを意味します。

  3. getSlRootInportMap への呼び出しの下と、if bdIsLoaded(modelName) への終了の前に、次のコード スニペットをコピーして貼り付けます。

if ~isempty(inputMap)
    emptyIndex = ~hasASignal;
end

このコード スニペットは、手順 1 および 2 を自動的に実行します。

マッピングの完了

前の手順で、logical ベクトル emptyIndex を作成し、信号に関連付けられていない inputMap オブジェクトがあるか確認しました。emptyIndex ベクトルのすべての要素が false の場合、マッピングが完了し、この節で追加したコードは実行されません。

emptyIndex ベクトルの少なくとも 1 つの値に true が含まれている場合、信号に関連付けられていない inputMap オブジェクトがあるということです。その inputMap に可変信号を手動で割り当てます。次に、予想される信号名と一致する信号名を使って、inputMap をオーバーライドします。

  1. emptyIndex ベクトルで、true の値をもつすべての項目を検出します。これらの項目は、信号に関連付ける必要がある inputMap(s) を指定しています。

  2. inputMap ごとに、'BlockName' プロパティを使って、inputMap の割り当て先となる Inport ブロックの名前を取得します。

  3. ブロック名に 'x' を追加して、inputMap に割り当てる信号の名前を取得します。

  4. signalNames 変数の cell 配列で、結果と各項目を比較します。

  5. 一致するものが見つかった場合、inputMap を、予想される信号名と一致する信号名でオーバーライドします。inputMap オブジェクトをオーバーライドするには、'InputMap' および 'SignalName' プロパティを指定して、関数 getRootInportMap を使用します。

if isa( signals{1}, 'Simulink.SimulationData.Dataset')
    signalNames = signals{1}.getElementNames';
end
idxEmpty = find(emptyIndex==true);
for kEmpty =1:length(idxEmpty)
    idxOfEmpty = idxEmpty(kEmpty);
    destBlockName = get(inputMap(idxOfEmpty),'BlockName');
    outSideToleranceSig = [destBlockName 'x'];
    isAMatch = strcmp(signalNames, outSideToleranceSig);
    if any(isAMatch)
        inputMap(idxOfEmpty) = getRootInportMap('InputMap', ...
            inputMap(idxOfEmpty),'SignalName',outSideToleranceSig);
    end
end

カスタム マップ ファイル

完了すると、ファイル AlmostBlockName.m は次のようなコードになります。

function inputMap = AlmostBlockName(modelName, signalNames, signals)
inputMap = getRootInportMap('empty');
if bdIsLoaded(modelName)
     [inputMap, hasASignal] = getSlRootInportMap('Model', modelName, ...
     'MappingMode','BlockName',...
     'signalName',signalNames, 'signalValue', signals);
     if ~isempty(inputMap)
        emptyIndex = ~hasASignal;
        idxEmpty = find(emptyIndex==1);
        if isa( signals{1}, 'Simulink.SimulationData.Dataset')
             signalNames = signals{1}.getElementNames';
        end
        for kEmpty =1:length(idxEmpty)
            idxOfEmpty = idxEmpty(kEmpty);
            destBlockName = get(inputMap(idxOfEmpty),'BlockName');
            nonNominalSig = [destBlockName 'x'];
            isAMatch = strcmp(signalNames, nonNominalSig);
            if any(isAMatch)
                inputMap(idxOfEmpty) = getRootInportMap('InputMap', ...
                    inputMap(idxOfEmpty),'SignalName',nonNominalSig);
            end
        end
     end
end

カスタム マッピングの検証

カスタム マッピングを検証するには、次の手順に従います。

  1. MATLAB パス上のファイルに関数 AlmostBlockName を保存します。

  2. マッピング関数の結果を確認するには、次のコード スニペットを MATLAB コマンド ウィンドウにコピーして貼り付けます。

modelName  = 'slexAutotransRootInportsExample';
Throttlex  = timeseries(zeros(10,1));
Brake      = timeseries(ones(10,1));
signalNames= {'Throttlex' ,'Brake'};
signals    = { Throttlex  , Brake };
open_system(modelName);
inputMap   = AlmostBlockName(modelName, signalNames, signals);
inputStr   = getInputString(inputMap,'base');
close_system(modelName);

このコード スニペットを実行した後、変数 inputStr は文字列 'Throttlex,Brake' を含みます。

信号が Simulink.SimulationData.Dataset 内にある場合、マッピング関数の結果を表示するには、次のコード スニペットを MATLAB コマンド ウィンドウで使用します。

modelName  = 'slexAutotransRootInportsExample';
Throttlex  = timeseries(zeros(10,1));
Brake      = timeseries(ones(10,1));
ds         = Simulink.SimulationData.Dataset;
ds         = ds.addElement( Throttlex, 'Throttlex' );
ds         = ds.addElement( Brake, 'Brake' );
signalNames= {'ds'};
signals    = { ds };
open_system(modelName);
inputMap   = AlmostBlockName(modelName, signalNames, signals);
inputStr   = getInputString(inputMap,'base');
close_system(modelName);

Simulink.SimulationData.Dataset 内の信号に対してコード スニペットを実行すると、変数 inputStr には文字列 'ds.getElement('Throttlex'),ds.getElement('Brake')' が含まれます。