Wind energy is the fastest and most mature resource of renewable energy. The increasing complexity of wind turbines requires advanced modeling tools for model-based design. In this tutorial, we will implement a utility-scale wind turbine model with the corresponding benchmark control system using Collimator. We will build the model developed by national renewable energy laboratory (NREL)(Jonkman et. al., 2009) following up with some modifications and simplifications provided by researchers at Aalborg university Grunnet et. al., 2010.
We begin by importing the libraries we will use:
In the first part of this tutorial, we will build a reduced-order wind turbine model which is more suitable for model-based control system design methods. A typical wind turbine system combines a set of interacting subsystems:
The wind turbine subsystem is illustrated in the following figure:
The aerodynamic thrust force \(F_T\) and aerodynamic torque \(T_r\) generated by wind inflow is defined as:
$$F_T = \frac{1}{2}\rho\pi R^2 C_T(\lambda,\beta) v_r^2$$
$$T_r = \frac{1}{2}\rho\pi R^3 \frac{C_P(\lambda,\beta)}{\lambda} v_r^3$$
where \(\rho=1.2231\ kg/m^3\) is the air density, \(R=63\ m\) is the rotor radius, \(\lambda\) is the tip speed ratio, and \(\beta\) is the collective blade pitch angle.
The relative wind speed \(v_r\) is the difference between the wind speed and the nacelle speed due to tower oscillations:
$$v_r = v-\dot{q}_t $$
where \(v\) is the wind inflow speed, and \(q_t\) is the tower oscillatory mode position.
The thrust \(C_T\) and power \(C_P\) coefficients curves are highly nonlinear functions and they are obtained as lookup tables through more specialized high-fidelty modeling softwares such as WT_perf and Aerodyn.
Here, we have uploaded and read the csv files to obtain the independent variables and coefficient matrices. In the following Python code, we load the csv files and plot a contour plot for each function.
The aerodynamics subsystem is modelled in Collimator as the submodel below.
The thrust and power coefficients are implemented as lookup tables. However, the elements are too many to be implemented in lookup table block by hand. Therefore, we will create a function to write the matrices and the vectors to be copied and pasted within the block.
The above matrices for beta and tsr are inserted as the input x array, and input y array, respectively. Similarly, we copy and paste the ct and cp matrices within the corresponding blocks.
The tower dynamics is modelled by a second-order linear system with a damping ration \(\zeta_t = 0.08\) and eigenfrequency \(f_t = 0.3210\ Hz\):
$$m_t\ddot{q}_t + 2\zeta_t\left(2\pi f_t\right)m_t\dot{q}_t+\left(2\pi f_t\right)^2 m_t q_t=F_T $$
$$F_t = -\left(2\pi f_t\right)^2 m_t $$
$$M_t = F_t h_t $$
$$M_b = \frac{2}{3} R F_T $$
where \(m_t=697462\ m\) is the tower mass, \(h_t=87.6\ m\), \(F_t\) is the tower deflection force and \(M_t\) is the tower deflection moment.
The above equations can be converted into a state-space form as:
$$\begin{bmatrix}\ddot{q}_t \\ \dot{q}_t \end{bmatrix} = \begin{bmatrix}-2\zeta_t\left(2\pi f_t\right) & -\left(2\pi f_t\right)^2 \\ 1 & 0 \end{bmatrix} \begin{bmatrix}\dot{q}_t \\ q_t \end{bmatrix} + \begin{bmatrix}\frac{1}{m_t} \\ 0 \end{bmatrix} F_T $$
$$\begin{bmatrix}\dot{q}_t \\ F_t \end{bmatrix} = \begin{bmatrix}1 & 0 \\ 0 & -\left(2\pi f_t\right)^2 m_t \end{bmatrix}\begin{bmatrix}\dot{q}_t \\ q_t \end{bmatrix} $$
The flexible structures dynamics are implemented in Collimator as shown in the following block diagram:
Regarding the state-space block, we will define the following state-space matrices to be implemented in the state-space block.
The drivetrain is assumed to have a two-mass model with torsional flexibility. The rotor-side is considered flexible whereas the generator-side is considered rigid. The rotor-side torque is defined as:
$$J_r \dot{\omega}_r = T_r - K_r \theta- B_r \dot{\theta}$$
The generator-side torque is defined as:
$$J_g \dot{\omega}_g = \frac{1}{N} \left(K_r \theta + B_r \dot{\theta}\right) - M_g $$
where \(\omega_r\) is the rotor-side shaft angular velocity, \(J_r=35444067\ Nm/rad\) is the rotor inertia, \(\omega_g\) is the generator-side shaft angular velocity, \(J_g=534.116\ kg.m^2\) is the generator inertia, \(M_g\) is the generator torque, \(K_r= 867637000\ Nm/rad\) is the rotor spring, \(B_r= 867637000\ Nm/(rad.s)\) is the rotor damping, \(N=97\) is the gear ratio, and \(\dot{\theta}\) is the angular torsional deflection in the shaft which is defined as follows.
$$\dot{\theta} = \omega_r-\frac{1}{N}\omega_g $$
The above drivetrain dynamics are implemented in Collimator as the following submodel.
The torsional deflection submodel contains the diagram for the angular torsional deflection in the shaft equation: \(\dot{\theta} = \omega_r-\frac{1}{N}\omega_g \)
Before we move on with the next submodel, we have to initialize the angular velocity integrators for the rotor-side \(\omega_r=0.5155\) and generator-side \(\omega_g=50\) to ensure that the simulation converges.
The specification for the NREL 5MW does not contain a definition for the generator model. Therefore, we will use here a simplified 1st-order model as the electrical dynamics are much faster than the mechanical dynamics. The generator torque is modelled by the following differential equation:
$$\tau_g \dot{M}_g = T_{ref}-M_g $$
where \(T_{ref}\) is the reference torque commanded by the controller, \(M_g\) is the generator torque, and \(\tau_g=0.1\ s\) is the generator time constant.
The generated power is defined as:
$$P_g = \eta M_g \omega_g $$
where \(\eta=94.4\%\) is the generator efficiency. The Collimator model diagram is illustrated in the following figure.
At this point, we will not use the original pitch servo system model described in the NREL 5MW reference. Instead, we will use the modified model defined in [Grunnet et. al., 2010]. The open-loop pitch drive system is modelled as the following second-order transfer function:
$$\frac{\beta \left(s\right)}{U\left(s\right)} = \frac{1}{s\left(\tau_{pitch}s+1\right)}$$
where \(\tau_{pitch}=0.05\ s\) is the pitch servo time constant. The pitch system is controlled by proportional controller:
$$u\left(t\right) = K_p\left(\beta_{ref}-\beta\right)$$
where \(K_p = 10\) is the proportional gain, and \(\beta_{ref}\) is the pitch angle reference commanded by the controller.
We can have a look at the closed-loop performance of the pitch servo:
The pitch system is modelled in Collimator as shown in the following diagram:
The Submodel blocks are connected together as in the following aggregate wind turbine model:
Variable-speed variable-pitch utility-scale wind turbine are usually controlled through two control systems:
Both of the control systems are working independently. This control configuration is a conventional control strategy for wind turbines. For more details and elaboration about this strategy, please refer to (Pao and Johnson, 2009). In this tutorial, we will implement the baseline controller developed in the NREL 5MW wind turbine definition report (Jonkman et. al., 2009).
The generator torque command is computed as a piecewise function of the generator speed based on regions of operation.
For the NREL 5MW wind turbine, the generator torque command function is defined as:
$$ T_{ref}= \left\{\begin{array}{} 0 & 0<\omega_{g(rpm)}<670 \\ 96.5338\ \omega_{g(rpm)}-64677.65123 & 670\leq\omega_{g(rpm)}<871 \\ 0.025576386\ \omega_{g(rpm)}^2 & 871\leq\omega_{g(rpm)}<1136.4978 \\ 412.076\ \omega_{g(rpm)}-435288.3165 & 1136.4978\leq\omega_{g(rpm)}<1161.9632 \\ \frac{50578944.12852911}{\omega_{g(rpm)}} & \omega_{g(rpm)}\geq 1161.9632\end{array} \right. $$
In addition, the generator has the following physical constraints:
$$0 \leq T_g \leq 474502.91 $$
$$-15000 \leq \dot{T}_g \leq 15000.91$$
Here, we can visualize the the torque command function:
The torque controller can be modelled in Collimator directly through a Python script block:
The physical constraints of the generator can be implemented by 'Saturation' and 'Rate Limiter' blocks.
This control system regulates the rotor speed at the rated value by manipulating the blade pitch angle. The blade pitch angle command is computed by a gain-scheduled PI controller. The PI controller is defined as:
$$U(z) = K_p + K_i \frac{T_s}{z-1}$$
where \(K_p = 0.196491203325120\), \(K_i=0.084210515710766\), and \(T_s = 0.01\) is the controller sampling time.
The control action is multiplied by a correction factor that is a function of the current blade pitch command:
$$C_f = \frac{1}{1+\frac{\beta_{ref}}{0.109997}} $$
also, the pitch servo system has the following physical constraints:
$$0 \leq \beta_{(deg)} \leq 90 $$
$$-8 \leq \dot{\beta}_{(deg)} \leq 8 $$
The PI controller is implemented in Collimator as the following diagram:
The complete gain-scheduled controller is modelled as:
We can see that besides the gain scheduled PI, we have added a mechanism to switch off the pitch controller while the wind turbine is below region 3. The off switch mechanism also resets the PI integrator to have an anti wind up effect.
The combined control strategy that contains the generator torque controller and the pitch controller is implemented in the Model Editor diagram below:
To test the performance of the controller, we will use three datasets for wind fields generated by specialized software's for modeling wind turbulence:
Then, from the data source block properties, we can selected the data set we have uploaded before: