Pitch control error

Hello all,

I’m working on the control of a 700kW wind turbine model. I’m using the NREL 5MW control (DISCON.dll) with some modifications. I have changed the Generator-Torque Controller to adapt it to the power curve of my wind turbine model (I have obtained good results). I have not changed anything on the blade-pitch controller.

I understand that when the generator speed is under the rated speed, the generator-torque controller is applied, and when the speed is over the rated speed, pitch controller starts. However, an error occurs when I try to start the simulation with an initial pitch angle, even when the generator speed is under rated speed.

The error is the following:

[i]FAST_Solution:FAST_AdvanceStates:AD_UpdateStates:BEMT_UnCoupledSolve:DeterminePhiBounds:There is
no valid value of phi for these operating conditions! psi = -1.8624, Vx = -0.91923, Vy = 27.819,
rlocal = 10.605, theta = 0.54263

a FAST encountered an error at simulation time 0.5875 of 600 seconds.
Simulation error level: FATAL ERROR

Aborting FAST.[/i]

Could anyone help me with that? How can I set a fixed value of pitch in the simulation when the generator-torque controller is applying?

Thank you all in advance,

Dear Pablo,

The error you receiving about “no valid value of phi” is a quite generic error meaning that the blade-element/momentum theory (BEMT) routines in AeroDyn can’t find a solution. Usually this error is indicative of a numerical problem with the simulation i.e. the error is usually preceded by a large jump in rotor speed or blade deflection. Is that happening in your case? If so, you’ll need to resolve the problem before proceeding. If not, you could see if an upgrade to FAST v8.15 (just released last week) fixes the problem: included in this update to FAST is some improvements to the AeroDyn BEMT solution procedure.

I’m not sure I understand why you would be choosing different blade-pitch angles below rated, but this may cause some problems i.e. the controller may not be initialized properly or it may be difficult (or take a long time) for the solution to reach a quasi-steady state. See the following forum topic for my recommendations on setting initial conditions for FAST simulations: http://forums.nrel.gov/t/initial-conditions-for-tower-and-rotor/609/1.

I hope that helps.

Best regards,

Thank for your reply.

I have done some additional simulations and I have notice that when you set the initial pitch of the blades to a non-zero value, the error occurs. The curious thing is that the simulations run for 1.5 seconds (more over) until it crashs. In these results, I can see how pitch start moving from the initial value to some extreme values that have no sense. The point is that I do not understand why is the pitch moving if the generator speed is under rated, so the pitch control shouldn’t be applying, am I wrong?

What I want to simulate is the WTG with a low wind speed (generator speed below rated) and an initial-constant non-zero pitch. What I’m specting to see in the result is how the torque control is actuating, and the pitch maintaining its value because pitch control is not applying.

Have you got any idea about why is the pitch moving on my simulations?

Thank you in advance,


Dear Pablo,

Depending on what pitch controller you’re using (e.g. the NREL 5-MW baseline controller), I can foresee the controller not being initialized properly if the pitch angle and rotor speed are not set consistently i.e. if the rotor speed is initialized below rated, the pitch should be initialized at rated; or if the pitch is initialized above rated, the rotor speed should be initialized at rated. And if the controller is not initialized properly, the solution may take a while to get to a “correct state” or it may never correct itself.

Regardless, if you want a fixed pitch angle, you can disable the pitch controller by setting PCMode to 0 in the ServoDyn input file.

I hope that helps.

Best regards,

Dear Jason,

Thanks for your fast reply. I think I’m getting close the solution. In your last reply you said: " i.e. if the rotor speed is initialized below rated, the pitch should be initialized at rated; or if the pitch is initialized above rated, the rotor speed should be initialized at rated". If I set the rated pitch to a value over 0 (i.e. pitch = 2º), the simulation will run with that pitch value, while generator speed is under rated, without changing it and then, when the WTG reach the rated speed, the pitch control will start and it will begin controlling the pitch.

Could you tell me where can I change the rated pitch value? I know that initial pitch can be set in Elastodyn file, but I don’t know how to set the rated pitch.

