Modelica Assignment 

Practical Information

  • Due Date: 17 October 2025, before 23:59.
  • Team Size: 2 (pair design/programming)
    As of the 2017-2018 Academic Year, each International student should team up with a "local" student (i.e., whose Bachelor degree was obtained at the University of Antwerp).
  • Submission Information:
    • Only one member of each team submits a full solution.
    • This must be a compressed archive (ZIP, RAR, TAR.GZ...) that includes your report and all models, images, code and other sources that you have used to create your solution.
    • The report must be in PDF and must be accompagnied by all images.
    • Images that are too large to render on one page of the PDF must still be rendered on the PDF (even though unclear), and the image label should mention the appropriate file included in the submission archive.
    • Make sure to mention the names and student IDs of both team members.
    • The other team member must submit a single HTML file containing the coordinates of both team members using this template.
  • Submission Medium: BlackBoard Ultra. Beware that BlackBoard's clock may differ slightly from yours. If BlackBoard is not reachable due to an (unpredicted) maintenance, you should submit your solution via e-mail to the TA. Make sure all group members are in CC!
  • Contact / TA: Rakshit Mittal.

Goals

In this assignment, you will use the Modelica Language to first create a model of a Cyber-Physical System (CPS) and then create a controller for optimal control of the CPS. You will learn:

  1. How Ordinary Differential Equations (ODE) can be used for the modeling and simulation of a CPS.
  2. Furthermore, you will learn how a generic model must be calibrated to fit real-world data.
  3. You will then design and model a controller to control the CPS.
  4. You will finally tune the control parameters to optimize some goal function based on the (simulated) behavior of the CPS.

You are discouraged but allowed to make use of any GenAI tool in solving the assignment or writing the report (for example, to correct grammatical mistakes) as long as you adhere to the UA Guidelines for students on responsible use of GenAI.

You are required to cite any use of GenAI and describe what portions of the assignment you used it for.
You should also mention all other sources, including collaborations.

Note that a significant part of demonstrating that the learning goals have been achieved, includes being able to

  1. explain the relevant concepts in the assignment,
  2. explain the design choices in your implementation, and
  3. critically discuss your solution.

This will be evaluated in a short (~15 minute) oral evaluation, which will be conducted in the week following the deadline of every assignment.

OpenModelica

You will use OpenModelica to perform all the tasks. You can install the latest stable version of OpenModelica on your systems by following the directions by going to the OpenModelica website > Download > Windows/Linux/Mac (based on your OS). Choose the 'Official Release' package.

Installing OpenModelica installs a number of applications in your system:

OMEdit

The OpenModelica Connection Editor (OMEdit) is the standard graphical user interface that is used for graphical Modelica model creation and editing. We will use OMEdit for all the tasks. Launch instructions and other features of OMEdit are described on the OMEdit website. OMEdit has 4 different views but we are only interested in the Modelling and Plotting views. We will primarily use OMEdit to design the model. Information about the other OpenModelica applications are just given for information.

Modelica Standard Library

A major advantage of using Modelica is the availability of a wide-variety of Modelica libraries, making it easier to re-use blocks and classes from these libraries. For the assignment, you should ensure, once you have installed OpenModelica, that the Modelica Standard Library (MSL) package is also correctly downloaded, and automatically loaded when you start OMEdit. To do so, go to File > Manage Libraries > Install Library > select Modelica with Version 4.0.0 > OK. The Modelica Standard Library should be visible when you restart OMEdit.

OMNotebook

OMNotebook is a notebook-like tool to learn the usage of OpenModelica and construct more-readable documentation which incorporates code-windows in between text. Think of Jupyter Notebooks.

OMShell

OMShell is an interactive session handler that parses and interprets commands and Modelica expressions for evaluation, simulation, plotting, etc. The session handler also contains simple history facilities, and completion of file names and certain identifiers in commands. We will not use OMShell because we want to learn and visualize graphically the models that we are building. Hence we will only use OMEdit.

We will use Python because we can then directly use the data obtained from simulation for analysis through a number of data analysis packages available in Python.

