S-Function Builder の API を使用した S-Function の作成
この例では、外部 C コードを統合してコンフィギュレーションの仕様から S-Function を生成するように、S-Function Builder ブロックをプログラムで構成する方法を示します。この例では、バネとダンパーにつながれた質量の位置と速度を C コードで計算します。マス-バネ-ダンパー系は一連の離散状態の微分方程式を使用して表されます。
モデルの設定
このセクションでは、モデル sfcnbuilderapi を作成して構成する方法を示します。この例を初めて実行するときは、new_system 関数を使用してモデルを作成します。
ただし、モデルが作業フォルダー内に既に存在する場合は、新しいモデルを作成する前に、コマンド ラインで clear mex を実行してから delete sfcnbuilderapi.slx mySFcn.mexw64 を使用します。また、前の MATLAB® セッションのモデルが開いている場合は閉じます。
mdl = "sfcnbuilderapi";
new_system(mdl);S-Function Builder ブロックを追加します。
add_block('simulink/User-Defined Functions/S-Function Builder',[gcs,'/S-Function Builder']);
ブロック ハンドル blk を取得します。このブロック ハンドルは S-Function Builder ブロックを構成するために使用します。
blk = getSimulinkBlockHandle('sfcnbuilderapi/S-Function Builder');S-Function Builder ブロックの構成
S-Function Builder ブロックの構成では、S-Function を設定し、状態とパラメーターを追加して、S-Function Builder ブロックのビルド オプションを設定します。
S-Function の設定
S-Function の名前を mySFcn に設定します。
Simulink.SFunctionBuilder.setSFunctionName(blk,'mySFcn');ブロックの設定を指定します。コードの配列レイアウトは列優先、サンプル モードは離散、サンプル時間は 0.1 秒です。
Simulink.SFunctionBuilder.setSettings(blk, ArrayLayout= "Column", SampleMode="Discrete", SampleTime= 0.1, DirectFeedthrough=true, CodeReuseSupport = false); Simulink.SFunctionBuilder.setTargetLanguage(blk,'c');
S-Function Builder ブロックの状態とパラメーターの追加
状態と速度の 2 つの離散状態を追加します。
Simulink.SFunctionBuilder.add(blk,'DiscreteState', InitialCondition="1"); %% Position Simulink.SFunctionBuilder.add(blk,'DiscreteState', InitialCondition="0"); %% Velocity
離散時間でのマス-バネ-ダンパー系の状態空間表現は次のとおりです。
ここで、ベクトル 、 は の時間における状態、入力、出力のベクトルです。
この例では、質量は 3.6 kg、バネ定数は 400 N/m、減衰係数は 10 N-s/m です。このワークフローでは、システム行列 () と入力配列 () の値はc2d (System Identification Toolbox)関数を使用して取得されます。
パラメーター値を追加します。
Simulink.SFunctionBuilder.add(blk,'Parameter', Name = "A", DataType= "double", Value ="[0.5369 0.07204; -8.004 0.3368]"); Simulink.SFunctionBuilder.add(blk,'Parameter', Name = "B", DataType= "double", Value ="[0.001158; 0.02001]"); Simulink.SFunctionBuilder.add(blk,'Parameter', Name = "C", DataType= "double", Value ="[1 0]"); Simulink.SFunctionBuilder.add(blk,'Parameter', Name = "D", DataType= "double", Value ="0");
S-Function メソッドのコードの指定
出力コードを追加します。このコード セクションは S-Function の出力値を決定します。
OL = "y0[0]= C[0]*xD[0]+C[1]*xD[1]+D[0]*u0[0];"; Simulink.SFunctionBuilder.setUserCode(blk,"output",OL);
更新コードを追加します。このコードはシミュレーションの各タイム ステップにおける状態値を計算します。
U1 = "real_T tempX[2] = {0.0,0.0};" + newline + "tempX[0] = A[0]*xD[0]+ A[2]*xD[1]+ B[0]*u0[0];"+ newline + "tempX[1]= A[1]*xD[0]+ A[3]*xD[1]+ B[1]*u0[0];" + newline + "xD[0] = tempX[0];" + newline + "xD[1] = tempX[1];"; U1 = U1 + newline + "tempX[1]= A[1]*xD[0]+ A[3]*xD[1]+ B[1]*u0[0];" + newline + "xD[0] = tempX[0];" + newline + "xD[1] = tempX[1];"; Simulink.SFunctionBuilder.setUserCode(blk,"update", U1);
S-Function Builder ブロックのビルド オプションの指定
この例では、ビルド ステップはログに記録されず、生成される MEX ファイルにデバッグ情報は含まれません。ただし、ShowCompileSteps の値を true に変更すると、ビルド ステップをログに記録できます。また、CreateDebuggableMEX の値を true に変更すると、生成される MEX ファイルにデバッグ情報を含めることができます。
Simulink.SFunctionBuilder.setBuildOptions (blk, "ShowCompileSteps",false,"CreateDebuggableMEX",false,"GenerateWrapperTLC",true); Simulink.SFunctionBuilder.build(blk);
Generating 'mySFcn.c' ....Please wait ### Output folder is '/tmp/Bdoc25b_2988451_621513/tpc20de554/simulink_general-ex62441600' ### 'mySFcn.c' created successfully ### 'mySFcn_wrapper.c' created successfully ### 'mySFcn.tlc' created successfully Compiling 'mySFcn.c' ....Please wait ### S-function 'mySFcn.mexa64' created successfully
シミュレーション環境の構成
Source ブロックと Sink ブロックを追加します。
add_block('simulink/Sources/Step',[gcs,'/Input']); % Step block add_block('simulink/Sinks/Scope',[gcs,'/Output']); % Scope block that displays the system response myScopeConfiguration = get_param('sfcnbuilderapi/Output','ScopeConfiguration'); myScopeConfiguration.OpenAtSimulationStart = true;
S-Function Builder ブロックを基準にして入力ブロックと出力ブロックを配置します。
h = getSimulinkBlockHandle('sfcnbuilderapi/S-Function Builder'); pos = get_param(h,'Position'); pos = [pos(1)*2 pos(2)*2 pos(3)*2 pos(4)*2]; set_param('sfcnbuilderapi/S-Function Builder','Position',pos); posStep = [pos(1)-200 pos(2) pos(3)-200 pos(4)]; %% Position of the Step block relative to the S-Function Builder block set_param('sfcnbuilderapi/Input','Position',posStep); posScope = [pos(1)+200 pos(2) pos(3)+200 pos(4)]; %% Position of the Scope block relative to the S-Function Builder block set_param('sfcnbuilderapi/Output','Position',posScope);
S-Function Builder ブロックを Step ブロックに接続します。
srcIn = 'sfcnbuilderapi/Input'; dstIn = 'sfcnbuilderapi/S-Function Builder'; Simulink.connectBlocks(srcIn,dstIn);
S-Function Builder ブロックを Scope ブロックに接続します。
srcOut = 'sfcnbuilderapi/S-Function Builder'; dstOut = 'sfcnbuilderapi/Output'; Simulink.connectBlocks(srcOut,dstOut);

