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
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.
setup(block);
%endfunction
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.
block.SetPreCompInpPortInfoToDynamic;
block.SetPreCompOutPortInfoToDynamic;
% 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.
block.AutoRegRuntimePrms;
function ProcessPrms(block)
block.AutoUpdateRuntimePrms;
%endfunction
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
%endfunction
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;
end
%endfunction
function Update(block)
block.Dwork(3).Data = block.InputPort(1).Data;
block.Dwork(6).Data = block.InputPort(1).Data;
%endfunction[/code]