This blog post describes the use of an external object class as described by the Modelica modelling language. In Modelica, a predefined partial class called an ExternalObject may be used for accessing external memory and performing various tasks using external functions written in C (specifically C89) and FORTRAN 77. For demonstration purposes, an example of detecting the initial rising edge using an external object is presented. The author of this blog post assumes that you have some familiarity with “C” language and the Modelica external “C” function interface (for more details, please refer to the Modelica Language specification, here).
Why use an external object in Modelica?
This section briefly explains the benefits of using the External Object in Modelica. The External Objects provide a way to store parameters and/or variables into an external memory. So, this stored data can be accessed by a Modelica function as shown in Figure 1.
Figure 1. A Modelica function with an external object that can be used to access externally stored data throughout the simulation.
Another reason to use an external object is that it ensures the initialisation, simulation call and termination functions are called in the correct order.
How to create an external object class?
In Modelica, an external object class can be extended from a builtin predefined partial class called the ExternalObject. This specialised class is used to declare external objects and shall only have two function definitions, say the constructor and destructor. Both the constructor and destructor functions are external functions and use either C or Fortran functions (please see the documentation for more details, here).
How an external object class is used?
This section explains how an external object class is used in Modelica using a flow diagram shown in Figure 2.
Figure 2. Flow diagram of a Modelica example with an external object class.
In Figure 2, the flow diagram describes the sequential operation of an external object with pseudo code. This includes the external object being instantiated, the data structure being allocated and initialised, the data structure being accessed by a function and how the structure’s memory is freed on termination.
An instance of the external object class created using a Modelica model is depicted in the leftmost column in Figure 2. When this class is instantiated, the constructor function is called which in turn calls the external initialisation function (steps 1 and 2 in Figure 2). This initialisation function allocates memory for a structure, initialises the structure and returns a pointer to this structure (steps 3 and 4 in Figure 2).
The external object can be used by functions throughout the simulation of the model (steps 6 to 10 in Figure 2). On termination or if the simulation halts with an error, the destructor function is called to free up the memory allocated to the structure (steps 11 to 13 in Figure 2).
A worked example below gives further details about how an external object can be created and used in Modelica.
Example: Initial Threshold Detection
This simple example demonstrates how an external object is used in Modelica for detecting a signal when it exceeds a threshold for the first time and calculates the time at which this incident happened. This example does not generate any events, so it can be suitable for Real-time situations.
In Figure 3, a Modelica code named as DectectThresholdExternalObject extends a predefined partial class, ExternalObject, and it contains constructor and destructor functions.
Figure 3. Modelica based External Object class.
Both these functions use an external “C” code function, and the code for these functions are given in Figure 4.
Figure 4. C code defining the initialisation (initialiseDetectThreshold) and termination (closeDetectThreshold) functions.
In Figure 4, the C code defines a structure called DetectThresholdStruct. This structure is used to store:
- threshold – the threshold being used
- triggered – if true, then the threshold has been exceeded
- triggeringTime – the time that the threshold was first exceeded
The initialisation function initialiseDetectThreshold allocates space for this structure, initialises the values of the structure and returns a pointer to this structure which is cast to void *. The closeDetectThreshold function frees up the memory used by the structure.
The code above only initialises and terminates the object, a Modelica code to detect if a signal has exceeded a threshold is as follows:
Figure 5. Modelica code to call the external detectThreshold function.
The detectThreshold Modelica function in Figure 5 has two inputs: (a) u, sends the signal on which the threshold is going to be detected and (b) simulationTime, the simulation time, and an output, timeThresholdTriggered. It also has an external object detectThresholdExternalObject to the external “C” function detectThreshold.
The external “C” function to detect the signal that exceeds the threshold is given in Figure 6.
Figure 6. C code used to detect a threshold being exceeded.
The Modelica example that uses an external object to detect a threshold being exceeded is provided below:
Figure 7. An example that detects a threshold being exceeded.
In Figure 7, the external object detectThresholdExternalObject is created that sets a threshold to 0.5 during initialisation. The detectThreshold function is used to detect when the threshold is exceeded.
Figure 8. Simulation result of the TestDetectThreshold example in Dymola.
An example of using multiple external objects
A further advantage of using external objects is that it is easy and safe to use multiple instances of the objects. An example of using multiple external objects is provided below:
Figure 9. An example that creates 5 external objects with thresholds set from 1/5 to 5/5.
The code for the examples provided in this blog post can be downloaded here.