S-Function Builder の API を使用した S-Function の作成
R2026bこの例では、外部 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 files: ### 'mySFcn.c' created successfully Generating files: ### 'mySFcn_wrapper.c' created successfully Generating files: ### Output folder is '/tmp/Bdoc_3323260_1915631/tp1b6f64c4/simulink_general-ex62441600' Generating files: ### 'mySFcn.tlc' created successfully Compiling: Compiling 'mySFcn.c' ....Please wait ### Using toolchain: GNU gcc/g++ | gmake (64-bit Linux) ### Creating '/tmp/Bdoc_3323260_1915631/tp1b6f64c4/simulink_general-ex62441600/SFBTemp/mex/mySFcn.mk' ... ### Building 'mySFcn': "/mathworks/devel/bat/filer/batfs2566-0/Bdoc.3323260/build/runnable/matlab/bin/glnxa64/gmake" -j 4 -l 4 -f mySFcn.mk all gcc -c -fwrapv -fPIC -Wno-error=incompatible-pointer-types -Wno-error=stringop-overflow -O0 -Wno-implicit-function-declaration -DMATLAB_MEX_FILE -DUSE_PUBLISHED_ONLY -DMATLAB_MEXCMD_RELEASE=R2018a -DMATLAB_DEFAULT_RELEASE=R2018a -I/mathworks/devel/bat/filer/batfs2566-0/Bdoc.3323260/build/runnable/matlab/simulink/include -I/mathworks/devel/bat/filer/batfs2566-0/Bdoc.3323260/build/runnable/matlab/extern/include -o "mySFcn.o" "/tmp/Bdoc_3323260_1915631/tp1b6f64c4/simulink_general-ex62441600/mySFcn.c" gcc -c -fwrapv -fPIC -Wno-error=incompatible-pointer-types -Wno-error=stringop-overflow -O0 -Wno-implicit-function-declaration -DMATLAB_MEX_FILE -DUSE_PUBLISHED_ONLY -DMATLAB_MEXCMD_RELEASE=R2018a -DMATLAB_DEFAULT_RELEASE=R2018a -I/mathworks/devel/bat/filer/batfs2566-0/Bdoc.3323260/build/runnable/matlab/simulink/include -I/mathworks/devel/bat/filer/batfs2566-0/Bdoc.3323260/build/runnable/matlab/extern/include -o "mySFcn_wrapper.o" "/tmp/Bdoc_3323260_1915631/tp1b6f64c4/simulink_general-ex62441600/mySFcn_wrapper.c" gcc -c -fwrapv -fPIC -Wno-error=incompatible-pointer-types -Wno-error=stringop-overflow -O0 -Wno-implicit-function-declaration -DMATLAB_MEX_FILE -DUSE_PUBLISHED_ONLY -DMATLAB_MEXCMD_RELEASE=R2018a -DMATLAB_DEFAULT_RELEASE=R2018a -I/mathworks/devel/bat/filer/batfs2566-0/Bdoc.3323260/build/runnable/matlab/simulink/include -I/mathworks/devel/bat/filer/batfs2566-0/Bdoc.3323260/build/runnable/matlab/extern/include -o "c_mexapi_version.o" "/mathworks/devel/bat/filer/batfs2566-0/Bdoc.3323260/build/runnable/matlab/extern/version/c_mexapi_version.c" ### Creating shared library "../../mySFcn.mexa64" ... g++ -shared -Wl,--no-undefined -Wl,--version-script,mySFcn.def -o ../../mySFcn.mexa64 mySFcn.o mySFcn_wrapper.o c_mexapi_version.o -Wl,--start-group -L/mathworks/devel/bat/filer/batfs2566-0/Bdoc.3323260/build/runnable/matlab/bin/glnxa64 -lmx -lmex -Wl,--end-group ### Created: "../../mySFcn.mexa64" ### Successfully generated all binary outputs. gmake: Nothing to be done for `all'.
シミュレーション環境の構成
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);