Main Content

転送テーブルを使用したライブラリ ブロックの互換性の維持

転送テーブルでは、ライブラリ ブロックの古いバージョンでモデルを保存した場合、ライブラリのブロックに対する変更によってモデルに不具合が発生していないことを確認できます。転送テーブルは、ライブラリのパスまたは名前を変更したり、ライブラリ ブロックのパラメーターを追加、削除、名前変更したりした場合に、ライブラリ ブロックの互換性を維持するのに役立ちます。詳細については、カスタム ライブラリの作成を参照してください。

古いライブラリ ブロックを新しいライブラリ ブロックにマッピングする転送テーブル エントリを作成します。モデルを開くと、データまたは機能を失わずに古いライブラリ ブロックへのリンクが自動的に更新されます。転送テーブルは、モデルを開くか、モデルを閉じるか、add_block または replace_block コマンドを実行すると実行されます。

転送テーブル エントリは以下の場合に作成します。

  • ブロックの名前を変更する。

  • ブロックをあるライブラリから別のライブラリに移動する。

  • ブロックからパラメーターを追加または削除する。

  • ブロックの機能を分割する。

名前が変更されたブロックの転送テーブル エントリ

ライブラリ testlib 内のブロック名が ss1 から ss2 に変更される例について考えます。

  1. ロックされたライブラリ Lib1 を開きます。

  2. ライブラリ ウィンドウの [ライブラリ] タブで、[ロックされたライブラリ] をクリックします。ライブラリのロックは解除され編集できるようになりました。

  3. [モデル化] タブで、[ライブラリ プロパティ] をクリックします。[ライブラリ プロパティ] ダイアログ ボックスが開きます。

  4. [転送テーブル] タブをクリックします。

  5. [新しいエントリの追加] をクリックします。転送テーブルに新しい列が追加されます。

  6. 古いブロックの名前を [古いブロック パス] に、対応する新しいブロック パスを [新しいブロック パス] に指定します。パスがわからない場合は、モデルのブロックを選択して [gcb の取得] ボタンをクリックします。ブロックのパスがそれぞれの列に自動的に入力されます。

古いパスから新しいパスへのマッピングが転送テーブルで作成されます。次に、ライブラリへのリンクを含むモデルを開きます。モデルの古いライブラリ ブロックへのリンクが自動的に更新されます。テーブル上部の検索バーを使用してテーブル内容をフィルターできます。列は昇順または降順に並べ替えできます。列をその値によってグループ化することもできます。

ライブラリ ブロックへのバージョン番号の割り当て

[バージョン] 列で、ライブラリ ブロックのバージョン番号を指定できます。

古いブロック名が新しいブロック名と同じである場合、転送テーブルはバージョン番号を自動的に設定します。ライブラリ バージョン LibraryVersion の初期値は、ライブラリ リンクの作成時のライブラリの ModelVersion プロパティから派生します。その後ライブラリ ブロックが更新されると、ライブラリのモデル バージョンと一致するようにライブラリ バージョンが更新されます。

バージョン番号には以下が適用されます。

  • 数値でなければなりません。

  • 古いブロック パスと新しいブロック パスが同じである場合は <major_version>. <minor_version> の形式でなければなりません。

  • 複数のドット表記を指定できません。たとえば、バージョン番号 1.3 は許可されます。バージョン番号 1.3.1 は許可されません。

  • 転送テーブルを使用して、ライブラリ ブロックをあるライブラリから別のライブラリに移動する場合、形式は重要ではありません。

あるライブラリから別のライブラリへのブロックの移動

