Modelica Assignment 

Practical Information

  • Due Date: 25 October 2024, 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 gantry system and then create a controller for optimal control of the system. You will learn:

  1. How Ordinary Differential Equations (ODE) can be used for the modeling and simulation of Cyber-Physical Systems (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 (resultant) behavior of the CPS.

OpenModelica

For the tutorial on TBD, you should make sure you have OMEdit installed in your laptops. You should also have downloaded this zip-file which contains an example model of cooling of an object based on Newton's law of cooling and corresponding Python code.

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 available 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 > for Name 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 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 compile the model again. 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 example, example_package. In Specialization, select Package. This is also shown in Fig.1. Click OK. You should now see your Modelica package in the Libraries class. 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 browsing window.

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 example, example_model. In Specialization, select Model. Make sure that for Insert in class, the textbox specifies the Modelica package within which you want to create your Modelica model. Click OK. You have created your first Modelica model!

You can edit the model from within the package or by opening the model. Ideally you should edit the model directly, since then you can visualize it if in the form of blocks and connectors. You cannot visualise a package since it just contains other modelica classes with no physical connections between them. The modelica classes are just organised that way since they may be related. For example, the Modelica package contains sub-packages like Electrical (for electrical components), etc. 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 graphical editor can only be used in case the model consists of blocks with causal/acausal connections between them. For the 1st and 2nd tasks of the assignment, you will not use the graphical editor, since we are just creating a model based on Ordinary Differential Equations which have no graphical concrete syntax (within OpenModelica at least).

In the text editing pane, you can now define your modelica model in-between the model and its corresponding end declarations. 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 low enough).

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 type, name and default value in this syntax:

parameter <type> <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 hve 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 sub-directory of the working directory as described above. This sub-directory is named 'package_name.model_name' and the executable in this sub-directory is executed with the command './model_name'. 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
  4. Controller Model Tuning

Each part is aligned with one of the learning goals

Problem Statement

A gantry system is an indispensable element of an efficient sea-port. It is used to move containers on and off docked ships. When a ship docks at the port, the following steps happen in order:

  1. The long arm suspended in the air lowers to a horizontal position, forming a long track on which the trolley can move, perpendicular to the ship's orientation. The trolley can even move to positions directly above the ship now.
  2. The gantry system moves on gantry tracks. Using these tracks, the gantry system moves into a suitable position facing the location of the container that needs to be loaded/unloaded.
  3. The trolley moves into position directly above the container that it wants to load/unload to/from the ship.
  4. The trolley is equipped with a pulley and rope system with a grabber at the end. The pulley is 'lowered' to grab the container, and then the pulley system is 'raised', so now the container is suspended in the air.
  5. Using the trolley tracks, the trolley moves (with the suspended container) to a position directly above the desired position of the container.
  6. The pulley system is lowered, and the container is released.
  7. Steps 2-7 are repeated for every container that needs to be moved.

Have a look at this video. It vividly demonstrates the steps above performed by gantry cranes to completely automate the loading/unloading of ships docked at the Port of Singapore.

Illustration of a gantry crane. We will only focus on the movement of the trolley and not of the crane (on the gantry tracks).
Figure 5: Illustration of a gantry crane. We will only focus on the movement of the trolley and not of the entire crane (on the gantry tracks).

Gantry cranes at Port of Antwerp - Bruges.
Figure 6: Gantry cranes at Port of Antwerp - Bruges.

Traditionally, these gantry systems are operated by skilled technicians with years of practice. However, as you may have seen in every other domain, there is a push to automate the operation of gantry cranes supposedly to increase efficiency compared to human labor. As can be deduced from the list of steps above, the operation of a gantry crane involves many steps, each of which has complexities of its own. 

In this assignment, we will only be focusing on step 5, which is, the movement of the trolley on its tracks (remember that this is not the same as the tracks for the whole gantry system!). In essence, we would like to design a suitable controller such that the position of the trolley is moved based on a desired set-point; movement of the trolley is only possible in one direction, i.e. perpendicular to the ship (if viewed from above). The complexity in this step comes from the fact that the trolley is loaded with the suspended container, giving the container a pendulum-like motion when the trolley is moved. For obvious reasons of safety and efficiency, it is desirable that the container/pendulum sways as little as possible. This means we need to design a controller that controls the movement of the trolley, while minimizing the angle of sway of the container. The obvious method is to move the trolley infinitesimally slowly, but this is not efficient w.r.t time required to execute the operation.

