Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
nikhar-abbas committed Jan 21, 2020
1 parent 3b25626 commit d385eca
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 40 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

cmake_minimum_required(VERSION 3.6)
project(DRC_Fortran VERSION 0.1 LANGUAGES Fortran)
project(ROSCO VERSION 1.0.0 LANGUAGES Fortran)

set(CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/ftnmods")

Expand Down
2 changes: 1 addition & 1 deletion parameter_files/NREL5MW/DISCON.IN
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

!------- CONTROLLER FLAGS -------------------------------------------------
1 ! F_LPFType - {1: first-order low-pass filter, 2: second-order low-pass filter}, [rad/s] (currently filters generator speed and pitch control signals
0 ! F_NotchType - Notch on the measured generator speed {0: disable, 1: enable}
0 ! F_NotchType - Notch filter on generator speed and/or tower fore-aft motion (for floating) {0: disable, 1: generator speed, 2: tower-top fore-aft motion, 3: generator speed and tower-top fore-aft motion}
0 ! IPC_ControlMode - Turn Individual Pitch Control (IPC) for fatigue load reductions (pitch contribution) {0: off, 1: 1P reductions, 2: 1P+2P reductions}
2 ! VS_ControlMode - Generator torque control mode in above rated conditions {0: constant torque, 1: constant power, 2: TSR tracking PI control}
1 ! PC_ControlMode - Blade pitch control mode {0: No pitch, fix to fine pitch, 1: active PI blade pitch control}
Expand Down
7 changes: 3 additions & 4 deletions src/Controllers.f90
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ SUBROUTINE VariableSpeedControl(avrSWAP, CntrPar, LocalVar, objInst)
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
! VS_MaxTq = CntrPar%VS_MaxTq ! NJA: May want to boost max torque
VS_MaxTq = CntrPar%VS_RtTq
ENDIF

! Optimal Tip-Speed-Ratio tracking controller
Expand Down Expand Up @@ -358,12 +358,11 @@ SUBROUTINE FloatingFeedback(LocalVar, CntrPar, objInst)
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
LocalVar%Fl_PitCom = (0.0 - NacIMU_FA_vel) * CntrPar%FL_Kp !* LocalVar%PC_KP/maxval(CntrPar%PC_GS_KP)

END SUBROUTINE FloatingFeedback
END MODULE Controllers
64 changes: 34 additions & 30 deletions src/Filters.f90
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@

MODULE Filters
!...............................................................................................................................

IMPLICIT NONE
USE Constants
IMPLICIT NONE

CONTAINS
!-------------------------------------------------------------------------------------------------------------------------------
REAL FUNCTION LPFilter(InputSignal, DT, CornerFreq, iStatus, reset, inst)
! Discrete time Low-Pass Filter of the form:
! H(z) = (b1z + b0) / (a1*z + a0)
! Continuous Time Form: H(s) = CornerFreq/(1 + CornerFreq)
! Discrete Time Form: H(z) = (b1z + b0) / (a1*z + a0)
!
REAL(4), INTENT(IN) :: InputSignal
REAL(4), INTENT(IN) :: DT ! time step [s]
Expand Down Expand Up @@ -70,8 +71,8 @@ END FUNCTION LPFilter
!-------------------------------------------------------------------------------------------------------------------------------
REAL FUNCTION SecLPFilter(InputSignal, DT, CornerFreq, Damp, iStatus, reset, inst)
! Discrete time Low-Pass Filter of the form:
! H(z) = (b2z^2 + b1z + b0) / (a2z^2 + a1*z + a0)
IMPLICIT NONE
! Continuous Time Form: H(s) = CornerFreq^2/(s^2 + 2*CornerFreq*Damp*s + CornerFreq^2)
! Discrete Time From: H(z) = (b2*z^2 + b1*z + b0) / (a2*z^2 + a1*z + a0)
REAL(4), INTENT(IN) :: InputSignal
REAL(4), INTENT(IN) :: DT ! time step [s]
REAL(4), INTENT(IN) :: CornerFreq ! corner frequency [rad/s]
Expand All @@ -84,38 +85,39 @@ REAL FUNCTION SecLPFilter(InputSignal, DT, CornerFreq, Damp, iStatus, reset, ins
REAL(4), SAVE :: a2 ! Denominator coefficient 2
REAL(4), SAVE :: a1 ! Denominator coefficient 1
REAL(4), SAVE :: a0 ! Denominator coefficient 0
REAL(4), SAVE :: b2 ! Numerator coefficient 2
REAL(4), SAVE :: b1 ! Numerator coefficient 1
REAL(4), SAVE :: b0 ! Numerator coefficient 0
REAL(4), DIMENSION(99), SAVE :: InputSignalLast1 ! Input signal the last time this filter was called. Supports 99 separate instances.
REAL(4), DIMENSION(99), SAVE :: InputSignalLast2 ! Input signal the next to last time this filter was called. Supports 99 separate instances.
REAL(4), DIMENSION(99), SAVE :: OutputSignalLast1 ! Output signal the last time this filter was called. Supports 99 separate instances.
REAL(4), DIMENSION(99), SAVE :: OutputSignalLast2 ! Output signal the next to last time this filter was called. Supports 99 separate instances.
REAL(4), SAVE :: b2 ! Numerator coefficient 2
REAL(4), SAVE :: b1 ! Numerator coefficient 1
REAL(4), SAVE :: b0 ! Numerator coefficient 0
REAL(4), DIMENSION(99), SAVE :: InputSignalLast1 ! Input signal the last time this filter was called. Supports 99 separate instances.
REAL(4), DIMENSION(99), SAVE :: InputSignalLast2 ! Input signal the next to last time this filter was called. Supports 99 separate instances.
REAL(4), DIMENSION(99), SAVE :: OutputSignalLast1 ! Output signal the last time this filter was called. Supports 99 separate instances.
REAL(4), DIMENSION(99), SAVE :: OutputSignalLast2 ! Output signal the next to last time this filter was called. Supports 99 separate instances.

! Initialization
IF ((iStatus == 0) .OR. reset ) THEN
OutputSignalLast1(inst) = InputSignal
OutputSignalLast2(inst) = InputSignal
InputSignalLast1(inst) = InputSignal
InputSignalLast2(inst) = InputSignal

! Coefficients
a2 = DT**2.0*CornerFreq**2.0 + 4.0 + 4.0*Damp*CornerFreq*DT
a1 = 2.0*DT**2.0*CornerFreq**2.0 - 8.0
a0 = DT**2.0*CornerFreq**2.0 + 4.0 - 4.0*Damp*CornerFreq*DT
b2 = DT**2.0*CornerFreq**2.0
b1 = 2.0*DT**2.0*CornerFreq**2.0
b0 = DT**2.0*CornerFreq**2.0
ENDIF

! Coefficients
a2 = DT**2*CornerFreq**2 + 4 + 4*Damp*CornerFreq*DT
a1 = 2*DT**2*CornerFreq**2 - 8
a0 = DT**2*CornerFreq**2 + 4 - 4*Damp*CornerFreq*DT
b2 = DT**2*CornerFreq**2
b1 = 2*DT**2*CornerFreq**2
b0 = DT**2*CornerFreq**2

SecLPFilter = 1.0/a2* (-a1*OutputSignalLast1(inst) - a0*OutputSignalLast2(inst) + b2*InputSignal &
+ b1*InputSignalLast1(inst) + b0*InputSignalLast2(inst))
! Filter
SecLPFilter = 1.0/a2 * (b2*InputSignal + b1*InputSignalLast1(inst) + b0*InputSignalLast2(inst) - a1*OutputSignalLast1(inst) - a0*OutputSignalLast2(inst))

! Save signals for next time step
InputSignalLast2(inst) = InputSignalLast1(inst)
InputSignalLast1(inst) = InputSignal
OutputSignalLast2(inst) = OutputSignalLast1(inst)
OutputSignalLast1(inst) = SecLPFilter

inst = inst + 1

END FUNCTION SecLPFilter
Expand Down Expand Up @@ -190,7 +192,9 @@ REAL FUNCTION NotchFilterSlopes(InputSignal, DT, CornerFreq, Damp, iStatus, rese
END FUNCTION NotchFilterSlopes
!-------------------------------------------------------------------------------------------------------------------------------
REAL FUNCTION NotchFilter(InputSignal, DT, omega, betaNum, betaDen, iStatus, reset, inst)
! Discrete time Notch Filter, G = (s^2 + 2*omega*betaNum*s + omega^2)/(s^2 + 2*omega*betaDen*s + omega^2)
! Discrete time Notch Filter
! Continuous Time Form: G(s) = (s^2 + 2*omega*betaNum*s + omega^2)/(s^2 + 2*omega*betaDen*s + omega^2)
! Discrete Time Form: H(z) = (b2*z^2 +b1*z^2 + b0*z)/((z^2 +a1*z^2 + a0*z))

REAL(4), INTENT(IN) :: InputSignal
REAL(4), INTENT(IN) :: DT ! time step [s]
Expand All @@ -201,7 +205,7 @@ REAL FUNCTION NotchFilter(InputSignal, DT, omega, betaNum, betaDen, iStatus, res
INTEGER, INTENT(INOUT) :: inst ! Instance number. Every instance of this function needs to have an unique instance number to ensure instances don't influence each other.
LOGICAL(4), INTENT(IN) :: reset ! Reset the filter to the input signal
! Local
REAL(4) :: K, P1, P2, P3, P4, P5 ! Constant gain
REAL(4) :: K, b2, b1, b0, a1, a0 ! Constant gain
REAL(4), DIMENSION(99), SAVE :: InputSignalLast1 ! Input signal the last time this filter was called. Supports 99 separate instances.
REAL(4), DIMENSION(99), SAVE :: InputSignalLast2 ! Input signal the next to last time this filter was called. Supports 99 separate instances.
REAL(4), DIMENSION(99), SAVE :: OutputSignalLast1 ! Output signal the last time this filter was called. Supports 99 separate instances.
Expand All @@ -215,14 +219,14 @@ REAL FUNCTION NotchFilter(InputSignal, DT, omega, betaNum, betaDen, iStatus, res
InputSignalLast2(inst) = InputSignal
ENDIF
K = 2/DT
P1 = (K**2 + 2*omega*BetaNum*K + omega**2)/(K**2 + 2*omega*BetaDen*K + omega**2)
P2 = (2*omega**2 - 2*K**2) / (K**2 + 2*omega*BetaDen*K + omega**2);
P3 = (K**2 - 2*omega*BetaNum*K + omega**2) / (K**2 + 2*omega*BetaDen*K + omega**2)
P4 = (2*omega**2 - 2*K**2) / (K**2 + 2*omega*BetaDen*K + omega**2)
P5 = (K**2 - 2*omega*BetaDen*K + omega**2)/ (K**2 + 2*omega*BetaDen*K + omega**2)
b2 = (K**2 + 2*omega*BetaNum*K + omega**2)/(K**2 + 2*omega*BetaDen*K + omega**2)
b1 = (2*omega**2 - 2*K**2) / (K**2 + 2*omega*BetaDen*K + omega**2);
b0 = (K**2 - 2*omega*BetaNum*K + omega**2) / (K**2 + 2*omega*BetaDen*K + omega**2)
a1 = (2*omega**2 - 2*K**2) / (K**2 + 2*omega*BetaDen*K + omega**2)
a0 = (K**2 - 2*omega*BetaDen*K + omega**2)/ (K**2 + 2*omega*BetaDen*K + omega**2)

! Body
NotchFilter = P1*InputSignal + P2*InputSignalLast1(inst) + P3*InputSignalLast2(inst) - P4*OutputSignalLast1(inst) - P5*OutputSignalLast2(inst)
NotchFilter = b2*InputSignal + b1*InputSignalLast1(inst) + b0*InputSignalLast2(inst) - a1*OutputSignalLast1(inst) - a0*OutputSignalLast2(inst)

! Save signals for next time step
InputSignalLast2(inst) = InputSignalLast1(inst)
Expand Down
6 changes: 3 additions & 3 deletions src/Functions.f90
Original file line number Diff line number Diff line change
Expand Up @@ -415,8 +415,8 @@ SUBROUTINE Debug(LocalVar, CntrPar, avrSWAP, RootName, size_avcOUTNAME)
! If we're debugging, open the debug file and write the header:
IF (CntrPar%LoggingLevel > 0) THEN
OPEN(unit=UnDb, FILE='DEBUG.dbg')
WRITE (UnDb,'(A)') ' Time ' //Tab//' WE_TowerTop ' //Tab//' WE_Vw ' //Tab//' NacIMU_FA_Acc ' //Tab//' FA_Acc ' //Tab//' Fl_Pitcom '
WRITE (UnDb,'(A)') ' (sec) ' //Tab//'(m/s) ' //Tab//'(rad) ' //Tab//'(rad/s^2) ' //Tab//'(m/s^2) '//Tab//'(rad) '
WRITE (UnDb,'(A)') ' Time ' //Tab//' NacIMU_FA_AccF ' //Tab//' WE_Vw ' //Tab//' NacIMU_FA_Acc ' //Tab//' FA_Acc ' //Tab//' Fl_Pitcom ' //Tab//' test '
WRITE (UnDb,'(A)') ' (sec) ' //Tab//'(m/s) ' //Tab//'(rad) ' //Tab//'(rad/s^2) ' //Tab//'(m/s^2) '//Tab//'(rad) ' //Tab//'(rad/s) '
END IF

IF (CntrPar%LoggingLevel > 1) THEN
Expand All @@ -434,7 +434,7 @@ SUBROUTINE Debug(LocalVar, CntrPar, avrSWAP, RootName, size_avcOUTNAME)

! Output debugging information if requested:
IF (CntrPar%LoggingLevel > 0) THEN
WRITE (UnDb,FmtDat) LocalVar%Time, LocalVar%TestType, LocalVar%WE_Vw, LocalVar%NacIMU_FA_Acc, LocalVar%FA_Acc, LocalVar%Fl_PitCom
WRITE (UnDb,FmtDat) LocalVar%Time, LocalVar%NacIMU_FA_AccF, LocalVar%WE_Vw, LocalVar%NacIMU_FA_Acc, LocalVar%FA_Acc, LocalVar%Fl_PitCom, LocalVar%TestType
END IF

IF (CntrPar%LoggingLevel > 1) THEN
Expand Down
2 changes: 1 addition & 1 deletion src/ROSCO_Types.f90
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ MODULE ROSCO_Types
REAL(4) :: Azimuth
INTEGER(4) :: NumBl
REAL(4) :: FA_Acc ! Tower fore-aft acceleration [m/s^2]
REAL(4) :: NacIMU_FA_Acc ! Tower fore-aft acceleration [m/s^2]
REAL(4) :: NacIMU_FA_Acc ! Tower fore-aft acceleration [rad/s^2]

! ---------- -Internal controller variables ----------
REAL(4) :: FA_AccHPF ! High-pass filtered fore-aft acceleration [m/s^2]
Expand Down
9 changes: 9 additions & 0 deletions src/ReadSetParameters.f90
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,15 @@ SUBROUTINE Assert(LocalVar, CntrPar, avrSWAP, aviFAIL, ErrMsg, size_avcMSG)
ErrMsg = 'Y_omegaLPSlow must be greater than zero.'
ENDIF
ENDIF

! --- Floating Control ---
IF (CntrPar%FL_Mode > 0) THEN
IF (CntrPar%F_NotchType <= 1 .OR. CntrPar%F_NotchCornerFreq == 0.0) THEN
aviFAIL = -1
ErrMsg = 'F_NotchType and F_NotchCornerFreq must be specified for Fl_Mode greater than zero.'
ENDIF
ENDIF

! Abort if the user has not requested a pitch angle actuator (See Appendix A
! of Bladed User's Guide):
IF (NINT(avrSWAP(10)) /= 0) THEN ! .TRUE. if a pitch angle actuator hasn't been requested
Expand Down

0 comments on commit d385eca

Please sign in to comment.