Level-2 S-function: finding the correct input value and type

5 views (last 30 days)
I used chatgpt to write a code for a s-function block for a system of 2 ODEs. It is suppose to have an input and two outputs. The two ODEs are as follows:
m, g, R, L are constants, T is the input, the outputs are supposed to be v and theta. The code, saved as myODESFunction.m, is as follows:
function sys = myODESFunction(t, x, u, flag)
m = 384986.21; % Mass
g = 9.81; % Gravity
R = 3.83; % drag constant
L = 59.367; % lift constant
switch flag
case 0 % Initialization
sizes = simsizes;
sizes.NumContStates = 2; % Number of continuous states
sizes.NumDiscStates = 0; % Number of discrete states
sizes.NumOutputs = 2; % Number of outputs
sizes.NumInputs = 1; % Number of inputs
sizes.DirFeedthrough = 0; % No direct feedthrough
sizes.NumSampleTimes = 1; % One continuous sample time
sys = simsizes(sizes);
x0 = [252.222; 0.1745]; % Initial state vector
str = [];
ts = [0 0]; % Continuous sample time
sys = x0;
sys(2) = str;
sys(3) = ts;
case 3 % Update
sys = [];
case 1 % Derivatives
x1 = x(1); % v
x2 = x(2); % theta
u1 = u(1); % T
% Define your differential equations here
dx1_dt = (-m*g*sin(x2) - R*x1^2 + u1) / m;
dx2_dt = (-m*g*cos(x2) + L*x1^2) / (m*x1);
sys = [dx1_dt; dx2_dt];
case 2 % Outputs
sys = [x(2); x(1)]; % Output theta and velocity
end
But when I tried to use it in a Level-2 s-function block, by entering [252.222 0.1745] as the two intial conditions in my code into the "s-function parameters" field, it tells me I don't have enough input arguments. But what more could I add?

Answers (1)

Aiswarya
Aiswarya on 15 Dec 2023
Edited: Aiswarya on 15 Dec 2023
I understand that you are trying to write a Level 2 S-function for a system of 2 ODEs. The error you are getting "Not enough input arguments" is because your function is a Level 1 S-function which you are trying to use with the Level-2 S-function block in Simulink. There are some issues with the chatgpt code for the Level 1 S-function as well.
If you want to write Level 2 S-function, you may refer to the following documentation: https://www.mathworks.com/help/simulink/sfg/writing-level-2-matlab-s-functions.html. We can also convert Level 1 S-function to Level 2 S-function by following the steps explained in detail in the following link : https://www.mathworks.com/help/simulink/sfg/maintaining-level-1-matlab-s-functions.html.
Based on your code, I have provided a Level 2 S-function code below:
function myODESFunction_Level2(block)
% Level-2 MATLAB S-Function for myODESFunction
setup(block);
%endfunction
function setup(block)
%% Register number of dialog parameters (2 parameters, v and theta)
block.NumDialogPrms = 2;
%% Register number of input and output ports
block.NumInputPorts = 1;
block.NumOutputPorts = 2;
%% Setup functional port properties to dynamically
%% inherited.
block.SetPreCompInpPortInfoToDynamic;
block.SetPreCompOutPortInfoToDynamic;
block.InputPort(1).Dimensions = 1;
block.InputPort(1).DirectFeedthrough = false;
block.OutputPort(1).Dimensions = 1;
block.OutputPort(2).Dimensions = 1;
%% Set block sample time to continuous
block.SampleTimes = [0 0];
%% Setup Dwork
block.NumContStates = 2;
%% Set the block simStateCompliance to default (i.e., same as a built-in block)
block.SimStateCompliance = 'DefaultSimState';
%% Register methods
block.RegBlockMethod('InitializeConditions', @InitConditions);
block.RegBlockMethod('Outputs', @Output);
block.RegBlockMethod('Derivatives', @Derivative);
%endfunction
function InitConditions(block)
%% Initialize Dwork
block.ContStates.Data(1) = block.DialogPrm(1).Data;
block.ContStates.Data(2) = block.DialogPrm(2).Data;
%endfunction
function Output(block)
block.OutputPort(1).Data = block.ContStates.Data(1);
block.OutputPort(2).Data = block.ContStates.Data(2);
%endfunction
function Derivative(block)
m = 384986.21; % Mass
g = 9.81; % Gravity
R = 3.83; % drag constant
L = 59.367; % lift constant
x1 = block.DialogPrm(1).Data;
x2 = block.DialogPrm(2).Data;
u1 = block.InputPort(1).Data;
block.Derivatives.Data(1) = (-m*g*sin(x2) - R*x1^2 + u1) / m;
block.Derivatives.Data(2) = (-m*g*cos(x2) + L*x1^2) / (m*x1);
%endfunction
Now you can use the Level 2 S-function block in Simulink and set the block parameters as shown in the figure below:
This is similar to a Level 2 S-function example provided in MATLAB (msfcn_limintm.m). This can be accessed by the command
edit('msfcn_limintm.m')
Hope this helps!

Products


Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!