Skip to content

Commit

Permalink
Merge branch 'develop' into f/flaps
Browse files Browse the repository at this point in the history
  • Loading branch information
nikhar-abbas committed Jan 10, 2020
2 parents a8ae292 + dcbb2bc commit 39e0ec3
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 66 deletions.
6 changes: 6 additions & 0 deletions parameter_files/DTU10MW/DISCON.IN
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
2 ! WE_Mode - Wind speed estimator mode {0: One-second low pass filtered hub height wind speed, 1: Immersion and Invariance Estimator, 2: Extended Kalman Filter}
1 ! PS_Mode - Peak shaving mode {0: no peak shaving, 1: implement peak shaving}
0 ! SD_Mode - Shutdown mode {0: no shutdown procedure, 1: pitch to max pitch at shutdown}
0 ! FL_Mode - Floating specific feedback mode {0: no nacelle velocity feedback, 1: nacelle velocity feedback}
1 ! Flp_Mode - Peak actuator mode {0: no flap actuation, 1: steady state flap angle}

!------- FILTERS ----------------------------------------------------------
Expand All @@ -23,6 +24,7 @@
0.00 ! F_NotchCornerFreq - Natural frequency of the notch filter, [rad/s]
0.0 0.0 ! F_NotchBetaNumDen - Two notch damping values (numerator and denominator, resp) - determines the width and depth of the notch, [-]
0.628319000000 ! F_SSCornerFreq - Corner frequency (-3dB point) in the first order low pass filter for the setpoint smoother, [rad/s].
0.0 0.7000 ! F_FlCornerFreq - Corner frequency and damping in the second order low pass filter of the tower-top fore-aft motion for floating feedback control [rad/s, -].

!------- BLADE PITCH CONTROL ----------------------------------------------
27 ! PC_GS_n - Amount of gain-scheduling table entries
Expand Down Expand Up @@ -108,6 +110,10 @@
!------- SHUTDOWN -------------------------------------------
0.407510000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]
0.418880000000 ! SD_CornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle, [rad/s]

!------- FLOATING --------------------------------------------
0.0 ! FL_Kp - Nacelle velocity proportional feedback gain [s]
0.418880000000 ! SD_CornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle, [rad/s]
-0.01745329 -0.01745329 -0.01745329 -0.01745329 -0.01745329 -0.01745329 -0.01745329 -0.01745329 -0.01745329 -0.01745329 -0.01745329 0.01139256 0.03954465 0.06151733 0.07951239 0.10218597 0.11346152 0.12442215 0.13515521 0.14568190 0.15604391 0.16623229 0.17621767 0.18609242 0.19591524 0.20553978 0.21504302 0.22459719 0.23380511 0.24321524 0.25220762 0.26147499 0.27028214 0.27930685 0.28810785 0.29682237 0.30579567 0.31417250 0.32274307 0.33155921 0.33969923 0.34802211 ! PS_BldPitchMin - Minimum blade pitch angles [rad]

!------- FLAP ACTUATION -------------------------------------------
Expand Down
5 changes: 5 additions & 0 deletions parameter_files/NREL5MW/DISCON.IN
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
2 ! WE_Mode - Wind speed estimator mode {0: One-second low pass filtered hub height wind speed, 1: Immersion and Invariance Estimator, 2: Extended Kalman Filter}
0 ! PS_Mode - Peak shaving mode {0: no peak shaving, 1: implement peak shaving}
0 ! SD_Mode - Shutdown mode {0: no shutdown procedure, 1: pitch to max pitch at shutdown}
0 ! FL_Mode - Floating specific feedback mode {0: no nacelle velocity feedback, 1: nacelle velocity feedback}
1 ! Flp_Mode - Peak actuator mode {0: no flap actuation, 1: steady state flap angle}

!------- FILTERS ----------------------------------------------------------
Expand All @@ -23,6 +24,7 @@
0.00 ! F_NotchCornerFreq - Natural frequency of the notch filter, [rad/s]
0.0 0.0 ! F_NotchBetaNumDen - Two notch damping values (numerator and denominator, resp) - determines the width and depth of the notch, [-]
0.628319000000 ! F_SSCornerFreq - Corner frequency (-3dB point) in the first order low pass filter for the setpoint smoother, [rad/s].
0.0 0.0000 ! F_FlCornerFreq - Corner frequency and damping in the second order low pass filter of the tower-top fore-aft motion for floating feedback control [rad/s, -].

