プログラム可能なスーパーブロックのアトミックタブ

プログラム可能なスーパーブロックのブロックビルダーのアトミックタブを定義します。

プログラム可能なスーパーブロックでは、シミュレーション関数を定義する必要はありません。アトミックタブでSetParameters関数を定義するだけです。定義されているのは基本的にサブシステムであり、OMLコードを使ってブロック内のダイアグラムを構築します。このコードには以下が含まれます:
_block = vssAddNewObject('SubSystem', _diagram);
_diagr = vssCreateObject('Diagram');

_diagrにブロックとリンクを入力し、ダイアグラムを構築します。

ダイアグラムでブロックを定義するには、以下の手順が必要です:

  1. OML structを使用してブロックパラメーターを定義します。
  2. 対応するライブラリからブロックをロードします。
  3. ブロックをインスタンス化します。
例として、init_condtypexternalActivationのパラメータを持つブロックDiscreteDelayを考えてみましょう。このブロックは、ダイアグラム_diagrで次のようにインスタンス化できます:
_params = struct();
_params.init_cond = z0;
_params.typ = 'double';
_params.externalActivation = 0;
vssLoadBlock('system', 'Dynamical', 'DiscreteDelay');
_vss._palettes.('_system').('Dynamical').('DiscreteDelay').setparams(_diagr, 'DiscreteDelay', _params);

この例では、初期条件はz0に設定されています。これはプログラム可能なスーパーブロックのパラメータでなければなりません。ブロック間のリンクは、OML関数、vssAdd_Linkを使用して確立します。例えば、次の命令は、Inputブロックの最初の出力を、通常のリンクを介してDiscreteDelayブロックの最初の出力に接続します:

vssAdd_Link(_diagram, 'Input', 'DiscreteDelay', 1, 1, 0, 1, 1);

マスクされたスーパーブロックでブロックビルダーを起動すると、ブロックの SetParameters関数が自動的に生成されます。 この関数には、スーパーブロックのダイアグラムを作成するコードが含まれています。この場合、ダイアグラムは固定されています。

固定ダイアグラムのブログラム可能なスーパーブロックは、標準的なマスクされたスーパーブロックでも実装できるため、有用ではないかもしれません。しかし、より一般的なプログラム可能なスーパーブロックのSetParameters関数を定義する際の出発点として役立ちます。このアプローチは次の例で説明します。

この例では、shift registerブロックを作成し、各レジスタ値を個別の出力から露出させることが問題です。レジスタと出力の数は可変で、ブロックパラメータとして与えられるnoutに等しくなります。3つのレジスタと出力(nout=3)の場合、図は次のようになります:
スーパーブロックは、プログラム可能なスーパーブロックを構築するための出発点として使用されます。モデルの初期化スクリプトで未定義の変数z0noutを定義して、マスクするスーパーブロックを準備します。その後、自動マスクを適用できます:
結果は次のとおりです。

スーパーブロックがマスクされたら、スーパーブロックを選択した状態でブロックビルダーをクリックします。ブロックビルダーインターフェイスには、新しいブロックを定義するための出発点が含まれています。