Plant Model Creation

Fig.7 describes the mechanics of the trolley-pendulum system and the associated forces. We will consider that the length of the pendulum rope is fixed and not variable. We will consider damping in the movement of the trolley on the tracks, and also damping in the swinging of the pendulum (primarily due to friction). As described earlier, we are interested in the position of the trolley $x(t)$, and the angle of the pendulum $\theta(t)$ at any given time t. The control signal applied to move the trolley is $u(t)$

.
Illustration of simplified kinematics of trolley and pendulum system.
Figure 7: Illustration of simplified kinematics of trolley and pendulum system.

To obtain the equations of motion in the forms of ODEs that can be used by Modelica to numerically solve the positions of the trolley and pendulum, we need to compute the Lagrangian of this kinematic system, and use it to derive the ODEs. Fear not! The task has already been performed by our colleague Joost Mertens from the CoSys Lab (where they have built a scaled model of the gantry system that we are studying in this assignment), and they have provided us with the solved ODEs that can be plugged into Modelica. They are: $$ \frac{d}{dt} x(t) = v(t) $$ $$ \frac{d}{dt} \theta(t) = w(t) $$ $$ \frac{d}{dt} v(t) = \frac{ r \cdot \left(d_{c} \cdot v{\left(t \right)} - m \cdot \left(g \cdot \sin{\left(\theta{\left(t \right)} \right)}\cdot \cos{\left(\theta{\left(t \right)} \right)} + r \cdot \sin{\left(\theta{\left(t \right)} \right)}\cdot\left(w{\left(t \right)}\right)^{2}\right) - u{\left(t \right)}\right) - {\left( d_{p} \cdot \cos{\left(\theta{\left(t \right)} \right)} \cdot w{\left(t \right)}\right)}}{- r \cdot \left(M + m \cdot \sin^{2}{\left(\theta{\left(t \right)} \right)}\right)} $$ $$ \frac{d}{d t} w{\left(t \right)} = \frac{{\left(d_{p} \cdot w{\left(t \right)} \cdot {\left(m + M \right)}\right)} + {\left(m^{2} \cdot r^{2} \cdot \sin{\left(\theta{\left(t \right)} \right)} \cdot \cos{\left(\theta{\left(t \right)} \right)} \left(w{\left(t \right)}\right)^{2}\right)} + m \cdot r \cdot \left({\left(g \cdot \sin{\left(\theta{\left(t \right)} \right)} \cdot {\left(m + M \right)}\right)} + {\left(\cos{\left(\theta{\left(t \right)} \right)} \cdot {\left(u{\left(t \right)} - d_{c}\cdot v{\left(t \right)} \right)}\right)}\right)}{(m \cdot r^2)\cdot {\left(- M - {\left( m \cdot \sin^{2}{\left(\theta{\left(t \right)} \right)}\right)}\right)}} $$