One thing to note is that a Modelica model needs to be compiled only once. Once compiled, the parameters can be changed in subsequent executions/simulation runs without having to re-compile the model. This is advantageous since compilation can prove to be a significant overhead if we are optimising for a number of different parameters and ranges (read: the number of simulation runs could go into the thousands or more, as I'm doing in my research, but that is the beauty of it).

Basics

While the Modelica language and its capabilities of object-oriented acausal modeling of the multi-physics have already been described in the lectures, what follows is a 'how-to' to get started building your own Modelica models for the assignment using OMEdit.

On the left of the OMEdit window, is the Libraries pane which displays all the libraries that have been loaded in the current Modelica session. Modelica models are organised in Packages which can contain other packages and Modelica classes.

Create a Modelica Package

Create new package example
Figure 1: Example package creation.

Go to File > New > New Modelica Class > in the Create New Modelica Class dialog box > enter a valid package name > for Specialization, select Package, this is also shown in Fig.1 > OK. You should now see your Modelica package in the Libraries pane. You should save it before proceeding further by clicking on the corresponding icon in the menu bar or going to File > Save.

If you have already created and saved a package, you can load it in the current session by going to File > Open Model/Library Files, and choosing the corresponding file in the file browser.

Create your first Modelica Model

Right click on your Modelica package in the Libraries window > in the drop-down menu > select New Modelica Class > in the create New Modelica Class dialog box > enter a valid class name > for Specialization, select Model > for Insert in class ensure the textbox specifies the Modelica package within which you want to create your Modelica model > OK. You have created your first Modelica model! You should save it before proceeding further by clicking on the corresponding icon in the menu bar or going to File > Save.

Modelica classes can extend other Modelica classes, i.e. inherit the declarations from the extended class. They may also simply re-use components defined in other Modelica classes.

Build/Edit your Modelica Model

Double click on the Modelica model you want to edit. This takes you to the Modeling view. In the top right corner of the Modeling view are 3 buttons to toggle between different editing interfaces. The 2nd button is to open the graphical editor and the 3rd button is to open the textual editor.

Modelica editor views
Figure 2: Buttons to change editor views. The Icon view is only used to arrange connector points for a block.

The diagram view can only be used in case the model consists of blocks with causal/acausal connections between them.

Look at the Modelica By Example website for simple introductory examples of Modelica models based on simple Ordinary Differential Equations of physics.

If you are making a component-based model. You can add components to the model by dragging them from the Libraries pane onto the graphical editor. You will be prompted to give the component a unique name. You can draw connections between the interfaces of components by holding the left mouse button while simultaneously moving it from one interface ot the other. This highly intuitive. You can modify parameters of the components by double-clicking on them, which will open the Element Parameters box.

Simulate your Modelica Model in OMEdit

Modelica 'Check Model' and 'Simulation' buttons
Figure 3: 'Check Model' and 'Simulation' buttons in OMEdit.

Once you have defined a complete and correct Modelica model, you can now simulate it. To do so, you should click on the S icon in the menu bar. This opens the Simulation Setup dialog box. You can set simulation parameters in this dialog box.

Make sure that you have verified the simulation start time, stop time, step-size/number of intervals, solver method (DASSL is preferred), and tolerance (the default 1e-6 is good enough, as low as possible is preferred ideally).

You can also set the output format to output the data to a file. However, we do not need to do so, since we will later perform simulations through Python where we will handle the simulation output directly. This is just for visualization and initial validation of the model.

Click OK to begin simulation.

Note: You can also 'check' the model by clicking on the tick-mark icon in the menu bar. The output from this can be observed in the message browser. The message browser will tell you if something is missing in the model, or if there are inconsistencies in the model.

Visualize simulation trace

Clicking OK in the Simulation Setup ideally takes you to the Plotting view. If not, you can go to the plotting view through the corresponding tab in the bottom-right corner.

On the right you will see the variable browser. You can select any variable/s to plot them in the pane and observe their values over the simulation. The values indicated in the variables pane is the value of that variable at the end of the simulation.

Parametrizing simulation quantities in OMEdit

To define a parameter you simply have to use the 'parameter' keyword followed by its unit name and default value in this syntax:

parameter <unit> <name> = <default value> ;

If you want to parametrize a quantity which is a parameter of a block in your model. Simply double-click on the block in the graphical editor and change the parameter value to the parameter name. This value need not be a numeric quantity, but it can be a reference to the name of the parameter within the model, or a function of the parameter as well. Once you have changed the value in the block, go to the textual editor of your model (not of the block!), and use the same syntax as above to define a parameter. Note that the name of this parameter should correspond to the name of the parameter you have defined in the value of the block. Look at the following image for an example:

Parametrization example
Figure 4: Parametrizing the values of the block-parameters of the blocks in your model.

Multiple simulations and analyses of your Modelica model

The example Python file contained in the zip file describes how to use Python to simulate and visualize data from an example Modelica model which will be introduced in the tutorial as well.

We will perform multiple simulations by generating the executable through OMEdit. You should make sure that the executable is generated and not deleted in the right directory by:

  1. go to Tools > Options > General > Adjust the value of Working Directory as you like. The executable will be stored in selected_working_directory/model_name/ . So, in the example, if I select example as the working directory, the executable will be example/NewtonCooling/NewtonCooling
  2. go to Tools > Options > General > disable 'Delete entire simulation directory of the model when OMEdit is closed'

To generate these files, once the settings mentioned above are correctly configured, you should simulate the model in OMEdit at least once.

To re-simulate your model, but not from OMEdit, you can simply use the terminal command to execute the executable which is in a subdirectory of the working directory as described above. This subdirectory is named 'package_name.model_name' and the executable in this subdirectory is executed with the command './model_name' (in Linux). For the example, it will be './NewtonCooling'. Note that you should change the current directory of the terminal session to the example/NewtonCooling/ directory before doing so. This cannot be done from within the example/ directory.

The simulation results will be stored in the same directory as the executable. By default, it is a MAT-file, and you should try to use the same because it is the most efficient (compared to CSV, etc.). At the end of each simulation you should read the MAT-file, and record the variables that you are interested in before performing the next simulation, because this file will be overwritten during re-simulation. You can read the MAT-files generated by OpenModelica using the read_mat_file() function in the example code!

To re-simulate the model, but with different parameters, you can use command line as well. You simply have to structure your command using the -override flag, as the following

'./model_name -override parameter1=value, parameter2=value ..'.

This is also described and demonstrated in the example code.

To implement a loop over the parameter values, you will have to write a Python script. You can execute shell commands using the os package as demonstrated in the example. Take special note that os.changeDir function is used to change the working directory of the virtual shell to the results directory.

Assignment Overview

This assignment consists of four main parts:
  1. Plant Model Creation
  2. Plant Model Calibration
  3. Controller Model Creation
    1. Bang-bang Controller
    2. PID Controller
  4. PID Controller Tuning

Each part is aligned with one of the learning goals

Problem Statement

A hot water storage tank is an indispensable component in many household and industrial heating systems. It serves as a buffer between the heater and the point of demand (e.g. tap water or heating circuits). The role of the tank is to ensure a steady supply of water at a sufficiently high temperature, even when demand fluctuates.

The operation of such a system can be described in the following simplified steps:

  1. The tank is filled with cold water from the inlet pipe by turning on a pump.
  2. An electric heating element transfers heat into the water stored in the tank.
  3. The tank inevitably loses heat to the surrounding environment due to imperfect insulation.
  4. A user draws hot water by opening a tap thereby reducing the volume of water in the tank.
Simplified illustration of a hot-water heating,storage and distribution system for a building.
Figure 5: Simplified illustration of a hot-water heating, storage and distribution system for a building. While this diagram shows multiple outlet valves (imagine each source of water in a building), in the assignment, we will only consider one outlet valve for simplicity.

Traditionally, simple thermostat control (on-off) is used to operate such water heaters. However, in more demanding applications, this is not sufficient - it can lead to temperature oscillations, slow responses, or excessive energy use. As can be deduced from the list of steps above, the operation of a water-heating system involves many steps, each of which has complexities of its own.

In this assignment, we will instead explore the use of two different controllers :

  1. a bang-bang controller that switches on and off, the pump to fill the tank with cold water;
  2. and a PID controller that regulates the heater power in order to track a desired temperature set-point. Since the tank is a thermal system, the controller must take into account both the heater input and the inevitable heat losses to the environment.

The goal in this assignment is to design suitable controllers for the water heating system such that:

  1. the temperature of water at the outlet is always at least 50°C
  2. the tank is at least at 80% and at most 95% capacity at any time

Plant Model Creation

You are the engineer and the designer/scientist/client has given you the information below. Your task is to model the whole system using the information given below, in Modelica. Special care should be taken to parametrize the model correctly.

The first step will always be to make an appropriately named Modelica package. This will serve as the package for your entire Modelica assignment. You SHOULD create NEW models ONLY within this package, for each part of the entire assignment.

Task 1: Modelling the hydronic system

You will first model the fluid transport network which serves as the backbone for the entire system. To do this you should use the Modelica.Fluid package from the Modelica Standard Library.

TIP: Have a look at the documentation and the examples section in the Modelica.Fluid package to learn how to use the different components. This is important to understand how to set the parameters for the different components.

The ambient conditions are as follows:

  • The medium in the entire network is modelled as Modelica.Media.Water.StandardWater which is based on the IF97 standard.
  • The ambient pressure is 1 atm.
  • The ambient temperature is 17°C.

The design parameters are set as follows:

  • We assume laminar flow throughout the network which allows us to make lumped-parameter models, in the first place.
  • Source: The source is a fixed body of water at ground-level, serving as a fixed boundary, at ambient pressure, and 15°C temperature.
  • Pump: The centrifugal pump with ideally controlled speed is on ground-level and has a nominal rotational speed of 1450 rpm. The pump has a check valve (which is initially closed), and its internal volume is 5 litres. We assume no heat transfer from the pump. The energy and mass equations are dynamically balanced with an initial guess value. The flow characteristics are deduced by obtaining a quadratic interpolation (and linear extrapolation) with the following results from performing experiments on the pump:
    1. At zero flow, the head is 80 metres (maximum head of the pump)
    2. At 3 litres / sec flow, the head is 60 metres
    3. At 6 litres / sec flow, the head is 30 metres
    BEWARE: The values for flow characteristics should be specified in m3/s and not litres/s, in the pump characteristics model !
  • Inlet pipe: There is a single straight circular steel pipe connected vertically from the pump at ground level to the top of the heating tank on the roof. This pipe is certified "NPS 4 Schedule 80S" giving it an internal diameter of 114.3 - (2 x 8.56) = 97.18 mm.
  • Tank: We assume that the contents of the tank are uniformly mixed at all times (i.e. the temperature of the water inside the tank is uniform). The cross-sectional area of the tank is 20 m2 whereas its height is 3 metres. The tank sits on the roof of the building 35 m above ground-level. The tank is half-full at the beginning of the simulation and the temperature of the water inside the tank is the same as the ambient temperature.
    • There is an inlet port at the top of the tank with the same diameter as that of the inlet pipe.
    • There is an outlet port at the bottom of the tank with the same diameter as that of the outlet pipe.
    • BEWARE: The values for diameters and heights should be specified in metres in the vessel ports data model !
    • For this subtask we are only modelling the fluid-transport system, hence disable the heatPort port of the tank.
  • Outlet pipe: There is a single straight circular steel pipe connected vertically from the bottom of the heating tank to a single valve that is 20 metres above ground-level. This pipe is certified "NPS 3 Schedule 30" giving it an internal diameter of 88.9 - (2 x 4.78) = 79.34 mm.
  • Outlet valve: The pressure drop is linear with a nominal value of 0.1 bars at full opening. The nominal mass flow-rate at full opening is 500 g/s.
  • Sink: The sink is a fixed body of water serving as a fixed boundary, at ambient pressure, and fixed specific enthalpy as defined in the Medium.

Implement the system described above, as a Modelica model, using the graphical editor in OMEdit, and blocks from the Modelica.Fluid library. To simulate and test your model, do the following:

  1. Set the pump to have a constant rotational speed same as its nominal rotational speed, throughout the simulation.
  2. To the outlet valve opening port, connect a Modelica.Blocks.Tables.CombiTable1Ds block (have a look at its documentation here) with the table values as follows. The valve opening values are piecewise-constant, and change every hour. (Hint: use a Modelica.Blocks.Sources.ContinuousClock to give the simulated time as input to the Table block). The values are taken from this paper describing a survey of daily water usage patterns of hospitals in a region of China:

    Hour 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23
    Valve Opening 0.09 0.07 0.07 0.12 0.41 0.45 0.48 0.61 0.53 0.60 0.59 0.48 0.43 0.37 0.44 0.38 0.46 0.53 0.50 0.59 0.60 0.51 0.35 0.23

    BEWARE: The Modelica.Blocks.Sources.ContinuousClock outputs the simulated time in seconds !

  3. Trace of valve opening through an average day, as described by the above table.
    Figure 6: Trace of valve opening through an average day, as described by the above table.
  4. Simulate the system in OMEdit, for 1 hour with a step-size of 1 second.

Report your model, and graph the traces of the tank level, flow through outlet valve, and valve opening signal.

Re-simulate your model for 4 hours. Do you run into a problem? What do you think is the solution (that we will eventually implement)?

Task 2: Modelling the electrical heating system

Now you will model the electrical heating system. To do this you should use the Modelica.Electrical.Analog and Modelica.Thermal.HeatTransfer packages from the Modelica Standard Library.

TIP: Have a look at the documentation and the examples section in the Modelica.Thermal.HeatTransfer package to learn how to use the different components. This is important to understand how to set the parameters for the different components.

The heating is provided by a circuit modelled as a simple resistor across a voltage source:

Diagram of electrical heating circuit.
Figure 7: Diagram of electrical heating circuit.
  • The voltage source is a generic voltage source which provides the same voltage as the value of a real input control signal. It has a maximum voltage of 500 V.
  • The resistor has a resistance of 200 mΩ, and its temperature coefficient of resistance and heat capacity ae considered negligible.
  • It is assumed that the resistor transfers all of its generated heat ideally to the water in the tank.
  • There is a thermal insulation around the tank with some unknown thermal conductance, that conducts heat from the tank to the ambient environment that has a fixed ambient temperature as described in the previous task.

To implement the system as described above:

  1. Modelica allows re-use of models by means of the 'extend' clause. Create a new Modelica model (lets call it the "plant model") that extends the model of the hydronic system (with one change in the hydronic model - enable the heatPort of the tank)
  2. To the plant model, add the electrical circuit, and directly connect the heatPort of the resistor to that of the tank.
  3. To the heatPort of the tank, add the necessary thermal components in order to represent the thermal conductance of heat energy to/from the ambient fixed temperature.

Report your model graphically and textually; you will simulate it in the next section.

BEWARE: Often customer requirements will be in multiple units as is done above. It is your task to unify and express them all in a single unitary system so that your solution is numerically correct. The recommended way is to use SI units in all cases.

BONUS: for giving meaningful names to all blocks and elements in your model/s.

NOTE: This is a highly simplified model of a heating circuit. In practice, there is a network of many resistors to distribute power dissipation, and there are complex high power electronics components.

Plant Model Calibration

You have successfully created an abstract model of the water heating system, however it is not complete. Remember the value of the thermal conductance of the conduction of heat from the tank to the ambient? This is a parameter that cannot be estimated from design alone. How will you decide the value of this parameter so that your model truly represents reality? This is done through parameter calibration. The idea is that, we try (combinations of) different parameters, and compare the output of the simulation of the Modelica model, with real-life data. The parameters, which give the least error between the two traces are said to be the best fit, and are chosen accordingly.

An exhaustive way of finding optimal parameter values is to loop over possible values for the parameters to find the one that gives the closest match mentioned above. This is known as a parameter sweep.

Experimental setup

In the real-world experiment, the same tank as described above was half-filled with water at 50°C, with no inlet or outlet port for the fluid to move. The ambient temperature was constant at 17°C. The evolution of the temperature was measured, as the water in the tank cooled down.

The real life-data from the experiment is provided in this csv file. This data represents the temperature of the water in the tank sampled every minute, for one day, in Kelvins.

Evolution of temperature of the water in the tank, in the real-life calibration experiment.
Figure 8: Evolution of temperature of the water in the tank, in the real-life calibration experiment.

Task 1: Calibrate thermal conductance parameter

The main purpose of this part of the assignment is finding the coefficient of conductance in the conduction of heat from the tank to the ambient air, based on experimental data (i.e., observations/measurements on the real system).

  1. Create a new Modelica model and add a tank block, configured similarly as before, but with a few key differences:
    1. There are no vessel openings.
    2. There is no electrical heater, however, the thermal conductance from the tank to a fixed temperature boundary are to be included.
    3. The initial temperature of the water is 50°C and the height of water is 1.5 metres.
  2. Create a Python script that executes this Modelica model. The Python file should be named 'parameter_calibration.py'
  3. This Python script should have a loop that iterates over all possible values of the thermal conductance of the insulating material G in the interval [ 2500 W/K , 7500 W/K ] correct to the nearest integer value in W/K.
  4. The Python script should be able to record the trace of the temperature of the medium in the tank, from all of these different simulations. The Python script may store the trace (for each simulation) in memory or save the data as files. You can choose as you prefer.
  5. Compute the sum of squared errors (SSE) between each of your simulations and the given trace from real-life data. The simulation that has the smallest total error is the simulation that has the most accurate value for the relevant parameter.
    • You may compute this directly from the parameter sweep script, but this will be generally slower.
    • You are free to chose how you compute this; whether you use Python, Matlab, Excel...
  6. Report the value of the parameter and the SSE in your report, with appropriate graphs comparing the simulation output versus real life data.

Task 2: Simulate plant model

Now that you have estimated a value for G, you can now simulate the plant model that you created in task 2 of the previous section:

  1. Change the thermal conductance of the thermal conductor to the value you obtained by calibration.
  2. Give a constant input signal of value 450 to the voltage source control input. This means we want the battery to output 450V for the entire duration of the simulation.
  3. Add a temperature sensor to measure the temperature of the tank, at its heatPort.
  4. Simulate the model for 3 hours, with 1 sec timestep.
  5. Report the graph of the trace of the temperature of the medium in the tank. Is it heating up? Is the rate of change of temperature decreasing? Can you think of any reason for that?

Controller Model Creation

Based on the description of the problem statement, we want to model the control system as shown below:

Architecture of the complete control system.
Figure 9: Architecture of the complete control system.

To do so, you will create three blocks, one each for the plant, bang-bang controller, and PID controller.

Task 1: Plant block

  1. In the hydronic model, modify the pump to get its rotational speed from a real input, which enables the relevant connector in the plant model (remember that you had set it to a constant 1450 rpm earlier, to test the hydronic model).
  2. In the plant model, remove the constant input of 450V to the voltage source (remember that you had set it earlier, to test the calibrated plant model)
  3. Create a new Modelica class in your assignment package, but this time of the type 'Block'. This class should extend the calibrated plant model (with the above changes).
  4. Add 2 blocks of the types Modelica.Blocks.Interfaces.RealInput and Modelica.Blocks.Interfaces.RealOutput each. Name them according to the inputs and outputs of the plant block shown in Figure 9. Connect the connectors to the relevant inputs and outputs of the blocks like pump, voltage source, temperature sensor. You can adjust the position of the connectors in the Icon View of OMEdit.
  5. Notice however that the Modelica.Fluid.Vessels.OpenTank class (which you should have used) does not expose an output connector to measure the height of the tank. In such a scenario, using the textual editor, you can simply equate (i.e. add an equation) your output connector to the level variable in the tank block, to achieve the same functionality.

Task 2: Bang-bang controller

A bang-bang controller is one of the simplest controllers to control a plant that accepts binary input i.e. something that is completely on or completely off. A bang-bang controller is usually used to keep some process variable within minimum and maximum limits. In our example, this process variable is the height of the medium in the heating tank.

Recall from the problem statement that we want to keep the water level between 80% and 95% of the tank's capacity.

Also recall the modelling of discontinuous behavior in Modelica using the 'when' statement, that you learnt in the theory lectures. Here is a reference to the syntax.

  1. Create a new Modelica block in your assignment package.
  2. This block should have one real input and output.
  3. Using the textual syntax, implement a bang-bang controller that
    • when its input (the level of the tank) becomes $\leq$ 80% of the maximum level of the tank, it outputs 1450 (the nominal rotational speed of the pump),
    • and when its input becomes $\ge$ 95% of the maximum level of the tank, it outputs 0 (to stop the pump).
    • Remember from the previous task that you can equate your connectors to variables in your equations.

BONUS: for parametrizing the different values moderating the behavior of the bang-bang controller block.

Create a new Modelica model of this assignment, lets call it the "heating control system":

  1. Add the plant block and bang-bang controller block (that you have created earlier) to this model. Connect them as shown in Figure 9.
  2. Provide a constant 450V input to the plant block for the heating voltage source control input.
  3. Simulate the model for 24 hours at 60 second intervals.

Recall that when you first tested the hydronic model, you were not able to simulate it for 4 hours. Was the simulation successful now? What made the difference?

Report the traces of the tank level, bang bang controller output, outlet valve opening, and temperature of the medium in the tank.

Is the temperature of the tank unnecessarily high? Recall, that the problem statement only asks for minimum 50°C.

Task 3: PID Controller

A PID (Proportional-Integral-Derivative) controller is widely used in practice to drive the output of the plant towards a set-point. This set-point could change in time. We will however, consider the set-point is constant. In our example, the set-point represents the desired temperature of the medium in the tank. The control output from the PID controller, i.e. $u(t)$ drives the plant / process. The plant produces an output i.e. $T(t)$. The difference between the measured output $T(t)$ and the desired output $r(t)$ (a.k.a the set-point) is called the error $e(t)$. This error value is processed in the PID controller in three different ways as shown in the figure:

PID control loop
Figure 10: PID control loop (adapted from Wikipedia).
  • Proportional. The error is multiplied by a constant gain $K_p$.
  • Integral. The integral of the error (over time) is multiplied by a constant gain $K_i$.
  • Derivative. The derivative of the error (over time) is multiplied by a constant gain $K_d$

Hence, the output from the PID controller $u(t)$ is given by:

$$u(t) = (K_p \cdot e(t)) + (K_i \cdot \int_0^t e(t) dt) + (K_d \cdot \dfrac{d e(t)}{dt}) $$

The gains $K_p$, $K_i$, and $K_d$ modulate the behavior of the PID controller. You may read more about a PID controller online. The essential point is that three signals are summed, which forms the PID control output $u(t)$.

So, to sum up, in our case:

  • The plant is the complete hydronic and electrical heating system.
  • The measured output from the plant is the temperature of the medium in the tank.
  • The set-point is the desired value of the temperature.
  • The control output is a signal that controls the voltage in the electrical heating circuit.
  • The error signal is the difference between the set-point and the current temperature.

Hence, the equation for implementing the control is:

$$ e(t) = r - T(t) $$ coupled with the equations above.

Note: In our simple case, the set-point is constant

  1. Create another (and I promise, the final!) block in your Modelica assignment package.
  2. Even though you have already been given the PID control equations in textual format, you will use the graphical modelling capabilities of Modelica to create the PID controller block.
  3. You should first add one input and one output connector to your block, the same way you did in the previous task.
  4. Then, you can use the graphical editor, with blocks from the Modelica.Blocks.Math library to create your PID controller, while graphically connecting blocks to each other, as described by the colored boxes in Figure 10.
  5. Read the description in the introduction to Modelica at the top of this web-page to understand how to parametrize quantities for blocks. You should parametrize the PID control parameters.
  6. Recall from the design of the heating system that the voltage source has a maximum voltage of 500V. So, before you output u(t) from the PID control block, add a limiter that limits the PID output between 0 and 500 V. HINT: use the Modelica.Blocks.Nonlinear.Limiter block to do this.

Note: The PID control output should not be negative. A negative output from the PID controller indicates that it wants the instrument to cool the plant. However, a negative voltage will still result in dissipation of heat from the resistive element. Hence, we simply set negative signals to zero by using a limiter block.

Once you have created the PID control block, add it to the "heating control system" model, and connect it as shown in Figure 8. Add a constant input of 50 (in °C, or the equivalent in Kelvin) as the set point to the PID control block.

Simulate the water heating system with $K_p = 3$, $K_i = 0.5$, and $K_d = 0.2$ for 24 hours with a step-size of 1 second. Report the trace of the temperature and the PID output. Do you think this is an optimal controller? Why or why not?

Note: Do not model any part of the PID control loop using textual equations. In this task of the assignment you should use the graphical view to model the PID equations. Only use the textual syntax to define the parameters and interfaces of your model.

Controller Model Tuning

Similar to the calibration of the plant parameters (recall that we calibrated the thermal conductance), the controller also needs to be tuned for the most ideal control outcome. However, we do not directly have reference data to compare the simulation output to like we had in parameter calibration. Instead, the designer (you) should come up with a cost function to ascertain if the plant behaves as required.

Task 1: Design of the cost function

  1. Recall from the assignment that we want the temperature to be at least 50°C efficiency of the trolley and stability of the pendulum.
  2. Create a cost function in Python that when given a trace (could be numpy ndarray, python native list, pandas dataframe, your choice), gives a single Real value that represents the "cost" in that simulation. This cost is a sum of the difference in temperature from the set-point of all samples when the tank was colder than the set-point. $$ J = | \sum_{i=1}^{N} \max \bigl(0,\; T_{\text{setpoint}} - T_i \bigr) | $$ Where,
    • $T_i$ is the value of temperature at the ithindex in the trace.
    • $N$ is the number of samples in the trace.
    • $T_{setpoint}$ is the setpoint temperature.
  3. Report your implementation of this cost function.

Task 2: Tune PID controller

  1. Create a Python script to simulate the "heating control system" model with the following possible ranges for the control parameters:
    • $100 \leq K_p \leq 500$ (only multiples of 100)
    • $0 \leq K_i \leq 1$ (upto 1 decimal place)
    • $30 \leq K_d \leq 40$ (only integers)
  2. The Python script should be able to record the trace of the temperature from all of these different simulations. The Python script may store the trace (for each simulation) in memory or save the data as files. You can choose as you prefer.
  3. The simulation duration should be 24 hours and the timestep 1 minute.
  4. Evaluate the 'cost' associated with each simulation trace, using the cost-function you developed in the previous task. The simulation that has the lowest cost is the simulation that has the best values for the control parameters.You are free to chose how you compute this; whether you use Python, Matlab, Excel...
  5. Report the best parameters, and also the trace of temperature and tank volume in the best simulation. Does the simulation trace make sense? Why or why not?

Task 3: Stricter cost function

Let's say the requirement became stricter, and we want the temperature of the water to be as close to 50°C as possible, at all times. This will affect the cost function. The new cost function will be:

$$ J = \sum_{i=1}^{N} | T_{\text{setpoint}} - T_i | $$ Where,
  • $T_i$ is the value of temperature at the ithindex in the trace.
  • $N$ is the number of samples in the trace.
  • $T_{setpoint}$ is the setpoint temperature.

Implement this cost function, and re-run the parameter tuning script with the new cost function. Is there a change in the optimal parameters? Why or why not?

Congratulations! You have successfully modeled a physical system and an optimal controller for it in Modelica!

Practical Issues

  • You should ignore the translation warning from the Modelica.Fluid.Machines library that says something like -
    • "The following equation is INCONSISTENT due to specified unit information: pump.delta_head_init = pump.flowCharacteristic(pump.V_flow_single_init * 1.1, {...}, {...}) - pump.flowCharacteristic(pump.V_flow_single_init, {...}, {...})"
    • The units of following sub-expressions need to be equal: - sub-expression "pump.V_flow_single_init * 1.1" has unit "m" - sub-expression "pump.flowCharacteristic().V_flow" has unit "m3/s"
  • While OpenModelica allows the creation of icons for your models, this is not required for the assignment.
Maintained by Hans Vangheluwe. Last Modified: 2025/10/09 15:21:33.