Using the Object Oriented Component-Based Approach

1 Tank System with a Continuous PI Controller

Now we show the tank model using the object oriented component-based approach. The structure of the tank system model using this approach is clearly visible in Figure 1 below.


A tank system with a continuous PI controller and a source for liquid.


The three components of the tank system: the tank, the PI controller and the source of liquid are explicit in Figure 1 and in the declaration of the class
TankPI below. Tank instances of tank, source and piContinuous are connected to controllers and liquid sources through their connectors.


x
 
1
model TankPI
2
  LiquidSource           source(flowLevel=0.02);
3
  PIcontinuousController piContinuous(ref=0.25);
4
  Tank                   tank(area=1);
5
equation
6
  connect(source.qOut, tank.qIn);
7
  connect(tank.tActuator, piContinuous.cOut);
8
  connect(tank.tSensor, piContinuous.cIn);
9
end TankPI;
10

2 Tank

The tank has four connectors: qIn for input flow, qOut for output flow, tSensor for providing fluid level measurements, and tActuator for setting the position of the valve at the outlet of the tank.

The central equation regulating the behavior of the tank is the mass balance equation, which in the current simple form assumes constant pressure. The output flow is related to the valve position by a
flowGain parameter, and by a limiter that guarantees that the flow does not exceed what corresponds to the open/closed positions of the valve.


16
 
1
model Tank
2
  ReadSignal     tSensor     "Connector, sensor reading tank level (m)";
3
  ActSignal      tActuator   "Connector, actuator controlling input flow";
4
  LiquidFlow     qIn         "Connector, flow (m3/s) through input valve";
5
  LiquidFlow     qOut        "Connector, flow (m3/s) through output valve";
6
  parameter Real area(unit = "m2")       =  0.5;
7
  parameter Real flowGain(unit = "m2/s") = 0.05;
8
  parameter Real minV= 0, maxV = 10;    // Limits for output valve flow
9
  Real           h(start = 0.0,fixed=true, unit = "m")   "Tank level";
10
 equation
11
  assert(minV>=0,"minV - minimum Valve level must be >= 0 ");
12
  der(h)      = (qIn.lflow - qOut.lflow)/area;    // Mass balance equation
13
  qOut.lflow  = limitValue(minV, maxV, -flowGain*tActuator.act);
14
  tSensor.val = h;
15
end Tank;
16

2.1 limitValue

A limiter function is needed in the model to reflect minimum and maximum flows through the output valve:


11
 
1
function limitValue
2
  input  Real pMin;
3
  input  Real pMax;
4
  input  Real p;
5
  output Real pLim;
6
 algorithm
7
  pLim := if p>pMax then pMax
8
          else if p<pMin then pMin
9
          else p;
10
end limitValue;
11

2.2 Connectors

As already stated, the tank has four connectors. These are instances of the following three connector classes:


4
 
1
connector ReadSignal     "Reading fluid level"
2
  Real val(unit = "m");
3
end ReadSignal;
4

4
 
1
connector ActSignal     "Signal to actuator for setting valve position"
2
  Real act;
3
end ActSignal;
4

4
 
1
connector LiquidFlow    "Liquid flow at inlets or outlets"
2
  Real lflow(unit = "m3/s");
3
end LiquidFlow;
4

2.3 LiquidSource

The fluid entering the tank must come from somewhere. Therefore we have a liquid source component in the tank system. The flow increases sharply at time = 150 to factor of three of the previous flow level, which creates an interesting control problem that the controller of the tank has to handle.


7
 
1
model LiquidSource
2
  LiquidFlow qOut;
3
  parameter Real flowLevel = 0.02;
4
equation
5
  qOut.lflow = if time > 150 then 3*flowLevel else flowLevel;
6
end LiquidSource;
7

2.4 PIcontinuousController

The controller needs to be specified. We will initially choose a PI controller but later replace this by other kinds of controllers.


8
 
1
model PIcontinuousController
2
  extends BaseController(K = 2, T = 10);
3
  Real  x (fixed=true) "State variable of continuous PI controller";
4
equation
5
  der(x) = error/T;
6
  outCtr = K*(error + x);
7
end PIcontinuousController;
8