いくつかのプロパティ、特に"ポート"タブのポート数を変更する必要があります。最初はポートが固定されています:
ポート数を2に減らし、出力を可変とし、noutに等しくします。
パラメータータブで、...をクリックしてnoutパラメータのプロパティを編集し、TypeをNumber、Valueを4に変更します。
アトミックタブでは、最初のSetParametersコードでブロックをインスタンス化し、 nout=3の場合の接続を行い、ダイアグラムを構築します。この時点ではグラフィカルプロパティは使用されていません。ブロックビルダーが生成する固定ダイアグラムのコードは以下のとおりです:
function _setdiagram_1 (_diagram, _label, __fenv__)
_curdiagram=_diagram;
_curlabel=_label;
importenv(__fenv__);
_diagram=_curdiagram;
_label=_curlabel;
clear _curdiagram;
clear _curlabel;
global _vss;
global __OBJ_ERR_;
_parent = __OBJ_ERR_.('block');
__OBJ_ERR_.('type')='context';
if isscalar(z0) z0=z0*ones(nout,1);end
__OBJ_ERR_.('block')=vssConstructBlockFullName(_parent,'Output_2');
__OBJ_ERR_.('type')='parameters';
_params=struct();
_params.portNumber=3;
_params.insize=[-1;-2];
_params.intyp='inherit';
vssLoadBlock('system','Ports','Output');
_vss._palettes.('_system').('Ports').('Output').setparams(_diagram,'Output_2',_params);
__OBJ_ERR_.('block')=vssConstructBlockFullName(_parent,'DiscreteDelay_2');
__OBJ_ERR_.('type')='parameters';
_params=struct();
_params.init_cond=z0(3);
_params.typ='double';
_params.externalActivation=0;
vssLoadBlock('system','Dynamical','DiscreteDelay');
_vss._palettes.('_system').('Dynamical').('DiscreteDelay').setparams(_diagram,'DiscreteDelay_2',_params);
__OBJ_ERR_.('block')=vssConstructBlockFullName(_parent,'Output_1');
__OBJ_ERR_.('type')='parameters';
_params=struct();
_params.portNumber=2;
_params.insize=[-1;-2];
_params.intyp='inherit';
vssLoadBlock('system','Ports','Output');
_vss._palettes.('_system').('Ports').('Output').setparams(_diagram,'Output_1',_params);
__OBJ_ERR_.('block')=vssConstructBlockFullName(_parent,'Output');
__OBJ_ERR_.('type')='parameters';
_params=struct();
_params.portNumber=1;
_params.insize=[-1;-2];
_params.intyp='inherit';
vssLoadBlock('system','Ports','Output');
_vss._palettes.('_system').('Ports').('Output').setparams(_diagram,'Output',_params);
__OBJ_ERR_.('block')=vssConstructBlockFullName(_parent,'Input');
__OBJ_ERR_.('type')='parameters';
_params=struct();
_params.portNumber=1;
_params.outsize=[-1;-2];
_params.outtyp='inherit';
_params.dept=0;
vssLoadBlock('system','Ports','Input');
_vss._palettes.('_system').('Ports').('Input').setparams(_diagram,'Input',_params);
__OBJ_ERR_.('block')=vssConstructBlockFullName(_parent,'Block');
__OBJ_ERR_.('type')='parameters';
_params=struct();
vssLoadBlock('system','Links','Split');
_vss._palettes.('_system').('Links').('Split').setparams(_diagram,'Block',_params);
__OBJ_ERR_.('block')=vssConstructBlockFullName(_parent,'DiscreteDelay_1');
__OBJ_ERR_.('type')='parameters';
_params=struct();
_params.init_cond=z0(2);
_params.typ='double';
_params.externalActivation=0;
vssLoadBlock('system','Dynamical','DiscreteDelay');
_vss._palettes.('_system').('Dynamical').('DiscreteDelay').setparams(_diagram,'DiscreteDelay_1',_params);
__OBJ_ERR_.('block')=vssConstructBlockFullName(_parent,'Split');
__OBJ_ERR_.('type')='parameters';
_params=struct();
vssLoadBlock('system','Links','Split');
_vss._palettes.('_system').('Links').('Split').setparams(_diagram,'Split',_params);
__OBJ_ERR_.('block')=vssConstructBlockFullName(_parent,'DiscreteDelay');
__OBJ_ERR_.('type')='parameters';
_params=struct();
_params.init_cond=z0(1);
_params.typ='double';
_params.externalActivation=0;
vssLoadBlock('system','Dynamical','DiscreteDelay');
_vss._palettes.('_system').('Dynamical').('DiscreteDelay').setparams(_diagram,'DiscreteDelay',_params);
vssAdd_Link(_diagram,'Output_2','DiscreteDelay_2',1,1,1,0,1);
vssAdd_Link(_diagram,'DiscreteDelay_1','Block',1,1,0,1,1);
vssAdd_Link(_diagram,'Block','Output_1',1,1,0,1,1);
vssAdd_Link(_diagram,'DiscreteDelay_2','Block',1,2,1,0,1);
vssAdd_Link(_diagram,'Input','DiscreteDelay',1,1,0,1,1);
vssAdd_Link(_diagram,'DiscreteDelay','Split',1,1,0,1,1);
vssAdd_Link(_diagram,'Split','DiscreteDelay_1',1,1,0,1,1);
vssAdd_Link(_diagram,'Split','Output',2,1,0,1,1);
end
_block = vssAddNewObject('SubSystem',_diagram);
_diagr= vssCreateObject('Diagram');
_setdiagram_1(_diagr,_label,getcurrentenv());
vssSet_SubSystem(_block,1,3,0,0,0,_label,_diagr);

変数__OBJ_ERR_は、正確なエラーメッセージを生成するためのエラー位置の固定に使用されます。プログラム可能なスーパーブロックの場合、これはあまり有用ではなく、すべてのエラーメッセージを親ブロックであるプログラム可能なスーパーブロックに参照する方がよいでしょう。一般的に、ユーザーはこのブロックの内容を知りません。