開ループ モデルのシミュレーション
テスト環境を作成するには、入力端子 (u0) に Step ブロックを接続し、出力 (y0) を表示するために Scope ブロックを接続します。モデルをシミュレートし、システムに対する開ループのステップ応答を可視化します。
save_system ("sfcnbuilderapi") outOL = sim("sfcnbuilderapi");
開ループ モデルから閉ループ モデルへの更新
コントローラーは、システムの整定時間を短縮する極を配置するためにplace (Control System Toolbox)関数を使用して設計されています。S-Function Builder ブロックのパラメーターを更新します。
Simulink.SFunctionBuilder.update(blk,"Parameter",Name="A",FieldToUpdate="Value",NewValue ="[0.8632 0.07103; -2.415 0.437]"); Simulink.SFunctionBuilder.update(blk,"Parameter",Name="B",FieldToUpdate="Value",NewValue ="[0.001117; 0.01973]"); Simulink.SFunctionBuilder.update(blk,"Parameter",Name="C",FieldToUpdate="Value",NewValue ="[1 0]"); Simulink.SFunctionBuilder.update(blk,"Parameter",Name="D",FieldToUpdate="Value",NewValue ="[0]");
閉ループ モデルのシミュレーション
sim コマンドを使用してモデルをシミュレートし、Scope ブロックを使用してステップ応答を可視化します。
outCL = sim("sfcnbuilderapi"); save_system("sfcnbuilderapi");

close_system("sfcnbuilderapi",1);