Thank you in advance.


Dear Pablo,

The rated pitch is set within the controller. For the NREL 5-MW baseline controller, we supply the source code along with the DLL. You’ll have to change this source code and recompile the DLL.

Best regards,

Dear Jason,

I’m working on the pitch control of Wind turbine. I’m using the Simulink to add my pitch controller. Actually, I just modify a little DISCON.dll and write it in a 2-level Matlab Sfunction. During the simulation(it just can run more than 0.1s), I have the same problem. I have outputed some results, and I found that after several steps, the ‘‘BldPitch’’ from outdata will change a lot and increasing very quickly. Before the simulation crash, it can be 9.2342e+17.

[code]Time =


GenSpeed =


PitAng =


PitCom =


Time =

GenSpeed =

PitAng =


PitCom =

here PitAng is the value BldPitch feedback by FAST.
Could you give me some ideal to remove the error.

Thank you in advance!

Best regards,

Dear Jinrui,

From what I can tell from the few results you’ve shown, the problem is in your Simulink-generated blade-pitch command. I would check that your Simulink model is as you intended.

Best regards,

Dear Jason,

Thank you for your reply and your suggestion.

This is the code of level-2 matlab SFunction and the image of the simulink model.
In my simulation, I set the PC_DT = 0.00625s as same as the discrete time step of wind speed(I generate the wind with my own model).
ZETA is an input parameter I want to use later, but for checking the model, it dosen’t work in this model, you can ignore it.

Many thanks :slight_smile:

Best regards

[code]function PitControl(block)
% 2016/07/04
% level-2 MATLAB file S-Function for pitch control
% Based on “Definition of a 5-MW Reference Wind Turbine for Offshore System Development ----- 7.3 Baseline Blade-pitch Controller”
% Original version was written by J. Jonkman of NREL/NWTC for use in the
% IEA Annex XXIII OC3 studies.



function setup(block)

% %% Register dialog
block.NumDialogPrms = 0;

%% Register number of input and output ports
block.NumInputPorts = 4; % Time, GenSpeed, Last time Pitch Angle , ZETA
block.NumOutputPorts = 1; % output–pitch angle

%% Setup functional port properities to dynamically
%% inherited.

% Input Parameter
block.InputPort(1).Complexity = ‘Real’; % Time
block.InputPort(1).DataTypeId = 0;
block.InputPort(1).SamplingMode = ‘Sample’;
block.InputPort(1).Dimensions = 1;

block.InputPort(2).Complexity = ‘Real’; % GenSpeed
block.InputPort(2).DataTypeId = 0;
block.InputPort(2).SamplingMode = ‘Sample’;
block.InputPort(2).Dimensions = 1;

block.InputPort(3).Complexity = ‘Real’; % PitAngle
block.InputPort(3).DataTypeId = 0;
block.InputPort(3).SamplingMode = ‘Sample’;
block.InputPort(3).Dimensions = 1;

block.InputPort(4).Complexity = ‘Real’; % ZETA
block.InputPort(4).DataTypeId = 0;
block.InputPort(4).SamplingMode = ‘Sample’;
block.InputPort(4).Dimensions = 1;

% OutPut Parameter
block.OutputPort(1).Complexity = ‘Real’; % PitComT
block.OutputPort(1).DataTypeId = 0;
block.OutputPort(1).SamplingMode = ‘Sample’;
block.OutputPort(1).Dimensions = 1;

block.SampleTimes = [0 0];

%% Set the block simStateCompliance to default
block.SimStateCompliance = ‘DefaultSimState’;

%% Register methods
block.RegBlockMethod(‘ProcessParameters’, @ProcessPrms);
block.RegBlockMethod(‘PostPropagationSetup’, @DoPostPropSetup);
block.RegBlockMethod(‘Start’, @Start);
block.RegBlockMethod(‘Outputs’, @Outputs);
block.RegBlockMethod(‘Update’, @Update);

% endfunction

