- Index
- » Usage and Applications
- » OpenModelica Usage and Applications
- » PI controller
PI controller
PI controller
Dears,
I am looking for advice, I want to have a very simple PI controller implemented as function:
function pi
input Real y;
output Real u;
parameter Real K = 1 "Proportional gain";
parameter Real Ti = 1 "Integral time";
algorithm
u := K * y + Ti * der(u);
end pi;
I try to use this pi-function in my test-model as
model test_pi
import pi;
Real y(start = 1);
Real action;
equation
action = pi(y);
end test_pi;
Unfortunately I am getting
[C:/OpenModelica1.9.1/work/pi.mo:5:3-5:40] Warning: Invalid public variable Ki, function variables that are not input/output must be protected.
[C:/OpenModelica1.9.1/work/pi.mo:4:3-4:43] Warning: Invalid public variable K, function variables that are not input/output must be protected.
What's the correct way to have params within function?
Thank you.
Best regards,
Peb
Re: PI controller
Well. You can't really have parameters in a function as there is no initialization. The warning is correct that only inputs and outputs may be public.
Make them either protected constants or simply protected:
Code:
function pi
input Real y;
output Real u;
protected
Real K = 1 "Proportional gain";
Real Ti = 1 "Integral time";
algorithm
u := K * y + Ti * der(u);
end pi;
- sjoelund.se
- 1700 Posts
Re: PI controller
It seems to me that integration under "function" is not working as I expected - maybe I am doing something wrong
function pi
input Real y;
output Real u;
protected
Real K = 1;
Real Ti = 1;
algorithm
u := K * y + Ti * der(u);
end pi;
Now "variables K,Ti" seems OK but cannot run test_pi:
I got following
[C:/OpenModelica1.9.1/work/pi.mo:8:3-8:27] Warning: u was used before it was defined (given a value). Additional such uses may exist for the variable, but some messages were suppressed.
Simulation Output
test_pi_functions.c
gcc -falign-functions -msse2 -mfpmath=sse -I"C:/OpenModelica1.9.1//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME -c -o test_pi_records.o test_pi_records.c
gcc -falign-functions -msse2 -mfpmath=sse -I"C:/OpenModelica1.9.1//include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME -c -o test_pi_01exo.o test_pi_01exo.c
test_pi_functions.c: In function 'omc_pi':
test_pi_functions.c:20: error: '$P$DER$Pu' undeclared (first use in this function)
test_pi_functions.c:20: error: (Each undeclared identifier is reported only once
test_pi_functions.c:20: error: for each function it appears in.)
mingw32-make: *** [test_pi_functions.o] Error 1
mingw32-make: *** Waiting for unfinished jobs....
Compilation process exited with code 2
Re: PI controller
Yes. derivative operator is forbidden in functions. Maybe you want to use a block instead of a function?
Also, keep in mind that the integrator needs der(u) in order to calculate u. Not the other way around.
- sjoelund.se
- 1700 Posts
Re: PI controller
I did my PI as
model pi
Real y(start = 0);
Real u(start = 0);
parameter Real K = 1;
parameter Real Ti = 1;
equation
u = K * y + Ti * u;
y = der(u);
end pi;
and I just want to try it:
model test_pi
pi controller;
Real fbck;
equation
fbck = 1;
controller.y = fbck;
end test_pi;
[:0:0-0:0] Error: Too many equations, over-determined system. The model has 1 equation(s) and 0 variable(s).
is there a way how to go around this?
Do you have any tricks how to handle integration under Modelica?
Re: PI controller
Flatten the model (instantiate model) and you see:
Code:
class test_pi
Real controller.y(start = 0.0);
Real controller.u(start = 0.0);
parameter Real controller.K = 1.0;
parameter Real controller.Ti = 1.0;
Real fbck;
equation
controller.u = controller.K * controller.y + controller.Ti * controller.u;
controller.y = der(controller.u);
fbck = 1.0;
controller.y = fbck;
end test_pi;
You pretty much have:
Code:
controller.y := fbck;
controller.y := der(controller.u);
Modelica has a single assignment rule. Remove controller.t = fbck and the model translates. Note that it is unbalanced because controller.u is not given an initial value: u(start=0, fixed=true) solves that.
- sjoelund.se
- 1700 Posts
Re: PI controller
(Note: I updated OpenModelica to check if you are in function context when you try to use der; users should get nicer error messages if they try to do this in the future)
- sjoelund.se
- 1700 Posts
Re: PI controller
I am really appreciate a help of you.
I would like to ask that if I can run simple model (e.g. PI) in "open-loop". I apply just input signal and await what's on output by running simulation and plotting it.
I did try:
model pi
Real y(start = 0);
Real u(start = 0, fixed = true);
parameter Real K = 1;
parameter Real Ti = 1;
equation
u = K * y + Ti * u;
y = der(u);
end pi;
model test_pi
pi controller;
Real fbck(start = 1, fixed = true);
equation
controller.y = fbck;
end test_pi;
other way how to do it? I just want the integrator to be 0 at start - expect to see that input value is integrated... I want to keep "fbck" at some non-zero const value..
Simulation Output (crashed)
assert | debug | division by zero at time 0, (a=1) / (b=0), where divisor b expression is: 1.0 - controller.Ti Debug more
assert | info | simulation terminated by an assertion at initialization
Process crashed
Simulation process exited with code -1
Re: PI controller
You might want to look at the code of Modelica.Blocks.Continuous.PI:
Code:
block PI "Proportional-Integral controller"
import Modelica.Blocks.Types.Init;
parameter Real k(unit="1")=1 "Gain";
parameter SIunits.Time T(start=1,min=Modelica.Constants.small)
"Time Constant (T>0 required)";
parameter Modelica.Blocks.Types.Init initType=Modelica.Blocks.Types.Init.NoInit
"Type of initialization (1: no init, 2: steady state, 3: initial state, 4: initial output)"
annotation(Evaluate=true,
Dialog(group="Initialization"));
parameter Real x_start=0 "Initial or guess value of state"
annotation (Dialog(group="Initialization"));
parameter Real y_start=0 "Initial value of output"
annotation(Dialog(enable=initType == Init.SteadyState or initType == Init.InitialOutput, group=
"Initialization"));
extends Interfaces.SISO;
output Real x(start=x_start) "State of block";
initial equation
if initType == Init.SteadyState then
der(x) = 0;
elseif initType == Init.InitialState then
x = x_start;
elseif initType == Init.InitialOutput then
y = y_start;
end if;
equation
der(x) = u/T;
y = k*(x + u);
end PI;
- sjoelund.se
- 1700 Posts
Re: PI controller
I did "PI controller model" as
model pi
Real y;
Real u;
Real x;
parameter Real K = 1;
parameter Real Ti = 1;
equation
der(x) = u;
y = K * u + Ti * x;
end pi;
it seems to be working fine and even comparing to Modelica built-in controller
model test_pi
pi controller(K = 10, Ti = 10);
Modelica.Blocks.Continuous.PI mcontroller(k = 10);
equation
mcontroller.u = 1;
controller.u = 1;
end test_pi;
- Index
- » Usage and Applications
- » OpenModelica Usage and Applications
- » PI controller