2.5 BaseController

Both the PI controller and the PID controller to be defined later inherit the partial controller class BaseController, containing common parameters, state variables, and two connectors: one to read the sensor and one to control the valve actuator.


14
 
1
partial model BaseController
2
  parameter Real Ts(unit = "s") = 0.1  "Time period between discrete samples";
3
  parameter Real K = 2          "Gain";
4
  parameter Real T(unit = "s") = 10    "Time constant";
5
  ReadSignal cIn            "Input sensor level, connector";
6
  ActSignal  cOut            "Control to actuator, connector";
7
  parameter Real ref          "Reference level";
8
  Real error              "Deviation from reference level";
9
  Real outCtr              "Output control signal";
10
equation
11
  error = ref - cIn.val;
12
  cOut.act = outCtr;
13
end BaseController;
14

3 Simulation of TankPI

We simulate the TankPI model and obtain the same response as for the FlatTank model, which is not surprising given that both models have the same basic equations.


2
 
1
simulate( TankPI, stopTime=250 )
2

2
 
1
plot( tank.h )
2

tank.h
0
0.1
0.2
0.3
0.4
0.5
0
50
100
150
200

4 Tank with PID Continuous Controller

We define a TankPID system which is the same as the TankPI system except that the PI controller has been the replaced by a PID controller. Here we see a clear advantage of the object oriented component-based approach over the traditional modeling approach, since system components can easily be replaced and changed in a plug-and-play manner.


The tank system with the PI controller replaced by a PID controller.


The Modelica class declaration for the
TankPID system appears as follows:


10
 
1
model TankPID
2
  LiquidSource            source(flowLevel  = 0.02);
3
  PIDcontinuousController pidContinuous(ref = 0.25);
4
  Tank                    tank(area = 1);
5
equation
6
  connect(source.qOut, tank.qIn);
7
  connect(tank.tActuator, pidContinuous.cOut);
8
  connect(tank.tSensor, pidContinuous.cIn);
9
end TankPID;
10


We create a
PIDcontinuousController class in Modelica containing the three defining equations:


10
 
1
model PIDcontinuousController
2
  extends BaseController(K = 2, T = 10);
3
  Real  x(fixed=true);       // State variable of continuous PID controller
4
  Real  y;                   // State variable of continuous PID controller
5
equation
6
  der(x) = error/T;
7
  y      = T*der(error);
8
  outCtr = K*(error + x + y);
9
end PIDcontinuousController;
10

5 Simulation of TankPID

We simulate the tank model once more but now including the PID controller:


2
 
1
simulate( TankPID, stopTime=250 )
2

2
 
1
plot( tank.h )
2

tank.h
0
0.1
0.2
0.3
0.4
0
50
100
150
200

6 Two Tanks Connected Together

Two connected tanks with PI controllers and a source for liquid connected to the first tank.


The Modelica model
TanksConnectedPI corresponding to Figure 3 appears as follows:


15
 
1
model TanksConnectedPI
2
  LiquidSource  source(flowLevel = 0.02);
3
  Tank          tank1(area = 1);
4
  Tank          tank2(area = 1.3);
5
  PIcontinuousController piContinuous1(ref = 0.25);
6
  PIcontinuousController piContinuous2(ref = 0.4);
7
 equation
8
  connect(source.qOut,tank1.qIn);
9
  connect(tank1.tActuator,piContinuous1.cOut);
10
  connect(tank1.tSensor,piContinuous1.cIn);
11
  connect(tank1.qOut,tank2.qIn);
12
  connect(tank2.tActuator,piContinuous2.cOut);
13
  connect(tank2.tSensor,piContinuous2.cIn);
14
end TanksConnectedPI;
15


We simulate the connected tank system. We clearly see the tank level responses of the first and second tank to the changes in fluid flow from the source, where the response from the first tank of course appears earlier in time than the response of the second tank.


7 Simulation of TanksConnectedPI

2
 
1
simulate( TanksConnectedPI, stopTime=400 )
2

2
 
1
plot( {tank1.h,tank2.h} )
2

tank1.h
tank2.h
0
0.2
0.4
0.6
0.8
1
0
100
200
300