How to continuously create an array of the latest values of a signal in SIMULINK?

38 views (last 30 days)
Commonly I'm using a 'To Workspace' block to store a certain number of the last data points in the MATLAB workspace to process them in a separate code. However, this is a quite cumbersome workaround, and I was wondering whether I could run the separate code directly in SIMULINK via a 'MATLAB Function' block. I just don't know how to continuously create an array of the latest values. Specifically, I want to create an array to store the values ​​of one period of sinusoidal force and position values ​​in order to calculate a linear regression for the spring stiffness. Any ideal?
  4 Comments
Walter Roberson
Walter Roberson on 29 Dec 2024
If you use a To Workspace block, then the workspace will be updated each time that Simulink is paused or stopped -- but will not be updated while Simulink is actively running.
If you use a MATLAB function block, Yes, you can store values in a shifting buffer that is a global variable or is tied to the base workspace, and that variable will be updated while Simulink is busy running. However, there is no callback or signal between Simulink and MATLAB. sim() calls do not return until simulation is finished. I believe that if you click the Run button in Simulink that Simulink will run asynchronously with MATLAB... but there is no "hook" for MATLAB to be notified that a new iteration of the variable is ready, so catching new iterations of the variable at the MATLAB level would be up to accidents of timing.
Paul
Paul on 29 Dec 2024
IIUC, you only need the last n points of a signal to run one function after the simulation is complete. I don't understand why it's preferred to repeatedly run that function internal to the simulation while it's running, which I think you realize based on "it is probably not very efficient." Presumaby the output of the Matlab Function still goes to a ToWorkspace block and only the last data point is saved?
Apparently the rationale for such an approach is the "need to frequently switch between different codes." I'm not sure what codes are being referenced here and don't understand how the Matlab Function block solves that problem in a way that can't be equally solved by processing the data after the simulation completes.
Unless the simulation is using a fixed-step solver, there is no guarantee as to the time steps between the data points collected by the ToWorkspace block or processed by the Matlab Function based on the step size in the model settings. If you are using a fixed-step solver, then keep in mind the implications of potentially wanting to change the step size in the future. Seems like a more robust approach is specify the sample time for the signal being sampled and subsequently being processed.
If the Matlab Function block has a continuous sample time, either set explicitly or inherited from a continuous input signal, the Matlab Function block is executing at the minor time steps (assuming a multi-step solver) as well as at the major time steps (as well as potentially other times as the solver may dictate), so that Matlab Function might not be doing what you want.
Either make sure the signal input to the Matlab Function has your desired sample time or set the sample time of the Matlab Function to the desired sample time for which the data should be collected and processed.

Sign in to comment.

Accepted Answer

Manish
Manish on 27 Dec 2024
Edited: Manish on 27 Dec 2024
Hi Bruce,
I understand that you want to create an array and add values to it during the simulation. This can be achieved with the help of persistent variables.
You can utilize a MATLAB Function block to define the length of an array and store data within it. Once the index reaches the specified number of samples, you can perform linear regression on the collected data.
You can refer the sample code below:
function calculateStiffness(force, position)
numSamples = 100;
% Persistent variables to store data across function calls
persistent forceData positionData index;
if isempty(index)
forceData = zeros(1, numSamples);
positionData = zeros(1, numSamples);
index = 1;
end
forceData(index) = force;
positionData(index) = position;
index = index + 1;
if all(forceData) && all(positionData)
% Perform linear regression
end
end
Refer the below links for better understanding:
Hope it helps!
  3 Comments
Walter Roberson
Walter Roberson on 28 Dec 2024
circshift(F_w_1_array,-1);
That performs the circshift and then assigns the result of the circshift to the special variable ans . The semi-colon tells it to not print out any results.
You probably want
F_w_1_array = circshift(F_w_1_array,-1);
but better yet would be
F_w_1_array = F_w_1_array(2:end);
Bruce
Bruce on 28 Dec 2024
Thanks for the hint. That was indeed a mistake. There is still a deviation between the force values obtained by the 'MATLAB Function' block and the 'To Workspace' block of up to 0.3 % which I cannot explain, but the calculated spring stiffnesses match quite well.

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 27 Dec 2024
You can use a buffer block https://www.mathworks.com/help/dsp/ref/buffer.html (requires the DSP System Toolbox)
  2 Comments
Bruce
Bruce on 28 Dec 2024
Thanks, I already tried the buffer block, but I got the following error message:
Error :Error in 'Cryocooler_heat_actuated_V01/Piston 1/Buffer': All sample times must be discrete. No continuous or constant sample times are allowed.
Walter Roberson
Walter Roberson on 28 Dec 2024
Specifically, I want to create an array to store the values ​​of one period of sinusoidal force and position values ​​in order to calculate a linear regression for the spring stiffness.
When you use continuous time, each MATLAB function block is normally processed a variable number of times by the solver. They are normally processed through Runge-Kutta type adaptive solvers. Such solvers evaluate the function block several different times with a variety of conditions, and use careful mathematical forms to create a prediction point. The prediction point is evaluated and the difference between the predicted solution and actual solution is compared; if the difference is too large then the adaptive solvers go back and try again with a shorter step size. As long as the predictions keep failing, the adaptive solvers fall back to shorter and shorter step sizes. Until eventually one of the prediction matches well enough.
Meanwhile, the MATLAB function block is evaluated about 6 times per prediction. The locations evaluated are are generally not locations that the solver intends to travel. The process is like walking on a hill in the dark, equipped with a strobe flashlight: you shine the flashlight in several different carefully chosen directions, and make guesses about the direction of the best slope to travel. You are not intending to move everywhere you shine the flashlight; you shine it there to get information about the shape of the hill.
Now... if you record the output of each call to the MATLAB function block, you are recording as well all of the trial locations -- including the trials where you eventually decided to back off to shorter steps. The MATLAB function block is not given information about which trial is taking place, and the final step location is not necessarily to any location that has been explicitly evaluated ! It isn't that you cannot record the results of each call to the MATLAB function block... it is that you don't know which calls are worth recording. Possibly none of them are worth recording if you end up backing off the step size.
The different calls to the MATLAB function block will be at variable time-steps, so if you planning to "store a certain number of the last data points", you run into the issue that the function block calls are not discrete times apart. You would need to record the times along with the results, and then do whatever with the variabably-timed points. None-uniform fft perhaps.
I want to create an array to store the values ​​of one period of sinusoidal force and position values ​​in order to calculate a linear regression for the spring stiffness
It is a bit tricky to perform linear regression on variably-timed points...
Now, if you were to switch to discrete times, then the situation would be different, and it would make sense to use buffer blocks...

Sign in to comment.

Products


Release

R2024a

Community Treasure Hunt

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

Start Hunting!