Manage constants and custom functions in Simulink
3 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
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 commentaires
Réponses (0)
Voir également
Catégories
En savoir plus sur Upgrading Hydraulic Models to Use Isothermal Liquid Blocks dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!