!------- BLADE PITCH CONTROL ----------------------------------------------
27 ! PC_GS_n - Amount of gain-scheduling table entries
Expand Down Expand Up @@ -109,6 +111,9 @@
0.261800000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]
0.418880000000 ! SD_CornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle, [rad/s]

!------- FLOATING --------------------------------------------
-122.923490000 ! FL_Kp - Nacelle velocity proportional feedback gain [s]

!------- FLAP ACTUATION -------------------------------------------
0 ! Flp_Angle - Steady state flap angle, [deg]
0.0 ! Flp_Kp - PI flap controller proportional gain
Expand Down
11 changes: 4 additions & 7 deletions src/ControllerBlocks.f90
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
! State Machine: determine the state of the wind turbine to specify the corresponding control actions
! WindSpeedEstimator: Estimate wind speed
! SetpointSmoother: Modify generator torque and blade pitch controller setpoints in transition region
! PeakShaving: Limit rotor thrust near rated operation
! PitchSaturation: Prescribe specific minimum pitch schedule
! Shutdown: Shutdown control for max bld pitch

MODULE ControllerBlocks
Expand Down Expand Up @@ -202,14 +202,10 @@ SUBROUTINE WindSpeedEstimator(LocalVar, CntrPar, objInst, PerfData)
! Measurement update
S = MATMUL(H,MATMUL(P,TRANSPOSE(H))) + R_m ! NJA: (H*T*H') \approx 0
K = MATMUL(P,TRANSPOSE(H))/S(1,1)
! xh = xh + K*(LocalVar%GenSpeedF/CntrPar%WE_GearboxRatio - xh(1,1))
xh = xh + K*(LocalVar%GenSpeedF/CntrPar%WE_GearboxRatio - om_r)
P = MATMUL(identity(3) - MATMUL(K,H),P)

! Wind Speed Estimate
! xh(1,1) = saturate(xh(1,1),0.0, CntrPar%PC_RefSpd * 1.5)
! xh(2,1) = saturate(xh(2,1),-10.0, 10.0)
! xh(3,1) = saturate(xh(3,1),0.0, MAXVAL(WE_EKF_Vref))
om_r = xh(1,1)
v_t = xh(2,1)
v_m = xh(3,1)
Expand Down Expand Up @@ -276,7 +272,7 @@ REAL FUNCTION PitchSaturation(LocalVar, CntrPar, objInst)

Vhat = LocalVar%WE_Vw
Vhatf = LPFilter(Vhat,LocalVar%DT,0.2,LocalVar%iStatus,.FALSE.,objInst%instLPF)
LocalVar%TestType = Vhatf

! Define minimum blade pitch angle as a function of estimated wind speed
PitchSaturation = interp1d(CntrPar%PS_WindSpeeds, CntrPar%PS_BldPitchMin, Vhatf)

Expand All @@ -301,7 +297,9 @@ REAL FUNCTION Shutdown(LocalVar, CntrPar, objInst)

! See if we should shutdown
IF (.NOT. LocalVar%SD ) THEN
! Filter pitch signal
SD_BlPitchF = LPFilter(LocalVar%PC_PitComT, LocalVar%DT, CntrPar%SD_CornerFreq, LocalVar%iStatus, .FALSE., objInst%instLPF)

! Go into shutdown if above max pit
IF (SD_BlPitchF > CntrPar%SD_MaxPit) THEN
LocalVar%SD = .TRUE.
Expand All @@ -323,5 +321,4 @@ REAL FUNCTION Shutdown(LocalVar, CntrPar, objInst)

END FUNCTION Shutdown
!-------------------------------------------------------------------------------------------------------------------------------

END MODULE ControllerBlocks
64 changes: 48 additions & 16 deletions src/Controllers.f90
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
! YawRateControl: Nacelle yaw control
! IPC: Individual pitch control
! ForeAftDamping: Tower fore-aft damping control
! FloatingFeedback: Tower fore-aft feedback for floating offshore wind turbines

MODULE Controllers

Expand Down Expand Up @@ -103,10 +104,19 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst)
LocalVar%PC_PitComT = Shutdown(LocalVar, CntrPar, objInst)
ENDIF

