カスタム マッピングされる外部入力をもつマッピング モードの使用
この例では、Simulink® マッピング モードに類似したカスタム マッピング アルゴリズムを実装する方法を示します。関数getSlRootInportMap
およびgetRootInportMap
を使用して、カスタム マッピングを実装します。
この例の実行にあたっては、getRootInportMap
コマンドおよびルート Inport マッパー ツールに精通していることを前提としています。詳細については、ルート Inport 信号データのマッピングを参照してください。
ワークフロー
この例では、組み込みの 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);
不足している入力信号の検出
前の手順では、ブロック名マッピング モードを使って、マッピングを作成しました。許容誤差内の信号に関連付けられていない、空の inputMap
と inputMap(s)
を考慮しなければなりません。関数 getSlRootInportMap
は、出力変数 hasASignal
を使って、これらの信号にフラグを設定しました。このためには、以下のことを行います。
変数
inputMap
をチェックします。変数
inputMap
が空でない場合、inputMap
ベクトルのどの要素が信号に割り当てられなかったかを判別します。そのためには、次に示すように、hasASignal
ベクトル上で logical ~ を使用します。これでemptyIndex
ベクトルに、logical ベクトルが含まれました。true はinputMap
には信号がマッピングされていないことを意味します。getSlRootInportMap
への呼び出しの下と、ifbdIsLoaded(modelName)
への終了の前に、次のコード スニペットをコピーして貼り付けます。
if ~isempty(inputMap) emptyIndex = ~hasASignal; end
このコード スニペットは、手順 1 および 2 を自動的に実行します。
マッピングの完了
前の手順で、logical ベクトル emptyIndex
を作成し、信号に関連付けられていない inputMap オブジェクトがあるか確認しました。emptyIndex ベクトルのすべての要素が false の場合、マッピングが完了し、この節で追加したコードは実行されません。
emptyIndex
ベクトルの少なくとも 1 つの値に true が含まれている場合、信号に関連付けられていない inputMap
オブジェクトがあるということです。その inputMap に可変信号を手動で割り当てます。次に、予想される信号名と一致する信号名を使って、inputMap
をオーバーライドします。
emptyIndex ベクトルで、true の値をもつすべての項目を検出します。これらの項目は、信号に関連付ける必要がある
inputMap(s)
を指定しています。inputMap
ごとに、'BlockName' プロパティを使って、inputMap
の割り当て先となる Inport ブロックの名前を取得します。ブロック名に 'x' を追加して、
inputMap
に割り当てる信号の名前を取得します。signalNames 変数の cell 配列で、結果と各項目を比較します。
一致するものが見つかった場合、
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
カスタム マッピングの検証
カスタム マッピングを検証するには、次の手順に従います。
MATLAB パス上のファイルに関数 AlmostBlockName を保存します。
マッピング関数の結果を確認するには、次のコード スニペットを 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')' が含まれます。
参考
getRootInportMap
| getSlRootInportMap