How to code a time delay specified by a value saved in a parameter structure in a Matlab block?

Hi,
I'm having an issue trying to go about coding a time delay within a matlab block.
Say I have a matlab block function for basic mass balance, such as:
function [X1,Y1] = fcn(Z1)
% Set transfer function value(s).
A1 = 0.8;
% Calculate the products.
X1 = Z1*A1;
Y1 = Z1*(1-A1);
end
But I need the outputs [X1,Y1] to be delayed by a certain length of time (NOT paused) specified by a value in a parameter structure in the base workspace, such as:
% Example parameter structure index for time delay value.
myParams.dt(1) = 24.8
I've been looking into other feeds for using persistent variables, but my Matlab skills are not yet very advanced. This needs to be coded in for my purposes and not looking to use a predefined simulink block (e.g. transport delay, triggered subsystems, etc.).
Could someone please help me with this seemingly simple piece of code?
Thanks so much in advance!
Cheers,

Answers (1)

In the MATLAB Function block editor, click the "edit data" button, then add parameter. Define the "myParams" in base workspace as the parameter of the MATLAB Function block and then you will be able to use it. I am not sure if a structure has anything special, you could try a regular variable first.

5 Comments

Hi Fangjun,
Thank you for your response - that's definitely helpful for being able to access/index from my structure. There would be no issues using a regular variable - the problem is that my model will have a lot of changing parameters to optimize using Monte Carlo.
But I think your suggestion will work for my needs re: the parameter structure.
Have you any insight regarding the time delay coding portion of my question?
Thanks again and cheers.
That is actually harder. Assume you have a fixed step size but the value of myParams.dt(1) is varying, you need to program a buffer but the size of the buffer is variable. Variable-size data is usually complex in Simulink.
What you can do is to define a max-size buffer, say 500. In the MATLAB Function block, fill in and shift the buffer at every simulation step. When myParams.dt(1) = 24.8, output the 248th value. When myParams.dt(1) = 34.8, output the 348th value.
Thanks for the follow-up.
Ok but while these time parameters will be changing across different simulation replications, they will hold constant within each individual simulation run. The parameter structure is only necessary to feed the new set of parameters into the model at the beginning of each simulation trial.
That being said, I envision being able to declare the outputs as persistent variables and applying a delay with the specified time for that run (similar effect to using a transport delay block after the outputs exit the matlab block).
I've seen some code snippets for unit delays, such as:
function y = fcn(u) % Unit delay implementation that maps to a register in hardware
persistent u_d;
if isempty(u_d)
% defines initial value driven by unit delay at time step 0
u_d = cast(0, 'like', u);
end
% return delayed input from last sample time hit
y = u_d;
% store the current input
u_d = u;
But this seems to be applying a delay on the input (I'd prefer to keep a running total on the states of the output variables, i.e. X1, Y1 from my original example above), and I'm not sure how I could alter the code to use the specified time from my parameter structure.
Does that better explain what I'm trying to accomplish?
Thanks again and cheers.
The code in the comment looks right. But it is only one step delay (the delay time is the same as the simulation step).
If you want to delay for arbitrary time, you need to calculate N=DelayTime/SimulationStepTime before the simulation in your initilization routine. Then in the code, something like this:
if isempty(u_d)
u_d=zeros(1,N);
end
% shift the buffer, there might be better way than using for-loop
for k=N:-1:2
u_d(k)=u_d(k-1);
end
% take the current input
u_d(1)=u;
y=u_d(k);
Thanks for your continued input.
But I'm still confused - I don't think I need a rolling buffer because the arbitrary time is not changing during the simulation.
Going back to my original example, could I not insert the param structure as a parameter to the matlab function block (as you explained above), and use the called time parameter to modify the delay code? Something like:
function [X1,Y1] = fcn(Z1, myParams)
persistent Z1_d;
if isempty(Z1_d)
Z1_d = cast(myParams.dt(1), 'like', Z1)
end
% Set transfer function value(s).
A1 = 0.8;
% Calculate the products.
X1 = Z1_d*A1;
Y1 = Z1_d*(1-A1);
end
If I still need to calculate N=delayTime/simulationStepTime in my initialization routine, how do I go about doing that? My delayTime would be my 'myParams.dt(1)', but I'm not sure how to access the simulationStepTime...
Thanks again for your time!
Cheers

Sign in to comment.

Categories

Products

Release

R2021b

Asked:

on 12 Apr 2022

Commented:

on 20 Apr 2022

Community Treasure Hunt

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

Start Hunting!