上記のコードを拡張して、nout任意の数の遅延と出力に対して動作させることができます。個々のエラータグが削除され、すべてのエラーが親に参照されることに注意してください。スーパーブロックのコンテキストで使用される以下の新しいスクリプトは、より良いエラーメッセージを生成するために拡張されています:
function shiftreg_setdiagram_1 (_diagram, _label, __fenv__)
_curdiagram=_diagram;
_curlabel=_label;
importenv(__fenv__);
_diagram=_curdiagram;
_label=_curlabel;
clear _curdiagram;
clear _curlabel;
global _vss;
global __OBJ_ERR_;
_parent = __OBJ_ERR_.('block');
__OBJ_ERR_.('type')='context';
if isscalar(z0) z0=z0*ones(nout,1); elseif length(z0)~=nout error('size of z0 must match nb of outputs.');end
__OBJ_ERR_.('block')=vssConstructBlockFullName(_parent,'DiscreteDelay');
_params=struct();
_params.init_cond=z0(1);
_params.typ='double';
_params.externalActivation=0;
vssLoadBlock('system','Dynamical','DiscreteDelay');
_vss._palettes.('_system').('Dynamical').('DiscreteDelay').setparams(_diagram,'DiscreteDelay',_params);
_params=struct();
vssLoadBlock('system','Links','Split');
_vss._palettes.('_system').('Links').('Split').setparams(_diagram,'Split_1',_params);
_params=struct();
_params.portNumber=1;
_params.outsize=[-1;-2];
_params.outtyp='inherit';
_params.dept=0;
vssLoadBlock('system','Ports','Input');
_vss._palettes.('_system').('Ports').('Input').setparams(_diagram,'Input',_params);
_params=struct();
_params.portNumber=1;
_params.insize=[-1;-2];
_params.intyp='inherit';
vssLoadBlock('system','Ports','Output');
_vss._palettes.('_system').('Ports').('Output').setparams(_diagram,'Output',_params);
vssAdd_Link(_diagram,'Input','DiscreteDelay',1,1,0,1,1);
vssAdd_Link(_diagram,'DiscreteDelay','Split_1',1,1,0,1,1);
vssAdd_Link(_diagram,'Split_1','Output',2,1,0,1,1);
for i=2:nout-1
	_params=struct();
	_params.init_cond=z0(i);
	_params.typ='double';
	_params.externalActivation=0;
	vssLoadBlock('system','Dynamical','DiscreteDelay');
	_vss._palettes.('_system').('Dynamical').('DiscreteDelay').setparams(_diagram,['DiscreteDelay_',...
	num2str(i-1)],_params);
	_params=struct();
	_params.portNumber=i;
	_params.insize=[-1;-2];
	_params.intyp='inherit';
	vssLoadBlock('system','Ports','Output');
	_vss._palettes.('_system').('Ports').('Output').setparams(_diagram,['Output_',num2str(i-1)],_params);
	_params=struct();
	vssLoadBlock('system','Links','Split');
	_vss._palettes.('_system').('Links').('Split').setparams(_diagram,['Split_',num2str(i)],_params);
	vssAdd_Link(_diagram,['Split_',num2str(i-1)],['DiscreteDelay_',num2str(i-1)],1,1,0,1,1);
	vssAdd_Link(_diagram,['DiscreteDelay_',num2str(i-1)],['Split_',num2str(i)],1,1,0,1,1);
	vssAdd_Link(_diagram,['Split_',num2str(i)],['Output_',num2str(i-1)],2,1,0,1,1);
end
_params=struct();
_params.init_cond=z0(nout);
_params.typ='double';
_params.externalActivation=0;
vssLoadBlock('system','Dynamical','DiscreteDelay');
_vss._palettes.('_system').('Dynamical').('DiscreteDelay').setparams(_diagram,['DiscreteDelay_',...
	num2str(nout-1)],_params);
_params=struct();
_params.portNumber=nout;
_params.insize=[-1;-2];
_params.intyp='inherit';
vssLoadBlock('system','Ports','Output');
_vss._palettes.('_system').('Ports').('Output').setparams(_diagram,['Output_',num2str(nout-1)],_params);
vssAdd_Link(_diagram,['DiscreteDelay_',num2str(nout-1)],['Output_',num2str(nout-1)],1,1,0,1,1);
vssAdd_Link(_diagram,['Split_',num2str(nout-1)],['DiscreteDelay_',num2str(nout-1)],1,1,0,1,1);
end
_block = vssAddNewObject('SubSystem',_diagram);
_diagr= vssCreateObject('Diagram');
shiftreg_setdiagram_1(_diagr,_label,getcurrentenv());
vssSet_SubSystem(_block,1,nout,0,0,0,_label,_diagr);

新しいスクリプトを見ると、新しい繰り返しブロックには _2_3noutまでの拡張子が付けられています。これは名前のないリンクには必要ありません。

ブロックの最初のレイヤーを作成した後、次のforループ内で繰り返し構造が作成されます:

for i=2:nout-1
    ....
end

最後のレイヤーはforループの後に作成されます。新しいブロックの出力数を変更するために、コードに別の変更を加える必要があります:

vssSet_SubSystem(_block,1,3,0,0,0,_label,_diagr);

これは以下に置き換えられます:

vssSet_SubSystem(_block,1,nout,0,0,0,_label,_diagr);

ブロックの出力は、3ではなくnout

新しいブロックを別のモデルに移動し、そのパラメータを適切な値に設定してテストすることができます。