! Combine and saturate all pitch commands:
! FloatingFeedback
IF (CntrPar%Fl_Mode == 1) THEN
CALL FloatingFeedback(LocalVar, CntrPar, objInst)
LocalVar%PC_PitComT = LocalVar%PC_PitComT + LocalVar%Fl_PitCom
ENDIF

! Saturate collective pitch commands:
LocalVar%PC_PitComT = saturate(LocalVar%PC_PitComT, LocalVar%PC_MinPit, CntrPar%PC_MaxPit) ! Saturate the overall command using the pitch angle limits

! Combine and saturate all individual pitch commands:
DO K = 1,LocalVar%NumBl ! Loop through all blades, add IPC contribution and limit pitch rate
LocalVar%PitCom(K) = saturate(LocalVar%PC_PitComT, LocalVar%PC_MinPit, CntrPar%PC_MaxPit) ! Saturate the overall command using the pitch angle limits
LocalVar%PitCom(K) = LocalVar%PitCom(K) + LocalVar%IPC_PitComF(K) + LocalVar%FA_PitCom(K) + LocalVar%PC_SineExcitation
LocalVar%PitCom(K) = LocalVar%PC_PitComT + LocalVar%IPC_PitComF(K) + LocalVar%FA_PitCom(K) + LocalVar%PC_SineExcitation
LocalVar%PitCom(K) = saturate(LocalVar%PitCom(K), LocalVar%PC_MinPit, CntrPar%PC_MaxPit) ! Saturate the overall command using the pitch angle limits
LocalVar%PitCom(K) = ratelimit(LocalVar%PitCom(K), LocalVar%BlPitch(K), CntrPar%PC_MinRat, CntrPar%PC_MaxRat, LocalVar%DT) ! Saturate the overall command of blade K using the pitch rate limit
END DO

Expand Down Expand Up @@ -137,27 +147,28 @@ SUBROUTINE VariableSpeedControl(avrSWAP, CntrPar, LocalVar, objInst)
REAL(4) :: VS_MaxTq ! Locally allocated maximum torque saturation limits

! -------- Variable-Speed Torque Controller --------
! Define max torque
IF (LocalVar%VS_State == 4) THEN
VS_MaxTq = CntrPar%VS_RtTq
ELSE
VS_MaxTq = CntrPar%VS_MaxTq ! NJA: May want to boost max torque
! VS_MaxTq = CntrPar%VS_RtTq
ENDIF

! Optimal Tip-Speed-Ratio tracking controller
IF (CntrPar%VS_ControlMode == 2) THEN
! Define max torque
IF (LocalVar%VS_State >= 4) THEN
VS_MaxTq = CntrPar%VS_RtTq
ELSE
! VS_MaxTq = CntrPar%VS_MaxTq ! NJA: May want to boost max torque
VS_MaxTq = CntrPar%VS_RtTq
ENDIF

! TSR tracking vs control
! PI controller
LocalVar%GenTq = PIController(LocalVar%VS_SpdErr, CntrPar%VS_KP(1), CntrPar%VS_KI(1), CntrPar%VS_MinTq, VS_MaxTq, LocalVar%DT, LocalVar%VS_LastGenTrq, .FALSE., objInst%instPI)

LocalVar%GenTq = saturate(LocalVar%GenTq, CntrPar%VS_MinTq, VS_MaxTq)