function DoPostPropSetup(block)

%% Setup Dwork
N = 1;
block.NumDworks = 8;
block.Dwork(1).Name = ‘Alpha’;
block.Dwork(1).Dimensions = N;
block.Dwork(1).DatatypeID = 0;
block.Dwork(1).Complexity = ‘Real’;
block.Dwork(1).UsedAsDiscState = true;

block.Dwork(2).Name = ‘GenSpeedF’;
block.Dwork(2).Dimensions = N;
block.Dwork(2).DatatypeID = 0;
block.Dwork(2).Complexity = ‘Real’;
block.Dwork(2).UsedAsDiscState = true;

block.Dwork(3).Name = ‘LastTimePC’;
block.Dwork(3).Dimensions = N;
block.Dwork(3).DatatypeID = 0;
block.Dwork(3).Complexity = ‘Real’;
block.Dwork(3).UsedAsDiscState = true;

block.Dwork(4).Name = ‘GK’; %
block.Dwork(4).Dimensions = N;
block.Dwork(4).DatatypeID = 0;
block.Dwork(4).Complexity = ‘Real’;
block.Dwork(4).UsedAsDiscState = true;

block.Dwork(5).Name = ‘IntSpdErr’; %
block.Dwork(5).Dimensions = N;
block.Dwork(5).DatatypeID = 0;
block.Dwork(5).Complexity = ‘Real’;
block.Dwork(5).UsedAsDiscState = true;

block.Dwork(6).Name = ‘LastTime’;
block.Dwork(6).Dimensions = N;
block.Dwork(6).DatatypeID = 0;
block.Dwork(6).Complexity = ‘Real’;
block.Dwork(6).UsedAsDiscState = true;

block.Dwork(7).Name = ‘PC_KP’;
block.Dwork(7).Dimensions = N;
block.Dwork(7).DatatypeID = 0;
block.Dwork(7).Complexity = ‘Real’;
block.Dwork(7).UsedAsDiscState = true;

block.Dwork(8).Name = ‘PitCom’;
block.Dwork(8).Dimensions = N;
block.Dwork(8).DatatypeID = 0;
block.Dwork(8).Complexity = ‘Real’;
block.Dwork(8).UsedAsDiscState = true;

%% Register all tunable parameters as runtime parameters.

function ProcessPrms(block)



function Start(block)

%% Initialize Dwork

% PC_DT = 0.00125;
PC_DT = 0.00625;
PC_KI = 0.008068634;
PC_KK = 0.1099965;

block.Dwork(1).Data = 0; % initialize Alpha
block.Dwork(2).Data = block.InputPort(2).Data; % initialize GenSpeedF = GenSpeed
block.Dwork(3).Data = block.InputPort(1).Data - PC_DT; % initialize LastTimePC
block.Dwork(4).Data = 1.0/(1.0 + block.InputPort(3).Data/PC_KK ); % initialize GK
block.Dwork(5).Data = block.InputPort(3).Data/(block.Dwork(4).Data * PC_KI); % initialize IntSpdErr
block.Dwork(6).Data = block.InputPort(1).Data; % initialize the LastTime
block.Dwork(7).Data = 0;
block.Dwork(8).Data = block.InputPort(3).Data; % initialize PitCom


function Outputs(block)
CornerFreq = 1.570796;
PC_DT = 0.00625;
% PC_DT = 0.00125;
PC_KI = 0.008068634;
PC_KK = 0.1099965;
PC_KP = 0.01882681;
PC_MinPit = 0.0;
PC_MaxPit = 1.570796;
PC_MaxRat = 0.1396263;
PC_RefSpd = 122.9096;

% caculate Alpha
% Alpha = exp((LastTime - Time)*CornerFreq)
block.Dwork(1).Data = exp((block.Dwork(6).Data - Time)*CornerFreq);

% caculate GenSpdErr
% GenSpeedF = (1.0 - Alpha)*GenSpeed + Alpha * GenSpeedF
block.Dwork(2).Data = (1.0 - block.Dwork(1).Data)*GenSpeed + block.Dwork(1).Data * block.Dwork(2).Data;

