Execute Matlab function in Simulink
1 view (last 30 days)
Show older comments
Hello to all,
I have this Matlab function, i would like to execute in Simulink using "User-Defined->Matlab Function" from the Library.
This is the function I want to execute:
function y = moving_average2(u, Tf, Ts)
% Check if the input data is long enough
N = ceil(Tf/Ts);
if numel(u) < N
N = numel(u);
end
% Initialize the result array
y = zeros(size(u));
disp(N)
% Calculate the moving average
for i = N:numel(u)
y(i) = mean(u(i-N+1:i));
end
end
and when tested, I have called this function from the following simple script:
clear; clc; close all
t = 0:0.1:10;
u = sin(t);
Tf = 2; T = 0.1;
y = moving_average(u, Tf, T);
plot(t, u);hold on; grid on;
plot(t, y, 'r');
legend("Input", "Output");
The above script when executed produce the following result:
However, when this very same function is called from the Simulink as shown in picture:
The result is very different, as if averaging is not applied at all. Input and output signals are matching perfectly (Simulation s 10 sec, auto, fixed size (auto).
Can you please suggest what I'm doing wrong?
My guess it is because Simulink executes this function for each input sample, and that is the difference comparing with the script, so basically I would need to modife the function as it would be called in an infinite loop in cyclic manner.
Thank you!
0 Comments
Accepted Answer
Paul
on 13 Feb 2024
You are correct. In Matlab, the code looks like this (actually making the call to moving_average2)
t = 0:0.1:10;
u = sin(t);
Tf = 2; T = 0.1;
%y = moving_average(u, Tf, T);
y = moving_average2(u, Tf, T);
figure
plot(t, u);hold on; grid on;
plot(t, y, 'r');
legend("Input", "Output");
In Simulink, the implementation is essentially a loop on scalar values of u, one for each value of t (assuming the simulink step size is 0.1 for illustration). As the disp command would show (I commented it out), in Simulink it's just a one point moving average.
figure
for tval = t
u = sin(tval);
Tf = 2; T = 0.1;
%y = moving_average(u, Tf, T);
y = moving_average2(u, Tf, T);
plot(tval, u,'o');hold on; grid on;
plot(tval, y, 'or');
legend("Input", "Output");
end
Is there a reason you want to use this function in Simulink instead of just computing the moving average wtih a simplle transfer function block (though some extra work would be required if you really want the output to be zero for the first N-1 samples.
function y = moving_average2(u, Tf, Ts)
% Check if the input data is long enough
N = ceil(Tf/Ts);
if numel(u) < N
N = numel(u);
end
% Initialize the result array
y = zeros(size(u));
%disp(N)
% Calculate the moving average
for i = N:numel(u)
y(i) = mean(u(i-N+1:i));
end
end
2 Comments
Paul
on 13 Feb 2024
Persistent variables inside a Matlab Function block is certainly one option to model static memory. Another option would be to take outputs from the Matlab Function block and route them through one of the delay blocks, like Dleay or Tapped Delay as needed, and feed the output of the delay block back around as input to the Matlab Function. In your example of the moving average (which I realize was just for illustration) you could add a Tapped Delay block on the sine wave to send into the Matlab Function the current value and N-1 most recent values of that sin as a vetor input with N elements.
More Answers (0)
See Also
Categories
Find more on Simulink Functions in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!