! K*Omega^2 control law with PI torque control in transition regions
ELSE
! Update PI loops for region 1.5 and 2.5 PI control
! LocalVar%GenArTq = PIController(LocalVar%VS_SpdErrAr, CntrPar%VS_KP(1), CntrPar%VS_KI(1), CntrPar%VS_MaxOMTq, CntrPar%VS_ArSatTq, LocalVar%DT, CntrPar%VS_RtTq, .TRUE., objInst%instPI)
LocalVar%GenArTq = PIController(LocalVar%VS_SpdErrAr, CntrPar%VS_KP(1), CntrPar%VS_KI(1), CntrPar%VS_MaxOMTq, CntrPar%VS_ArSatTq, LocalVar%DT, CntrPar%VS_MaxOMTq, .FALSE., objInst%instPI)
LocalVar%GenBrTq = PIController(LocalVar%VS_SpdErrBr, CntrPar%VS_KP(1), CntrPar%VS_KI(1), CntrPar%VS_MinTq, CntrPar%VS_MinOMTq, LocalVar%DT, CntrPar%VS_MinOMTq, .TRUE., objInst%instPI)
LocalVar%GenBrTq = PIController(LocalVar%VS_SpdErrBr, CntrPar%VS_KP(1), CntrPar%VS_KI(1), CntrPar%VS_MinTq, CntrPar%VS_MinOMTq, LocalVar%DT, CntrPar%VS_MinOMTq, .FALSE., objInst%instPI)

! The action
IF (LocalVar%VS_State == 1) THEN ! Region 1.5
LocalVar%GenTq = LocalVar%GenBrTq
ELSEIF (LocalVar%VS_State == 2) THEN ! Region 2
Expand All @@ -169,7 +180,9 @@ SUBROUTINE VariableSpeedControl(avrSWAP, CntrPar, LocalVar, objInst)
ELSEIF (LocalVar%VS_State == 5) THEN ! Region 3, constant power
LocalVar%GenTq = (CntrPar%VS_RtPwr/(CntrPar%VS_GenEff/100.0))/LocalVar%GenSpeedF
END IF


! Saturate
LocalVar%GenTq = saturate(LocalVar%GenTq, CntrPar%VS_MinTq, VS_MaxTq)
ENDIF


Expand Down Expand Up @@ -333,8 +346,27 @@ SUBROUTINE ForeAftDamping(CntrPar, LocalVar, objInst)
END DO

END SUBROUTINE ForeAftDamping
!-------------------------------------------------------------------------------------------------------------------------------
SUBROUTINE FloatingFeedback(LocalVar, CntrPar, objInst)
! FloatingFeedback defines a minimum blade pitch angle based on a lookup table provided by DISON.IN
! FL_Mode = 0, No feedback
! FL_Mode = 1, Proportional feedback of nacelle velocity
USE ROSCO_Types, ONLY : LocalVariables, ControlParameters, ObjectInstances
IMPLICIT NONE
! Inputs
TYPE(ControlParameters), INTENT(IN) :: CntrPar
TYPE(LocalVariables), INTENT(INOUT) :: LocalVar
TYPE(ObjectInstances), INTENT(INOUT) :: objInst
! Allocate Variables
REAL(4) :: NACIMU_FA_AccF ! Low-pass filtered tower fore-aft acceleration
REAL(4) :: NacIMU_FA_vel ! Tower fore-aft velocity

! Calculate floating contribution to pitch command
NacIMU_FA_vel = PIController(LocalVar%NacIMU_FA_AccF, 0.0, 1.0, -100.0 , 100.0 ,LocalVar%DT, 0.0, .FALSE., objInst%instPI) ! NJA: should never reach saturation limits....
LocalVar%Fl_PitCom = (0.0 - NacIMU_FA_vel) * CntrPar%FL_Kp

!-------------------------------------------------------------------------------------------------------------------------------
END SUBROUTINE FloatingFeedback
!-------------------------------------------------------------------------------------------------------------------------------
SUBROUTINE FlapControl(avrSWAP, CntrPar, LocalVar, objInst)
! Yaw rate controller
! Y_ControlMode = 0, No yaw control
Expand Down
2 changes: 1 addition & 1 deletion src/DISCON.F90
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
! specific language governing permissions and limitations under the License.
! -------------------------------------------------------------------------------------------

! Hih level run script
! High level run script

!=======================================================================
SUBROUTINE DISCON(avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAME='DISCON')
Expand Down
Loading

0 comments on commit 39e0ec3

Please sign in to comment.