Where:

  • $x(t)$: the displacement of the trolley/cart
  • $v(t)$: the velocity of the trolley/cart
  • $\theta (t)$: the angular displacement of the pendulum, w.r.t the trolley
  • $w(t)$: the angular velocity of the pendulum
  • $u(t)$: the control signal to move the trolley and pendulum
  • $m$: mass of pendulum bob/container
  • $M$: mass of trolley/cart
  • $r$: length of the rope connecting the pendulum bob to the trolley
  • $d_p$: damping factor swinging of pendulum
  • $d_c$: damping factor for motion of cart
  • $g$: constant for gravitational acceleration on the surface of the Earth (not Newton's gravitational constant!!).
You are referred to this website to learn more about this derivation. Note that the system on this website uses a spring which provides a force $k \cdot x$, whereas we replace this with the variable control signal $u(t)$ in our assignment.

Tasks

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

  1. 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 within this package, for each part of the entire assignment.
  2. Implement the given plant equation(s) in a new model.
    Hint: you can use the der() function to represent the time-based derivatives in Modelica.
    Note: I use the term 'plant' above to refer the concept by the same name prevalent in control theory, where the plant is the system whose behavior is controlled by the control signal/s
  3. Model the trolley's displacement and velocity, and the pendulum's angular displacement, and angular velocity as variables. Also model the control signal as a variable. The equations should specify the corresponding dependencies between these variables as described above.
  4. Parametrize the rest of the terms described in the list above.
  5. Include your code in your report. It could even be a screen-grab of the editor window, but preferably a code-block.
  6. Simulate the model with the following values:
    • $m=200 gms$
    • $M=10 kgs$
    • $r=1 m$
    • $d_p=0.5$
    • $d_c=2$
    • $u=0$
  7. If you have not already noticed, something is missing in all the descriptions above. It is the initial values of the variables! In all of the assignment the initial values of the variables are as follows:
    • $x=0$
    • $v=0$
    • $\theta=0$
    • $w=0$
    This means the gantry is initialized in a state with the lowest possible potential energy and with zero kinetic energy.
  8. Simulate this model for $20$ seconds with a time step size of $0.004$ seconds.
  9. Use the animation code provided here to plot an animation of the gantry system based on your simulation results. Notice that the control input $u=0$ specified above. This means that the system should have no motion and the inputs to the animation should just be arrays of zeros.
    Does your system move in the above simulation? You have probably made a mistake in your Modelica code for the equations. This is an excellent self-test for your implementation!
    Note: You do not need to provide a plot for this simulation in your report. Do feel free to report IF this helped diagnose a problem in your model.
  10. Now replace $u=0$ with:
    if time < 0.5 then u = 1000; else u = 0 end if;
    This essentially models a control signal that provides a positive impulse-like control input.
    Note: This also demonstrates the beauty of Modelica, the ability to use elements from the procedural programming paradigm.
  11. Simulate with the new control signal and provide plots of $x$ and $\theta$. Discuss the results in your report and describe the motion of the system in simple words. The animation function is especially useful here.

BEWARE! Often customer requirements will be in multiple units as is done above (for example metres and kilometres). 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 explicitly specifying the units of all the variables and parameters in your Modelica model by reusing definitions from the MSL.

BONUS: for explicitly describing each parameter and variable with comments in your Modelica code.

Note: There are many assumptions in our model, for example, the rigidity of the rope, the point-estimation of masses, drag friction, etc..

Plant Model Calibration

You have successfully created an abstract model of the gantry, but how will you decide the values of the parameters 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 gantry data. The parameters, which give the least error between the two datas are said to be the best fit, and are chosen accordingly.

An exhaustive way of finding optimal parameter values (note that in each experiment, there is one parameter) 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.

Because we designed the gantry, we already know that:

  • $m=200 gms$
  • $M=10 kgs$
  • $r=1 m$

Hence, we need to find the damping coefficients $d_p$ and $d_c$. In our case, we can simplify the estimation of these parameters, by performing two different experiments, where the effect associated with one of the coefficients are nullified and hence the parameters can be estimated independently.

Experiment 1

In the first experiment, you will 'lock' the pendulum. In real life, this would be performed by setting $r=0$ and $m=0$ by 'reeling in' the pendulum rope with no container attached to it.

  • We cannot just set $m$ and $r$ to zero in our model because that leads to divide-by-zero error. Hence we must create a new proxy model that does not include the pendulum but only the trolley/cart and its movement on its rails.
  • The equation for such a system is the simple set of kinematic equations: $$ \frac{d}{dt}x(t) = v(t)$$ $$ \frac{d}{dt}v(t) = -(\frac{d_c}{M}) \cdot v(t)$$
  • The control signal is non-existent in this experiment.
  • The initial values $x=0$ and $v=5 m/s$. The values of parameters: $M=10 kgs$ and $d_c$ should be in the range $(0,5.00]$.
  • The above set-up will essentially create a deceleration profile.

The real life-data from experiment 1 (to estimate $d_c$) is provided in this csv file. This data represents the recorded position of the trolley/cart (in metres) at intervals of 0.004 sec for 20 sec.

Experiment 2

In the second experiment, you will 'lock' the trolley's movement. This is also how it will be performed in real-life:

  • We cannot just set $x = 0$ in our model because that leads to divide-by-zero error. Hence we must create a new proxy model that does not include the trolley or its motion but only the pendulum and its swinging motion.
  • The equation for such a system is the simple set of kinematic equations: $$ \frac{d}{dt}\theta(t) = w(t)$$ $$ \frac{d}{dt}w(t) = \frac{-((d_p \cdot w(t)) + (m \cdot g \cdot r \cdot sin(\theta)))}{m \cdot (r ^ 2)}$$
  • The control signal is non-existent in this experiment.
  • The initial values $w=0$ and $\theta=30\deg$. The values of parameters: $m = 200 gms$, $r = 100 cm$, and $d_p$ should be in the range $(0,5.00]$.
  • .
  • The above set-up will essentially create a profile of dropping the pendulum from a certain angle, and recording its oscillations of decreasing amplitude due to damping - the angular deceleration profile.

The real life-data from experiment 2 (to estimate $d_p$) is provided in this csv file. This data represents the recorded angular position of the pendulum bob/container (in radians) at intervals of 0.004 sec for 20 sec.

Tasks

The main purpose of this part of the assignment is finding the damping coefficients $d_p$ and $d_c$ of the gantry system, based on experimental data (i.e., observations/measurements on the real system). You will have to repeat the following steps for each parameter that needs to be estimated.

  1. Create and simulate a new Modelica model for the experiment that corresponds to the parameter (since we cannot directly use the initial model).
  2. You need to create a Python script that executes the Modelica model of the experiment. The Python file should be named 'parameter_tuning.py'
  3. This Python script should also contain a loop that iterates over all possible values of the parameter based on the given interval in the experiment description.
  4. The Python script should be able to record the trace of the displacement of the gantry and/or the angular displacement of the bob 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 between each of your experiments/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...
    • The parameters should be precise upto 2 decimal digits.
  6. Report the value of the parameter in your report, with appropriate graphs comparing the simulation output versus real life data.

BEWARE! The csv data is at a time-step of 0.004 seconds, with start time at 0 seconds and stop time at 20 seconds (5001 data-points).

Controller Model Creation

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 lateral position of the gantry trolley/cart. The control output from the PID controller, i.e. $u(t)$ drives the plant / process. The plant produces an output i.e. $x(t)$. The difference between the measured output $x(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 controller
Figure 8: PID controller (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)$. We will also be exploring how the three quantities affect the behavior of the PID control through the tasks.

So, to sum up, in our case:

  • The plant is the complete gantry trolley-pendulum system.
  • The measured output from the plant is its position $x(t)$.
  • The set-point is the desired value of the position of the gantry trolley/cart.
  • The control output is an electronic acceleration / deceleration signal to the trolley.
  • The error signal is the difference of distance between the set-point and the current position of the trolley.

Hence the equation for implementing the control is:

$$ e(t) = r - x(t) $$ coupled with the equation above.

Note: In our simple case, the set-point is constant; we only want to test the trolley's movement from point a to point b. However, realistically, the set-point changes with time, often discontinuously.

Tasks

You modeled equations using a textual language in the first task. In this task, you will model equations using block diagram representations in Modelica.

Sub-task 1: Creating a Block from the plant model

  1. Modelica allows re-use of models by means of the 'extend' clause.
  2. We want to re-use the model we created originally (not the calibration experiment models!!)
  3. First, set the parameters $d_p$ and $d_c$ in the original model, based on your findings from the previous task.
  4. Create a new Modelica class in your assignment package, but this time of the type 'Block'
  5. You can add the following piece of code using the textual editor, in the block you just created:
    extends <name of your original plant model> ;
    extends Modelica.Blocks.Icons.Block ;
    Modelica.Blocks.Interfaces.RealInput u_input "Input signal connector";
    Modelica.Blocks.Interfaces.RealOutput x_output "Output signal connector";
    equation
    u_input = <name of control variable in your original plant model> ;
    x_output = <name of the displacement variable your original plant model> ;
  6. Basically, in the piece of code above, you have 'copied' your original plant model into the block via the extends clause. Then you defined Real connectors for the input and output using the MSL. Finally, you have equated the values of the input and output connectors to variables in your plant model.

Note: The above is a description of using your gantry plant model as a block, but the same principles apply for any other plant model that you have defined textually and want to use as a causal block. There are different kinds of connectors available in the MSL for causal and a-causal quantities. One can add as many meaningful interfaces as they like.

Note: The 'extension' of Icons.Block is only a cosmetic change about the appearance of the block in the next sub-task, and is not functional in any way.

Sub-task 2: Creating the PID controller block

  1. Create another block in your Modelica assignment package, to model the PID controller.
  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 sub-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. You will want to have an architecture like described by the colored boxes in Fig. 8.
  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.

Note: You have not yet created the whole PID control loop yet! That is the next step.

Sub-task 3: Creating the PID control loop

  1. We can finally use all the blocks that we have defined before, in our own PID control loop!
  2. Create another Model in your Modelica assignment package, to implement the PID control loop.
  3. You can simply drag and drop the relevant blocks (including the blocks that you have created yourself), and connect them to each other, based on the complete described in Fig.8.
  4. You should explore the MSL yourself and search for the relevant blocks, including a constant output block for the set-point.
  5. Create another python function to simulate the PID control loop in action.
  6. You can set block parameters by using <block_name>.<parameter_name> = value in the override flag.
  7. Simulate the PID control loop by varying each control parameter. The value of the set-point is always going to be $20$ metres.
  8. You are free to use the appropriate simulation duration and time-step.
  9. Report your observations about the varying of each parameter. The animation function is particularly helpful to understand the traces.

Note: Students often forget to include the analysis of varying the three control parameters in their report. Avoid making the same mistake!

Examples on how to compose blocks in Modelica is described on this site. These example blocks are available in the Modelica library.

Note: Do not model any part of the control loop using textual equations. In this part of the assignment you should use the graphical view to model your 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, the controller also needs to be tuned for the most ideal solution. However, we do not directly have reference data to compare the simulation output to. Instead, the designer (you) should come up with a cost function to ascertain if the plant behaves as required.

Tasks

Sub-task 1: Design of the cost function

  1. We are interested in two aspects of the PID controlled system: efficiency of the trolley and stability of the pendulum.
  2. It is obvious that it is desirable to minimize the angular displacement of the pendulum, and also minimize the time taken for the trolley to reach the set-point (remember $x=10 mtrs$).
  3. You will create a very naive linear cost function of the form: $$a \cdot \theta_{max} + b \cdot t_{task} $$ Where,
    • $\theta_{max}$ is the maximum amplitude of $\theta$ observed from the particular simulation trace.
    • $t_{task}$ is the time taken by the trolley to reach the set-point with $10 cm$ accuracy, meaning the time when the trolley reaches/crosses $9.9 mtrs$. You should also consider that the oscillations of the pendulum remain within 10 degrees magnitude (after the task is considered complete), to consider the pendulum sufficiently positioned. You can do this by calculating the first moment, starting from which the angular displacement remains within the prescribed bounds. You need to compare this time with the time taken to reach the set-point, and chose the larger. Beware that the SI unit for angular displacement is radians and the simulation trace will probably be expressed in radians if you used SI units.
    • $a$ and $b$ are modifiers that modulate the cost function. You will obtain these values by plugging in the last four digits of your student number/s in this Python function. The function prints the value of $a$ and $b$ to stdout.
  4. Report the cost-function that you will use.

Sub-task 2: Perform simulations and calculate costs

  1. Based on the above information, and your efforts in the previous task, it is an intuition that we need to use only the PD controller and not the entire PID controller, for this cost function.
  2. To do so, you can set $K_i = 0$ and leave it unchanged in the rest of the simulations.
  3. Create yet another Python function to simulate the entire PID control loop with the following possible ranges for the control parameters:
    • $1 \leq K_p \leq 40$ (only positive integers, higher resolution is not required)
    • $10 \leq K_d \leq 500$ (only multiples of 10, higher resolution is not required)
  4. The Python script should be able to record the trace of the displacement of the gantry AND the angular displacement of the bob 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. You are free to use the appropriate simulation duration and time-step. Make sure that your simulation duration is enough for the trolley to reach the set-point in all cases.
  6. Evaluate the 'cost' associated with each simulation trace, using the cost-function you developed in the previous sub-task. The simulation that has the lowest cost is the simulation that has the best values for the control parameters.
    • 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...
  7. Report the best parameters, and also the graph of the resultant simulation. Does the simulation trace make sense? Why or why not?

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

Note: This is a very naive controller not fit for use in production. Look at this video. It demonstrates an automated gantry crane. Notice the irregular movement of the trolley, and how the gantry moves the container in 2 'swoops' ensuring maximum stability while being efficient. Modern controller are very complex, with features like state-estimation that makes the controller aware of the physics of the system at a more fine-grained level.

Practical Issues

  • It is allowed to have unresolved "warnings" in your solution, but be aware they might yield different results on other machines.
  • Use of the provided animation code requires a Python interface to a GUI backend. The provided code uses tkinter, but you may switch to any GUI backend of choice. For tkinter, the necessary package is named 'python3-tk'.
  • While OpenModelica allows the creation of icons for your models, this is not required, necessary or encouraged for the given assignment.
Maintained by Hans Vangheluwe. Last Modified: 2023/11/03 17:30:23.