summaryrefslogtreecommitdiff
path: root/PID_Practice_Cases
diff options
context:
space:
mode:
authorSiddharth112352019-09-03 18:09:16 +0530
committerSiddharth112352019-09-03 18:09:16 +0530
commitb4b6aa36e3486a3544acc52419149b5671f841e9 (patch)
tree66c1783158f23e6d21c77324156fc57e18d4ac67 /PID_Practice_Cases
parentf5266f634f4fb4fd39933a83551a01cf446256b8 (diff)
downloadOpenModelica_HIL-master.tar.gz
OpenModelica_HIL-master.tar.bz2
OpenModelica_HIL-master.zip
Pushing entire Modelica HIL Tasks repoHEADmaster
Diffstat (limited to 'PID_Practice_Cases')
-rw-r--r--PID_Practice_Cases/PulseDCMotorPID.mo37
-rw-r--r--PID_Practice_Cases/RLC_ckt.mo43
-rwxr-xr-xPID_Practice_Cases/SpringMassHIl.mo75
-rwxr-xr-xPID_Practice_Cases/SpringMassPID.mo38
-rwxr-xr-xPID_Practice_Cases/Virtual_PID.mo23
-rw-r--r--PID_Practice_Cases/tank_model.mo205
6 files changed, 421 insertions, 0 deletions
diff --git a/PID_Practice_Cases/PulseDCMotorPID.mo b/PID_Practice_Cases/PulseDCMotorPID.mo
new file mode 100644
index 0000000..be2c6b8
--- /dev/null
+++ b/PID_Practice_Cases/PulseDCMotorPID.mo
@@ -0,0 +1,37 @@
+model PulseDCMotorPID"PID and Motor combine model with Pulse input"
+ Modelica.Blocks.Continuous.PID PID( Td = 0, Ti = 10 ^ 20, k = 15) annotation(
+ Placement(visible = true, transformation(origin = {-30, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Blocks.Math.Feedback feedback1 annotation(
+ Placement(visible = true, transformation(origin = {-60, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Mechanics.Rotational.Sources.Torque torque1 annotation(
+ Placement(visible = true, transformation(origin = {30, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Mechanics.Rotational.Components.Inertia inertia1(J = 5) annotation(
+ Placement(visible = true, transformation(origin = {70, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Mechanics.Rotational.Sensors.SpeedSensor speedSensor1 annotation(
+ Placement(visible = true, transformation(origin = {90, -28}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
+ Modelica.Blocks.Sources.Pulse pulse1(amplitude = 833, offset = 0, period = 20, startTime = 0) annotation(
+ Placement(visible = true, transformation(origin = {-90, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+equation
+ connect(pulse1.y,feedback1.u1) annotation(
+ Line(points = {{-78, 10}, {-68, 10}}, color = {0, 0, 127}));
+ connect(PID.y, torque1.tau) annotation(
+ Line(points = {{-18, 10}, {16, 10}, {16, 10}, {18, 10}}, color = {0, 0, 127}));
+ connect(inertia1.flange_b, speedSensor1.flange) annotation(
+ Line(points = {{80, 10}, {90, 10}, {90, -18}, {90, -18}}));
+ connect(feedback1.u2, speedSensor1.w) annotation(
+ Line(points = {{-60, 2}, {-60, -46}, {90, -46}, {90, -38}}, color = {0, 0, 127}));
+ connect(feedback1.y, PID.u) annotation(
+ Line(points = {{-51, 10}, {-42, 10}}, color = {0, 0, 127}));
+ connect(torque1.flange, inertia1.flange_a) annotation(
+ Line(points = {{40, 10}, {60, 10}, {60, 10}, {60, 10}}));
+ annotation (Documentation(info= "<html>
+<p>
+<b>Inter Process Communication Library V1.0</b><br /><br />
+This is a combined model for PID and Motor model with square pulse input.
+</p>
+<p>
+<b>License:</b> OSMC-PL v1.2 2017<br /><br />
+</p>
+</html>"));
+
+end PulseDCMotorPID; \ No newline at end of file
diff --git a/PID_Practice_Cases/RLC_ckt.mo b/PID_Practice_Cases/RLC_ckt.mo
new file mode 100644
index 0000000..2caffad
--- /dev/null
+++ b/PID_Practice_Cases/RLC_ckt.mo
@@ -0,0 +1,43 @@
+model RLC_ckt
+ Modelica.Electrical.Analog.Basic.Resistor resistor1(R = 10) annotation(
+ Placement(visible = true, transformation(origin = {-14, 34}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Electrical.Analog.Basic.Capacitor capacitor1 annotation(
+ Placement(visible = true, transformation(origin = {24, 34}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Electrical.Analog.Basic.Inductor inductor1(L = 1) annotation(
+ Placement(visible = true, transformation(origin = {54, 34}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Electrical.Analog.Basic.Ground ground1 annotation(
+ Placement(visible = true, transformation(origin = {26, -58}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Electrical.Analog.Sources.SignalVoltage signalVoltage1 annotation(
+ Placement(visible = true, transformation(origin = {-44, 34}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Electrical.Analog.Sensors.VoltageSensor voltageSensor1 annotation(
+ Placement(visible = true, transformation(origin = {22, -16}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Blocks.Continuous.PID PID(Td = 1, Ti = 0.5, k = 1) annotation(
+ Placement(visible = true, transformation(origin = {-72, 62}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Blocks.Math.Feedback feedback1 annotation(
+ Placement(visible = true, transformation(origin = {-100, 62}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Blocks.Sources.Step step1(startTime = 50) annotation(
+ Placement(visible = true, transformation(origin = {-128, 62}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+equation
+ connect(feedback1.u1, step1.y) annotation(
+ Line(points = {{-108, 62}, {-116, 62}, {-116, 62}, {-116, 62}}, color = {0, 0, 127}));
+ connect(voltageSensor1.v, feedback1.u2) annotation(
+ Line(points = {{22, -26}, {-96, -26}, {-96, 52}, {-100, 52}, {-100, 54}}, color = {0, 0, 127}));
+ connect(PID.y, signalVoltage1.v) annotation(
+ Line(points = {{-60, 62}, {-44, 62}, {-44, 42}, {-44, 42}}, color = {0, 0, 127}));
+ connect(feedback1.y, PID.u) annotation(
+ Line(points = {{-90, 62}, {-84, 62}, {-84, 62}, {-84, 62}}, color = {0, 0, 127}));
+ connect(voltageSensor1.n, ground1.p) annotation(
+ Line(points = {{32, -16}, {26, -16}, {26, -48}, {26, -48}}, color = {0, 0, 255}));
+ connect(voltageSensor1.p, signalVoltage1.p) annotation(
+ Line(points = {{12, -16}, {-74, -16}, {-74, 32}, {-54, 32}, {-54, 34}, {-54, 34}}, color = {0, 0, 255}));
+ connect(inductor1.n, voltageSensor1.n) annotation(
+ Line(points = {{64, 34}, {74, 34}, {74, -14}, {32, -14}, {32, -16}, {32, -16}}, color = {0, 0, 255}));
+ connect(resistor1.p, signalVoltage1.n) annotation(
+ Line(points = {{-24, 34}, {-34, 34}, {-34, 34}, {-34, 34}}, color = {0, 0, 255}));
+ connect(capacitor1.n, inductor1.p) annotation(
+ Line(points = {{34, 34}, {44, 34}, {44, 34}, {44, 34}, {44, 34}, {44, 34}}, color = {0, 0, 255}));
+ connect(resistor1.n, capacitor1.p) annotation(
+ Line(points = {{-4, 34}, {14, 34}, {14, 34}, {14, 34}}, color = {0, 0, 255}));
+
+annotation(
+ uses(Modelica(version = "3.2.2")));end RLC_ckt; \ No newline at end of file
diff --git a/PID_Practice_Cases/SpringMassHIl.mo b/PID_Practice_Cases/SpringMassHIl.mo
new file mode 100755
index 0000000..6cc16dc
--- /dev/null
+++ b/PID_Practice_Cases/SpringMassHIl.mo
@@ -0,0 +1,75 @@
+model SpringMassHIl
+import InterProcessCommunication.SharedMemory.*;
+ Modelica.Mechanics.Translational.Components.Mass mass1(L = 1, m = 1) annotation(
+ Placement(visible = true, transformation(origin = {36, 4}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Mechanics.Translational.Sources.Force force1 annotation(
+ Placement(visible = true, transformation(origin = {6, 4}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Mechanics.Translational.Components.Fixed fixed1 annotation(
+ Placement(visible = true, transformation(origin = {94, 4}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Blocks.Interfaces.RealOutput y annotation(
+ Placement(visible = true, transformation(origin = {-28, -36}, extent = {{10, -10}, {-10, 10}}, rotation = 0), iconTransformation(origin = {80, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+
+ // Declaration of variables and constants
+ Real motorInputValue "Value of input to the Discrete PID Controller" ;
+ Real motorOutputValue "Value of output of Discrete PID Controller" ;
+ Integer motorInputIndex = 1;
+ Real ReferenceOp "Reference Output";
+ //Address from where to read, can be any number between 0 to 10, it must match the address given to output value in second model i.e. DiscretePID_SM_Example in this case
+ Integer motorOutputIndex = 1;//Address where to write, can be any number between 0 to 10
+ Real motorOutputDummy "Dummy value to be returned by the SharedMemoryWrite function";
+ //Functions from serial_read
+ Modelica_DeviceDrivers.Blocks.Packaging.SerialPackager.UnpackUnsignedInteger unpackInt(nu = 1, width = 8) annotation(
+ Placement(visible = true, transformation(extent = {{-90, -6}, {-70, 14}}, rotation = 0)));
+ Modelica_DeviceDrivers.Blocks.Packaging.SerialPackager.GetInteger getInteger annotation(
+ Placement(visible = true, transformation(extent = {{-90, -62}, {-70, -42}}, rotation = 0)));
+ Modelica_DeviceDrivers.Blocks.Communication.SerialPortReceive serialReceive(Serial_Port = "/dev/ttyACM1", autoBufferSize = true, baud = Modelica_DeviceDrivers.Utilities.Types.SerialBaudRate.B115200, enableExternalTrigger = false, sampleTime = 0.01) annotation(
+ Placement(visible = true, transformation(origin = {-80, 58}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
+ Modelica.Mechanics.Translational.Components.SpringDamper springDamper1(c = 100, d = 10, s_rel0 = 1) annotation(
+ Placement(visible = true, transformation(origin = {66, 4}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Mechanics.Translational.Sensors.PositionSensor positionSensor1 annotation(
+ Placement(visible = true, transformation(origin = {16, -36}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
+equation
+ connect(mass1.flange_b, positionSensor1.flange) annotation(
+ Line(points = {{46, 4}, {48, 4}, {48, -36}, {26, -36}, {26, -36}}, color = {0, 127, 0}));
+ connect(positionSensor1.s, y) annotation(
+ Line(points = {{4, -36}, {-20, -36}, {-20, -36}, {-28, -36}}, color = {0, 0, 127}));
+ connect(springDamper1.flange_b, fixed1.flange) annotation(
+ Line(points = {{76, 4}, {92, 4}, {92, 4}, {94, 4}}, color = {0, 127, 0}));
+ connect(mass1.flange_b, springDamper1.flange_a) annotation(
+ Line(points = {{46, 4}, {56, 4}, {56, 4}, {56, 4}}, color = {0, 127, 0}));
+ connect(unpackInt.pkgOut[1], getInteger.pkgIn) annotation(
+ Line(points = {{-80, -7}, {-80, -41}}, thickness = 0.5));
+ connect(serialReceive.pkgOut, unpackInt.pkgIn) annotation(
+ Line(points = {{-80, 47}, {-80, 15}}));
+ connect(force1.flange, mass1.flange_a) annotation(
+ Line(points = {{16, 4}, {26, 4}, {26, 4}, {26, 4}}, color = {0, 127, 0}));
+ force1.f = motorInputValue "The value of control signal (pidOutputValue) is acquired by the SharedMemoryRead function and it is assigned to the input of the system";
+ motorOutputValue = y "The measured speed of the system is assigned to pidInputValue, which is written into the shared memory using SharedMemoryWrite Function";
+ when sample(0, 0.05) then
+ motorInputValue = InterProcessCommunication.SharedMemory.SharedMemoryRead(motorInputIndex) "SharedMemoryRead Function reads the value from the shared memory, pointed by pidOutputIndex tag and assigns it to the input of the system";
+ motorOutputDummy = InterProcessCommunication.SharedMemory.SharedMemoryWrite(motorOutputIndex, motorOutputValue) "SharedMemoryWrite Function writes the value of measured speed into the shared memory, pointed by pidInputIndex tag";
+ end when;
+ ReferenceOp= unpackInt.y;
+//equations from serial_read
+ annotation(
+ Diagram(coordinateSystem(preserveAspectRatio = false, extent = {{-140, -100}, {140, 100}}, initialScale = 0.1), graphics = {Text(lineColor = {255, 0, 0}, extent = {{40, 37}, {90, 31}}, textString = "plant"), Rectangle(origin = {-12, -2},lineColor = {255, 0, 0}, extent = {{0, 68}, {140, -54}})}),
+ Icon(coordinateSystem(preserveAspectRatio = true, extent = {{-100, -100}, {100, 100}}, grid = {2, 2})),
+ Documentation(info = "<html>
+
+<p>
+<b>Inter Process Communication Library V1.0</b><br /><br />
+The <b>DCMotor</b> model contains the DC motor, which reads the control signal from shared memory (given by discrete PID controller) and the speed sensor measures the resulting rotation. The measured speed from speed sensor is written into the shared memory.
+
+ </p>
+
+ <p>
+The values of control signal and speed of the spring mass system are read from and written into the shared memory at sampling interval of 0.05 seconds. <a href=\"modelica://InterProcessCommunication.SharedMemory.SharedMemoryRead\"> SharedMemoryRead </a> and <a href=\"modelica://InterProcessCommunication.SharedMemory.SharedMemoryWrite\"> SharedMemoryWrite </a> functions are used to read the control signal from the shared memory and write the measured speed into the shared memory respectively. The motorOutputIndex and motorInputIndex variables serve as index of the tag i.e. motorInputIndex points to the value of control signal and motorOutputIndex points to the value of speed of the DC motor. The value of the control signal, returned by the <a href=\"modelica://InterProcessCommunication.SharedMemory.SharedMemoryRead\"> SharedMemoryRead </a> function is stored in the motorInputValue variable. The value of the motorInputValue is in turn assigned to the force.u variable, which serves as an input to the spring-mass system. Similarly, the value of the measured speed is assigned to motorOutputvalue variable. Therefore, the value of the motorOutputvalue is written into shared memory using <a href=\"modelica://InterProcessCommunication.SharedMemory.SharedMemoryWrite\"> SharedMemoryWrite </a> function.
+</p>
+
+
+</html>"),
+ experiment(StopTime = 60, StartTime = 0, Tolerance = 1e-06, Interval = 0.01),
+ __OpenModelica_simulationFlags(jacobian = "coloredNumerical", s = "dassl", lv = "LOG_STATS", nls = "homotopy", clock = "RT"),
+ uses(Modelica(version = "3.2.2")));
+
+end SpringMassHIl; \ No newline at end of file
diff --git a/PID_Practice_Cases/SpringMassPID.mo b/PID_Practice_Cases/SpringMassPID.mo
new file mode 100755
index 0000000..36f48de
--- /dev/null
+++ b/PID_Practice_Cases/SpringMassPID.mo
@@ -0,0 +1,38 @@
+model SpringMassPID
+ import Modelica.Mechanics.*;
+ Modelica.Mechanics.Translational.Components.Mass mass1(L = 1, m = 1) annotation(
+ Placement(visible = true, transformation(origin = {36, 4}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Mechanics.Translational.Sources.Force force1 annotation(
+ Placement(visible = true, transformation(origin = {0, 4}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Mechanics.Translational.Components.Fixed fixed1 annotation(
+ Placement(visible = true, transformation(origin = {94, 4}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Blocks.Sources.Pulse pulse1(amplitude = 158, period = 20, startTime = 10) annotation(
+ Placement(visible = true, transformation(origin = {-88, 4}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Mechanics.Translational.Sensors.PositionSensor positionSensor1 annotation(
+ Placement(visible = true, transformation(origin = {-12, -56}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
+ Modelica.Mechanics.Translational.Components.SpringDamper springDamper1(c = 100, d = 10, s_rel0 = 1) annotation(
+ Placement(visible = true, transformation(origin = {66, 4}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Blocks.Math.Feedback feedback1 annotation(
+ Placement(visible = true, transformation(origin = {-61, 5}, extent = {{-5, -5}, {5, 5}}, rotation = 0)));
+ Modelica.Blocks.Continuous.PID PID(Nd = 20, Td = 0.05, Ti = 0.1, k = 50) annotation(
+ Placement(visible = true, transformation(origin = {-34, 6}, extent = {{-8, -8}, {8, 8}}, rotation = 0)));
+equation
+ connect(feedback1.y, PID.u) annotation(
+ Line(points = {{-56.5, 5}, {-55.25, 5}, {-55.25, 4}, {-44, 4}}, color = {0, 0, 127}));
+ connect(PID.y, force1.f) annotation(
+ Line(points = {{-25, 4}, {-12, 4}}, color = {0, 0, 127}));
+ connect(positionSensor1.s, feedback1.u2) annotation(
+ Line(points = {{-23, -56}, {-61, -56}, {-61, 1}}, color = {0, 0, 127}));
+ connect(pulse1.y, feedback1.u1) annotation(
+ Line(points = {{-76, 4}, {-72, 4}, {-72, 5}, {-65, 5}}, color = {0, 0, 127}));
+ connect(mass1.flange_b, positionSensor1.flange) annotation(
+ Line(points = {{46, 4}, {46, 4}, {46, -56}, {-2, -56}, {-2, -56}}, color = {0, 127, 0}));
+ connect(force1.flange, mass1.flange_a) annotation(
+ Line(points = {{10, 4}, {26, 4}}, color = {0, 127, 0}));
+ connect(springDamper1.flange_b, fixed1.flange) annotation(
+ Line(points = {{76, 4}, {92, 4}, {92, 4}, {94, 4}}, color = {0, 127, 0}));
+ connect(mass1.flange_b, springDamper1.flange_a) annotation(
+ Line(points = {{46, 4}, {56, 4}, {56, 4}, {56, 4}}, color = {0, 127, 0}));
+ annotation(
+ uses(Modelica(version = "3.2.2")));
+end SpringMassPID; \ No newline at end of file
diff --git a/PID_Practice_Cases/Virtual_PID.mo b/PID_Practice_Cases/Virtual_PID.mo
new file mode 100755
index 0000000..e7c1ac7
--- /dev/null
+++ b/PID_Practice_Cases/Virtual_PID.mo
@@ -0,0 +1,23 @@
+//Provides a virtual PID against which the arduino PID can be compared.
+class Virtual_PID
+ Modelica.Blocks.Math.Feedback feedback1 annotation(
+ Placement(visible = true, transformation(origin = {-44, 22}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Blocks.Continuous.FirstOrder firstOrder1(T = 1, initType = Modelica.Blocks.Types.Init.NoInit, k = 1, y_start = 1) annotation(
+ Placement(visible = true, transformation(origin = {54, 22}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Blocks.Sources.Sine sine1(amplitude = 50, freqHz = 0.5, offset = 150) annotation(
+ Placement(visible = true, transformation(origin = {-88, 22}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+ Modelica.Blocks.Continuous.PID PID(Nd = 0.5, Td = 10 ^ 10, Ti = 10 ^ 10, k = 2) annotation(
+ Placement(visible = true, transformation(origin = {0, 22}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
+equation
+ connect(PID.y, firstOrder1.u) annotation(
+ Line(points = {{12, 22}, {42, 22}, {42, 22}, {42, 22}}, color = {0, 0, 127}));
+ connect(feedback1.y, PID.u) annotation(
+ Line(points = {{-34, 22}, {-12, 22}, {-12, 22}, {-12, 22}}, color = {0, 0, 127}));
+ connect(sine1.y, feedback1.u1) annotation(
+ Line(points = {{-76, 22}, {-52, 22}, {-52, 22}, {-52, 22}}, color = {0, 0, 127}));
+ connect(firstOrder1.y, feedback1.u2) annotation(
+ Line(points = {{66, 22}, {80, 22}, {80, 0}, {-46, 0}, {-46, 14}, {-44, 14}, {-44, 14}}, color = {0, 0, 127}));
+ annotation(
+ uses(Modelica(version = "3.2.2")),
+ Diagram);
+end Virtual_PID; \ No newline at end of file
diff --git a/PID_Practice_Cases/tank_model.mo b/PID_Practice_Cases/tank_model.mo
new file mode 100644
index 0000000..8e57dc9
--- /dev/null
+++ b/PID_Practice_Cases/tank_model.mo
@@ -0,0 +1,205 @@
+model tank_model
+ package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater;
+
+ Modelica.Fluid.Examples.ControlledTankSystem.Utilities.TankController
+ tankController(
+ waitTime=50,
+ maxLevel=0.9*tank1.height,
+ minLevel=0.01)
+ annotation (Placement(transformation(extent={{-60,-20},{-20,20}})));
+ Modelica.Fluid.Examples.ControlledTankSystem.Utilities.RadioButton start(
+ reset={stop.on,shut.on},
+ buttonTimeTable={20,280})
+ annotation (Placement(transformation(extent={{-100,20},{-80,40}})));
+ Modelica.Fluid.Examples.ControlledTankSystem.Utilities.RadioButton stop(
+ reset={start.on,shut.on},
+ buttonTimeTable={220,650})
+ annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+ Modelica.Fluid.Examples.ControlledTankSystem.Utilities.RadioButton shut(
+ reset={start.on,stop.on},
+ buttonTimeTable={700})
+ annotation (Placement(transformation(extent={{-100,-40},{-80,-20}})));
+ Modelica.Fluid.Valves.ValveDiscrete valve1( redeclare
+ package Medium = Medium,
+ m_flow_nominal=40,
+ dp_nominal=100000)
+ annotation (Placement(transformation(
+ origin={-10,70},
+ extent={{10,-10},{-10,10}},
+ rotation=180)));
+ Modelica.Fluid.Vessels.OpenTank tank1(
+ level_start=0.05,
+ redeclare package Medium = Medium,
+ crossArea=6,
+ height=4,
+ nPorts=2,
+ portsData={Modelica.Fluid.Vessels.BaseClasses.VesselPortsData(
+ diameter=0.2,
+ height=4,
+ zeta_out=0,
+ zeta_in=1),Modelica.Fluid.Vessels.BaseClasses.VesselPortsData(
+ diameter=0.2,
+ height=0,
+ zeta_out=0,
+ zeta_in=1)}) annotation (Placement(transformation(extent={{10,30},
+ {50,70}})));
+ Modelica.Blocks.Sources.RealExpression level1(y=tank1.level)
+ annotation (Placement(transformation(extent={{-90,-60},{-55,-40}})));
+ Modelica.Fluid.Valves.ValveDiscrete valve2( redeclare package Medium
+ = Medium,
+ dp_nominal(displayUnit="Pa") = 1,
+ m_flow_nominal=100)
+ annotation (Placement(transformation(
+ origin={34,0},
+ extent={{10,-10},{-10,10}},
+ rotation=90)));
+ Modelica.Fluid.Valves.ValveDiscrete valve3( redeclare package Medium
+ = Medium,
+ dp_nominal(displayUnit="Pa") = 1,
+ m_flow_nominal=10)
+ annotation (Placement(transformation(
+ origin={35,-80},
+ extent={{10,-10},{-10,10}})));
+ Modelica.Fluid.Vessels.OpenTank tank2(
+ level_start=0.05,
+ redeclare package Medium = Medium,
+ height=5,
+ crossArea=6,
+ nPorts=2,
+ portsData={Modelica.Fluid.Vessels.BaseClasses.VesselPortsData(
+ diameter=0.2,
+ height=5,
+ zeta_out=0,
+ zeta_in=1),Modelica.Fluid.Vessels.BaseClasses.VesselPortsData(
+ diameter=0.2,
+ height=0,
+ zeta_out=0,
+ zeta_in=1)}) annotation (Placement(transformation(extent={{50,-60},
+ {90,-20}})));
+ Modelica.Fluid.Sources.Boundary_pT ambient1(redeclare package Medium =
+ Medium,nPorts=1,
+ p=system.p_ambient,
+ T=system.T_ambient)
+ annotation (Placement(transformation(extent={{-10,-90},{10,-70}})));
+ Modelica.Blocks.Sources.RealExpression level2(y=tank2.level)
+ annotation (Placement(transformation(extent={{-70,-80},{-33,-60}})));
+ Modelica.Fluid.Sources.Boundary_pT source(redeclare package Medium =
+ Medium, p=2.5e6,nPorts=1,
+ T=system.T_ambient)
+ annotation (Placement(transformation(
+ origin={-40,70},
+ extent={{-10,-10},{10,10}})));
+ inner Modelica.Fluid.System system(energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial)
+ annotation (Placement(transformation(extent={{-90,70},
+ {-70,90}})));
+equation
+ connect(shut.on, tankController.shut) annotation (Line(points={{-79,-30},{
+ -72,-30},{-72,-12},{-62,-12}}, color={255,0,255}));
+ connect(stop.on, tankController.stop) annotation (Line(points={{-79,0},{-62,
+ 0}}, color={255,0,255}));
+ connect(start.on, tankController.start) annotation (Line(points={{-79,30},{
+ -70,30},{-70,12},{-62,12}}, color={255,0,255}));
+ connect(tankController.valve1, valve1.open) annotation (Line(points={{-19,12},
+ {-10,12},{-10,62}}, color={255,0,255}));
+ connect(level1.y, tankController.level1) annotation (Line(points={{-53.25,
+ -50},{-52,-50},{-52,-22}}, color={0,0,127}));
+ connect(tankController.valve2, valve2.open) annotation (Line(points={{-19,0},
+ {-5,0},{26,0}}, color={255,0,255}));
+ connect(tankController.valve3, valve3.open) annotation (Line(points={{-19,-12},
+ {-10,-12},{-10,-50},{35,-50},{35,-72}},
+ color={255,0,255}));
+ connect(level2.y, tankController.level2) annotation (Line(points={{-31.15,
+ -70},{-28,-70},{-28,-22}}, color={0,0,127}));
+
+ connect(source.ports[1], valve1.port_a) annotation (Line(
+ points={{-30,70},{-20,70}},
+ color={0,127,255}));
+ connect(valve3.port_b, ambient1.ports[1]) annotation (Line(
+ points={{25,-80},{10,-80}},
+ color={0,127,255}));
+ connect(tank2.ports[2], valve3.port_a) annotation (Line(
+ points={{74,-60},{74,-80},{45,-80}},
+ color={0,127,255}));
+ connect(valve2.port_b, tank2.ports[1]) annotation (Line(
+ points={{34,-10},{34,-20},{50,-20},{50,-60},{66,-60}},
+ color={0,127,255}));
+ connect(valve1.port_b, tank1.ports[1]) annotation (Line(
+ points={{0,70},{10,70},{10,30},{26,30}},
+ color={0,127,255}));
+ connect(tank1.ports[2], valve2.port_a) annotation (Line(
+ points={{34,30},{34,10}},
+ color={0,127,255}));
+ annotation (
+ experiment(StopTime=900),
+ Documentation(info="<html>
+<p>
+With this example, the controller of a tank filling/emptying system
+is demonstrated.
+</p>
+
+<p>
+The basic operation is to fill and empty the two tanks:
+</p>
+<ol>
+<li> Valve 1 is opened and tank 1 is filled.</li>
+<li> When tank 1 reaches its fill level limit,
+ valve 1 is closed. </li>
+<li> After a waiting time, valve 2 is
+ opened and the fluid flows from tank 1 into tank 2.</li>
+<li> When tank 1 reaches its minimum level, valve 2 is closed. </li>
+<li> After a waiting time, valve 3 is opened and
+ the fluid flows out of tank 2</li>
+<li> When tank 2 reaches its minimum level, valve 3 is closed</li>
+</ol>
+<p>
+The above \"normal\" process can be influenced by three
+buttons:
+</p>
+<ul>
+<li> Button <b>start</b> starts the above process.
+ When this button is pressed after a \"stop\" or
+ \"shut\" operation, the process operation continues.
+ </li>
+<li> Button <b>stop</b> stops the above process by
+ closing all valves. Then, the controller waits for
+ further input (either \"start\" or \"shut\" operation).</li>
+<li> Button <b>shut</b> is used to shutdown the process,
+ by emptying at once both tanks by opening valve 2 and
+ valve 3. When this is achieved,
+ the process goes back to its start configuration
+ where all 3 valves are closed.
+ Clicking on \"start\", restarts the process.</li>
+</ul>
+
+<p>
+The demo-run uses the following button presses:
+</p>
+
+<ul>
+<li> Button <b>start</b> pressed at 20 s.</li>
+<li> Button <b>stop</b> pressed at 220 s </li>
+<li> Button <b>start</b> pressed at 280 s </li>
+<li> Button <b>stop</b> pressed at 650 s </li>
+<li> Button <b>shut</b> pressed at 700 s </li>
+<li> Simulate for 900 s</li>
+</ul>
+
+<p>
+This example is based on
+</p>
+
+<dl>
+<dt>Dressler I. (2004):</dt>
+<dd> <b>Code Generation From JGrafchart to Modelica</b>.
+ Master thesis, supervisor: Karl-Erik Arzen,
+ Department of Automatic Control, Lund Institute of Technology,
+ Lund, Sweden, March 30, 2004<br>&nbsp;</dd>
+</dl>
+
+<img src=\"modelica://Modelica/Resources/Images/Fluid/Examples/ControlledTanks.png\" border=\"1\"
+ alt=\"ControlledTanks.png\">
+</html>"),
+ __Dymola_Commands(file=
+ "modelica://Modelica/Resources/Scripts/Dymola/Fluid/ControlledTanks/plot level and ports.m_flow.mos"
+ "plot level and ports.m_flow"));
+end tank_model; \ No newline at end of file