ElapTime = Time - block.Dwork(3).Data;
if (Time*(1+realmin) - block.Dwork(3).Data) >= PC_DT

% GK = 1.0/(1.0+PitCom/PC_KK)
block.Dwork(4).Data      = 1.0/(1.0 + block.Dwork(8).Data/PC_KK); 

% SpdErr = GenSpeedF - PC_Refspd
SpdErr                   = block.Dwork(2).Data - PC_RefSpd;

% caculate IntSpdErr
% IntSpdErr = IntSpdErr + SdpErr*ElapTime
% IntSpdErr = min(max(IntSpdErr, PC_MinPit/(GK*PC_KI)), PC_MaxPit/(GK*PC_KI))
block.Dwork(5).Data      = block.Dwork(5).Data + SpdErr * ElapTime;
block.Dwork(5).Data      = min(max(block.Dwork(5).Data, PC_MinPit/(block.Dwork(4).Data*PC_KI)),PC_MaxPit/(block.Dwork(4).Data*PC_KI)); 

PitComP                  = block.Dwork(4).Data * PC_KP * SpdErr;
PitComI                  = block.Dwork(4).Data * PC_KI * block.Dwork(5).Data;

PitComT  = PitComP + PitComI;
PitComT  = min(max(PitComT,PC_MinPit),PC_MaxPit);

PitRate  = (PitComT -PitAng)/ElapTime;
PitRate  = min(max(PitRate,-PC_MaxRat), PC_MaxRat);

block.Dwork(8).Data   = PitAng + PitRate * ElapTime;
block.Dwork(8).Data   = min(max(block.Dwork(8).Data, -PC_MaxRat),PC_MaxRat);

% output PitCom
block.OutputPort(1).Data = block.Dwork(8).Data;



function Update(block)

block.Dwork(3).Data = block.InputPort(1).Data;
block.Dwork(6).Data = block.InputPort(1).Data;


Dear Jinrui,

I don’t have the resources to debug your code. I suggest that you start with simpler control logic, check that the model runs as expected, and build-up complexity in steps.

Best regards,

Dear Jason,

Thank you very much.

This time I want to feedback an error (maybe it is or not).
I have checked the Matlab code and simulink, there is no mistake.
I turn TPmode to 5 using the DISCON.dll to caculate pitch angle, then I input the pitch angle and generator speed which are caculted by FAST to my pitch controller(written by matlab), so the two controller have the same wind speed, same time, same feedback value of pitch ange and generator speed, also, they have the same algorithm.
Then, of course, they have the same results!!!
But the problem is when I want to use the pitch control defined from simulink, it seems that the interface has some problem. I can’t get the right results and FAST always gives the error of “no valid value of phi”.
Now I think that may be the best way is to use Bladed-style DLL. But if you have any ideal of this problem, please tell me! Manys thanks.

Best Regards,

Dear Jinrui,

My understanding of what you are doing is:
(1) You are using the baseline NREL 5-MW controller implemented in the DISCON.dll within Simulink.
(2) You are taking the blade-pitch angle and generator speed calculated by the FAST S-Function and passing it to your MATLAB implementation of the baseline NREL 5-MW control logic.
(3) You are comparing the controller outputs of blade-pitch angle and generator torque computed by (1) and (2).
From your plots of blade-pitch angle, the curves are similar but there are certainly some differences. Do you know what is causing these differences? You haven’t plotted generator torque; how similar are those?

Best regards,

Dear Jason,

Thank you for your reply.

I’m sorry that I have made a mistake, i.e I have posted an uncorrect image. Now I have modified my last post. Form that, we can find that, the curves are same.
I never take gernerator torque into account cause I don’t think that I need this value in the caculation and I never realize that I need to check this value after each caculation. Maybe this is my negligence.

Thank you!

Best Regards

Dear Jason,