ブロック ss1testlib1 から testlib2` に移動される例について考えます。この場合の転送テーブル エントリは次のとおりです。

moving block from one library to another

ブロックからのパラメーターの追加または削除

ライブラリ testlibss1[ゲイン] パラメーターが削除され、他の 2 つのパラメーター Initial conditionDelay length がそれに追加される例について考えます。

add or remove parameter

この変更を処理するために、変換関数を使用します。変換関数は、新しいライブラリ リンクと古いライブラリ リンク間のパラメーターの不一致を修正します。これにより、ライブラリ リンクは引き続き確実に動作します。MATLAB パスで .m 関数ファイルを使用して変換関数を定義してから、[転送テーブル][変換関数] 列でその関数を呼び出せます。

リンク付きブロックにはブロック パラメーターのインスタンスが名前と値の引数の形式で含まれ、ブロックのインスタンスを作成します。このインスタンス データは転送エントリと共に InstanceData として変換関数に渡されます。このデータは struct フィールドとして格納されます。

ライブラリ ブロックのバージョンを作成する場合、パラメーターは InstanceData から追加または削除できます。この例では、[ゲイン] パラメーターの削除前と、初期条件および遅延の長さの追加後の InstanceData は次のようになります。

前:

'RTWMemSecFuncInitTerm' 'Inherit from model'
'RTWMemSecFuncExecute' 'Inherit from model'
'RTWMemSecDataConstants' 'Inherit from model'
'RTWMemSecDataInternal' 'Inherit from model'
'RTWMemSecDataParameters' 'Inherit from model'
'ContentPreviewEnabled' 'on'
'Gain' '0'

後:

'RTWMemSecFuncInitTerm'    'Inherit from model'
'RTWMemSecFuncExecute'    'Inherit from model'
'RTWMemSecDataConstants'    'Inherit from model'
'RTWMemSecDataInternal'    'Inherit from model'
'RTWMemSecDataParameters'    'Inherit from model'
'ContentPreviewEnabled'    'on'
'DelayLength'    '1'
'InitialCondition'    '0' 

これは変換関数の構文です。

function outData = TransformationFcn(inData)

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

  • inData はフィールド ForwardingTableEntry および InstanceData をもつ構造体です。ForwardingTableEntry も構造体です。

    • ForwardingTableEntry にはブロックの古い名前、新しい名前、古いパス、および新しいパスがあります。ForwardingTableEntry のメンバーにアクセスするコードを参照してください。

  • outData は、フィールド NewInstanceDataNewBlockPath をもつ構造体です。

ブロックからパラメーターを追加または削除するには、次のようにします。

  1. インスタンス データおよび転送テーブル エントリを取得します。

  2. 名前と値のペアとブロック名のリストを抽出します。

  3. 古いブロック名と新しいブロック名を取得します。

  4. 古いブロック名と新しいブロック名が同じかどうかを確認します。そうであった場合、ブロックのバージョンを抽出します。

  5. 古いバージョンが 1.1 で、新しいバージョンが 1.2 であるかどうかを確認します。次に、Gain パラメーターを削除し、パラメーター Delay lengthInitial condition を追加します。

メモ

ライブラリ用に複数の変換関数ファイルを含めることができます。ただし、効果的に保守できるように、ライブラリごとに 1 つの変換関数を含めることをお勧めします。

パラメーターを追加または削除するには、次の変換関数を使用します。

function [outData] = txFcnTestlib(inData)
    outData.NewBlockPath = '';
    outData.NewInstanceData = [];
    
    % Get linked block instance data and forwarding entry for which
    % function is called
    instanceData = inData.InstanceData;
    forwardingTableEntry = inData.ForwardingTableEntry;
    
    % Get list of name value pair and block names
    [ParamNames{1:length(instanceData)}] = instanceData.Name;
    
    % Get old and new block paths or simply names
    oldName = forwardingTableEntry.('__slOldName__');
    newName = forwardingTableEntry.('__slNewName__');
    
    % If block names are same and its subsys block in the lib
    if strcmp(oldName, newName)
        % Get old and new block versions from forwarding table
        oldVer = forwardingTableEntry.('__slOldVersion__');
        newVer = forwardingTableEntry.('__slNewVersion__');

        % Each forwarding entry with different version can have separate
        % entry. Here, for one single entry in forwarding table i.e.
        % 1.2->1.3 or 1.3->2.0, we have separate transformation making one
        % TX Fcn for one library or block.
        if strcmp(oldName, 'testlib/ss1')
            % Forwarding with same block name ss1
            if oldVer == '1.1' && newVer == '1.2'
                % Remove gain param
                if (ismember('Gain',ParamNames))
                    for (i = 1:length(instanceData))
                        if (strcmp(instanceData(i).Name,'Gain') == true)
                            instanceData(i) = [];
                            break;
                        end
                    end
                end
                
                % Add delay length param
                if (ismember('DelayLength',ParamNames))
                    for (i = 1:length(instanceData))
                        if (strcmp(instanceData(i).Name,'Value') == true)
                            instanceData(i).Value = '5';
                            break;
                        end
                    end
                else
                    instanceData(end+1).Name = 'DelayLength';
                    instanceData(end).Value = '1';
                end
                
                % Add initial condition param
                if (ismember('InitialCondition',ParamNames))
                    for (i = 1:length(instanceData))
                        if (strcmp(instanceData(i).Name,'InitialCondition') == true)
                            instanceData(i).Value = '0';
                            break;
                        end
                    end
                else
                    instanceData(end+1).Name = 'InitialCondition';
                    instanceData(end).Value = '0';
                end
            elseif (oldVer == '1.2' && newVer == '1.3')
                % Do version 1.2 to 1.3 specific changes
            elseif (oldVer == '1.3' && newVer == '2.0')
                % Do version 1.3 to 2.0 specific changes
            else
                % Do default changes not applicable to any version if
                % required
            end
        elseif strcmp(oldName, 'testlib/ss2')
            % Forwarding for block ss2  with version upgrade
        end
    elseif strcmp(oldName, 'testlib/oldblk') && strcmp(newName, 'testlib2/newblk')
        % Block moved to new library or just block is renamed within same
        % library, no version is checked here. Do transformation is
        % required i.e. is block has been modified while renaming or moving
        % to new lib.
    elseif strcmp(oldName, 'testlib/blkX') && isempty(newName)
        % We are splitting the block into 2 different blocks. Hence, kept
        % newName empty in fwd table. Using one of the block param from its
        % instance data (which is name-value pair of all block params) to
        % decide how and what to divide.
        
        % Get the index of param we are interested in i.e. param X
        i = find(contains({instanceData.Name},'X'), true);
        
        % Based on its value, do block splitting
        switch (instanceData(i).Value)
            case 'op1'
                newName = 'newlibX/blkX';
                % Remove existing param or add new param or modify existing
                % params etc.
            case 'op2'
                newName = 'newlibY/blkX';
            otherwise
                newName = oldName;
        end
    end
    
    % Return new instance data and new block path
    outData.NewInstanceData = instanceData;
    outData.NewBlockPath = newName;
end

ブロック機能の分割

ブロックの機能の分割では、ブロックの既存のパラメーターを追加、削除、または変更して、それを新しいブロックに追加します。ブロックの機能を分割するには、次のようにします。

  1. newName 引数を空のままにします。

  2. パラメーターのインデックスと値を取得します。

  3. その値に基づいてブロックを分割します。

  4. 必要に応じて、更新された InstanceData と共に NewBlockPath を返します。

マスク パラメーター エイリアスの作成

マスク パラメーターの名前を変更する場合、古いパラメーター名を使用する既存の MATLAB® スクリプトが引き続き動作することを確認しなければなりません。互換性をチェックするために、マスク パラメーター名のエイリアスを作成できます。エイリアスによって、既存のモデル内のブロックへのリンクを再作成しなくても、ライブラリ ブロック内のマスク パラメーターの名前を変更できます。

[エディット] パラメーターを含むマスクされたブロックについて考えます。この [エディット] パラメーターのマスク パラメーター名は p1 です。

MaskObj = Simulink.Mask.get(gcb)); 
hEdit = MaskObj.getParameter('p1');

hEdit= 
% MaskParameter with properties:

           Type: 'edit'
    TypeOptions: {0×1 cell}
           Name: 'p1'
         Prompt: 'p1'
          Value: '0'
       Evaluate: 'on'
        Tunable: 'on'
      NeverSave: 'off'
         Hidden: 'off'
        Enabled: 'on'
        Visible: 'on'
        ToolTip: 'on'
       Callback: ''
          Alias: ''

[エディット] マスク パラメーターにはエイリアス名がないことに注意してください。マスク パラメーターのエイリアスを追加するには、Alias マスク パラメーターのプロパティに値を設定します。

MaskObj.Alias = 'pa'

マスク パラメーターの名前またはエイリアスのいずれかを使用して、マスク パラメーターに対して関数呼び出しを実行します。たとえば、set_param(gcb, 'p1, '10) (マスク パラメーター名) または set_param(gcb, 'pa, '10) (マスク パラメーターのエイリアス) を使用して、[エディット] マスク パラメーターの値を設定できます。

関連するトピック