Simulink Difference Equation Implementation

I have a homework(a). My professor ask me for implement a discrete pid controller in difference equation form to matlab function. This function block should run as a discrete pid controller block in simulink model(b). When simulation began, the Matlab function block is executed once. Because of for loop an array occurs. Then that array signal goes the plant. And this is not usefull. During the simulation what i want is every iteration of for loop gives a value and that value must go to plant. But i could not do this. The same issue happened previous homework(c). I don't even know whether this way is proper or not.

4 件のコメント

Alvery
Alvery 2020 年 12 月 15 日
Think of your function as only solving a single step - it takes the current input, applies the difference function just once to it, and then produces the next result. This leaves you with a challenge - in order to make the difference function work, you also need to know the previous value that was computed.
How do you do memory? you can either store it externally (i.e. not in Matlab code, but in a separate Simulink block) in a 1/Z block, or you can store it internally in the Matlab. Internal storage is easy if you cheat - using 'persistent' variables, but this hides the memory from the solver which potentially messes up backtracking behaviour if your solver setting uses it. The correct alternative is to use stored state.
Sezer Memis
Sezer Memis 2020 年 12 月 16 日
Thank you for answer. But is your advice proper for my situation? I don't get it. Here is some figures from previous homework but same issue:
When function run as matlab script, this output occurs.
When function run as matlab script, above output occurs.
Same function in Matlab Function block in Simulink, above output occurs. Function code is given as follows:
function y2 = serialProgramming(e1)
T = 0.1;
t_final = 20;
t_initial = 0;
lenght_of_loop = (t_final-t_initial)/T;
y1 = zeros(lenght_of_loop,1);
y2 = zeros(lenght_of_loop,1);
x1 = zeros(lenght_of_loop,1);
x2 = zeros(lenght_of_loop,1);
%initial conditions
x0 = 0;
x1(1,1) = x0;
x2(1,1) = x0;
for k = 2:lenght_of_loop
x1(k,1) = e1 + 0.9 * x1(k-1,1) ;
y1(k) = 0.004617 * x1(k-1,1) ;
x1(k-1,1) = x1(k,1) ;
x2(k,1) = y1(k,1) + 0.874 * x2(k-1,1) ;
y2(k,1) = x2(k,1) + 0.9231 * x2(k-1,1) ;
x2(k-1,1) = x2(k,1) ;
end
Simulink structure is simple like this:
I want the output which is in Simuink like script's output. But i could not do that. If my method is completely wrong, how can i replace a PID(z) block with a difference equation Matlab function in Simulink. The summary :
Walter Roberson
Walter Roberson 2020 年 12 月 20 日
If you are using a discrete system then use https://www.mathworks.com/help/simulink/slref/memory.html memory block.
If you are using a continuous system, then you would have difficulty implementing something like the trapazoid rule.
Paul
Paul 2020 年 12 月 20 日
Hard to say how to make the two equivalent without knowing exactly what's inside the block C(s)1.

サインインしてコメントする。

 採用された回答

Paul
Paul 2020 年 12 月 20 日

0 投票

Maybe this example will help, which essentially illustrates the comment made by Alvery.
Consider a plant P(s) = 1/(s + 5) that is controlled via PI compensation with Ki = Kp = 1. The sample time of the discrete control is Ts = 0.01, with Ts defined as such in the base workspace. This system is modeled in the top half of this diagram, where the sample time parameter for the Zero Order Hold and Discrete Time Integrator blocks is set to Ts.
Now we wish to implement the PI control in a Matlab Function block as in the boltom half of the diagram. We have the following equation for the control input:
u[k] = x[k] + Kp*e[k] % Kp = 1
The difference equation for x[k] is determined from the z-transform of the integrator:
X(z)/E(z) = Ki*Ts/(z-1) % Ki = 1
(z-1)*X(z) = Ki*Ts*E(z)
x[k+1] - x[k] = Ki*Ts*e[k]
x[k+1] = Ki*Ts*e[k] + x[k]
so the PI function needs to impement the equations for u[k] and x[k]. Here's the function
function u = PI(e)
persistent x
% initialize the integrator output
if isempty(x)
x = 0;
end
Kp = 1;
Ki = 1;
Ts = 0.01; % needs to be same value as Ts defined in the workspace
% control at the current time step
u = Kp*e + x;
% update the integrator for the next time step
x = Ki*Ts*e + x;
end
And here is the scope from the model showing that the implementation works as expected:

3 件のコメント

Sezer Memis
Sezer Memis 2020 年 12 月 22 日
Thank you so much. It works well. You are great!
Tomàs
Tomàs 2024 年 5 月 30 日
What if you put a ZOH inbetween the Controller and the plant and replace the original ZOH by a "Rate Transition" black ?
From my understanding it looks more "academic" in this way. What do you think , Paul?
Paul
Paul 2024 年 5 月 30 日
編集済み: Paul 2024 年 5 月 30 日
You could probably replace the ZOH on the error signal with a Rate Transition, but I'm pretty sure that, with proper parameter settings, the Rate Transition will just be a ZOH anyway. You could put a ZOH between the controller and the plant with same sample time as the controller, but we have to remember that the Simulink ZOH block isn't really the same as an "academic" ZOH that represnts a D/A converter. The output of the ZOH block can't have a continuous sample time; at least I don't think it can.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

製品

リリース

R2020a

質問済み:

2020 年 12 月 15 日

編集済み:

2024 年 5 月 30 日

Community Treasure Hunt

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

Start Hunting!

Translated by