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

4 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!

Categories

Find more on Block and Blockset Authoring in Help Center and File Exchange

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!