Calculating partial derivatives of a model

This blog post looks at how partial derivatives of a model can be calculated by exporting a model as an FMU, then importing the FMU into Dymola and using the fmiGetDirectionalDerivative() function.

How can partial derivatives be calculated?

Modelica does not supply an easy way to calculate partial derivatives of a model or system. There are ways for calculating partial derivatives of functions, described in Using Automatic Differentiation for Partial Derivatives of Functions in Modelica, and the PDE library, which calculates partial derivatives for the use of creating models that use partial derivatives.

Fortunately, the FMI standard defines a fmi2GetDirectionalDerivative() function for calculating partial derivatives (see page 26 of the FMI-Specification). Therefore, one method to get the partial derivative of a model is to create an FMU of the model, and then import the FMU into Dymola and use this partial derivative function.

Calculating partial derivatives using an FMU

Creating and importing an FMU

For example, let’s take a simple driven pendulum model, Figure 1, and export it.

Figure 1. A simple driven pendulum model

Figure 1. A simple driven pendulum model

The driven pendulum model can be exported as an FMU by pressing Ctrl+F9; see this blog post for more details. It can be imported by going to File>Open>Import FMU, either as “Model Exchange” or “Co-simulate” as both support the calculation of partial derivatives.

Modifying the FMU so interfacing functions can be used

When Dymola imports FMUs, it creates all the functions for interfacing with the FMU dll within the FMU code in Dymola. These FMU functions include the fmiGetDirectionalDerivative() function for calculating partial derivatives. However, these functions are stored in a protected section. The FMU model has to be modified to be able to make use of these functions as in Figure 2.

Figure 2. Commenting out protected so FMU interfacing functions can be used

Figure 2. Commenting out protected so FMU interfacing functions can be used

Comment out the protected statement in the Dymola FMU code (as in Figure 2) that is found above the following line:

  constant Integer fmi_NumberOfEventIndicators = 0;

This will allow the FMU interfacing functions to be used.

The fmiGetDirectionalDerivative() function

The fmiGetDirectionalDerivative() function in the Dymola FMU is used in the same way the fmi2GetDirectionalDerivative() function described on page 26 of the FMI-Specification. Except the nUnknown and nKnown inputs are not present in the Dymola fmiGetDirectionalDerivative() function, as in Figure 3.

Figure 3.  Inputs and outputs of the fmiGetDirectionalDerivative() function

Figure 3. Inputs and outputs of the fmiGetDirectionalDerivative() function

The fmi input is the index to the external fmi object (see the external object blog). The z_refs and v_refs inputs, in Figure 3, are the valueReference values of the signals. The valueReference for rev.w is obtained from the modelDescription.xml file below:

<ScalarVariable
  name="rev.w"
  valueReference="33554433"
  description="First derivative of angle phi (relative angular velocity)"
  initial="exact">
  <Real
    declaredType="Modelica.Units.SI.AngularVelocity"
    start="0"
    derivative="356"/>
</ScalarVariable>

The valueReference values are the indexes to the signals in the FMU.

The z_ref signal is the output or derivative signal for which the partial derivative is to be calculated, taken with respect to the v_ref signal which is the input or state signal. dv is a gain applied to the partial derivative. Please refer to page 26 of the FMI-Specification for a complete description.

Using the fmiGetDirectionalDerivative() function

I recommend creating a separate model, placing the modified FMU (see Figure 2) and adding in a Modelica.Blocks.Source.RealExpression block to this model as in Figure 4.

Figure 4.  FMU block with partial derivatives used to calculate A and B matrices

Figure 4. FMU block with partial derivatives used to calculate A and B matrices

Then set the real expression component as:

<fmu component name>.fmi_Functions.fmiGetDirectionalDerivative(<fmu component name>.fmi, z_ref, v_ref, {1}))

Where z_ref and v_ref are the valueReference signal vectors as described in “The fmiGetDirectionalDerivative() function” section, above. In Figure 4 the Real expressions components are matrices and the fmiGetDirectionalDerivative() is called multiple times to populate these matrices.

How can partial derivatives be used?

Partial derivatives of models can have many uses, two cases where they are used is for calculating state observers such as in the extended Kalman filter and for control purposes such as LQR.

A nonlinear LQR controller example

A LQR controller is designed to be used with linear systems. This example looks at a way of using LQR controllers with nonlinear models by calculating the A and B matrices at each instance using fmiGetDirectionalDerivative() and then updating the LQR controller accordingly. This example is purely for demonstration purposes.

FMU plus partial derivatives model

A model of the driven pendulum in Figure 1 was exported as an FMU and imported into Dymola. This FMU was modified as in Figure 2 to allow access to fmiGetDirectionalDerivative(). A model with partial derivatives was created as in Figure 4.

Calculate LQR K value

The infinite-horizon continuous time LQR method was implemented as described in the wikipedia entry. This required solving P in the Riccati equation:

Figure 5.  The Ricatti equation.

Figure 5. The Ricatti equation. N was set to zero in this example. Figure: wikipedia.

Solving the above equation introduced four nonlinear equations for this example. In some cases better results were obtained by supplying an initial guess value for P.

Simulation of the driven pendulum

The full controlled driven pendulum model was created as in Figure 6.

Figure 6.  Full driven pendulum model with lqr controller that is updated

Figure 6. Full driven pendulum model with lqr controller that is updated

The FMI value calculates the A and B matrices which are passed to the LQR designer which determines the value of K. This K value is negated and multiplied with the states of the system to determine controlling torque of the driven pendulum in Figure 6.

The revolute angle is 0 (radians) when the pendulum is inverted and is pi at the bottom. In this example the pendulum is initially stationary at the bottom and then is driven to the inverted position.

The value for Q (see LQR wiki) had to be set to Q=[100,0;0,1], low values for Q[1,1] would result in the pendulum getting “stuck” while going up. The R value was set to 1.

Figure 7.  Driven pendulum simulated using nonlinear LQR

Figure 7. Driven pendulum simulated using nonlinear LQR

Conclusion

This post describes how to calculate partial derivatives of a Modelica model and an example is provided on how these partial derivatives can be used to control a driven pendulum.

The code for the driven pendulum is available on request, via: Driven Pendulum Code

Written by: Garron Fish – Chief Engineer

Please get in touch if you have any questions or have got a topic in mind that you would like us to write about. You can submit your questions / topics via: Tech Blog Questions / Topic Suggestion

CONTACT US

Got a question? Just fill in this form and send it to us and we'll get back to you shortly.

Sending

© Copyright 2010-2021 Claytex Services Ltd All Rights Reserved

Log in with your credentials

Forgot your details?