MATLAB Answers

Manage constants and custom functions in Simulink

8 views (last 30 days)
Stefano Casarin
Stefano Casarin on 22 Jun 2020
I am working on a dynamic simulation of a physical hydraulic system which I can not describe in a very detailed way.
The machine of interest in the issue, and which I want to represent in Simulink as a block, has the following characteristics:
  • it takes as input three signals: and outputs two quantities: (all double precision floats).
  • The relationship between quantities are the following: , where f and g are two polynomials of 2nd degree in x and y.
  • Everytime z changes, the polynomial coefficients of f and g change too. Better phrased: for each value of z there exists one and only one set of coefficients of the polynomial. Both and are arrays that contain the polynomial coefficients: e.g. .
  • z changes according a certain control logic that has not been yet implemented, but anyways different strategies will be tested: one with z constant over time, one with z being updated every T minutes/seconds, and one with z being updated continuously.
I am now struggling with creating a proper block subsystem with the related blocks in Simulink to address this situation.
The polynomial coefficients are calculated from a set of experimental data which is interpolated under some constraints (with lsqlin). An example is given by the following function:
function [cf,cg,DB] = load_coeffs(z,const1,const2,DB)
% const1, const2 are fixed constants
% DB is a struct
qkey = erase(strcat('z',num2str(z)),'.');
if ~isempty(DB.(key))
[cf,cg] = DB.(key)
else
[cf,cg] = genCoeffs(z,const1,const2) %this function contains nested functions
%that load the experimental data, genera-
%tes the C,d,A,b matrices for lsqlin and
%runs lsqlin, and checks that the coeffi-
%cients respect the set constraints.
DB.(key) = [cf,cg];
end
After the simulation, DB is saved into a .mat file, and it is loaded before the simulation is started.
One approach I have thought to implement this in Simulink was to add a MATLAB function (waring: the following function is only conceptual, I know that it would probably not work in Simulink, I have implemented a conceptually equivalent one that was working).
function [m,n,DB] = myfun(x,y,z,DB)
coder.extrinsic('load_coeffs')
[cf,cg,DB] = load_coeffs(z,const1,const2,DB)
m = 0;
n = 0;
m = cf(1) + cf(2)*x + cf(3)*y + cf(4)*x^2 + cf(5)*x*y + cf(6)*y^2;
n = cg(1) + cg(2)*x + cg(3)*y + cg(4)*x^2 + cg(5)*x*y + cg(6)*y^2;
The m,n signals will then go around the model's blocks, whereas the DB signal goes to a To Workspace block.
This approach proved to be extremely slow (0.01 simulation time was performed in around 10 seconds). Hence I have to change strategy.
I thought about having two "Constant" blocks, for respectively and have them updated during the simulation. This approach is considered bad practice.
Another approach would be using Simulink Bus, but I have never used them and I would like if they are actually useful for my purposes before starting to study their documentation.
A third approach would be running a script that fills the DB with any possible state of z before running the simulation, use a Difference block to check when the z signal changes, and use the output signal to activate a switch state.
Eventually I have thought about event listeners.
This is the first time I am addressing this kind of situation, and I have no previous experience about much of the approaches I have thought about.
Thank you.

  0 Comments

Sign in to comment.

Answers (0)


Translated by