I am simulating the WP_Baseline turbine.My controller is from Simulink.I want to be able to suddenly brake and again start the turbine.For this I give a pitch value of about -57 to -86 degrees for braking and a pitch of 0 for it to start again.I am doing this repeatedly for many cycles.I give these pitch values through the Simulink interface.This method works fine for angles such as 10 degrees for braking and 0 degrees for starting.When I make the pitch larger such as -57 for all three blades or -86 for all three blades and then 0 for all three I get two different types of errors depending on the magnitude of the pitch angle for brakes.These errors do not come for other values of brake pitch angles which are small in magnitude.

1)No phi value found
2)Mach no > 1

I think that these errors are coming due to the change of pitch from say -57 to 0 and from 0 to -57 as a constant pitch of -57 seems to work properly.Please can you tell me how to avoid such errors and perform these simulations.
Thank you in advance!

Dear Shar,

I’m not sure what is triggering the large mach number – is the model going numerically unstable with very large blade deflection or rotor speed?

Normally wind turbine blades pitch in the range of around 0-90 degrees for pitch-to-feather controller. You are using negative pitch angles; are you using pitch-to-stall control?

I’m not sure which version of FAST you are using, but an upgrade to OpenFAST v1.0.0 (which includes several improvements to AeroDyn) will not result an error triggered by “no valid value of phi”.

Best regards,


I’m having a similar problem with inputs from Simulink. I feel that the topic wasn’t completely resolved in the previous posts. So I hope to clarify the issue with my post.

I’m using FAST v8.16 on a 64bit Windows 7 installation with Matlab R2017a.

I’m trying to run Test18.fst with OpenLoop.mdl with the following modifications:
PCMode: 4

The simulation completes successfully with a constant blade pitch angle of 0°.
However, when I specify a constant non-zero blade pitch angle of e.g. 5° the simulation crashes with the following error in the matlab command window:

Error using Run_OpenLoop (line 32)
Error reported by S-function ‘FAST_SFunc’ in ‘OpenLoop/FAST Nonlinear Wind Turbine/S-Function’:
FAST_Solution:FAST_AdvanceStates:AD_UpdateStates:BEMT_UpdateStates(node 8, blade 2):BEMT_UnCoupledSolve:DeterminePhiBounds:There is no valid value of phi for these operating
conditions! Vx = 0.99766, Vy = -21.502, rlocal = 24.145, theta = 0.1716

From the output file it is evident that only 4 time steps are computed and the blade pitch angle oscillates wildly (from 0° to +45° and back to -45°). This is obviously what causes the error displayed in the matlab command window.

I don’t think I’ve made any modelling mistakes as all I’ve done is modify the model to accept its pitch angle input from Simulink and then supply it with a constant non-zero pitch angle.

Could the FAST_SFunc be incompatible with my version of Matlab?

Best regards,

Dear Barry,

The rapidly varying blade-pitch angles you are seeing in your Simulink model are likely caused by the extrapolation of inputs implemented within the FAST S-Function (as discussed in other forum topics e.g. http://forums.nrel.gov/t/s-function-input-output-signal-mismatch/1502/2). My guess is the pitch angle of 5 degrees that you are setting in your Simulink model does not match the initial blade-pitch angle set within the ElastoDyn primary input file, hence the large variation in pitch angles resulting from the extrapolation. I would always ensure that (1) the initial pitch angle set within the ElastoDyn primary input file matches the pitch specified within the Simulink model at time zero and (2) the pitch angle changes are defined smoothly within Simulink.

Best regards,

Dear Jason,

thanks for your answer. Setting the initial blade pitch angles in the Elastodyn input file solved the problem.

After reading the other topics which you linked, I also found that by setting the interpolation type to linear the oscillations I observed with the quadratic interpolation are much smaller. So small in fact that they do not cause any error during the simulation. This may be helpful for someone who wants to calculate a Cp surface using inputs from Simulink, since it means that it won’t be necessary to create a separate Elastodyn input file (in which the inital pitch angle is set) for every single pitch angle simulated.

Best regards,

OK, thanks for the advice!