Skip to content

Commit

Permalink
Added constant power contol mode, updated compiled binary, updated pa…
Browse files Browse the repository at this point in the history
…rameter files, made IPC more modular
  • Loading branch information
Sebastiaan Mulders committed Sep 29, 2017
1 parent c2711ac commit 23c7033
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 41 deletions.
Binary file modified DISCON/DISCON_gwin32.dll
Binary file not shown.
4 changes: 2 additions & 2 deletions Parameter_files/DTU10MW/DISCON.IN
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
26.179938 = User Variable 3: VS_CtInSp, cut-in speed, [rad/s]
150000.0 = User Variable 4: VS_MaxRat, maximum torque change rate, [Nm/s]
50.26548 = User Variable 5: PC_RefSpd, generator speed setpoint for the pitch controller, [rad/s]
0.0 = User Variable 6:
0.0 = User Variable 7:
0 = User Variable 6: IPC mode for load reductions (0 = off, 1 = on)
0 = User Variable 7: Above rated control (0 = constant torque control, 1 = constant power control)
0.0 = User Variable 8:
0.0 = User Variable 9:
0.0 = User Variable 10:
8 changes: 4 additions & 4 deletions Parameter_files/DTU10MW/PitchGains.IN
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
12
0.0719 0.1255 0.1638 0.1958 0.2752 0.2985 0.3206 0.3417 0.3622 0.3819 0.4011 0.4196
-0.0669 -0.0393 -0.03 -0.0253 -0.0171 -0.0155 -0.0146 -0.0139 -0.0098 -0.0091 -0.008 -0.0074
-0.004 -0.0047 -0.0035 -0.003 -0.0032 -0.0029 -0.0028 -0.0028 -0.0062 -0.0061 -0.0063 -0.0062
0.0076 0.0115 0.0064 0.0082 0.0078 0.0085 0.0094 0.0105 0.0029 0.0032 0.0023 0.0025
0.9251 0.2918 0.2918 0.4364 0.5881 0.5881 0.7497 0.9251 0.4364 0.5881 0.4364 0.5881
-0.0338 -0.0172 -0.0141 -0.0118 -0.0079 -0.0066 -0.0055 -0.005 -0.0035 -0.0031 -0.0026 -0.0017
-0.0044 -0.0039 -0.0018 -0.0016 -0.0016 -0.0017 -0.0018 -0.0019 -0.003 -0.003 -0.003 -0.0032
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
1
-3.48e+04
-2.26e+04
4 changes: 2 additions & 2 deletions Parameter_files/DTU10MW/ServoDynBladedInterface.dat
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---------------------- BLADED INTERFACE ---------------------------------------- [used only with Bladed Interface]
"ServoData/DISCON_gwin32.dll" DLL_FileName - Name/location of the dynamic library {.dll [Windows] or .so [Linux]} in the Bladed-DLL format (-) [used only with Bladed Interface]
"../Controller/DISCON_gwin32.dll" DLL_FileName - Name/location of the dynamic library {.dll [Windows] or .so [Linux]} in the Bladed-DLL format (-) [used only with Bladed Interface]
"DISCON.IN" DLL_InFile - Name of input file sent to the DLL (-) [used only with Bladed Interface]
"DISCON" DLL_ProcName - Name of procedure in DLL to be called (-) [case sensitive; used only with DLL Interface]
"default" DLL_DT - Communication interval for dynamic library (s) (or "default") [used only with Bladed Interface]
Expand All @@ -16,5 +16,5 @@ false DLL_Ramp - Whether a linear ramp should be used between DLL_DT
300.0 GenSpd_MinOM - Record 17: Minimum generator speed (rpm) [used only with Bladed Interface]
405.0 GenSpd_MaxOM - Record 18: Optimal mode maximum speed (rpm) [used only with Bladed Interface]
405.0 GenSpd_Dem - Record 19: Demanded generator speed above rated (rpm) [used only with Bladed Interface]
235785.1 GenTrq_Dem - Record 22: Demanded generator torque above rated (Nm) [used only with Bladed Interface]
198943.6 GenTrq_Dem - Record 22: Demanded generator torque above rated (Nm) [used only with Bladed Interface]
1.0E+07 GenPwr_Dem - Record 13: Demanded power (W) [used only with Bladed Interface]
4 changes: 2 additions & 2 deletions Parameter_files/NREL5MW/DISCON.IN
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
70.16224 = User Variable 3: VS_CtInSp, cut-in speed, [rad/s]
15000.0 = User Variable 4: VS_MaxRat, maximum torque change rate, [Nm/s]
122.909576 = User Variable 5: PC_RefSpd, generator speed setpoint for the pitch controller, [rad/s]
0.0 = User Variable 6:
0.0 = User Variable 7:
0 = User Variable 6: IPC mode for load reductions (0 = off, 1 = on)
0 = User Variable 7: Above rated control (0 = constant torque control, 1 = constant power control)
0.0 = User Variable 8:
0.0 = User Variable 9:
0.0 = User Variable 10:
2 changes: 1 addition & 1 deletion Parameter_files/NREL5MW/ServoDynBladedInterface.dat
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ false DLL_Ramp - Whether a linear ramp should be used between DLL_DT
1173.70 GenSpd_MaxOM - Record 18: Optimal mode maximum speed (rpm) [used only with Bladed Interface]
1173.70 GenSpd_Dem - Record 19: Demanded generator speed above rated (rpm) [used only with Bladed Interface]
43093.55 GenTrq_Dem - Record 22: Demanded generator torque above rated (Nm) [used only with Bladed Interface]
0 GenPwr_Dem - Record 13: Demanded power (W) [used only with Bladed Interface]
5.0E+06 GenPwr_Dem - Record 13: Demanded power (W) [used only with Bladed Interface]
62 changes: 44 additions & 18 deletions Source/DISCON.f90
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,15 @@ SUBROUTINE DISCON (avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAM

REAL(4) :: Azimuth ! Rotor azimuth angle [rad].
REAL(4) :: BlPitch(3) ! Current values of the blade pitch angles [rad].
REAL(4), PARAMETER :: CornerFreq = 3.1415926 ! Corner frequency (-3dB point) in the first-order low-pass filter, [rad/s]
REAL(4), PARAMETER :: CornerFreq = 1.570796 ! Corner frequency (-3dB point) in the first-order low-pass filter, [rad/s]
REAL(4) :: DT ! Time step [s].
REAL(4) :: ElapTime ! Elapsed time since the last call to the controller [s].
REAL(4) :: GenSpeed ! Current HSS (generator) speed [rad/s].
REAL(4) :: GenSpeedF ! Filtered HSS (generator) speed [rad/s].
REAL(4) :: GenTrq ! Electrical generator torque, [Nm].
REAL(4) :: HorWindV ! Horizontal wind speed at hub-height, [m/s].
REAL(4), PARAMETER :: IPC_KI = 8E-10 ! Integral gain for the individual pitch controller, [-].
INTEGER(4), SAVE :: IPC_ControlMode ! Turn Individual Pitch Control (IPC) for fatigue load reductions (pitch contribution) on = 1/off = 1
REAL(4), PARAMETER :: IPC_omegaHP = 0.3141592 ! High-pass filter cut-in frequency used to separate yaw-by-IPC contribution from blade load reduction contribution, [rad/s].
REAL(4), PARAMETER :: IPC_omegaLP = 0.6283185 ! Low-pass filter corner frequency for the individual pitch controller, [rad/s].
REAL(4), PARAMETER :: IPC_omegaNotch = 1.269330365 ! Notch filter corner frequency for the individual pitch controller, [rad/s].
Expand Down Expand Up @@ -87,6 +88,7 @@ SUBROUTINE DISCON (avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAM
REAL(4) :: rootMOOP(3) ! Blade root out of plane bending moments, [Nm].
REAL(4), PARAMETER :: RPS2RPM = 9.5492966 ! Factor to convert radians per second to revolutions per minute.
REAL(4) :: Time ! Current simulation time, [s].
INTEGER(4), SAVE :: VS_ControlMode ! Generator torque control mode in above rated conditions, 0 = constant torque / 1 = constant power
REAL(4), SAVE :: VS_CtInSp ! Transitional generator speed (HSS side) between regions 1 and 1 1/2, [rad/s].
INTEGER(4), SAVE :: VS_n ! Number of controller gains
REAL(4), DIMENSION(:), ALLOCATABLE, SAVE :: VS_KP ! Proportional gain for generator PI torque controller, used in the transitional 2.5 region
Expand All @@ -98,6 +100,7 @@ SUBROUTINE DISCON (avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAM
REAL(4) :: VS_Rgn2K ! Generator torque constant in Region 2 (HSS side), N-m/(rad/s)^2.
REAL(4), SAVE :: VS_Rgn2MaxTq ! Maximum torque at the end of the below-rated region 2, [Nm]
REAL(4), SAVE :: VS_Rgn3MP ! Minimum pitch angle at which the torque is computed as if we are in region 3 regardless of the generator speed, [rad]. -- chosen to be 1.0 degree above PC_SetPnt
REAL(4), SAVE :: VS_RtPwr ! Wind turbine rated power [W]
REAL(4) :: VS_RtTq ! Rated torque, [Nm].
REAL(4) :: VS_RtSpd ! Rated generator speed [rad/s]
REAL(4), SAVE :: VS_Slope15 ! Torque/speed slope of region 1 1/2 cut-in torque ramp , [Nm/(rad/s)].
Expand All @@ -110,10 +113,12 @@ SUBROUTINE DISCON (avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAM
REAL(4), SAVE :: Y_YawRate ! Yaw rate [rad/s].
REAL(4) :: Y_MErr ! Measured yaw error [rad].
REAL(4), PARAMETER :: Y_omegaLPFast = 1.0 ! Corner frequency fast low pass filter, [Hz].
REAL(4), PARAMETER :: Y_omegaLPSlow = 0.016666667 ! Corner frequency slow low pass filter, 1/60 [Hz].
REAL(4), PARAMETER :: Y_omegaLPSlow = 0.05 ! Corner frequency slow low pass filter, 1/60 [Hz].
REAL(4), SAVE :: Y_YawEndT ! Yaw end time, [s]. Indicates the time up until which yaw is active with a fixed rate.

! REAL(4) :: testValue ! TestValue
REAL(4), SAVE :: testValue ! TestValue
REAL(4) :: PC_KPtest
REAL(4) :: PC_KItest

INTEGER(4) :: I ! Generic index.
INTEGER(4) :: iStatus ! A status flag set by the simulation as follows: 0 if this is the first call, 1 for all subsequent time steps, -1 if this is the final call at the end of the simulation.
Expand Down Expand Up @@ -145,6 +150,7 @@ SUBROUTINE DISCON (avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAM
PC_MaxPit = avrSWAP(7)
PC_MinRat = avrSWAP(8)
PC_MaxRat = avrSWAP(9)
VS_RtPwr = avrSWAP(13)
VS_Rgn2K = avrSWAP(16)
VS_MinOM = avrSWAP(17)
VS_MaxOM = avrSWAP(18)
Expand Down Expand Up @@ -206,6 +212,12 @@ SUBROUTINE DISCON (avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAM
VS_CtInSp = avrSWAP(122)
VS_MaxRat = avrSWAP(123)
PC_RefSpd = avrSWAP(124)
IPC_ControlMode = avrSWAP(125)
VS_ControlMode = avrSWAP(126)

! Initialize testValue (debugging variable)

testValue = 0.0

! Determine some torque control parameters not specified directly:

Expand Down Expand Up @@ -385,8 +397,8 @@ SUBROUTINE DISCON (avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAM

IF (DbgOut) THEN
OPEN (UnDb, FILE=TRIM(RootName)//'.dbg', STATUS='REPLACE')
WRITE (UnDb,'(A)') ' Time ' //Tab//'PitComT ' //Tab//'PC_KP ' //Tab//'PC_KI ' //Tab//'Y_MErr ' //Tab//'rootMOOP(1) '
WRITE (UnDb,'(A)') ' (sec) ' //Tab//'(rad) ' //Tab//'(-) ' //Tab//'(-) ' //Tab//'(rad) ' //Tab//'(?) '
WRITE (UnDb,'(A)') ' Time ' //Tab//'PitComT ' //Tab//'PC_SpdError ' //Tab//'PC_KP ' //Tab//'PC_KI ' //Tab//'Y_MErr ' //Tab//'rootMOOP(1) '//Tab//'VS_RtPwr '//Tab//'GenTrq '
WRITE (UnDb,'(A)') ' (sec) ' //Tab//'(rad) ' //Tab//'(rad/s) '//Tab//'(-) ' //Tab//'(-) ' //Tab//'(rad) ' //Tab//'(?) ' //Tab//'(W) '//Tab//'(Nm) '

OPEN(UnDb2, FILE=TRIM(RootName)//'.dbg2', STATUS='REPLACE')
WRITE(UnDb2,'(/////)')
Expand Down Expand Up @@ -437,9 +449,13 @@ SUBROUTINE DISCON (avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAM

! Compute the generator torque, which depends on which region we are in:

VS_SpdErr = VS_RtSpd - GenSpeedF ! Current speed error
IF (PitComT >= VS_Rgn3MP) THEN ! We are in region 3 - power is constant
GenTrq = VS_RtTq
VS_SpdErr = VS_RtSpd - GenSpeedF ! Current speed error
IF (PitComT >= VS_Rgn3MP) THEN ! We are in region 3
IF (VS_ControlMode == 1) THEN ! Constant power tracking
GenTrq = VS_RtPwr/GenSpeedF
ELSE ! Constant torque tracking
GenTrq = VS_RtTq
END IF
ELSE
GenTrq = PIController(VS_SpdErr, VS_KP(1), VS_KI(1), VS_Rgn2MaxTq, VS_RtTq, DT, VS_Rgn2MaxTq, 1)
IF (GenTrq >= VS_Rgn2MaxTq*1.01) THEN
Expand Down Expand Up @@ -481,11 +497,14 @@ SUBROUTINE DISCON (avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAM
! Pitch control
!..............................................................................................................................

IF (GenTrq > PC_RtTq99) THEN
IF (VS_ControlMode == 0 .AND. GenTrq > PC_RtTq99) THEN
PC_MaxPitVar = PC_MaxPit
ELSEIF (VS_ControlMode == 1 .AND. GenTrq >= VS_RtPwr/GenSpeedF*0.99) THEN
PC_MaxPitVar = PC_MaxPit
ELSE
PC_MaxPitVar = PC_SetPnt
END IF

! Compute the elapsed time since the last call to the controller:

ElapTime = Time - LastTimePC
Expand All @@ -497,29 +516,36 @@ SUBROUTINE DISCON (avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAM
PC_KI = interp1d(PC_GS_angles, PC_GS_ki, PitComT)
PC_KD = interp1d(PC_GS_angles, PC_GS_kd, PitComT)
PC_TF = interp1d(PC_GS_angles, PC_GS_tf, PitComT)
PC_KPtest = interp1d(PC_GS_angles, PC_GS_kp, testValue)
PC_KItest = interp1d(PC_GS_angles, PC_GS_ki, testValue)
testValue = testValue + 0.001

! Compute the current speed error and its integral w.r.t. time; saturate the
! integral term using the pitch angle limits:

PC_SpdErr = PC_RefSpd - GenSpeedF ! Current speed error [UNFILTERED SIGNAL!!]
PC_SpdErr = PC_RefSpd - GenSpeedF ! Current speed error

! Compute the pitch commands associated with the proportional and integral
! gains:

PitComT = PIController(PC_SpdErr, PC_KP, PC_KI, PC_SetPnt, PC_MaxPitVar, ElapTime, PC_SetPnt, 2) + DFController(PC_SpdErr, PC_KD, PC_TF, DT, 1)

! Individual pitch control

CALL IPC(rootMOOP, Azimuth, IPC_phi, Y_MErr, DT, IPC_KI, IPC_omegaHP, IPC_omegaLP, IPC_omegaNotch, IPC_zetaHP, IPC_zetaLP, IPC_zetaNotch, iStatus, Y_ControlMode, NumBl, IPC_PitComF)
IF (IPC_ControlMode == 1) THEN
CALL IPC(rootMOOP, Azimuth, IPC_phi, Y_MErr, DT, IPC_KI, IPC_omegaHP, IPC_omegaLP, IPC_omegaNotch, IPC_zetaHP, IPC_zetaLP, IPC_zetaNotch, iStatus, IPC_ControlMode, Y_ControlMode, NumBl, IPC_PitComF)
ELSE
IPC_PitComF = 0.0
END IF

! Combine and saturate all pitch commands:

DO K = 1,NumBl ! Loop through all blades, add IPC contribution and limit pitch rate
PitComT_IPC(K) = PitComT + IPC_PitComF(K) ! Add the individual pitch command
PitComT_IPC(K) = saturate(PitComT_IPC(K), PC_MinPit, PC_MaxPit) ! Saturate the overall command using the pitch angle limits
PitComT_IPC(K) = PitComT + IPC_PitComF(K) ! Add the individual pitch command
PitComT_IPC(K) = saturate(PitComT_IPC(K), PC_MinPit, PC_MaxPit) ! Saturate the overall command using the pitch angle limits

PitCom(K) = ratelimit(PitComT_IPC(K), BlPitch(K), PC_MinRat, PC_MaxRat, DT) ! Saturate the overall command of blade K using the pitch rate limit
PitCom(K) = saturate(PitComT_IPC(K), PC_MinPit, PC_MaxPit) ! Saturate the overall command using the pitch angle limits
! PitCom(K) = ratelimit(PitComT_IPC(K), BlPitch(K), PC_MinRat, PC_MaxRat, DT) ! Saturate the overall command of blade K using the pitch rate limit
PitCom(K) = saturate(PitComT_IPC(K), PC_MinPit, PC_MaxPit) ! Saturate the overall command using the pitch angle limits
PitCom(K) = LPFilter(PitCom(K), DT, CornerFreq, iStatus, .FALSE., K+3)
ENDDO

! Set the pitch override to yes and command the pitch demanded from the last
Expand Down Expand Up @@ -565,7 +591,7 @@ SUBROUTINE DISCON (avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAM
! Output debugging information if requested:

IF (DbgOut) THEN
WRITE (UnDb,FmtDat) Time, PitComT, PC_KP, PC_KI, Y_MErr, rootMOOP(1)
WRITE (UnDb,FmtDat) Time, PitComT, PC_SpdErr, PC_KP, PC_KI, Y_MErr, rootMOOP(1), VS_RtPwr, GenTrq, testValue, PC_KPtest, PC_KItest
WRITE (UnDb2,FmtDat) Time, avrSWAP(1:85)
END IF

Expand Down
6 changes: 3 additions & 3 deletions Source/FunctionToolbox.f90
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@ REAL FUNCTION interp1d(xData, yData, xq)
INTEGER(4) :: I ! Iteration index

IF (xq <= MINVAL(xData)) THEN
interp1d = MINVAL(yData)
interp1d = yData(1)
ELSEIF (xq >= MAXVAL(xData)) THEN
interp1d = MAXVAL(yData)
interp1d = yData(SIZE(xData))
ELSE
DO I = 1, SIZE(xData)
IF (xData(I) >= xq) THEN
IF (xq <= xData(I)) THEN
interp1d = yData(I-1) + (yData(I) - yData(I-1))/(xData(I) - xData(I-1))*(xq - xData(I-1))
EXIT
ELSE
Expand Down
Loading

0 comments on commit 23c7033

Please sign in to comment.