Pitch actuator DLL Interface Specification
Users with a licence for the Advanced Pitch actuator interface module may run Bladed simulations with user-defined pitch
actuator dynamics contained in a separate file. For dynamic simulation run on a Windows operating system a DLL or Dynamic Link Library must be compiled. Likewise dynamic simulation on a Linux operating system an SO or Shared Object must be compiled. Only a continuous time interface is supported. It is still possible to simulate a discrete time model. As the feedback loops of pitch actuator dynamics work on a very short time-scale, the continuous time interface is recommended for performance reasons. This article specifies the DLL interfaces in detail.
For the DLL interfaces, all pitch variables hold the convention of positive from fine to feather, with pitch angle defined to be zero at fine pitch.
Continuous DLL interface
The pitch actuator dynamics in the DLL are defined in state-space form:
\[
\begin{align}
\dot{\bvector{x}} &= \bmatrix{A}\bvector{x} + \bmatrix{B}\bvector{u} \\[1ex]
\bvector{y} &= \bmatrix{C}\bvector{x} + \bmatrix{D}\bvector{u}_{in} \\[1ex]
\bvector{y}_{out} &= \bmatrix{C}_{out}\bvector{x} + \bmatrix{D}_{out}\bvector{u}
\label{eq:LinearModel}
\end{align}
\]
where \(\bvector{x}\) is a vector of state variables defined in the DLL, \(\bvector{u}\) and \(\bvector{u}_{in}\) are vectors of input variables defined below, \(\bvector{y}\) is a vector of output variables, and \(\bvector{y}_{out}\) is a vector that is written to disk. Matrices \(\bmatrix{A}\), \(\bmatrix{B}\), \(\bmatrix{C}\), \(\bmatrix{D}\), \(\bmatrix{C}_{out}\) and \(\bmatrix{D}_{out}\) represent terms defined in the DLL. These need not be defined explicitly as matrices, and need not be constant: in other words the pitch actuator model may be non-linear and time-varying. Discontinuous changes are allowed. The Bladed integrator will integrate the states \(\bvector{x}\); note however that the number of states defined by the DLL and integrated by Bladed may be zero, in which case the DLL may define internal states and use its own integrator, whether in continuous or discrete time, to integrate any dynamic equations it contains. This is known as co-simulation. It is possible, using co-simulation, to implement a discrete time model using the continuous time DLL interface.
If co-simulation is used it is important to realise that any dynamic coupling to the Bladed equations of motion will be
lost, and this should therefore be done only for dynamics which do not couple strongly with the dynamics of the turbine modelled by Bladed. It is also important to realise that the variable time step integrator used by Bladed will make DLL calls at varying intervals of simulated time, and that the integrator trial steps, which result in call types 5 and 6 defined below, may step backwards in time as well as forwards, but will never step backwards further than the last completed integrator step which corresponds to call type 9 defined below. It is also possible to use a combination of Bladed and co-simulation states. Using the terms 'displacement' and 'velocity' as the last word in the state name for physical states that are part of a pair will help in the identification of states for the Campbell diagram.
The DLL may be written in any language which can be compiled to a Windows DLL or Linux SO. The DLL entry point from Bladed is a single procedure called DLL_PITCH (upper case) with eight arguments and an integer return value. Either the __cdecl
or the __stdcall
calling convention may be used. The procedure definition is as follows:
Name : DLL_PITCH |
Return value: 0 means OK,
<0 means Abort |
Arguments: |
Data type |
Array length |
Description |
Arg1 |
4-byte
integer |
11 |
See below |
Arg2 |
8-byte
real |
1 |
Time (s) since start of
simulation |
Arg3 |
4-byte
integer |
Arg1(3) |
See below |
Arg4 |
1-byte char |
Arg1(4) |
See below |
Arg5 |
8-byte
real |
Arg1(5) |
See below |
Arg6 |
8-byte
real |
Arg1(6) |
See below |
Arg7 |
8-byte
real |
Arg1(7) |
See below |
Arg8 |
1-byte char |
Arg1(8) |
Message returned by DLL |
All arguments are passed by reference, so for example Arg1 is a pointer to the start of an array of ten 4-byte integers, Arg2 is a pointer to a single 8-byte real, and Arg4 is a pointer to an array of one-byte characters, the number of elements in the array being given by the fourth element of Arg1. The other elements of Arg1 are defined as follows:
Elements of Arg1 INTEGER array |
1 |
To DLL |
DLL interface version number = 4301 |
2 |
To DLL |
Call type: 1 to 9. |
3 |
To DLL |
NI = Size of Arg3 |
4 |
To DLL |
NC = Size of Arg4 |
5 |
To DLL |
NR1 = Size of Arg5 |
6 |
To DLL |
NR2 = Size of Arg6 |
7 |
To DLL |
NR3 = Size of Arg7 |
8 |
To DLL |
NC1 = Size of Arg8. |
9 |
To DLL |
Blade number starting from 1. So that blades may
be modelled individually. The DLL is called for
each blade on every call type. |
The procedure is called in different ways by Bladed, depending on the Call Type given by element 2 of Arg1. Please see Table 1 for a list of all call types. Arg2 always contains the time in seconds since the start of the simulation. Arg3 to Arg7 depend on the value of the Call type, Arg1(2), as described below. Any arguments not mentioned are not used in that call, but must still be present.
Table 1 - Definition of the interface call types controlled by Arg1(2)
If the return value is returned with a non-zero value an explanatory message (terminated by a null character) should be returned in Arg8.
The number of characters returned in Arg4 and Arg8 must never exceed NC and NC1 respectively.
1 Initialisation
This call initialises the DLL model (using any constants which might come from the Bladed model) and returns the required number of integrator states and output variables.
To read model parameters into the pitch DLL the user can make use of information contained in Arg4 as explained in the table below.
Elements of Arg3 INTEGER array (NI = 2) |
1 |
From DLL |
Nx = Number of states to integrate |
2 |
From DLL |
Nout = Number of variables to output |
3 |
To DLL |
Input type: 0 = position demand, 1 = rate demand. |
4 |
From DLL |
Output type: 1 = pitch acceleration (rad/s$^2$)
2 = pitch actuator torque (Nm). |
Elements of Arg4 CHAR*1 array (NI = 2) |
1
to
NC(max) |
To DLL |
Name of Parameter File and Verification File,
each terminated by a semi-colon (;). If desired
the DLL may open and read the Parameter File,
which contains any user-defined data. The
Verification File must be opened FOR
APPENDING ONLY, and can be used to keep a
record of the DLL parameters. This will be the
$VE file for the simulation, so it is
important not to overwrite the data which it
already contains. If opened, this file must
be closed again before the DLL returns. |
2 State definition
This call returns the names and absolute tolerances of the integrator
states required by the DLL.
Elements of Arg3 INTEGER array (NI \(\geq\) Nx + 1) |
1 |
To DLL |
Nx |
2 to
Nx+1 |
From DLL |
Auto-initialisation flag for each state:
normally 0, but set to 1 if the state
derivative must be zero in the steady state and
you wish to include this state in the
Bladed initial condition refinement step. |
Elements of Arg4 CHAR*1 array (NI \(\geq\) Nx + 1) |
1 to
NC(max) |
From DLL |
"State name:Units;" for each state |
2 to
Nx+1 |
From DLL |
Auto-initialisation flag for each state:
normally 0, but set to 1 if the state
derivative must be zero in the steady state and
you wish to include this state in the
Bladed initial condition refinement step. |
Elements of Arg5 REAL*8 array (NR1 \(\geq\) Nx) |
1 to
Nx |
From DLL |
Absolute tolerances of the integrator states |
3 Output variable definition
This call returns the names and units of variables from the DLL to be output in time history output from Bladed (i.e. \(\bvector{y}_{out}\) from the second state-space equation \(\bvector{y}_{out} = \bmatrix{C}_{out} \bvector{x} + \bmatrix{D}_{out} \bvector{u}\)).
Elements of Arg3 INTEGER array (NI \(\geq\) 1) |
1 |
To DLL |
Nout |
Elements of Arg4 CHAR*1 array |
1 to
NC(max) |
From DLL |
"Variable name:Units;" for each output
variable |
4 Initial conditions
This call executes one step of the initial conditions iteration, and
also returns the initial values of the states (assuming everything is in
the steady state).
Elements of Arg3 INTEGER array (NI \(\geq\) Nx+4) |
1 |
To DLL |
Nx |
2 |
To DLL |
NinInit = Number of variables to DLL = 7 |
3 |
To DLL |
NoutInit = Number of variables from DLL = 1 |
4 |
To DLL |
0 = trial call, 1 = final call |
5 to
Nx+4 |
From DLL |
0 = State disabled; 1 = State enabled |
Elements of Arg5 REAL*8 array (NR1 \(\geq\) NinInit) |
1 |
To DLL |
Pitch position/velocity demand (rad)/(rad/s) [^Input] |
2 |
To DLL |
Pitch angular displacement (rad) |
3 |
To DLL |
Pitch angular velocity (rad/s) |
4 |
To DLL |
Pitch Bearing \(F_x\) (N) |
5 |
To DLL |
Pitch Bearing \(F_y\) (N) |
6 |
To DLL |
Pitch Bearing \(F_z\) (N) |
7 |
To DLL |
Pitch Bearing \(M_x\) (N) |
8 |
To DLL |
Pitch Bearing \(M_y\) (N) |
9 |
To DLL |
Pitch Bearing \(M_z\) (N) |
10 |
To DLL |
Pitching inertia (kgm$^2$) |
11 |
To DLL |
Pitching friction (Nm) |
12 |
To DLL |
Pitching stiction (Nm) |
Elements of Arg6 REAL*8 array (NR2 \(\geq\) NoutInit) |
1 |
From DLL |
Pitch output variable according to output type |
Elements of Arg7 REAL*8 array (NR3 \(\geq\) Nx+10) |
1 to Nx |
From DLL |
Initial values of states if Arg3(4) = 1 |
Nx+1
To
Nx+10 |
To/From
DLL |
User variables 1 to 10 |
5 State derivatives
This call passes the current DLL state values and any required variables
derived from Bladed states to the DLL, which returns
the state derivatives (xdot) calculated by the DLL.
Elements of Arg3 INTEGER array (NI \(\geq\) Nx+2) |
1 |
To DLL |
Nx |
2 |
To DLL |
Nu = Number of input variables to DLL = 7 |
3 to
Nx+2 |
To DLL |
0 = State disabled; 1 = State enabled |
Elements of Arg5 REAL*8 array (NR1 \(\geq\) Nx+10) |
1 to Nx |
To DLL |
State variables |
Nx+1 to
Nx+10 |
To/From
DLL |
User variables 1 to 10 |
Elements of Arg6 REAL*8 array (NR2 \(\geq\) Nu) |
1 |
To DLL |
Pitch position/velocity demand (rad)/(rad/s) | |
2 |
To DLL |
Pitch angular displacement (rad) |
3 |
To DLL |
Pitch angular velocity (rad/s) |
4 |
To DLL |
Pitch Bearing \(F_x\) (N) |
5 |
To DLL |
Pitch Bearing \(F_y\) (N) |
6 |
To DLL |
Pitch Bearing \(F_z\) (N) |
7 |
To DLL |
Pitch Bearing \(M_x\) (N) |
8 |
To DLL |
Pitch Bearing \(M_y\) (N) |
9 |
To DLL |
Pitch Bearing \(M_z\) (N) |
10 |
To DLL |
Pitching inertia (kgm$^2$) |
11 |
To DLL |
Pitching friction (Nm) |
12 |
To DLL |
Pitching stiction (Nm) |
Elements of Arg7 REAL*8 array (NR3 \(\geq\) Nx) |
1 to Nx |
From |
State derivatives |
6 Variables required by Bladed
This call passes the current DLL state values and any required variables derived from Bladed states to the DLL, which returns the values of variables \(\bvector{y} (\bvector{y} = \bmatrix{C} \bvector{x} + \bmatrix{D} \bvector{u}_{in})\) which are required by Bladed.
Elements of Arg3 INTEGER array (NI \(\geq\) Nx+3) |
1 |
To DLL |
Nx |
2 |
To DLL |
Nin = 7 |
3 |
To DLL |
Ny = Number of variables required = 1 |
4 to
Nx+3 |
To DLL |
0 = State disabled; 1 = State enabled |
Elements of Arg5 REAL*8 array (NR1 \(\geq\) Nx+10) |
1 to Nx |
To DLL |
State variables |
Nx+1 to
Nx+10 |
To/From
DLL |
User variables 1 to 10 |
Elements of Arg6 REAL*8 array (NR2 \(\geq\) Nin) | |
1 |
To DLL |
Pitch position/velocity demand (rad)/(rad/s) [^Input] |
2 |
To DLL |
Pitch angular displacement (rad) |
3 |
To DLL |
Pitch angular velocity (rad/s) |
4 |
To DLL |
Pitch Bearing \(F_x\) (N) |
5 |
To DLL |
Pitch Bearing \(F_y\) (N) |
6 |
To DLL |
Pitch Bearing \(F_z\) (N) |
7 |
To DLL |
Pitch Bearing \(M_x\) (N) |
8 |
To DLL |
Pitch Bearing \(M_y\) (N) |
9 |
To DLL |
Pitch Bearing \(M_z\) (N) |
10 |
To DLL |
Pitching inertia (kgm$^2$) |
11 |
To DLL |
Pitching friction (Nm) |
12 |
To DLL |
Pitching stiction (Nm) |
Elements of Arg7 REAL*8 array (NR3 \(\geq\) Ny) |
1 to Nx |
From DLL |
Pitch output variable according to output type |
7 Output variables
This call passes the current DLL state values and any required variables
derived from Bladed states to the DLL, which returns
the values of the output variables \(\bvector{y}_{out}\) which will be presented in
the simulation time-history output.
Elements of Arg3 INTEGER array (NI \(\geq\) Nx+3) |
1 |
To DLL |
Nx |
2 |
To DLL |
Nu = 7 |
3 |
To DLL |
Nout |
4 to
Nx+3 |
To DLL |
0 = State disabled; 1 = State enabled |
Elements of Arg5 REAL*8 array (NR1 \(\geq\) Nx+10) |
1 to Nx |
To DLL |
State variables |
Nx+1 to
Nx+10 |
To/From
DLL |
User variables 1 to 10 |
Elements of Arg6 REAL*8 array (NR2 \(\geq\) Nu) |
1 |
To DLL |
Pitch position/velocity demand (rad)/(rad/s) [^Input] |
2 |
To DLL |
Pitch angular displacement (rad) |
3 |
To DLL |
Pitch angular velocity (rad/s) |
4 |
To DLL |
Pitch Bearing \(F_x\) (N) |
5 |
To DLL |
Pitch Bearing \(F_y\) (N) |
6 |
To DLL |
Pitch Bearing \(F_z\) (N) |
7 |
To DLL |
Pitch Bearing \(M_x\) (N) |
8 |
To DLL |
Pitch Bearing \(M_y\) (N) |
9 |
To DLL |
Pitch Bearing \(M_z\) (N) |
10 |
To DLL |
Pitching inertia (kgm$^2$) |
11 |
To DLL |
Pitching friction (Nm) |
12 |
To DLL |
Pitching stiction (Nm) |
Elements of Arg7 REAL*8 array (NR3 \(\geq\) Nout) |
1 to Nx |
From DLL |
Output variables |
8 Discontinuity check
This call asks the DLL whether a discontinuity has been passed; if so,
the DLL has the option of specifying a particular step reduction. These
calls may be ignored by the DLL if it does not model any
discontinuities.
Elements of Arg3 INTEGER array (NI \(\geq\) Nx+4) |
1 |
To DLL |
Nx |
2 |
To DLL |
Nu = 7 |
3 |
To DLL |
0 means OK, <0 means need to step back |
4 to
Nx+3 |
To DLL |
0 = State disabled; 1 = State enabled |
Elements of Arg5 REAL*8 array (NR1 \(\geq\) Nx+10) |
1 to Nx |
To DLL |
State variables |
Nx+1 to
Nx+10 |
To/From
DLL |
User variables 1 to 10 |
Elements of Arg6 REAL*8 array (NR2 \(\geq\) Nu) |
1 |
To DLL |
Pitch position/velocity demand (rad)/(rad/s)[^Input] |
2 |
To DLL |
Pitch angular displacement (rad) |
3 |
To DLL |
Pitch angular velocity (rad/s) |
4 |
To DLL |
Pitch Bearing \(F_x\) (N) |
5 |
To DLL |
Pitch Bearing \(F_y\) (N) |
6 |
To DLL |
Pitch Bearing \(F_z\) (N) |
7 |
To DLL |
Pitch Bearing \(M_x\) (N) |
8 |
To DLL |
Pitch Bearing \(M_y\) (N) |
9 |
To DLL |
Pitch Bearing \(M_z\) (N) |
10 |
To DLL |
Pitching inertia (kgm$^2$) |
11 |
To DLL |
Pitching friction (Nm) |
12 |
To DLL |
Pitching stiction (Nm) |
Elements of Arg7 REAL*8 array (NR3 \(\geq\) 1) |
1 to Nx |
From DLL |
Suggested time to step back to if Arg3(3) = -2 |
9 Completed step
This call tells the DLL that the time step is complete, so that a
discontinuous change to the dynamics can be implemented if required.
These calls may be ignored by the DLL if it does not model any
discontinuities.
Elements of Arg3 INTEGER array (NI \(\geq\) Nx+2) |
1 |
To DLL |
Nx |
2 |
To DLL |
Nu = 7 |
3 |
To DLL |
Blade failure type: 0 = no failure, 1 = blade is seized,
2 = blade runaway, 3 = blade is free/constrained,
4 = safety system activated |
4 |
From DLL |
Output type: 0 = pitch rate, 1 = pitch acceleration,
2 = actuator torque. |
5 to
Nx+4 |
To/From
DLL |
0 = State disabled; 1 = State enabled |
Elements of Arg5 REAL*8 array (NR1 \(\geq\) Nx+10) |
1 to Nx |
To/From
DLL |
State variables |
Nx+1 to
Nx+10 |
To/From
DLL |
User variables 1 to 10 |
Elements of Arg6 REAL*8 array (NR2 \(\geq\) Nu) |
1 |
To DLL |
Pitch position/velocity demand (rad)/(rad/s)[^Input] |
2 |
To DLL |
Pitch angular displacement (rad) |
3 |
To DLL |
Pitch angular velocity (rad/s) |
4 |
To DLL |
Pitch Bearing \(F_x\) (N) |
5 |
To DLL |
Pitch Bearing \(F_y\) (N) |
6 |
To DLL |
Pitch Bearing \(F_z\) (N) |
7 |
To DLL |
Pitch Bearing \(M_x\) (N) |
8 |
To DLL |
Pitch Bearing \(M_y\) (N) |
9 |
To DLL |
Pitch Bearing \(M_z\) (N) |
10 |
To DLL |
Pitching inertia (kgm$^2$) |
11 |
To DLL |
Pitching friction (Nm) |
12 |
To DLL |
Pitching stiction (Nm) |
Table 2- DLL responsibility on blade failures
Index |
Failure Type |
DLL responsibility |
0 |
No failure |
DLL has normal responsibilities. |
1 |
Blade seized |
Inputs to DLL are not modified. DLL is
responsible for modelling failure. |
2 |
Blade runaway |
Input position/rate demand is changed by Bladed. |
3 |
Blade free/
constrained |
Bladed handles failure. DLL is ignored. |
4 |
Safety system
(rate demand) |
Input position/rate demand is changed by Bladed |
5 |
Safety system
(torque) |
Bladed handles failure. DLL is ignored. |
Discrete DLL interface
To implement a discrete time pitch actuator model use the continuous time interface and define internal discrete time states as described below.
Instead of continuous time states, the DLL may define internal discrete time states \(\left( \bvector{x}_{d} \right)\) and pitch actuator or controller dynamics may be represented in discrete time state-space form:
\[
\begin{align}
\dot{\bvector{x}}_d(k+1) &= \bmatrix{A}_d\bvector{x}_d(k) + \bmatrix{B}_d\bvector{u}(k) \\[1ex]
\bvector{y}(k) &= \bmatrix{C}\bvector{x}_d(k) + \bmatrix{D}\bvector{u}(k) \\[1ex]
\end{align}
\]
where \(k\) is the sample instance count, \(\bmatrix{A}_d\) is the discrete time state matrix and \(\bmatrix{B}_d\) is the discrete time input matrix.
The output and feedforward matrices (\(\bmatrix{C}\) and \(\bmatrix{D}\)) are identical to the corresponding continuous time matrices.
The new discrete state values \(\left( \bvector{x}_{d}(k + 1) \right)\) may be
updated during the Completed step call (call type 9) at simulation time
\(kT_s\), where \(T_s\) is the sample period. Thus, a discrete time
dynamic model can be implemented using the same DLL interface as a
continuous time model. It is also posssible to implement both continuous
and discrete time models in the same DLL.
The pitch actuator DLL should check during a Completed step call for
simulation time equal to a sample instance (\(kT_s\)) before updating any
discrete states. If a Bladed fixed step integrator is used then, to
ensure that a Completed step call will occur at a sample instance, the
pitch actuator model sample period (\(T_s\)) should be a multiple of the
Bladed integrator time step. If the Bladed variable time step integrator
is used, then simulation time at the end of a time step may exceed the
discrete tiime model sample time \(kT_s\). In this case, the DLL should
request Bladed to re-step back to \(kT_s\) during the Discontinuity check
call (call type 8).
Last updated 07-10-2024