From 349714fdfa17573ffcf0a7d72e0ec3ca2cd4773a Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Sat, 9 Nov 2024 18:22:38 -0700 Subject: [PATCH 01/33] Shutdown: Add framework for more shutdown modes --- Examples/30_shutdown.py | 107 +++++++++++++++++ Examples/Tune_Cases/NREL5MW.yaml | 1 - .../rosco_registry/rosco_types.yaml | 42 ++++++- rosco/controller/src/ROSCO_Types.f90 | 18 ++- rosco/controller/src/ReadSetParameters.f90 | 18 ++- rosco/toolbox/controller.py | 26 ++-- rosco/toolbox/inputs/toolbox_schema.yaml | 112 ++++++++++++++++-- rosco/toolbox/utilities.py | 34 +++++- 8 files changed, 327 insertions(+), 31 deletions(-) create mode 100644 Examples/30_shutdown.py diff --git a/Examples/30_shutdown.py b/Examples/30_shutdown.py new file mode 100644 index 00000000..d75f842b --- /dev/null +++ b/Examples/30_shutdown.py @@ -0,0 +1,107 @@ +""" +30_shutdown +---------------- +This example demonstrates turbine shutdown. +""" + +import os +import numpy as np +import matplotlib.pyplot as plt +from rosco.toolbox.ofTools.case_gen.run_FAST import run_FAST_ROSCO +from rosco.toolbox.ofTools.case_gen import CaseLibrary as cl +from rosco.toolbox import controller as ROSCO_controller + +rpm2RadSec = 2.0 * (np.pi) / 60.0 + +# directories +this_dir = os.path.dirname(os.path.abspath(__file__)) +example_out_dir = os.path.join(this_dir, "examples_out") +os.makedirs(example_out_dir, exist_ok=True) + + +def main(): + + FULL_TEST = False # FULL_TEST for local testing, otherwise shorter for CI + + # Input yaml and output directory + parameter_filename = os.path.join(this_dir, "Tune_Cases/IEA15MW.yaml") + + # Set DISCON input dynamically through yaml/dict + controller_params = {} + controller_params["DISCON"] = {} + controller_params["DISCON"]["Echo"] = 1 + controller_params["SD_Mode"] = 4 + controller_params["DISCON"]["SD_Time"] = 10 + + + + # simulation set up + r = run_FAST_ROSCO() + r.tuning_yaml = parameter_filename + r.case_inputs = {} + + # Disable floating DOFs for clarity + r.case_inputs[("ElastoDyn", "PtfmSgDOF")] = {"vals": ["False"], "group": 0} + r.case_inputs[("ElastoDyn", "PtfmSwDOF")] = {"vals": ["False"], "group": 0} + r.case_inputs[("ElastoDyn", "PtfmHvDOF")] = {"vals": ["False"], "group": 0} + r.case_inputs[("ElastoDyn", "PtfmRDOF")] = {"vals": ["False"], "group": 0} + r.case_inputs[("ElastoDyn", "PtfmPDOF")] = {"vals": ["False"], "group": 0} + r.case_inputs[("ElastoDyn", "PtfmYDOF")] = {"vals": ["False"], "group": 0} + + sim_config = 1 + # 1. Shutdown due to pitch exceeding threshold + # 2. Shutdown due to yaw error exceeding threshold + # 3. Shutdown due to generator speed exceeding threshold + # 4. Shutdown at a particular time + + if sim_config == 1: + t_max = 120 + + run_dir = os.path.join(example_out_dir, "30_shutdown_demo/1_pitch") + olc = ROSCO_controller.OpenLoopControl(t_max=t_max) + olc.interp_series("blade_pitch", [0, 120], [10, 50], "linear") + + + # Wind case + r.wind_case_fcn = cl.ramp + r.wind_case_opts = { + "U_start": 20, + "U_end": 40, + "t_start": 0, + "t_end": t_max, + } + r.case_inputs[("ElastoDyn", "BlPitch1")] = {"vals": [10.0], "group": 0} + r.case_inputs[("ElastoDyn", "BlPitch2")] = {"vals": [10.0], "group": 0} + r.case_inputs[("ElastoDyn", "BlPitch3")] = {"vals": [10.0], "group": 0} + r.case_inputs[("ElastoDyn", "RotSpeed")] = {"vals": [10.0], "group": 0} + + # fig, ax = olc.plot_series() + # fig.savefig(os.path.join(example_out_dir, "29_OL_Inputs.png")) + + # Write open loop input, get OL indices + os.makedirs(run_dir, exist_ok=True) + ol_filename = os.path.join(run_dir, "30_OL_Input.dat") + ol_dict = olc.write_input(ol_filename) + controller_params["open_loop"] = ol_dict + controller_params["OL_Mode"] = 0 + + r.controller_params = controller_params + r.save_dir = run_dir + r.run_FAST() + + plotoutput(run_dir) + +def plotoutput(run_dir): + from rosco.toolbox.ofTools.fast_io import output_processing + outfile = [os.path.join(run_dir,'IEA15MW','ramp','base','IEA15MW_0.outb')] + + cases = {} + cases['Baseline'] = ['Wind1VelX', 'BldPitch1', 'GenTq', 'RotSpeed'] + fast_out = output_processing.output_processing() + fastout = fast_out.load_fast_out(outfile) + fast_out.plot_fast_out(cases=cases,showplot=False) + + plt.savefig(os.path.join(example_out_dir,'30_shutdown_pitch.png')) + +if __name__ == "__main__": + main() diff --git a/Examples/Tune_Cases/NREL5MW.yaml b/Examples/Tune_Cases/NREL5MW.yaml index 51d9a0ac..5b601f0c 100644 --- a/Examples/Tune_Cases/NREL5MW.yaml +++ b/Examples/Tune_Cases/NREL5MW.yaml @@ -48,4 +48,3 @@ controller_params: ptfm_freq: 0.2325 # Platform natural frequency [rad/s] (OC4Hywind Parameters, here) # Optional ps_percent: 0.80 # Percent peak shaving [%, <= 1 ], {default = 80%} - sd_maxpit: 0.4363 # Maximum blade pitch angle to initiate shutdown [rad], {default = bld pitch at v_max} diff --git a/rosco/controller/rosco_registry/rosco_types.yaml b/rosco/controller/rosco_registry/rosco_types.yaml index d1a2ff21..5b5b7dab 100644 --- a/rosco/controller/rosco_registry/rosco_types.yaml +++ b/rosco/controller/rosco_registry/rosco_types.yaml @@ -465,13 +465,49 @@ ControlParameters: # Shutdown SD_Mode: <<: *integer - description: Shutdown mode {0 - no shutdown procedure, 1 - pitch to max pitch at shutdown} + description: Shutdown mode {0 - no shutdown procedure, 1 - enable shutdown} + SD_EnablePitch: + <<: *integer + description: Shutdown when collective blade pitch exceeds a threshold, [-] + SD_EnableYawError: + <<: *integer + description: Shutdown when yaw error exceeds a threshold, [-] + SD_EnableGenSpeed: + <<: *integer + description: Shutdown when generator speed exceeds a threshold, [-] + SD_EnableTime: + <<: *integer + description: Shutdown at a predefined time, [-] SD_MaxPit: <<: *real description: Maximum blade pitch angle to initiate shutdown, [rad] - SD_CornerFreq: + SD_PitchCornerFreq: + <<: *real + description: Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] + SD_MaxYawError: + <<: *real + description: Maximum yaw error to initiate shutdown, [rad] + SD_YawErrorCornerFreq: + <<: *real + description: Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] + SD_MaxGenSpd: + <<: *real + description: Maximum generator speed to initiate shutdown, [rad/s] + SD_GenCornerFreq: + <<: *real + description: Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] + SD_Time: + <<: *real + description: Shutdown time, [s] + SD_Method: + <<: *integer + description: Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] + SD_MaxTorqueRate: + <<: *real + description: Maximum torque rate for shutdown, [Nm/s] + SD_MaxPitchRate: <<: *real - description: Cutoff Frequency for first order low-pass filter for blade pitch angle, [rad/s] + description: Maximum pitch rate used for shutdown, [rad/s] # Floating Fl_Mode: diff --git a/rosco/controller/src/ROSCO_Types.f90 b/rosco/controller/src/ROSCO_Types.f90 index a1c53f6b..a9587619 100644 --- a/rosco/controller/src/ROSCO_Types.f90 +++ b/rosco/controller/src/ROSCO_Types.f90 @@ -119,9 +119,21 @@ MODULE ROSCO_Types INTEGER(IntKi) :: PS_BldPitchMin_N ! Number of values in minimum blade pitch lookup table (should equal number of values in PS_WindSpeeds and PS_BldPitchMin) REAL(DbKi), DIMENSION(:), ALLOCATABLE :: PS_WindSpeeds ! Wind speeds corresponding to minimum blade pitch angles [m/s] REAL(DbKi), DIMENSION(:), ALLOCATABLE :: PS_BldPitchMin ! Minimum blade pitch angles [rad] - INTEGER(IntKi) :: SD_Mode ! Shutdown mode {0 - no shutdown procedure, 1 - pitch to max pitch at shutdown} + INTEGER(IntKi) :: SD_Mode ! Shutdown mode {0 - no shutdown procedure, 1 - shutdown enabled} + INTEGER(IntKi) :: SD_EnablePitch ! Shutdown when collective blade pitch exceeds a threshold, [-] + INTEGER(IntKi) :: SD_EnableYawError ! Shutdown when yaw error exceeds a threshold, [-] + INTEGER(IntKi) :: SD_EnableGenSpeed ! Shutdown when generator speed exceeds a threshold, [-] + INTEGER(IntKi) :: SD_EnableTime ! Shutdown at a predefined time, [-] REAL(DbKi) :: SD_MaxPit ! Maximum blade pitch angle to initiate shutdown, [rad] - REAL(DbKi) :: SD_CornerFreq ! Cutoff Frequency for first order low-pass filter for blade pitch angle, [rad/s] + REAL(DbKi) :: SD_PitchCornerFreq ! Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] + REAL(DbKi) :: SD_MaxYawError ! Maximum yaw error to initiate shutdown, [rad] + REAL(DbKi) :: SD_YawErrorCornerFreq ! Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] + REAL(DbKi) :: SD_MaxGenSpd ! Maximum generator speed to initiate shutdown, [rad/s] + REAL(DbKi) :: SD_GenCornerFreq ! Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] + REAL(DbKi) :: SD_Time ! Shutdown time, [s] + INTEGER(IntKi) :: SD_Method ! Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] + REAL(DbKi) :: SD_MaxTorqueRate ! Maximum torque rate for shutdown, [Nm/s] + REAL(DbKi) :: SD_MaxPitchRate ! Maximum pitch rate used for shutdown, [rad/s] INTEGER(IntKi) :: Fl_Mode ! Floating specific feedback mode {0 - no nacelle velocity feedback, 1 - nacelle velocity feedback} INTEGER(IntKi) :: Fl_n ! Number of Fl_Kp for gain scheduling REAL(DbKi), DIMENSION(:), ALLOCATABLE :: Fl_Kp ! Nacelle velocity proportional feedback gain [s] @@ -478,4 +490,4 @@ MODULE ROSCO_Types REAL(ReKi), DIMENSION(:), ALLOCATABLE :: avrSWAP ! The swap array- used to pass data to and from the DLL controller [see Bladed DLL documentation] END TYPE ExtControlType -END MODULE ROSCO_Types \ No newline at end of file +END MODULE ROSCO_Types diff --git a/rosco/controller/src/ReadSetParameters.f90 b/rosco/controller/src/ReadSetParameters.f90 index a1dbdfde..a36e8ad1 100644 --- a/rosco/controller/src/ReadSetParameters.f90 +++ b/rosco/controller/src/ReadSetParameters.f90 @@ -514,8 +514,20 @@ SUBROUTINE ReadControlParameterFileSub(CntrPar, LocalVar, accINFILE, accINFILE_s IF (ErrVar%aviFAIL < 0) RETURN !------------ SHUTDOWN ------------ - CALL ParseInput(FileLines, 'SD_MaxPit', CntrPar%SD_MaxPit, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) - CALL ParseInput(FileLines, 'SD_CornerFreq', CntrPar%SD_CornerFreq, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_EnablePitch', CntrPar%SD_EnablePitch, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_EnableYawError', CntrPar%SD_EnableYawError, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_EnableGenSpeed', CntrPar%SD_EnableGenSpeed, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_EnableTime', CntrPar%SD_EnableTime, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_MaxPit', CntrPar%SD_MaxPit, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_PitchCornerFreq', CntrPar%SD_PitchCornerFreq, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_MaxYawError', CntrPar%SD_MaxYawError, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_YawErrorCornerFreq', CntrPar%SD_YawErrorCornerFreq, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_MaxGenSpd', CntrPar%SD_MaxGenSpd, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_GenCornerFreq', CntrPar%SD_GenCornerFreq, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_Time', CntrPar%SD_Time, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_Method', CntrPar%SD_Method, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_MaxTorqueRate', CntrPar%SD_MaxTorqueRate, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_MaxPitchRate', CntrPar%SD_MaxPitchRate, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) IF (ErrVar%aviFAIL < 0) RETURN !------------ FLOATING ------------ @@ -999,7 +1011,7 @@ SUBROUTINE CheckInputs(LocalVar, CntrPar, avrSWAP, ErrVar, size_avcMSG) ENDIF ! SD_Mode - IF ((CntrPar%SD_Mode < 0) .OR. (CntrPar%SD_Mode > 1)) THEN + IF ((CntrPar%SD_Mode < 0) .OR. (CntrPar%SD_Mode > 5)) THEN ErrVar%aviFAIL = -1 ErrVar%ErrMsg = 'SD_Mode must be 0 or 1.' ENDIF diff --git a/rosco/toolbox/controller.py b/rosco/toolbox/controller.py index 1fdec790..2e85558a 100644 --- a/rosco/toolbox/controller.py +++ b/rosco/toolbox/controller.py @@ -88,7 +88,6 @@ def __init__(self, controller_params): self.ss_vsgain = controller_params['ss_vsgain'] self.ss_pcgain = controller_params['ss_pcgain'] self.ps_percent = controller_params['ps_percent'] - self.sd_maxpit = controller_params['sd_maxpit'] self.WS_GS_n = controller_params['WS_GS_n'] self.PC_GS_n = controller_params['PC_GS_n'] self.flp_maxpit = controller_params['flp_maxpit'] @@ -98,6 +97,18 @@ def __init__(self, controller_params): self.Ki_ipc2p = controller_params['IPC_Kp2p'] self.IPC_Vramp = controller_params['IPC_Vramp'] self.ZMQ_UpdatePeriod = controller_params['ZMQ_UpdatePeriod'] + ## shutdownparameters + self.sd_enablepitch = controller_params['sd_enablepitch'] + self.sd_enableyawerror = controller_params['sd_enableyawerror'] + self.sd_enablegenspeed = controller_params['sd_enablegenspeed'] + self.sd_enabletime = controller_params['sd_enabletime'] + self.sd_maxpitch = controller_params['sd_maxpitch'] + self.sd_maxyawerror = controller_params['sd_maxyawerror'] + self.sd_maxgenspd = controller_params['sd_maxgenspd'] + self.sd_time = controller_params['sd_time'] + self.sd_maxtorquerate = controller_params['sd_maxtorquerate'] + self.sd_maxpitchrate = controller_params['sd_maxpitchrate'] + # Optional parameters without defaults if self.Flp_Mode > 0: @@ -139,8 +150,9 @@ def __init__(self, controller_params): self.f_fl_highpassfreq = controller_params['filter_params']['f_fl_highpassfreq'] self.f_ss_cornerfreq = controller_params['filter_params']['f_ss_cornerfreq'] self.f_yawerr = controller_params['filter_params']['f_yawerr'] - self.f_sd_cornerfreq = controller_params['filter_params']['f_sd_cornerfreq'] - + self.f_sd_pitchcornerfreq = controller_params['filter_params']['f_sd_pitchcornerfreq'] + self.f_sd_yawerrorcornerfreq = controller_params['filter_params']['f_sd_yawerrorcornerfreq'] + self.f_sd_gencornerfreq = controller_params['filter_params']['f_sd_gencornerfreq'] # Open loop parameters: set up and error catching self.OL_Mode = controller_params['OL_Mode'] @@ -350,10 +362,10 @@ def tune_controller(self, turbine): self.pc_minspd = self.vs_minspd # max pitch angle for shutdown - if self.sd_maxpit: - self.sd_maxpit = self.sd_maxpit - else: - self.sd_maxpit = pitch_op[-1] + # if self.sd_maxpit: + # self.sd_maxpit = self.sd_maxpit + # else: + # self.sd_maxpit = pitch_op[-1] # Set IPC ramp inputs if not already defined if max(self.IPC_Vramp) == 0.0: diff --git a/rosco/toolbox/inputs/toolbox_schema.yaml b/rosco/toolbox/inputs/toolbox_schema.yaml index 3131f8bf..dcd7dfec 100644 --- a/rosco/toolbox/inputs/toolbox_schema.yaml +++ b/rosco/toolbox/inputs/toolbox_schema.yaml @@ -172,7 +172,7 @@ properties: minimum: 0 maximum: 1 default: 0 - description: Shutdown mode (0- no shutdown procedure, 1- pitch to max pitch at shutdown) + description: Shutdown mode (0- no shutdown procedure, 1- enable shutdown) TD_Mode: type: number minimum: 0 @@ -329,12 +329,53 @@ properties: default: 0.8 maximum: 1 unit: rad - sd_maxpit: + sd_enablepitch: + description: Shutdown when collective blade pitch exceeds a threshold [-], {default = 0} + type: number + default: 0 + sd_enableyawerror: + description: Shutdown when yaw error exceeds a threshold, [-], {default = 0} + type: number + default: 0 + sd_enablegenspeed: + description: Shutdown when generator speed exceeds a threshold, [-], {default = 9} + type: number + default: 0 + sd_enabletime: + description: Shutdown at a predefined time, [-] {default = 0} + type: number + default: 0 + sd_maxpitch: description: Maximum blade pitch angle to initiate shutdown [rad], {default = 40 deg.} type: number default: 0.6981 unit: rad - flp_maxpit: + sd_maxyawerror: + description: Maximum yaw error to initiate shutdown [rad], {default = 30 deg.} + type: number + default: 0.5236 + unit: rad + sd_maxgenspd: + description: Maximum generator speed to initiate shutdown, [rad/s], {default = 10 rad/s.} + type: number + default: 10 + unit: rad/s + sd_time: + description: Shutdown time, [s], {default = 9999 s.} + type: number + default: 9999 + unit: s + sd_maxtorquerate: + description: Maximum torque rate for shutdown, [Nm/s], {default = 99999 Nm/s., High value to simulate instant cuttoff} + type: number + default: 99999 + unit: Nm/s + sd_maxpitchrate: + description: Maximum pitch rate used for shutdown, [rad/s], {default = 1 rad/s.} + type: number + default: 1.0 + unit: s + flp_maxpit: description: Maximum (and minimum) flap pitch angle [rad] type: number default: 0.1745 @@ -475,11 +516,21 @@ properties: minimum: 0 unit: rad/s default: 0.17952 - f_sd_cornerfreq: - description: Cutoff Frequency for first order low-pass filter for blade pitch angle [rad/s], {default = 0.41888 ~ time constant of 15s} + f_sd_pitchcornerfreq: + description: Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s], {default = 0.41888 ~ time constant of 15s} type: number default: 0.41888 - unit: rad + unit: rad/s + f_sd_yawerrorcornerfreq: + description: Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s], {default = 0.41888 ~ time constant of 15s} + type: number + default: 0.41888 + unit: rad/s + f_sd_gencornerfreq: + description: utoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s], {default = 0.41888 ~ time constant of 15s} + type: number + default: 0.41888 + unit: rad/s open_loop: type: object default: {} @@ -621,7 +672,7 @@ properties: description: Pitch saturation mode (0- no pitch saturation, 1- implement pitch saturation) SD_Mode: type: number - description: Shutdown mode (0- no shutdown procedure, 1- pitch to max pitch at shutdown) + description: Shutdown mode (0- no shutdown procedure, 1- enable shutdown) Fl_Mode: type: number description: Floating specific feedback mode (0- no nacelle velocity feedback, 1- feed back translational velocity, 2- feed back rotational veloicty) @@ -1029,13 +1080,56 @@ properties: type: number description: Minimum blade pitch angles units: rad + SD_EnablePitch: + type: number + description: Shutdown when collective blade pitch exceeds a threshold + SD_EnableYawError: + type: number + description: Shutdown when yaw error exceeds a threshold + SD_EnableGenSpeed: + type: number + description: Shutdown when generator speed exceeds a threshold + SD_EnableTime: + type: number + description: Shutdown at a predefined time SD_MaxPit: type: number description: Maximum blade pitch angle to initiate shutdown units: rad - SD_CornerFreq: + SD_PitchCornerFreq: + type: number + description: Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, + units: rad/s + SD_MaxYawError: + type: number + description: Maximum yaw error to initiate shutdown + units: rad + SD_YawErrorCornerFreq: + type: number + description: Cutoff Frequency for first order low-pass filter for yaw error for shutdown + units: rad/s + SD_MaxGenSpd: + type: number + description: Maximum generator speed to initiate shutdown + units: rad/s + SD_GenCornerFreq: + type: number + description: Cutoff Frequency for first order low-pass filter for generator speed for shutdown + units: rad/s + SD_Time: + type: number + description: Shutdown time + units: s + SD_Method: + type: number + description: Shutdown method {1- Reduce generator torque and increase blade pitch} + SD_MaxTorqueRate: + type: number + description: Maximum torque rate for shutdown + units: Nm/s + SD_MaxPitchRate: type: number - description: Cutoff Frequency for first order low-pass filter for blade pitch angle + description: Maximum pitch rate used for shutdown units: rad/s Fl_n: type: number diff --git a/rosco/toolbox/utilities.py b/rosco/toolbox/utilities.py index 30224f49..ea45ca01 100644 --- a/rosco/toolbox/utilities.py +++ b/rosco/toolbox/utilities.py @@ -104,7 +104,7 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('{0:<12d} ! PRC_Mode - Power reference tracking mode{{0: power control disabled, 1: lookup table from wind speed to generator speed setpoints, 2: change speed, torque, pitch to control power}}\n'.format(int(rosco_vt['PRC_Mode']))) file.write('{0:<12d} ! 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}}\n'.format(int(rosco_vt['WE_Mode']))) file.write('{0:<12d} ! PS_Mode - Pitch saturation mode {{0: no pitch saturation, 1: implement pitch saturation}}\n'.format(int(rosco_vt['PS_Mode']))) - file.write('{0:<12d} ! SD_Mode - Shutdown mode {{0: no shutdown procedure, 1: pitch to max pitch at shutdown}}\n'.format(int(rosco_vt['SD_Mode']))) + file.write('{0:<12d} ! SD_Mode - Shutdown mode {{0: no shutdown procedure, 1: shutdown enabled}}\n'.format(int(rosco_vt['SD_Mode']))) file.write('{0:<12d} ! Fl_Mode - Floating specific feedback mode {{0: no nacelle velocity feedback, 1: feed back translational velocity, 2: feed back rotational veloicty}}\n'.format(int(rosco_vt['Fl_Mode']))) file.write('{:<12d} ! TD_Mode - {}\n'.format(int(rosco_vt['TD_Mode']),mode_descriptions['TD_Mode'])) file.write('{:<12d} ! TRA_Mode - {}\n'.format(int(rosco_vt['TRA_Mode']),mode_descriptions['TRA_Mode'])) @@ -233,8 +233,20 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('{} ! PS_BldPitchMin - Minimum blade pitch angles [rad]\n'.format(''.join('{:<10.3f} '.format(rosco_vt['PS_BldPitchMin'][i]) for i in range(len(rosco_vt['PS_BldPitchMin']))))) file.write('\n') file.write('!------- SHUTDOWN -----------------------------------------------------------\n') - file.write('{:<014.5f} ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]\n'.format(rosco_vt['SD_MaxPit'])) - file.write('{:<014.5f} ! SD_CornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle, [rad/s]\n'.format(rosco_vt['SD_CornerFreq'])) + file.write('{:<12d} ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]​\n'.format(rosco_vt['SD_EnablePitch'])) + file.write('{:<12d} ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]​\n'.format(rosco_vt['SD_EnableYawError'])) + file.write('{:<12d} ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]​\n'.format(rosco_vt['SD_EnableGenSpeed'])) + file.write('{:<12d} ! SD_EnableTime - Shutdown at a predefined time, [-]​\n'.format(rosco_vt['SD_EnableTime'])) + file.write('{:<014.5f} ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​\n'.format(rosco_vt['SD_MaxPit'])) + file.write('{:<014.5f} ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​\n'.format(rosco_vt['SD_PitchCornerFreq'])) + file.write('{:<014.5f} ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​\n'.format(rosco_vt['SD_MaxYawError'])) + file.write('{:<014.5f} ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s]\n'.format(rosco_vt['SD_YawErrorCornerFreq'])) + file.write('{:<014.5f} ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​\n'.format(rosco_vt['SD_MaxGenSpd'])) + file.write('{:<014.5f} ! SD_GenCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​\n'.format(rosco_vt['SD_GenCornerFreq'])) + file.write('{:<014.5f} ! SD_Time - Shutdown time, [s]​\n'.format(rosco_vt['SD_Time'])) + file.write('{:<012d} ! SD_Method - Shutdown method {{1: Reduce generator torque and increase blade pitch}},​ [-]​\n'.format(rosco_vt['SD_Method'])) + file.write('{:<014.5f} ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​\n'.format(rosco_vt['SD_MaxTorqueRate'])) + file.write('{:<014.5f} ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​\n'.format(rosco_vt['SD_MaxPitchRate'])) file.write('\n') file.write('!------- Floating -----------------------------------------------------------\n') if rosco_vt['Fl_Mode'] == 2: @@ -602,8 +614,20 @@ def DISCON_dict(turbine, controller, txt_filename=None): DISCON_dict['PS_WindSpeeds'] = controller.v DISCON_dict['PS_BldPitchMin'] = controller.ps_min_bld_pitch # ------- SHUTDOWN ------- - DISCON_dict['SD_MaxPit'] = controller.sd_maxpit - DISCON_dict['SD_CornerFreq'] = controller.f_sd_cornerfreq + DISCON_dict['SD_EnablePitch'] = controller.sd_enablepitch + DISCON_dict['SD_EnableYawError'] = controller.sd_enableyawerror + DISCON_dict['SD_EnableGenSpeed'] = controller.sd_enablegenspeed + DISCON_dict['SD_EnableTime'] = controller.sd_enabletime + DISCON_dict['SD_MaxPitch'] = controller.sd_maxpitch + DISCON_dict['SD_PitchCornerFreq'] = controller.f_sd_pitchcornerfreq + DISCON_dict['SD_MaxYawError'] = controller.sd_maxyawerror + DISCON_dict['SD_YawErrorCornerFreq'] = controller.f_sd_yawerrorcornerfreq + DISCON_dict['SD_MaxGenSpd'] = controller.sd_maxgenspd + DISCON_dict['SD_GenCornerFreq'] = controller.f_sd_gencornerfreq + DISCON_dict['SD_Time'] = controller.sd_time + DISCON_dict['SD_Method'] = controller.sd_enablegenspeed + DISCON_dict['SD_MaxTorqueRate'] = controller.sd_maxtorquerate + DISCON_dict['SD_MaxPitchRate'] = controller.sd_maxpitchrate # ------- Floating ------- DISCON_dict['Fl_n'] = len(controller.Kp_float) DISCON_dict['Fl_Kp'] = controller.Kp_float From 3414e8fadc29e5e82d24a786924795bb52429d36 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Mon, 11 Nov 2024 23:32:55 -0700 Subject: [PATCH 02/33] shutdown: add a working shutdown model, needs more polish --- Examples/30_shutdown.py | 33 +++++----- .../rosco_registry/rosco_types.yaml | 9 ++- rosco/controller/src/ControllerBlocks.f90 | 65 +++++++++++-------- rosco/controller/src/Controllers.f90 | 10 +-- rosco/controller/src/DISCON.F90 | 1 + rosco/controller/src/ROSCO_Types.f90 | 4 +- rosco/controller/src/ReadSetParameters.f90 | 10 ++- rosco/toolbox/controller.py | 3 +- rosco/toolbox/inputs/toolbox_schema.yaml | 8 ++- rosco/toolbox/utilities.py | 8 +-- 10 files changed, 87 insertions(+), 64 deletions(-) diff --git a/Examples/30_shutdown.py b/Examples/30_shutdown.py index d75f842b..c06f4af0 100644 --- a/Examples/30_shutdown.py +++ b/Examples/30_shutdown.py @@ -19,8 +19,9 @@ os.makedirs(example_out_dir, exist_ok=True) -def main(): +def main(): + # Test Config FULL_TEST = False # FULL_TEST for local testing, otherwise shorter for CI # Input yaml and output directory @@ -30,10 +31,17 @@ def main(): controller_params = {} controller_params["DISCON"] = {} controller_params["DISCON"]["Echo"] = 1 - controller_params["SD_Mode"] = 4 - controller_params["DISCON"]["SD_Time"] = 10 - - + controller_params["SD_Mode"] = 1 + # controller_params["DISCON"]["SD_EnablePitch"] = 1 + # controller_params["DISCON"]["SD_MaxPit"] = 0.5236 + controller_params["DISCON"]["SD_EnableGenSpeed"] = 1 + controller_params["DISCON"]["SD_MaxGenSpd"] = 12*2*3.1415/60 + # controller_params["DISCON"]["SD_EnableTime"] = 1 + # controller_params["DISCON"]["SD_Time"] = 75 + controller_params['DISCON']['PRC_Mode'] = 2 + controller_params['DISCON']['PRC_Comm'] = 0 + controller_params['DISCON']['PRC_R_Speed'] = 2.0 + controller_params['DISCON']['OL_BP_FiltFreq'] = 2 * np.pi / 30 # simulation set up r = run_FAST_ROSCO() @@ -58,15 +66,13 @@ def main(): t_max = 120 run_dir = os.path.join(example_out_dir, "30_shutdown_demo/1_pitch") - olc = ROSCO_controller.OpenLoopControl(t_max=t_max) - olc.interp_series("blade_pitch", [0, 120], [10, 50], "linear") # Wind case r.wind_case_fcn = cl.ramp r.wind_case_opts = { - "U_start": 20, - "U_end": 40, + "U_start": 4, + "U_end": 30, "t_start": 0, "t_end": t_max, } @@ -80,23 +86,16 @@ def main(): # Write open loop input, get OL indices os.makedirs(run_dir, exist_ok=True) - ol_filename = os.path.join(run_dir, "30_OL_Input.dat") - ol_dict = olc.write_input(ol_filename) - controller_params["open_loop"] = ol_dict - controller_params["OL_Mode"] = 0 r.controller_params = controller_params r.save_dir = run_dir r.run_FAST() - plotoutput(run_dir) - -def plotoutput(run_dir): from rosco.toolbox.ofTools.fast_io import output_processing outfile = [os.path.join(run_dir,'IEA15MW','ramp','base','IEA15MW_0.outb')] cases = {} - cases['Baseline'] = ['Wind1VelX', 'BldPitch1', 'GenTq', 'RotSpeed'] + cases['Baseline'] = ['Wind1VelX', 'BldPitch1', 'GenTq', 'RotSpeed','GenPwr'] fast_out = output_processing.output_processing() fastout = fast_out.load_fast_out(outfile) fast_out.plot_fast_out(cases=cases,showplot=False) diff --git a/rosco/controller/rosco_registry/rosco_types.yaml b/rosco/controller/rosco_registry/rosco_types.yaml index 5b5b7dab..6067e64f 100644 --- a/rosco/controller/rosco_registry/rosco_types.yaml +++ b/rosco/controller/rosco_registry/rosco_types.yaml @@ -251,7 +251,7 @@ ControlParameters: PC_MaxRat: <<: *real description: Maximum pitch rate (in absolute value) in pitch controller, [rad/s]. - PC_MinRat: + : <<: *real description: Minimum pitch rate (in absolute value) in pitch controller, [rad/s]. PC_RefSpd: @@ -461,7 +461,6 @@ ControlParameters: <<: *real description: Minimum blade pitch angles [rad] allocatable: True - # Shutdown SD_Mode: <<: *integer @@ -493,7 +492,7 @@ ControlParameters: SD_MaxGenSpd: <<: *real description: Maximum generator speed to initiate shutdown, [rad/s] - SD_GenCornerFreq: + SD_GenSpdCornerFreq: <<: *real description: Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] SD_Time: @@ -1323,7 +1322,7 @@ LocalVariables: OL_Index: <<: *real description: Open loop indexing variable (time or wind speed) - SD: + SD_Trigger: <<: *logical description: Shutdown, .FALSE. if inactive, .TRUE. if active Fl_PitCom: @@ -1490,7 +1489,7 @@ ObjectInstances: <<: *integer description: Notch filter instance instPI: - <<: *integer + <<: *integer description: PI controller instance instRL: <<: *integer diff --git a/rosco/controller/src/ControllerBlocks.f90 b/rosco/controller/src/ControllerBlocks.f90 index 42bd6094..9c9057f0 100644 --- a/rosco/controller/src/ControllerBlocks.f90 +++ b/rosco/controller/src/ControllerBlocks.f90 @@ -137,9 +137,9 @@ SUBROUTINE ComputeVariablesSetpoints(CntrPar, LocalVar, objInst, DebugVar, ErrVa ENDIF ! Force zero torque in shutdown mode - IF (LocalVar%SD) THEN - LocalVar%VS_RefSpd = CntrPar%VS_MinOMSpd - ENDIF + !IF (LocalVar%SD_Trigger) THEN + ! LocalVar%VS_RefSpd = CntrPar%VS_MinOMSpd + !ENDIF ! Force minimum rotor speed LocalVar%VS_RefSpd = max(LocalVar%VS_RefSpd, CntrPar%VS_MinOmSpd) @@ -512,47 +512,58 @@ REAL(DbKi) FUNCTION PitchSaturation(LocalVar, CntrPar, objInst, DebugVar, ErrVar END FUNCTION PitchSaturation !------------------------------------------------------------------------------------------------------------------------------- - REAL(DbKi) FUNCTION Shutdown(LocalVar, CntrPar, objInst) - ! Shutdown controller + SUBROUTINE ShutdownCheck(LocalVar, CntrPar, objInst,ErrVar) + ! Check for shutdown 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 + TYPE(ErrorVariables), INTENT(INOUT) :: ErrVar ! Local Variables REAL(DbKi) :: SD_BlPitchF - ! Initialize Shutdown Varible + REAL(DbKi) :: SD_NacVaneF + REAL(DbKi) :: SD_GenSpeedF + CHARACTER(*), PARAMETER :: RoutineName = 'VariableSpeedControl' + + !Initialize shutdown trigger variable IF (LocalVar%iStatus == 0) THEN - LocalVar%SD = .FALSE. + LocalVar%SD_Trigger = 0 ENDIF + + ! Filter pitch signal + SD_BlPitchF = LPFilter(LocalVar%PC_PitComT, LocalVar%DT, CntrPar%SD_PitchCornerFreq, LocalVar%FP,LocalVar%iStatus, LocalVar%restart, objInst%instLPF) + ! Filter yaw error signal (NacVane) + SD_NacVaneF = LPFilter(LocalVar%NacVane, LocalVar%DT, CntrPar%SD_YawErrorCornerFreq, LocalVar%FP,LocalVar%iStatus, LocalVar%restart, objInst%instLPF) + ! Filter yaw generator speed + SD_GenSpeedF = LPFilter(LocalVar%Genspeed, LocalVar%DT, CntrPar%SD_GenSpdCornerFreq, LocalVar%FP,LocalVar%iStatus, LocalVar%restart, objInst%instLPF) + ! 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%FP, LocalVar%iStatus, LocalVar%restart, objInst%instLPF) - - ! Go into shutdown if above max pit - IF (SD_BlPitchF > CntrPar%SD_MaxPit) THEN - LocalVar%SD = .TRUE. - ELSE - LocalVar%SD = .FALSE. + IF (LocalVar%SD_Trigger == 0) THEN + IF (CntrPar%SD_EnablePitch==1 .AND. SD_BlPitchF > CntrPar%SD_MaxPit) THEN + ! Shutdown if above pitch exceeds shutdown threshold + LocalVar%SD_Trigger = 1 + ENDIF + IF (CntrPar%SD_EnableYawError==1 .AND. SD_NacVaneF > CntrPar%SD_MaxYawError) THEN + LocalVar%SD_Trigger = 2 + ENDIF + IF (CntrPar%SD_EnableGenSpeed==1 .AND. SD_GenSpeedF > CntrPar%SD_MaxGenSpd) THEN + LocalVar%SD_Trigger = 3 + ENDIF + IF (CntrPar%SD_EnableTime==1 .AND. LocalVar%Time > CntrPar%SD_Time) THEN + LocalVar%SD_Trigger = 4 ENDIF ENDIF - - ! Pitch Blades to 90 degrees at max pitch rate if in shutdown mode - IF (LocalVar%SD) THEN - Shutdown = LocalVar%BlPitchCMeas + CntrPar%PC_MaxRat*LocalVar%DT - IF (MODULO(LocalVar%Time, 10.0_DbKi) == 0) THEN - print *, ' ** SHUTDOWN MODE **' - ENDIF - ELSE - Shutdown = LocalVar%PC_PitComT + + ! Add RoutineName to error message + IF (ErrVar%aviFAIL < 0) THEN + ErrVar%ErrMsg = RoutineName//':'//TRIM(ErrVar%ErrMsg) ENDIF - - END FUNCTION Shutdown + END SUBROUTINE ShutdownCheck !------------------------------------------------------------------------------------------------------------------------------- !------------------------------------------------------------------------------------------------------------------------------- SUBROUTINE RefSpeedExclusion(LocalVar, CntrPar, objInst, DebugVar) diff --git a/rosco/controller/src/Controllers.f90 b/rosco/controller/src/Controllers.f90 index 912a3706..2be4f26f 100644 --- a/rosco/controller/src/Controllers.f90 +++ b/rosco/controller/src/Controllers.f90 @@ -88,10 +88,13 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst, DebugVar, ErrVar) DebugVar%FL_PitCom = LocalVar%Fl_PitCom LocalVar%PC_PitComT = LocalVar%PC_PitComT + LocalVar%Fl_PitCom ENDIF - + ! Shutdown - IF (CntrPar%SD_Mode == 1) THEN - LocalVar%PC_PitComT = Shutdown(LocalVar, CntrPar, objInst) + + IF (LocalVar%SD_Trigger /= 0) THEN + IF (CntrPar%SD_Method == 1) THEN !Only SD_Method==1 supported for now + LocalVar%PC_PitComT = LocalVar%BlPitchCMeas + CntrPar%SD_MaxPitchRate*LocalVar%DT + ENDIF ENDIF ! Saturate collective pitch commands: @@ -180,7 +183,6 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst, DebugVar, ErrVar) IF (ErrVar%aviFAIL < 0) THEN ErrVar%ErrMsg = RoutineName//':'//TRIM(ErrVar%ErrMsg) ENDIF - END SUBROUTINE PitchControl !------------------------------------------------------------------------------------------------------------------------------- SUBROUTINE VariableSpeedControl(avrSWAP, CntrPar, LocalVar, objInst, ErrVar) diff --git a/rosco/controller/src/DISCON.F90 b/rosco/controller/src/DISCON.F90 index 4787e19f..02081bfe 100644 --- a/rosco/controller/src/DISCON.F90 +++ b/rosco/controller/src/DISCON.F90 @@ -100,6 +100,7 @@ SUBROUTINE DISCON(avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAME CALL UpdateZeroMQ(LocalVar, CntrPar, ErrVar) ENDIF + CALL ShutdownCheck(LocalVar, CntrPar, objInst,ErrVar) CALL WindSpeedEstimator(LocalVar, CntrPar, objInst, PerfData, DebugVar, ErrVar) CALL ComputeVariablesSetpoints(CntrPar, LocalVar, objInst, DebugVar, ErrVar) CALL StateMachine(CntrPar, LocalVar) diff --git a/rosco/controller/src/ROSCO_Types.f90 b/rosco/controller/src/ROSCO_Types.f90 index a9587619..da3d4b3d 100644 --- a/rosco/controller/src/ROSCO_Types.f90 +++ b/rosco/controller/src/ROSCO_Types.f90 @@ -129,7 +129,7 @@ MODULE ROSCO_Types REAL(DbKi) :: SD_MaxYawError ! Maximum yaw error to initiate shutdown, [rad] REAL(DbKi) :: SD_YawErrorCornerFreq ! Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] REAL(DbKi) :: SD_MaxGenSpd ! Maximum generator speed to initiate shutdown, [rad/s] - REAL(DbKi) :: SD_GenCornerFreq ! Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] + REAL(DbKi) :: SD_GenSpdCornerFreq ! Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] REAL(DbKi) :: SD_Time ! Shutdown time, [s] INTEGER(IntKi) :: SD_Method ! Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] REAL(DbKi) :: SD_MaxTorqueRate ! Maximum torque rate for shutdown, [Nm/s] @@ -375,7 +375,7 @@ MODULE ROSCO_Types REAL(DbKi) :: PRC_Min_Pitch ! Instantaneous PRC_Min_Pitch REAL(DbKi) :: PS_Min_Pitch ! Instantaneous peak shaving REAL(DbKi) :: OL_Index ! Open loop indexing variable (time or wind speed) - LOGICAL :: SD ! Shutdown, .FALSE. if inactive, .TRUE. if active + INTEGER(IntKi) :: SD_Trigger ! Shutdown, .FALSE. if inactive, .TRUE. if active REAL(DbKi) :: Fl_PitCom ! Shutdown, .FALSE. if inactive, .TRUE. if active REAL(DbKi) :: NACIMU_FA_AccF ! None REAL(DbKi) :: FA_AccF ! None diff --git a/rosco/controller/src/ReadSetParameters.f90 b/rosco/controller/src/ReadSetParameters.f90 index a36e8ad1..b7a9bbaf 100644 --- a/rosco/controller/src/ReadSetParameters.f90 +++ b/rosco/controller/src/ReadSetParameters.f90 @@ -523,7 +523,7 @@ SUBROUTINE ReadControlParameterFileSub(CntrPar, LocalVar, accINFILE, accINFILE_s CALL ParseInput(FileLines, 'SD_MaxYawError', CntrPar%SD_MaxYawError, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) CALL ParseInput(FileLines, 'SD_YawErrorCornerFreq', CntrPar%SD_YawErrorCornerFreq, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) CALL ParseInput(FileLines, 'SD_MaxGenSpd', CntrPar%SD_MaxGenSpd, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) - CALL ParseInput(FileLines, 'SD_GenCornerFreq', CntrPar%SD_GenCornerFreq, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_GenSpdCornerFreq', CntrPar%SD_GenSpdCornerFreq, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) CALL ParseInput(FileLines, 'SD_Time', CntrPar%SD_Time, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) CALL ParseInput(FileLines, 'SD_Method', CntrPar%SD_Method, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) CALL ParseInput(FileLines, 'SD_MaxTorqueRate', CntrPar%SD_MaxTorqueRate, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) @@ -1011,11 +1011,17 @@ SUBROUTINE CheckInputs(LocalVar, CntrPar, avrSWAP, ErrVar, size_avcMSG) ENDIF ! SD_Mode - IF ((CntrPar%SD_Mode < 0) .OR. (CntrPar%SD_Mode > 5)) THEN + IF ((CntrPar%SD_Mode < 0) .OR. (CntrPar%SD_Mode > 1)) THEN ErrVar%aviFAIL = -1 ErrVar%ErrMsg = 'SD_Mode must be 0 or 1.' ENDIF + ! SD_Mothod + IF (CntrPar%SD_Method /= 1) THEN + ErrVar%aviFAIL = -1 + ErrVar%ErrMsg = 'SD_Method must be 1.' + ENDIF + ! Fl_Mode IF ((CntrPar%Fl_Mode < 0) .OR. (CntrPar%Fl_Mode > 2)) THEN ErrVar%aviFAIL = -1 diff --git a/rosco/toolbox/controller.py b/rosco/toolbox/controller.py index 2e85558a..68c68fe2 100644 --- a/rosco/toolbox/controller.py +++ b/rosco/toolbox/controller.py @@ -106,6 +106,7 @@ def __init__(self, controller_params): self.sd_maxyawerror = controller_params['sd_maxyawerror'] self.sd_maxgenspd = controller_params['sd_maxgenspd'] self.sd_time = controller_params['sd_time'] + self.sd_method = controller_params['sd_method'] self.sd_maxtorquerate = controller_params['sd_maxtorquerate'] self.sd_maxpitchrate = controller_params['sd_maxpitchrate'] @@ -152,7 +153,7 @@ def __init__(self, controller_params): self.f_yawerr = controller_params['filter_params']['f_yawerr'] self.f_sd_pitchcornerfreq = controller_params['filter_params']['f_sd_pitchcornerfreq'] self.f_sd_yawerrorcornerfreq = controller_params['filter_params']['f_sd_yawerrorcornerfreq'] - self.f_sd_gencornerfreq = controller_params['filter_params']['f_sd_gencornerfreq'] + self.f_sd_genspdcornerfreq = controller_params['filter_params']['f_sd_genspdcornerfreq'] # Open loop parameters: set up and error catching self.OL_Mode = controller_params['OL_Mode'] diff --git a/rosco/toolbox/inputs/toolbox_schema.yaml b/rosco/toolbox/inputs/toolbox_schema.yaml index dcd7dfec..87f86d89 100644 --- a/rosco/toolbox/inputs/toolbox_schema.yaml +++ b/rosco/toolbox/inputs/toolbox_schema.yaml @@ -365,6 +365,10 @@ properties: type: number default: 9999 unit: s + sd_method: + description: Shutdown method {Only 1 supported for now} + type: number + default: 1 sd_maxtorquerate: description: Maximum torque rate for shutdown, [Nm/s], {default = 99999 Nm/s., High value to simulate instant cuttoff} type: number @@ -526,7 +530,7 @@ properties: type: number default: 0.41888 unit: rad/s - f_sd_gencornerfreq: + f_sd_genspdcornerfreq: description: utoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s], {default = 0.41888 ~ time constant of 15s} type: number default: 0.41888 @@ -1112,7 +1116,7 @@ properties: type: number description: Maximum generator speed to initiate shutdown units: rad/s - SD_GenCornerFreq: + SD_GenSpdCornerFreq: type: number description: Cutoff Frequency for first order low-pass filter for generator speed for shutdown units: rad/s diff --git a/rosco/toolbox/utilities.py b/rosco/toolbox/utilities.py index ea45ca01..dac1a27a 100644 --- a/rosco/toolbox/utilities.py +++ b/rosco/toolbox/utilities.py @@ -242,9 +242,9 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('{:<014.5f} ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​\n'.format(rosco_vt['SD_MaxYawError'])) file.write('{:<014.5f} ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s]\n'.format(rosco_vt['SD_YawErrorCornerFreq'])) file.write('{:<014.5f} ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​\n'.format(rosco_vt['SD_MaxGenSpd'])) - file.write('{:<014.5f} ! SD_GenCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​\n'.format(rosco_vt['SD_GenCornerFreq'])) + file.write('{:<014.5f} ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​\n'.format(rosco_vt['SD_GenSpdCornerFreq'])) file.write('{:<014.5f} ! SD_Time - Shutdown time, [s]​\n'.format(rosco_vt['SD_Time'])) - file.write('{:<012d} ! SD_Method - Shutdown method {{1: Reduce generator torque and increase blade pitch}},​ [-]​\n'.format(rosco_vt['SD_Method'])) + file.write('{:<12d} ! SD_Method - Shutdown method {{1: Reduce generator torque and increase blade pitch}},​ [-]​\n'.format(rosco_vt['SD_Method'])) file.write('{:<014.5f} ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​\n'.format(rosco_vt['SD_MaxTorqueRate'])) file.write('{:<014.5f} ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​\n'.format(rosco_vt['SD_MaxPitchRate'])) file.write('\n') @@ -623,9 +623,9 @@ def DISCON_dict(turbine, controller, txt_filename=None): DISCON_dict['SD_MaxYawError'] = controller.sd_maxyawerror DISCON_dict['SD_YawErrorCornerFreq'] = controller.f_sd_yawerrorcornerfreq DISCON_dict['SD_MaxGenSpd'] = controller.sd_maxgenspd - DISCON_dict['SD_GenCornerFreq'] = controller.f_sd_gencornerfreq + DISCON_dict['SD_GenSpdCornerFreq'] = controller.f_sd_genspdcornerfreq DISCON_dict['SD_Time'] = controller.sd_time - DISCON_dict['SD_Method'] = controller.sd_enablegenspeed + DISCON_dict['SD_Method'] = controller.sd_method DISCON_dict['SD_MaxTorqueRate'] = controller.sd_maxtorquerate DISCON_dict['SD_MaxPitchRate'] = controller.sd_maxpitchrate # ------- Floating ------- From 8715a02ed9f297163fead85dfe97eed2c94a0b5e Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Wed, 13 Nov 2024 11:57:00 -0700 Subject: [PATCH 03/33] shutdown: add torque control to shutdown and other small changes --- Examples/30_shutdown.py | 51 ++++++------ rosco/controller/src/ControllerBlocks.f90 | 4 +- rosco/controller/src/Controllers.f90 | 98 ++++++++++++----------- rosco/controller/src/DISCON.F90 | 2 +- rosco/controller/src/ROSCO_IO.f90 | 6 +- 5 files changed, 87 insertions(+), 74 deletions(-) diff --git a/Examples/30_shutdown.py b/Examples/30_shutdown.py index c06f4af0..acd2739b 100644 --- a/Examples/30_shutdown.py +++ b/Examples/30_shutdown.py @@ -12,6 +12,7 @@ from rosco.toolbox import controller as ROSCO_controller rpm2RadSec = 2.0 * (np.pi) / 60.0 +deg2rad = np.pi/180.0 # directories this_dir = os.path.dirname(os.path.abspath(__file__)) @@ -19,7 +20,6 @@ os.makedirs(example_out_dir, exist_ok=True) - def main(): # Test Config FULL_TEST = False # FULL_TEST for local testing, otherwise shorter for CI @@ -31,17 +31,21 @@ def main(): controller_params = {} controller_params["DISCON"] = {} controller_params["DISCON"]["Echo"] = 1 + controller_params["LoggingLevel"] = 3 controller_params["SD_Mode"] = 1 - # controller_params["DISCON"]["SD_EnablePitch"] = 1 - # controller_params["DISCON"]["SD_MaxPit"] = 0.5236 - controller_params["DISCON"]["SD_EnableGenSpeed"] = 1 - controller_params["DISCON"]["SD_MaxGenSpd"] = 12*2*3.1415/60 - # controller_params["DISCON"]["SD_EnableTime"] = 1 - # controller_params["DISCON"]["SD_Time"] = 75 - controller_params['DISCON']['PRC_Mode'] = 2 - controller_params['DISCON']['PRC_Comm'] = 0 - controller_params['DISCON']['PRC_R_Speed'] = 2.0 - controller_params['DISCON']['OL_BP_FiltFreq'] = 2 * np.pi / 30 + # controller_params["DISCON"]["PA_Mode"] = 0 + controller_params["DISCON"]["SD_EnablePitch"] = 1 + controller_params["DISCON"]["SD_MaxPit"] = 0.523599 + controller_params["DISCON"]["SD_MaxPitchRate"] = 1 + controller_params["DISCON"]["SD_MaxTorqueRate"] = 10000000.0 + # controller_params["DISCON"]["SD_EnableGenSpeed"] = 1 + # controller_params["DISCON"]["SD_MaxGenSpd"] = 12*2*3.1415/60 + controller_params["DISCON"]["SD_EnableTime"] = 1 + controller_params["DISCON"]["SD_Time"] = 20 + # controller_params['DISCON']['PRC_Mode'] = 2 + # controller_params['DISCON']['PRC_Comm'] = 0 + # controller_params['DISCON']['PRC_R_Speed'] = 2.0 + # # controller_params['DISCON']['OL_BP_FiltFreq'] = 2 * np.pi / 30 # simulation set up r = run_FAST_ROSCO() @@ -63,22 +67,21 @@ def main(): # 4. Shutdown at a particular time if sim_config == 1: - t_max = 120 + t_max = 80 run_dir = os.path.join(example_out_dir, "30_shutdown_demo/1_pitch") - # Wind case r.wind_case_fcn = cl.ramp r.wind_case_opts = { - "U_start": 4, - "U_end": 30, + "U_start": 25, + "U_end": 50, "t_start": 0, "t_end": t_max, } - r.case_inputs[("ElastoDyn", "BlPitch1")] = {"vals": [10.0], "group": 0} - r.case_inputs[("ElastoDyn", "BlPitch2")] = {"vals": [10.0], "group": 0} - r.case_inputs[("ElastoDyn", "BlPitch3")] = {"vals": [10.0], "group": 0} + r.case_inputs[("ElastoDyn", "BlPitch1")] = {"vals": [20.0], "group": 0} + r.case_inputs[("ElastoDyn", "BlPitch2")] = {"vals": [20.0], "group": 0} + r.case_inputs[("ElastoDyn", "BlPitch3")] = {"vals": [20.0], "group": 0} r.case_inputs[("ElastoDyn", "RotSpeed")] = {"vals": [10.0], "group": 0} # fig, ax = olc.plot_series() @@ -92,15 +95,17 @@ def main(): r.run_FAST() from rosco.toolbox.ofTools.fast_io import output_processing - outfile = [os.path.join(run_dir,'IEA15MW','ramp','base','IEA15MW_0.outb')] - + + outfile = [os.path.join(run_dir, "IEA15MW", "ramp", "base", "IEA15MW_0.outb")] + cases = {} - cases['Baseline'] = ['Wind1VelX', 'BldPitch1', 'GenTq', 'RotSpeed','GenPwr'] + cases["Baseline"] = ["Wind1VelX", "BldPitch1", "GenTq", "RotSpeed", "GenPwr"] fast_out = output_processing.output_processing() fastout = fast_out.load_fast_out(outfile) - fast_out.plot_fast_out(cases=cases,showplot=False) + fast_out.plot_fast_out(cases=cases, showplot=False) + + plt.savefig(os.path.join(example_out_dir, "30_shutdown_pitch.png")) - plt.savefig(os.path.join(example_out_dir,'30_shutdown_pitch.png')) if __name__ == "__main__": main() diff --git a/rosco/controller/src/ControllerBlocks.f90 b/rosco/controller/src/ControllerBlocks.f90 index 9c9057f0..fbb82bcc 100644 --- a/rosco/controller/src/ControllerBlocks.f90 +++ b/rosco/controller/src/ControllerBlocks.f90 @@ -512,7 +512,7 @@ REAL(DbKi) FUNCTION PitchSaturation(LocalVar, CntrPar, objInst, DebugVar, ErrVar END FUNCTION PitchSaturation !------------------------------------------------------------------------------------------------------------------------------- - SUBROUTINE ShutdownCheck(LocalVar, CntrPar, objInst,ErrVar) + SUBROUTINE Shutdown(LocalVar, CntrPar, objInst,ErrVar) ! Check for shutdown USE ROSCO_Types, ONLY : LocalVariables, ControlParameters, ObjectInstances IMPLICIT NONE @@ -563,7 +563,7 @@ SUBROUTINE ShutdownCheck(LocalVar, CntrPar, objInst,ErrVar) ErrVar%ErrMsg = RoutineName//':'//TRIM(ErrVar%ErrMsg) ENDIF - END SUBROUTINE ShutdownCheck + END SUBROUTINE Shutdown !------------------------------------------------------------------------------------------------------------------------------- !------------------------------------------------------------------------------------------------------------------------------- SUBROUTINE RefSpeedExclusion(LocalVar, CntrPar, objInst, DebugVar) diff --git a/rosco/controller/src/Controllers.f90 b/rosco/controller/src/Controllers.f90 index 2be4f26f..1ee17bef 100644 --- a/rosco/controller/src/Controllers.f90 +++ b/rosco/controller/src/Controllers.f90 @@ -90,10 +90,10 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst, DebugVar, ErrVar) ENDIF ! Shutdown - IF (LocalVar%SD_Trigger /= 0) THEN IF (CntrPar%SD_Method == 1) THEN !Only SD_Method==1 supported for now LocalVar%PC_PitComT = LocalVar%BlPitchCMeas + CntrPar%SD_MaxPitchRate*LocalVar%DT + !LocalVar%PC_PitComT = ratelimit(LocalVar%BlPitchCMeas, CntrPar%SD_MaxPitchRate, CntrPar%SD_MaxPitchRate,LocalVar%DT, LocalVar%restart, LocalVar%rlP,objInst%instRL,LocalVar%BlPitchCMeas) ENDIF ENDIF @@ -142,7 +142,8 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst, DebugVar, ErrVar) IF (CntrPar%AWC_Mode > 0) THEN CALL ActiveWakeControl(CntrPar, LocalVar, DebugVar) ENDIF - + !AG: Place shutdown here + ! AG: Put in a warning if SD_MaxPitchRate > PC_MaxRat ! Place pitch actuator here, so it can be used with or without open-loop DO K = 1,LocalVar%NumBl ! Loop through all blades, add IPC contribution and limit pitch rate IF (CntrPar%PA_Mode > 0) THEN @@ -208,53 +209,60 @@ SUBROUTINE VariableSpeedControl(avrSWAP, CntrPar, LocalVar, objInst, ErrVar) ! -------- Variable-Speed Torque Controller -------- ! Define max torque - IF (LocalVar%VS_State == 4) THEN - LocalVar%VS_MaxTq = CntrPar%VS_RtTq * LocalVar%PRC_R_Torque - ELSE + IF (LocalVar%SD_Trigger == 0) THEN + IF (LocalVar%VS_State == 4) THEN LocalVar%VS_MaxTq = CntrPar%VS_RtTq * LocalVar%PRC_R_Torque - ENDIF - - ! Optimal Tip-Speed-Ratio tracking controller - IF ((CntrPar%VS_ControlMode == 2) .OR. (CntrPar%VS_ControlMode == 3)) THEN - ! Constant Power, update VS_MaxTq - IF (CntrPar%VS_ConstPower == 1) THEN - LocalVar%VS_MaxTq = min((CntrPar%VS_RtPwr * LocalVar%PRC_R_Torque /(CntrPar%VS_GenEff/100.0))/LocalVar%GenSpeedF, CntrPar%VS_MaxTq) - END IF - - ! PI controller - LocalVar%GenTq = PIController( & - LocalVar%VS_SpdErr, & - CntrPar%VS_KP(1), & - CntrPar%VS_KI(1), & - CntrPar%VS_MinTq, LocalVar%VS_MaxTq, & - LocalVar%DT, LocalVar%VS_LastGenTrq, LocalVar%piP, LocalVar%restart, objInst%instPI) - LocalVar%GenTq = saturate(LocalVar%GenTq, CntrPar%VS_MinTq, LocalVar%VS_MaxTq) - - ! K*Omega^2 control law with PI torque control in transition regions - ELSEIF (CntrPar%VS_ControlMode == 1) THEN - ! 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_MaxOMTq, LocalVar%piP, LocalVar%restart, 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, LocalVar%piP, LocalVar%restart, objInst%instPI) + ELSE + LocalVar%VS_MaxTq = CntrPar%VS_RtTq * LocalVar%PRC_R_Torque + ENDIF - ! The action - IF (LocalVar%VS_State == 1) THEN ! Region 1.5 - LocalVar%GenTq = LocalVar%GenBrTq - ELSEIF (LocalVar%VS_State == 2) THEN ! Region 2 - LocalVar%GenTq = CntrPar%VS_Rgn2K*LocalVar%GenSpeedF*LocalVar%GenSpeedF - ELSEIF (LocalVar%VS_State == 3) THEN ! Region 2.5 - LocalVar%GenTq = LocalVar%GenArTq - ELSEIF (LocalVar%VS_State == 4) THEN ! Region 3, constant torque - LocalVar%GenTq = CntrPar%VS_RtTq - ELSEIF (LocalVar%VS_State == 5) THEN ! Region 3, constant power - LocalVar%GenTq = (CntrPar%VS_RtPwr/(CntrPar%VS_GenEff/100.0))/LocalVar%GenSpeedF - END IF + ! Optimal Tip-Speed-Ratio tracking controller + IF ((CntrPar%VS_ControlMode == 2) .OR. (CntrPar%VS_ControlMode == 3)) THEN + ! Constant Power, update VS_MaxTq + IF (CntrPar%VS_ConstPower == 1) THEN + LocalVar%VS_MaxTq = min((CntrPar%VS_RtPwr * LocalVar%PRC_R_Torque /(CntrPar%VS_GenEff/100.0))/LocalVar%GenSpeedF, CntrPar%VS_MaxTq) + END IF + + ! PI controller + LocalVar%GenTq = PIController( & + LocalVar%VS_SpdErr, & + CntrPar%VS_KP(1), & + CntrPar%VS_KI(1), & + CntrPar%VS_MinTq, LocalVar%VS_MaxTq, & + LocalVar%DT, LocalVar%VS_LastGenTrq, LocalVar%piP, LocalVar%restart, objInst%instPI) + LocalVar%GenTq = saturate(LocalVar%GenTq, CntrPar%VS_MinTq, LocalVar%VS_MaxTq) - ! Saturate - LocalVar%GenTq = saturate(LocalVar%GenTq, CntrPar%VS_MinTq, CntrPar%VS_MaxTq) - ELSE ! VS_ControlMode of 0 - LocalVar%GenTq = 0 + ! K*Omega^2 control law with PI torque control in transition regions + ELSEIF (CntrPar%VS_ControlMode == 1) THEN + ! 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_MaxOMTq, LocalVar%piP, LocalVar%restart, 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, LocalVar%piP, LocalVar%restart, 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 + LocalVar%GenTq = CntrPar%VS_Rgn2K*LocalVar%GenSpeedF*LocalVar%GenSpeedF + ELSEIF (LocalVar%VS_State == 3) THEN ! Region 2.5 + LocalVar%GenTq = LocalVar%GenArTq + ELSEIF (LocalVar%VS_State == 4) THEN ! Region 3, constant torque + LocalVar%GenTq = CntrPar%VS_RtTq + 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, CntrPar%VS_MaxTq) + ELSE ! VS_ControlMode of 0 + LocalVar%GenTq = 0 + ENDIF + ELSE + IF (CntrPar%SD_Method == 1) THEN !Only SD_Method==1 supported for now + LocalVar%GenTq = LocalVar%GenTq - CntrPar%SD_MaxTorqueRate*LocalVar%DT + LocalVar%GenTq = saturate(LocalVar%GenTq, CntrPar%VS_MinTq, CntrPar%VS_MaxTq) + ENDIF ENDIF - + ! Saturate the commanded torque using the maximum torque limit: LocalVar%GenTq = MIN(LocalVar%GenTq, CntrPar%VS_MaxTq) ! Saturate the command using the maximum torque limit diff --git a/rosco/controller/src/DISCON.F90 b/rosco/controller/src/DISCON.F90 index 02081bfe..32a04ea4 100644 --- a/rosco/controller/src/DISCON.F90 +++ b/rosco/controller/src/DISCON.F90 @@ -100,7 +100,7 @@ SUBROUTINE DISCON(avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAME CALL UpdateZeroMQ(LocalVar, CntrPar, ErrVar) ENDIF - CALL ShutdownCheck(LocalVar, CntrPar, objInst,ErrVar) + CALL Shutdown(LocalVar, CntrPar, objInst,ErrVar) CALL WindSpeedEstimator(LocalVar, CntrPar, objInst, PerfData, DebugVar, ErrVar) CALL ComputeVariablesSetpoints(CntrPar, LocalVar, objInst, DebugVar, ErrVar) CALL StateMachine(CntrPar, LocalVar) diff --git a/rosco/controller/src/ROSCO_IO.f90 b/rosco/controller/src/ROSCO_IO.f90 index 33b2bddc..f2cb05f9 100644 --- a/rosco/controller/src/ROSCO_IO.f90 +++ b/rosco/controller/src/ROSCO_IO.f90 @@ -156,7 +156,7 @@ SUBROUTINE WriteRestartFile(LocalVar, CntrPar, ErrVar, objInst, RootName, size_a WRITE( Un, IOSTAT=ErrStat) LocalVar%PRC_Min_Pitch WRITE( Un, IOSTAT=ErrStat) LocalVar%PS_Min_Pitch WRITE( Un, IOSTAT=ErrStat) LocalVar%OL_Index - WRITE( Un, IOSTAT=ErrStat) LocalVar%SD + WRITE( Un, IOSTAT=ErrStat) LocalVar%SD_Trigger WRITE( Un, IOSTAT=ErrStat) LocalVar%Fl_PitCom WRITE( Un, IOSTAT=ErrStat) LocalVar%NACIMU_FA_AccF WRITE( Un, IOSTAT=ErrStat) LocalVar%FA_AccF @@ -473,7 +473,7 @@ SUBROUTINE ReadRestartFile(avrSWAP, LocalVar, CntrPar, objInst, PerfData, RootNa READ( Un, IOSTAT=ErrStat) LocalVar%PRC_Min_Pitch READ( Un, IOSTAT=ErrStat) LocalVar%PS_Min_Pitch READ( Un, IOSTAT=ErrStat) LocalVar%OL_Index - READ( Un, IOSTAT=ErrStat) LocalVar%SD + READ( Un, IOSTAT=ErrStat) LocalVar%SD_Trigger READ( Un, IOSTAT=ErrStat) LocalVar%Fl_PitCom READ( Un, IOSTAT=ErrStat) LocalVar%NACIMU_FA_AccF READ( Un, IOSTAT=ErrStat) LocalVar%FA_AccF @@ -993,4 +993,4 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av ENDIF END SUBROUTINE Debug -END MODULE ROSCO_IO \ No newline at end of file +END MODULE ROSCO_IO From 46c53f826bcefce84b5772ad74775f82dc1093c2 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Fri, 15 Nov 2024 10:04:08 -0700 Subject: [PATCH 04/33] shutdown: Run rosco controller registry to add shutdown variables --- .../rosco_registry/rosco_types.yaml | 4 +-- rosco/controller/src/ROSCO_IO.f90 | 2 +- rosco/controller/src/ROSCO_Types.f90 | 32 +++++++++---------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/rosco/controller/rosco_registry/rosco_types.yaml b/rosco/controller/rosco_registry/rosco_types.yaml index 6067e64f..289e70a8 100644 --- a/rosco/controller/rosco_registry/rosco_types.yaml +++ b/rosco/controller/rosco_registry/rosco_types.yaml @@ -251,7 +251,7 @@ ControlParameters: PC_MaxRat: <<: *real description: Maximum pitch rate (in absolute value) in pitch controller, [rad/s]. - : + PC_MinRat: <<: *real description: Minimum pitch rate (in absolute value) in pitch controller, [rad/s]. PC_RefSpd: @@ -500,7 +500,7 @@ ControlParameters: description: Shutdown time, [s] SD_Method: <<: *integer - description: Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] + description: Shutdown method {1 - Reduce generator torque and increase blade pitch}, [-] SD_MaxTorqueRate: <<: *real description: Maximum torque rate for shutdown, [Nm/s] diff --git a/rosco/controller/src/ROSCO_IO.f90 b/rosco/controller/src/ROSCO_IO.f90 index f2cb05f9..8761d284 100644 --- a/rosco/controller/src/ROSCO_IO.f90 +++ b/rosco/controller/src/ROSCO_IO.f90 @@ -993,4 +993,4 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av ENDIF END SUBROUTINE Debug -END MODULE ROSCO_IO +END MODULE ROSCO_IO \ No newline at end of file diff --git a/rosco/controller/src/ROSCO_Types.f90 b/rosco/controller/src/ROSCO_Types.f90 index da3d4b3d..980e5b2b 100644 --- a/rosco/controller/src/ROSCO_Types.f90 +++ b/rosco/controller/src/ROSCO_Types.f90 @@ -119,21 +119,21 @@ MODULE ROSCO_Types INTEGER(IntKi) :: PS_BldPitchMin_N ! Number of values in minimum blade pitch lookup table (should equal number of values in PS_WindSpeeds and PS_BldPitchMin) REAL(DbKi), DIMENSION(:), ALLOCATABLE :: PS_WindSpeeds ! Wind speeds corresponding to minimum blade pitch angles [m/s] REAL(DbKi), DIMENSION(:), ALLOCATABLE :: PS_BldPitchMin ! Minimum blade pitch angles [rad] - INTEGER(IntKi) :: SD_Mode ! Shutdown mode {0 - no shutdown procedure, 1 - shutdown enabled} - INTEGER(IntKi) :: SD_EnablePitch ! Shutdown when collective blade pitch exceeds a threshold, [-] - INTEGER(IntKi) :: SD_EnableYawError ! Shutdown when yaw error exceeds a threshold, [-] - INTEGER(IntKi) :: SD_EnableGenSpeed ! Shutdown when generator speed exceeds a threshold, [-] - INTEGER(IntKi) :: SD_EnableTime ! Shutdown at a predefined time, [-] + INTEGER(IntKi) :: SD_Mode ! Shutdown mode {0 - no shutdown procedure, 1 - enable shutdown} + INTEGER(IntKi) :: SD_EnablePitch ! Shutdown when collective blade pitch exceeds a threshold, [-] + INTEGER(IntKi) :: SD_EnableYawError ! Shutdown when yaw error exceeds a threshold, [-] + INTEGER(IntKi) :: SD_EnableGenSpeed ! Shutdown when generator speed exceeds a threshold, [-] + INTEGER(IntKi) :: SD_EnableTime ! Shutdown at a predefined time, [-] REAL(DbKi) :: SD_MaxPit ! Maximum blade pitch angle to initiate shutdown, [rad] - REAL(DbKi) :: SD_PitchCornerFreq ! Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] - REAL(DbKi) :: SD_MaxYawError ! Maximum yaw error to initiate shutdown, [rad] - REAL(DbKi) :: SD_YawErrorCornerFreq ! Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] - REAL(DbKi) :: SD_MaxGenSpd ! Maximum generator speed to initiate shutdown, [rad/s] - REAL(DbKi) :: SD_GenSpdCornerFreq ! Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] - REAL(DbKi) :: SD_Time ! Shutdown time, [s] - INTEGER(IntKi) :: SD_Method ! Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] - REAL(DbKi) :: SD_MaxTorqueRate ! Maximum torque rate for shutdown, [Nm/s] - REAL(DbKi) :: SD_MaxPitchRate ! Maximum pitch rate used for shutdown, [rad/s] + REAL(DbKi) :: SD_PitchCornerFreq ! Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] + REAL(DbKi) :: SD_MaxYawError ! Maximum yaw error to initiate shutdown, [rad] + REAL(DbKi) :: SD_YawErrorCornerFreq ! Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] + REAL(DbKi) :: SD_MaxGenSpd ! Maximum generator speed to initiate shutdown, [rad/s] + REAL(DbKi) :: SD_GenSpdCornerFreq ! Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] + REAL(DbKi) :: SD_Time ! Shutdown time, [s] + INTEGER(IntKi) :: SD_Method ! Shutdown method {1 - Reduce generator torque and increase blade pitch}, [-] + REAL(DbKi) :: SD_MaxTorqueRate ! Maximum torque rate for shutdown, [Nm/s] + REAL(DbKi) :: SD_MaxPitchRate ! Maximum pitch rate used for shutdown, [rad/s] INTEGER(IntKi) :: Fl_Mode ! Floating specific feedback mode {0 - no nacelle velocity feedback, 1 - nacelle velocity feedback} INTEGER(IntKi) :: Fl_n ! Number of Fl_Kp for gain scheduling REAL(DbKi), DIMENSION(:), ALLOCATABLE :: Fl_Kp ! Nacelle velocity proportional feedback gain [s] @@ -375,7 +375,7 @@ MODULE ROSCO_Types REAL(DbKi) :: PRC_Min_Pitch ! Instantaneous PRC_Min_Pitch REAL(DbKi) :: PS_Min_Pitch ! Instantaneous peak shaving REAL(DbKi) :: OL_Index ! Open loop indexing variable (time or wind speed) - INTEGER(IntKi) :: SD_Trigger ! Shutdown, .FALSE. if inactive, .TRUE. if active + LOGICAL :: SD_Trigger ! Shutdown, .FALSE. if inactive, .TRUE. if active REAL(DbKi) :: Fl_PitCom ! Shutdown, .FALSE. if inactive, .TRUE. if active REAL(DbKi) :: NACIMU_FA_AccF ! None REAL(DbKi) :: FA_AccF ! None @@ -490,4 +490,4 @@ MODULE ROSCO_Types REAL(ReKi), DIMENSION(:), ALLOCATABLE :: avrSWAP ! The swap array- used to pass data to and from the DLL controller [see Bladed DLL documentation] END TYPE ExtControlType -END MODULE ROSCO_Types +END MODULE ROSCO_Types \ No newline at end of file From d8f05ecc68d5f371c34c1d8a7427d7df6ebf5edb Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Fri, 15 Nov 2024 10:18:49 -0700 Subject: [PATCH 05/33] Shutdown: Fix registry to solve build issue --- .../rosco_registry/rosco_types.yaml | 4 +- rosco/controller/src/Controllers.f90 | 19 ++-- rosco/controller/src/ROSCO_IO.f90 | 104 +++++++++--------- rosco/controller/src/ROSCO_Types.f90 | 2 +- rosco/controller/src/ReadSetParameters.f90 | 19 +++- 5 files changed, 79 insertions(+), 69 deletions(-) diff --git a/rosco/controller/rosco_registry/rosco_types.yaml b/rosco/controller/rosco_registry/rosco_types.yaml index 289e70a8..d2966daf 100644 --- a/rosco/controller/rosco_registry/rosco_types.yaml +++ b/rosco/controller/rosco_registry/rosco_types.yaml @@ -1323,8 +1323,8 @@ LocalVariables: <<: *real description: Open loop indexing variable (time or wind speed) SD_Trigger: - <<: *logical - description: Shutdown, .FALSE. if inactive, .TRUE. if active + <<: *integer + description: Shutdown trigger (1 - shutdown due to pitch, 2 - shutdown due to yaw error, 3 - shutdown due to generator speed, 4 - shutdown due to time) Fl_PitCom: <<: *real description: Shutdown, .FALSE. if inactive, .TRUE. if active diff --git a/rosco/controller/src/Controllers.f90 b/rosco/controller/src/Controllers.f90 index 1ee17bef..732a032c 100644 --- a/rosco/controller/src/Controllers.f90 +++ b/rosco/controller/src/Controllers.f90 @@ -88,14 +88,6 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst, DebugVar, ErrVar) DebugVar%FL_PitCom = LocalVar%Fl_PitCom LocalVar%PC_PitComT = LocalVar%PC_PitComT + LocalVar%Fl_PitCom ENDIF - - ! Shutdown - IF (LocalVar%SD_Trigger /= 0) THEN - IF (CntrPar%SD_Method == 1) THEN !Only SD_Method==1 supported for now - LocalVar%PC_PitComT = LocalVar%BlPitchCMeas + CntrPar%SD_MaxPitchRate*LocalVar%DT - !LocalVar%PC_PitComT = ratelimit(LocalVar%BlPitchCMeas, CntrPar%SD_MaxPitchRate, CntrPar%SD_MaxPitchRate,LocalVar%DT, LocalVar%restart, LocalVar%rlP,objInst%instRL,LocalVar%BlPitchCMeas) - ENDIF - 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 @@ -142,7 +134,16 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst, DebugVar, ErrVar) IF (CntrPar%AWC_Mode > 0) THEN CALL ActiveWakeControl(CntrPar, LocalVar, DebugVar) ENDIF - !AG: Place shutdown here + + ! Shutdown + IF (LocalVar%SD_Trigger /= 0) THEN + IF (CntrPar%SD_Method == 1) THEN !Only SD_Method==1 supported for now + LocalVar%PC_PitComT = LocalVar%BlPitchCMeas + CntrPar%SD_MaxPitchRate*LocalVar%DT + !LocalVar%PC_PitComT = ratelimit(LocalVar%BlPitchCMeas, CntrPar%SD_MaxPitchRate, CntrPar%SD_MaxPitchRate,LocalVar%DT, LocalVar%restart, LocalVar%rlP,objInst%instRL,LocalVar%BlPitchCMeas) + ENDIF + ENDIF + + ! AG: Put in a warning if SD_MaxPitchRate > PC_MaxRat ! Place pitch actuator here, so it can be used with or without open-loop DO K = 1,LocalVar%NumBl ! Loop through all blades, add IPC contribution and limit pitch rate diff --git a/rosco/controller/src/ROSCO_IO.f90 b/rosco/controller/src/ROSCO_IO.f90 index 8761d284..41517ca7 100644 --- a/rosco/controller/src/ROSCO_IO.f90 +++ b/rosco/controller/src/ROSCO_IO.f90 @@ -722,7 +722,7 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av '[N/A]', '[N/A]', '[N/A]', '[N/A]', '[rad/s]', & '[deg]', '[deg]', '[deg]', '[N/A]', '[rad/s]', & '[rad/s]'] - nLocalVars = 139 + nLocalVars = 140 Allocate(LocalVarOutData(nLocalVars)) Allocate(LocalVarOutStrings(nLocalVars)) LocalVarOutData(1) = LocalVar%iStatus @@ -825,45 +825,46 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av LocalVarOutData(98) = LocalVar%PRC_Min_Pitch LocalVarOutData(99) = LocalVar%PS_Min_Pitch LocalVarOutData(100) = LocalVar%OL_Index - LocalVarOutData(101) = LocalVar%Fl_PitCom - LocalVarOutData(102) = LocalVar%NACIMU_FA_AccF - LocalVarOutData(103) = LocalVar%FA_AccF - LocalVarOutData(104) = LocalVar%FA_Hist - LocalVarOutData(105) = LocalVar%TRA_LastRefSpd - LocalVarOutData(106) = LocalVar%VS_RefSpeed - LocalVarOutData(107) = LocalVar%PtfmTDX - LocalVarOutData(108) = LocalVar%PtfmTDY - LocalVarOutData(109) = LocalVar%PtfmTDZ - LocalVarOutData(110) = LocalVar%PtfmRDX - LocalVarOutData(111) = LocalVar%PtfmRDY - LocalVarOutData(112) = LocalVar%PtfmRDZ - LocalVarOutData(113) = LocalVar%PtfmTVX - LocalVarOutData(114) = LocalVar%PtfmTVY - LocalVarOutData(115) = LocalVar%PtfmTVZ - LocalVarOutData(116) = LocalVar%PtfmRVX - LocalVarOutData(117) = LocalVar%PtfmRVY - LocalVarOutData(118) = LocalVar%PtfmRVZ - LocalVarOutData(119) = LocalVar%PtfmTAX - LocalVarOutData(120) = LocalVar%PtfmTAY - LocalVarOutData(121) = LocalVar%PtfmTAZ - LocalVarOutData(122) = LocalVar%PtfmRAX - LocalVarOutData(123) = LocalVar%PtfmRAY - LocalVarOutData(124) = LocalVar%PtfmRAZ - LocalVarOutData(125) = LocalVar%CC_DesiredL(1) - LocalVarOutData(126) = LocalVar%CC_ActuatedL(1) - LocalVarOutData(127) = LocalVar%CC_ActuatedDL(1) - LocalVarOutData(128) = LocalVar%StC_Input(1) - LocalVarOutData(129) = LocalVar%Flp_Angle(1) - LocalVarOutData(130) = LocalVar%RootMyb_Last(1) - LocalVarOutData(131) = LocalVar%ACC_INFILE_SIZE - LocalVarOutData(132) = LocalVar%AWC_complexangle(1) - LocalVarOutData(133) = LocalVar%ZMQ_ID - LocalVarOutData(134) = LocalVar%ZMQ_YawOffset - LocalVarOutData(135) = LocalVar%ZMQ_TorqueOffset - LocalVarOutData(136) = LocalVar%ZMQ_PitOffset(1) - LocalVarOutData(137) = LocalVar%ZMQ_R_Speed - LocalVarOutData(138) = LocalVar%ZMQ_R_Torque - LocalVarOutData(139) = LocalVar%ZMQ_R_Pitch + LocalVarOutData(101) = LocalVar%SD_Trigger + LocalVarOutData(102) = LocalVar%Fl_PitCom + LocalVarOutData(103) = LocalVar%NACIMU_FA_AccF + LocalVarOutData(104) = LocalVar%FA_AccF + LocalVarOutData(105) = LocalVar%FA_Hist + LocalVarOutData(106) = LocalVar%TRA_LastRefSpd + LocalVarOutData(107) = LocalVar%VS_RefSpeed + LocalVarOutData(108) = LocalVar%PtfmTDX + LocalVarOutData(109) = LocalVar%PtfmTDY + LocalVarOutData(110) = LocalVar%PtfmTDZ + LocalVarOutData(111) = LocalVar%PtfmRDX + LocalVarOutData(112) = LocalVar%PtfmRDY + LocalVarOutData(113) = LocalVar%PtfmRDZ + LocalVarOutData(114) = LocalVar%PtfmTVX + LocalVarOutData(115) = LocalVar%PtfmTVY + LocalVarOutData(116) = LocalVar%PtfmTVZ + LocalVarOutData(117) = LocalVar%PtfmRVX + LocalVarOutData(118) = LocalVar%PtfmRVY + LocalVarOutData(119) = LocalVar%PtfmRVZ + LocalVarOutData(120) = LocalVar%PtfmTAX + LocalVarOutData(121) = LocalVar%PtfmTAY + LocalVarOutData(122) = LocalVar%PtfmTAZ + LocalVarOutData(123) = LocalVar%PtfmRAX + LocalVarOutData(124) = LocalVar%PtfmRAY + LocalVarOutData(125) = LocalVar%PtfmRAZ + LocalVarOutData(126) = LocalVar%CC_DesiredL(1) + LocalVarOutData(127) = LocalVar%CC_ActuatedL(1) + LocalVarOutData(128) = LocalVar%CC_ActuatedDL(1) + LocalVarOutData(129) = LocalVar%StC_Input(1) + LocalVarOutData(130) = LocalVar%Flp_Angle(1) + LocalVarOutData(131) = LocalVar%RootMyb_Last(1) + LocalVarOutData(132) = LocalVar%ACC_INFILE_SIZE + LocalVarOutData(133) = LocalVar%AWC_complexangle(1) + LocalVarOutData(134) = LocalVar%ZMQ_ID + LocalVarOutData(135) = LocalVar%ZMQ_YawOffset + LocalVarOutData(136) = LocalVar%ZMQ_TorqueOffset + LocalVarOutData(137) = LocalVar%ZMQ_PitOffset(1) + LocalVarOutData(138) = LocalVar%ZMQ_R_Speed + LocalVarOutData(139) = LocalVar%ZMQ_R_Torque + LocalVarOutData(140) = LocalVar%ZMQ_R_Pitch LocalVarOutStrings = [CHARACTER(15) :: 'iStatus', 'RestartWSE', 'Time', 'DT', 'n_DT', & 'Time_Last', 'VS_GenPwr', 'VS_GenPwrF', 'GenSpeed', 'RotSpeed', & 'NacHeading', 'NacVane', 'NacVaneF', 'HorWindV', 'HorWindV_F', & @@ -884,14 +885,15 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av 'WE_Vw', 'WE_Vw_F', 'WE_VwI', 'WE_VwIdot', 'WE_Op', & 'WE_Op_Last', 'VS_LastGenTrqF', 'PRC_WSE_F', 'PRC_R_Speed', 'PRC_R_Torque', & 'PRC_R_Pitch', 'PRC_R_Total', 'PRC_Min_Pitch', 'PS_Min_Pitch', 'OL_Index', & - 'Fl_PitCom', 'NACIMU_FA_AccF', 'FA_AccF', 'FA_Hist', 'TRA_LastRefSpd', & - 'VS_RefSpeed', 'PtfmTDX', 'PtfmTDY', 'PtfmTDZ', 'PtfmRDX', & - 'PtfmRDY', 'PtfmRDZ', 'PtfmTVX', 'PtfmTVY', 'PtfmTVZ', & - 'PtfmRVX', 'PtfmRVY', 'PtfmRVZ', 'PtfmTAX', 'PtfmTAY', & - 'PtfmTAZ', 'PtfmRAX', 'PtfmRAY', 'PtfmRAZ', 'CC_DesiredL', & - 'CC_ActuatedL', 'CC_ActuatedDL', 'StC_Input', 'Flp_Angle', 'RootMyb_Last', & - 'ACC_INFILE_SIZE', 'AWC_complexangle', 'ZMQ_ID', 'ZMQ_YawOffset', 'ZMQ_TorqueOffset', & - 'ZMQ_PitOffset', 'ZMQ_R_Speed', 'ZMQ_R_Torque', 'ZMQ_R_Pitch'] + 'SD_Trigger', 'Fl_PitCom', 'NACIMU_FA_AccF', 'FA_AccF', 'FA_Hist', & + 'TRA_LastRefSpd', 'VS_RefSpeed', 'PtfmTDX', 'PtfmTDY', 'PtfmTDZ', & + 'PtfmRDX', 'PtfmRDY', 'PtfmRDZ', 'PtfmTVX', 'PtfmTVY', & + 'PtfmTVZ', 'PtfmRVX', 'PtfmRVY', 'PtfmRVZ', 'PtfmTAX', & + 'PtfmTAY', 'PtfmTAZ', 'PtfmRAX', 'PtfmRAY', 'PtfmRAZ', & + 'CC_DesiredL', 'CC_ActuatedL', 'CC_ActuatedDL', 'StC_Input', 'Flp_Angle', & + 'RootMyb_Last', 'ACC_INFILE_SIZE', 'AWC_complexangle', 'ZMQ_ID', 'ZMQ_YawOffset', & + 'ZMQ_TorqueOffset', 'ZMQ_PitOffset', 'ZMQ_R_Speed', 'ZMQ_R_Torque', 'ZMQ_R_Pitch' & + ] ! Initialize debug file IF ((LocalVar%iStatus == 0) .OR. (LocalVar%iStatus == -9)) THEN ! .TRUE. if we're on the first call to the DLL IF (CntrPar%LoggingLevel > 0) THEN @@ -906,8 +908,8 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av CALL GetNewUnit(UnDb2, ErrVar) OPEN(unit=UnDb2, FILE=TRIM(RootName)//'.RO.dbg2') WRITE(UnDb2, *) 'Generated on '//CurDate()//' at '//CurTime()//' using ROSCO-'//TRIM(rosco_version) - WRITE(UnDb2, '(140(a20,TR5:))') 'Time', LocalVarOutStrings - WRITE(UnDb2, '(140(a20,TR5:))') + WRITE(UnDb2, '(141(a20,TR5:))') 'Time', LocalVarOutStrings + WRITE(UnDb2, '(141(a20,TR5:))') END IF IF (CntrPar%LoggingLevel > 2) THEN @@ -970,7 +972,7 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av END DO ! Write debug files - FmtDat = "(F20.5,TR5,139(ES20.5E2,TR5:))" ! The format of the debugging data + FmtDat = "(F20.5,TR5,140(ES20.5E2,TR5:))" ! The format of the debugging data IF ( MOD(LocalVar%n_DT, CntrPar%n_DT_Out) == 0) THEN IF(CntrPar%LoggingLevel > 0) THEN WRITE (UnDb, TRIM(FmtDat)) LocalVar%Time, DebugOutData diff --git a/rosco/controller/src/ROSCO_Types.f90 b/rosco/controller/src/ROSCO_Types.f90 index 980e5b2b..8ec65cbd 100644 --- a/rosco/controller/src/ROSCO_Types.f90 +++ b/rosco/controller/src/ROSCO_Types.f90 @@ -375,7 +375,7 @@ MODULE ROSCO_Types REAL(DbKi) :: PRC_Min_Pitch ! Instantaneous PRC_Min_Pitch REAL(DbKi) :: PS_Min_Pitch ! Instantaneous peak shaving REAL(DbKi) :: OL_Index ! Open loop indexing variable (time or wind speed) - LOGICAL :: SD_Trigger ! Shutdown, .FALSE. if inactive, .TRUE. if active + INTEGER(IntKi) :: SD_Trigger ! Shutdown trigger (1 - shutdown due to pitch, 2 - shutdown due to yaw error, 3 - shutdown due to generator speed, 4 - shutdown due to time) REAL(DbKi) :: Fl_PitCom ! Shutdown, .FALSE. if inactive, .TRUE. if active REAL(DbKi) :: NACIMU_FA_AccF ! None REAL(DbKi) :: FA_AccF ! None diff --git a/rosco/controller/src/ReadSetParameters.f90 b/rosco/controller/src/ReadSetParameters.f90 index b7a9bbaf..be8a885a 100644 --- a/rosco/controller/src/ReadSetParameters.f90 +++ b/rosco/controller/src/ReadSetParameters.f90 @@ -1016,12 +1016,6 @@ SUBROUTINE CheckInputs(LocalVar, CntrPar, avrSWAP, ErrVar, size_avcMSG) ErrVar%ErrMsg = 'SD_Mode must be 0 or 1.' ENDIF - ! SD_Mothod - IF (CntrPar%SD_Method /= 1) THEN - ErrVar%aviFAIL = -1 - ErrVar%ErrMsg = 'SD_Method must be 1.' - ENDIF - ! Fl_Mode IF ((CntrPar%Fl_Mode < 0) .OR. (CntrPar%Fl_Mode > 2)) THEN ErrVar%aviFAIL = -1 @@ -1414,6 +1408,19 @@ SUBROUTINE CheckInputs(LocalVar, CntrPar, avrSWAP, ErrVar, size_avcMSG) ENDIF + ! --- Shutdown --- + + ! SD_Method + IF (CntrPar%SD_Method /= 1) THEN + ErrVar%aviFAIL = -1 + ErrVar%ErrMsg = 'SD_Method must be 1.' + ENDIF + + ! SD_MaxPitchRate + IF (CntrPar%SD_MaxPitchRate > CntrPar%PC_MaxRat) THEN + ErrVar%aviFAIL = -1 + ErrVar%ErrMsg = 'SD_MaxPitchRate should be less or equal to PC_MaxRat.' + ENDIF ! --- Open loop control --- IF (CntrPar%OL_Mode > 0) THEN From e4060b912130c55d0a273be1dcf73f9ea669f1a2 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Fri, 15 Nov 2024 12:57:34 -0700 Subject: [PATCH 06/33] Shutdown: Add separate shutdown variable for pitch --- Examples/30_shutdown.py | 69 +++---- .../rosco_registry/rosco_types.yaml | 7 + rosco/controller/src/Controllers.f90 | 112 ++++++----- rosco/controller/src/ROSCO_IO.f90 | 184 +++++++++--------- rosco/controller/src/ROSCO_Types.f90 | 2 + rosco/controller/src/ReadSetParameters.f90 | 6 + 6 files changed, 197 insertions(+), 183 deletions(-) diff --git a/Examples/30_shutdown.py b/Examples/30_shutdown.py index acd2739b..d319ec83 100644 --- a/Examples/30_shutdown.py +++ b/Examples/30_shutdown.py @@ -9,7 +9,7 @@ import matplotlib.pyplot as plt from rosco.toolbox.ofTools.case_gen.run_FAST import run_FAST_ROSCO from rosco.toolbox.ofTools.case_gen import CaseLibrary as cl -from rosco.toolbox import controller as ROSCO_controller +from rosco.toolbox.ofTools.fast_io import output_processing rpm2RadSec = 2.0 * (np.pi) / 60.0 deg2rad = np.pi/180.0 @@ -33,19 +33,12 @@ def main(): controller_params["DISCON"]["Echo"] = 1 controller_params["LoggingLevel"] = 3 controller_params["SD_Mode"] = 1 - # controller_params["DISCON"]["PA_Mode"] = 0 controller_params["DISCON"]["SD_EnablePitch"] = 1 - controller_params["DISCON"]["SD_MaxPit"] = 0.523599 - controller_params["DISCON"]["SD_MaxPitchRate"] = 1 - controller_params["DISCON"]["SD_MaxTorqueRate"] = 10000000.0 - # controller_params["DISCON"]["SD_EnableGenSpeed"] = 1 - # controller_params["DISCON"]["SD_MaxGenSpd"] = 12*2*3.1415/60 + controller_params["DISCON"]["SD_MaxPit"] = 30*deg2rad + controller_params["DISCON"]["SD_MaxPitchRate"] = 0.0348 + controller_params["DISCON"]["SD_MaxTorqueRate"] = 4500000 controller_params["DISCON"]["SD_EnableTime"] = 1 controller_params["DISCON"]["SD_Time"] = 20 - # controller_params['DISCON']['PRC_Mode'] = 2 - # controller_params['DISCON']['PRC_Comm'] = 0 - # controller_params['DISCON']['PRC_R_Speed'] = 2.0 - # # controller_params['DISCON']['OL_BP_FiltFreq'] = 2 * np.pi / 30 # simulation set up r = run_FAST_ROSCO() @@ -60,51 +53,39 @@ def main(): r.case_inputs[("ElastoDyn", "PtfmPDOF")] = {"vals": ["False"], "group": 0} r.case_inputs[("ElastoDyn", "PtfmYDOF")] = {"vals": ["False"], "group": 0} - sim_config = 1 - # 1. Shutdown due to pitch exceeding threshold - # 2. Shutdown due to yaw error exceeding threshold - # 3. Shutdown due to generator speed exceeding threshold - # 4. Shutdown at a particular time - - if sim_config == 1: - t_max = 80 - - run_dir = os.path.join(example_out_dir, "30_shutdown_demo/1_pitch") - - # Wind case - r.wind_case_fcn = cl.ramp - r.wind_case_opts = { - "U_start": 25, - "U_end": 50, - "t_start": 0, - "t_end": t_max, - } - r.case_inputs[("ElastoDyn", "BlPitch1")] = {"vals": [20.0], "group": 0} - r.case_inputs[("ElastoDyn", "BlPitch2")] = {"vals": [20.0], "group": 0} - r.case_inputs[("ElastoDyn", "BlPitch3")] = {"vals": [20.0], "group": 0} - r.case_inputs[("ElastoDyn", "RotSpeed")] = {"vals": [10.0], "group": 0} - - # fig, ax = olc.plot_series() - # fig.savefig(os.path.join(example_out_dir, "29_OL_Inputs.png")) - - # Write open loop input, get OL indices - os.makedirs(run_dir, exist_ok=True) + t_max = 80 + + run_dir = os.path.join(example_out_dir, "30_shutdown_demo/1_pitch") + + # Wind case + r.wind_case_fcn = cl.ramp + r.wind_case_opts = { + "U_start": 25, + "U_end": 50, + "t_start": 0, + "t_end": t_max, + } + r.case_inputs[("ElastoDyn", "BlPitch1")] = {"vals": [20.0], "group": 0} + r.case_inputs[("ElastoDyn", "BlPitch2")] = {"vals": [20.0], "group": 0} + r.case_inputs[("ElastoDyn", "BlPitch3")] = {"vals": [20.0], "group": 0} + r.case_inputs[("ElastoDyn", "RotSpeed")] = {"vals": [10.0], "group": 0} + + # Run simulation + os.makedirs(run_dir, exist_ok=True) r.controller_params = controller_params r.save_dir = run_dir r.run_FAST() - from rosco.toolbox.ofTools.fast_io import output_processing - + # Plot output outfile = [os.path.join(run_dir, "IEA15MW", "ramp", "base", "IEA15MW_0.outb")] - cases = {} cases["Baseline"] = ["Wind1VelX", "BldPitch1", "GenTq", "RotSpeed", "GenPwr"] fast_out = output_processing.output_processing() fastout = fast_out.load_fast_out(outfile) fast_out.plot_fast_out(cases=cases, showplot=False) - plt.savefig(os.path.join(example_out_dir, "30_shutdown_pitch.png")) + plt.savefig(os.path.join(example_out_dir, "30_shutdown.png")) if __name__ == "__main__": diff --git a/rosco/controller/rosco_registry/rosco_types.yaml b/rosco/controller/rosco_registry/rosco_types.yaml index d2966daf..0ae13670 100644 --- a/rosco/controller/rosco_registry/rosco_types.yaml +++ b/rosco/controller/rosco_registry/rosco_types.yaml @@ -1237,6 +1237,10 @@ LocalVariables: <<: *real description: Commanded pitch of each blade the last time the controller was called [rad]. size: 3 + PitCom_SD: + <<: *real + description: Commanded pitch of each blade due to shutdown [rad]. + size: 3 PitComAct: <<: *real description: Actuated pitch command of each blade [rad]. @@ -1325,6 +1329,9 @@ LocalVariables: SD_Trigger: <<: *integer description: Shutdown trigger (1 - shutdown due to pitch, 2 - shutdown due to yaw error, 3 - shutdown due to generator speed, 4 - shutdown due to time) + GenTq_SD: + <<: *real + description: Electrical generator torque command for shutdown, [Nm]. Fl_PitCom: <<: *real description: Shutdown, .FALSE. if inactive, .TRUE. if active diff --git a/rosco/controller/src/Controllers.f90 b/rosco/controller/src/Controllers.f90 index 732a032c..36d5593a 100644 --- a/rosco/controller/src/Controllers.f90 +++ b/rosco/controller/src/Controllers.f90 @@ -136,15 +136,18 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst, DebugVar, ErrVar) ENDIF ! Shutdown - IF (LocalVar%SD_Trigger /= 0) THEN + IF (LocalVar%SD_Trigger == 0) THEN + LocalVar%PitCom_SD = LocalVar%PitCom + ELSE IF (CntrPar%SD_Method == 1) THEN !Only SD_Method==1 supported for now - LocalVar%PC_PitComT = LocalVar%BlPitchCMeas + CntrPar%SD_MaxPitchRate*LocalVar%DT - !LocalVar%PC_PitComT = ratelimit(LocalVar%BlPitchCMeas, CntrPar%SD_MaxPitchRate, CntrPar%SD_MaxPitchRate,LocalVar%DT, LocalVar%restart, LocalVar%rlP,objInst%instRL,LocalVar%BlPitchCMeas) + DO K = 1,LocalVar%NumBl + LocalVar%PitCom_SD(K) = LocalVar%PitCom_SD(K) + CntrPar%SD_MaxPitchRate*LocalVar%DT + END DO ENDIF + LocalVar%PitCom = LocalVar%PitCom_SD ENDIF + - - ! AG: Put in a warning if SD_MaxPitchRate > PC_MaxRat ! Place pitch actuator here, so it can be used with or without open-loop DO K = 1,LocalVar%NumBl ! Loop through all blades, add IPC contribution and limit pitch rate IF (CntrPar%PA_Mode > 0) THEN @@ -210,59 +213,64 @@ SUBROUTINE VariableSpeedControl(avrSWAP, CntrPar, LocalVar, objInst, ErrVar) ! -------- Variable-Speed Torque Controller -------- ! Define max torque - IF (LocalVar%SD_Trigger == 0) THEN - IF (LocalVar%VS_State == 4) THEN + IF (LocalVar%VS_State == 4) THEN + LocalVar%VS_MaxTq = CntrPar%VS_RtTq * LocalVar%PRC_R_Torque + ELSE LocalVar%VS_MaxTq = CntrPar%VS_RtTq * LocalVar%PRC_R_Torque - ELSE - LocalVar%VS_MaxTq = CntrPar%VS_RtTq * LocalVar%PRC_R_Torque - ENDIF + ENDIF + + ! Optimal Tip-Speed-Ratio tracking controller + IF ((CntrPar%VS_ControlMode == 2) .OR. (CntrPar%VS_ControlMode == 3)) THEN + ! Constant Power, update VS_MaxTq + IF (CntrPar%VS_ConstPower == 1) THEN + LocalVar%VS_MaxTq = min((CntrPar%VS_RtPwr * LocalVar%PRC_R_Torque /(CntrPar%VS_GenEff/100.0))/LocalVar%GenSpeedF, CntrPar%VS_MaxTq) + END IF + + ! PI controller + LocalVar%GenTq = PIController( & + LocalVar%VS_SpdErr, & + CntrPar%VS_KP(1), & + CntrPar%VS_KI(1), & + CntrPar%VS_MinTq, LocalVar%VS_MaxTq, & + LocalVar%DT, LocalVar%VS_LastGenTrq, LocalVar%piP, LocalVar%restart, objInst%instPI) + LocalVar%GenTq = saturate(LocalVar%GenTq, CntrPar%VS_MinTq, LocalVar%VS_MaxTq) + + ! K*Omega^2 control law with PI torque control in transition regions + ELSEIF (CntrPar%VS_ControlMode == 1) THEN + ! 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_MaxOMTq, LocalVar%piP, LocalVar%restart, 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, LocalVar%piP, LocalVar%restart, objInst%instPI) - ! Optimal Tip-Speed-Ratio tracking controller - IF ((CntrPar%VS_ControlMode == 2) .OR. (CntrPar%VS_ControlMode == 3)) THEN - ! Constant Power, update VS_MaxTq - IF (CntrPar%VS_ConstPower == 1) THEN - LocalVar%VS_MaxTq = min((CntrPar%VS_RtPwr * LocalVar%PRC_R_Torque /(CntrPar%VS_GenEff/100.0))/LocalVar%GenSpeedF, CntrPar%VS_MaxTq) - END IF - - ! PI controller - LocalVar%GenTq = PIController( & - LocalVar%VS_SpdErr, & - CntrPar%VS_KP(1), & - CntrPar%VS_KI(1), & - CntrPar%VS_MinTq, LocalVar%VS_MaxTq, & - LocalVar%DT, LocalVar%VS_LastGenTrq, LocalVar%piP, LocalVar%restart, objInst%instPI) - LocalVar%GenTq = saturate(LocalVar%GenTq, CntrPar%VS_MinTq, LocalVar%VS_MaxTq) + ! The action + IF (LocalVar%VS_State == 1) THEN ! Region 1.5 + LocalVar%GenTq = LocalVar%GenBrTq + ELSEIF (LocalVar%VS_State == 2) THEN ! Region 2 + LocalVar%GenTq = CntrPar%VS_Rgn2K*LocalVar%GenSpeedF*LocalVar%GenSpeedF + ELSEIF (LocalVar%VS_State == 3) THEN ! Region 2.5 + LocalVar%GenTq = LocalVar%GenArTq + ELSEIF (LocalVar%VS_State == 4) THEN ! Region 3, constant torque + LocalVar%GenTq = CntrPar%VS_RtTq + ELSEIF (LocalVar%VS_State == 5) THEN ! Region 3, constant power + LocalVar%GenTq = (CntrPar%VS_RtPwr/(CntrPar%VS_GenEff/100.0))/LocalVar%GenSpeedF + END IF - ! K*Omega^2 control law with PI torque control in transition regions - ELSEIF (CntrPar%VS_ControlMode == 1) THEN - ! 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_MaxOMTq, LocalVar%piP, LocalVar%restart, 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, LocalVar%piP, LocalVar%restart, 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 - LocalVar%GenTq = CntrPar%VS_Rgn2K*LocalVar%GenSpeedF*LocalVar%GenSpeedF - ELSEIF (LocalVar%VS_State == 3) THEN ! Region 2.5 - LocalVar%GenTq = LocalVar%GenArTq - ELSEIF (LocalVar%VS_State == 4) THEN ! Region 3, constant torque - LocalVar%GenTq = CntrPar%VS_RtTq - 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, CntrPar%VS_MaxTq) - ELSE ! VS_ControlMode of 0 - LocalVar%GenTq = 0 - ENDIF - ELSE + ! Saturate + LocalVar%GenTq = saturate(LocalVar%GenTq, CntrPar%VS_MinTq, CntrPar%VS_MaxTq) + ELSE ! VS_ControlMode of 0 + LocalVar%GenTq = 0 + ENDIF + + ! Shutdown + IF (LocalVar%SD_Trigger == 0) THEN + LocalVar%GenTq_SD = LocalVar%GenTq + ELSE IF (CntrPar%SD_Method == 1) THEN !Only SD_Method==1 supported for now - LocalVar%GenTq = LocalVar%GenTq - CntrPar%SD_MaxTorqueRate*LocalVar%DT - LocalVar%GenTq = saturate(LocalVar%GenTq, CntrPar%VS_MinTq, CntrPar%VS_MaxTq) + LocalVar%GenTq_SD = LocalVar%GenTq_SD - CntrPar%SD_MaxTorqueRate*LocalVar%DT + LocalVar%GenTq_SD = saturate(LocalVar%GenTq_SD, CntrPar%VS_MinTq, CntrPar%VS_MaxTq) ENDIF + LocalVar%GenTq = LocalVar%GenTq_SD ENDIF + ! Saturate the commanded torque using the maximum torque limit: diff --git a/rosco/controller/src/ROSCO_IO.f90 b/rosco/controller/src/ROSCO_IO.f90 index 41517ca7..dda16e1f 100644 --- a/rosco/controller/src/ROSCO_IO.f90 +++ b/rosco/controller/src/ROSCO_IO.f90 @@ -126,6 +126,9 @@ SUBROUTINE WriteRestartFile(LocalVar, CntrPar, ErrVar, objInst, RootName, size_a WRITE( Un, IOSTAT=ErrStat) LocalVar%PitCom(1) WRITE( Un, IOSTAT=ErrStat) LocalVar%PitCom(2) WRITE( Un, IOSTAT=ErrStat) LocalVar%PitCom(3) + WRITE( Un, IOSTAT=ErrStat) LocalVar%PitCom_SD(1) + WRITE( Un, IOSTAT=ErrStat) LocalVar%PitCom_SD(2) + WRITE( Un, IOSTAT=ErrStat) LocalVar%PitCom_SD(3) WRITE( Un, IOSTAT=ErrStat) LocalVar%PitComAct(1) WRITE( Un, IOSTAT=ErrStat) LocalVar%PitComAct(2) WRITE( Un, IOSTAT=ErrStat) LocalVar%PitComAct(3) @@ -157,6 +160,7 @@ SUBROUTINE WriteRestartFile(LocalVar, CntrPar, ErrVar, objInst, RootName, size_a WRITE( Un, IOSTAT=ErrStat) LocalVar%PS_Min_Pitch WRITE( Un, IOSTAT=ErrStat) LocalVar%OL_Index WRITE( Un, IOSTAT=ErrStat) LocalVar%SD_Trigger + WRITE( Un, IOSTAT=ErrStat) LocalVar%GenTq_SD WRITE( Un, IOSTAT=ErrStat) LocalVar%Fl_PitCom WRITE( Un, IOSTAT=ErrStat) LocalVar%NACIMU_FA_AccF WRITE( Un, IOSTAT=ErrStat) LocalVar%FA_AccF @@ -443,6 +447,9 @@ SUBROUTINE ReadRestartFile(avrSWAP, LocalVar, CntrPar, objInst, PerfData, RootNa READ( Un, IOSTAT=ErrStat) LocalVar%PitCom(1) READ( Un, IOSTAT=ErrStat) LocalVar%PitCom(2) READ( Un, IOSTAT=ErrStat) LocalVar%PitCom(3) + READ( Un, IOSTAT=ErrStat) LocalVar%PitCom_SD(1) + READ( Un, IOSTAT=ErrStat) LocalVar%PitCom_SD(2) + READ( Un, IOSTAT=ErrStat) LocalVar%PitCom_SD(3) READ( Un, IOSTAT=ErrStat) LocalVar%PitComAct(1) READ( Un, IOSTAT=ErrStat) LocalVar%PitComAct(2) READ( Un, IOSTAT=ErrStat) LocalVar%PitComAct(3) @@ -474,6 +481,7 @@ SUBROUTINE ReadRestartFile(avrSWAP, LocalVar, CntrPar, objInst, PerfData, RootNa READ( Un, IOSTAT=ErrStat) LocalVar%PS_Min_Pitch READ( Un, IOSTAT=ErrStat) LocalVar%OL_Index READ( Un, IOSTAT=ErrStat) LocalVar%SD_Trigger + READ( Un, IOSTAT=ErrStat) LocalVar%GenTq_SD READ( Un, IOSTAT=ErrStat) LocalVar%Fl_PitCom READ( Un, IOSTAT=ErrStat) LocalVar%NACIMU_FA_AccF READ( Un, IOSTAT=ErrStat) LocalVar%FA_AccF @@ -722,7 +730,7 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av '[N/A]', '[N/A]', '[N/A]', '[N/A]', '[rad/s]', & '[deg]', '[deg]', '[deg]', '[N/A]', '[rad/s]', & '[rad/s]'] - nLocalVars = 140 + nLocalVars = 142 Allocate(LocalVarOutData(nLocalVars)) Allocate(LocalVarOutStrings(nLocalVars)) LocalVarOutData(1) = LocalVar%iStatus @@ -797,74 +805,76 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av LocalVarOutData(70) = LocalVar%IPC_IntSat LocalVarOutData(71) = LocalVar%PC_State LocalVarOutData(72) = LocalVar%PitCom(1) - LocalVarOutData(73) = LocalVar%PitComAct(1) - LocalVarOutData(74) = LocalVar%SS_DelOmegaF - LocalVarOutData(75) = LocalVar%TestType - LocalVarOutData(76) = LocalVar%Kp_Float - LocalVarOutData(77) = LocalVar%VS_MaxTq - LocalVarOutData(78) = LocalVar%VS_LastGenTrq - LocalVarOutData(79) = LocalVar%VS_LastGenPwr - LocalVarOutData(80) = LocalVar%VS_MechGenPwr - LocalVarOutData(81) = LocalVar%VS_SpdErrAr - LocalVarOutData(82) = LocalVar%VS_SpdErrBr - LocalVarOutData(83) = LocalVar%VS_SpdErr - LocalVarOutData(84) = LocalVar%VS_State - LocalVarOutData(85) = LocalVar%VS_Rgn3Pitch - LocalVarOutData(86) = LocalVar%WE_Vw - LocalVarOutData(87) = LocalVar%WE_Vw_F - LocalVarOutData(88) = LocalVar%WE_VwI - LocalVarOutData(89) = LocalVar%WE_VwIdot - LocalVarOutData(90) = LocalVar%WE_Op - LocalVarOutData(91) = LocalVar%WE_Op_Last - LocalVarOutData(92) = LocalVar%VS_LastGenTrqF - LocalVarOutData(93) = LocalVar%PRC_WSE_F - LocalVarOutData(94) = LocalVar%PRC_R_Speed - LocalVarOutData(95) = LocalVar%PRC_R_Torque - LocalVarOutData(96) = LocalVar%PRC_R_Pitch - LocalVarOutData(97) = LocalVar%PRC_R_Total - LocalVarOutData(98) = LocalVar%PRC_Min_Pitch - LocalVarOutData(99) = LocalVar%PS_Min_Pitch - LocalVarOutData(100) = LocalVar%OL_Index - LocalVarOutData(101) = LocalVar%SD_Trigger - LocalVarOutData(102) = LocalVar%Fl_PitCom - LocalVarOutData(103) = LocalVar%NACIMU_FA_AccF - LocalVarOutData(104) = LocalVar%FA_AccF - LocalVarOutData(105) = LocalVar%FA_Hist - LocalVarOutData(106) = LocalVar%TRA_LastRefSpd - LocalVarOutData(107) = LocalVar%VS_RefSpeed - LocalVarOutData(108) = LocalVar%PtfmTDX - LocalVarOutData(109) = LocalVar%PtfmTDY - LocalVarOutData(110) = LocalVar%PtfmTDZ - LocalVarOutData(111) = LocalVar%PtfmRDX - LocalVarOutData(112) = LocalVar%PtfmRDY - LocalVarOutData(113) = LocalVar%PtfmRDZ - LocalVarOutData(114) = LocalVar%PtfmTVX - LocalVarOutData(115) = LocalVar%PtfmTVY - LocalVarOutData(116) = LocalVar%PtfmTVZ - LocalVarOutData(117) = LocalVar%PtfmRVX - LocalVarOutData(118) = LocalVar%PtfmRVY - LocalVarOutData(119) = LocalVar%PtfmRVZ - LocalVarOutData(120) = LocalVar%PtfmTAX - LocalVarOutData(121) = LocalVar%PtfmTAY - LocalVarOutData(122) = LocalVar%PtfmTAZ - LocalVarOutData(123) = LocalVar%PtfmRAX - LocalVarOutData(124) = LocalVar%PtfmRAY - LocalVarOutData(125) = LocalVar%PtfmRAZ - LocalVarOutData(126) = LocalVar%CC_DesiredL(1) - LocalVarOutData(127) = LocalVar%CC_ActuatedL(1) - LocalVarOutData(128) = LocalVar%CC_ActuatedDL(1) - LocalVarOutData(129) = LocalVar%StC_Input(1) - LocalVarOutData(130) = LocalVar%Flp_Angle(1) - LocalVarOutData(131) = LocalVar%RootMyb_Last(1) - LocalVarOutData(132) = LocalVar%ACC_INFILE_SIZE - LocalVarOutData(133) = LocalVar%AWC_complexangle(1) - LocalVarOutData(134) = LocalVar%ZMQ_ID - LocalVarOutData(135) = LocalVar%ZMQ_YawOffset - LocalVarOutData(136) = LocalVar%ZMQ_TorqueOffset - LocalVarOutData(137) = LocalVar%ZMQ_PitOffset(1) - LocalVarOutData(138) = LocalVar%ZMQ_R_Speed - LocalVarOutData(139) = LocalVar%ZMQ_R_Torque - LocalVarOutData(140) = LocalVar%ZMQ_R_Pitch + LocalVarOutData(73) = LocalVar%PitCom_SD(1) + LocalVarOutData(74) = LocalVar%PitComAct(1) + LocalVarOutData(75) = LocalVar%SS_DelOmegaF + LocalVarOutData(76) = LocalVar%TestType + LocalVarOutData(77) = LocalVar%Kp_Float + LocalVarOutData(78) = LocalVar%VS_MaxTq + LocalVarOutData(79) = LocalVar%VS_LastGenTrq + LocalVarOutData(80) = LocalVar%VS_LastGenPwr + LocalVarOutData(81) = LocalVar%VS_MechGenPwr + LocalVarOutData(82) = LocalVar%VS_SpdErrAr + LocalVarOutData(83) = LocalVar%VS_SpdErrBr + LocalVarOutData(84) = LocalVar%VS_SpdErr + LocalVarOutData(85) = LocalVar%VS_State + LocalVarOutData(86) = LocalVar%VS_Rgn3Pitch + LocalVarOutData(87) = LocalVar%WE_Vw + LocalVarOutData(88) = LocalVar%WE_Vw_F + LocalVarOutData(89) = LocalVar%WE_VwI + LocalVarOutData(90) = LocalVar%WE_VwIdot + LocalVarOutData(91) = LocalVar%WE_Op + LocalVarOutData(92) = LocalVar%WE_Op_Last + LocalVarOutData(93) = LocalVar%VS_LastGenTrqF + LocalVarOutData(94) = LocalVar%PRC_WSE_F + LocalVarOutData(95) = LocalVar%PRC_R_Speed + LocalVarOutData(96) = LocalVar%PRC_R_Torque + LocalVarOutData(97) = LocalVar%PRC_R_Pitch + LocalVarOutData(98) = LocalVar%PRC_R_Total + LocalVarOutData(99) = LocalVar%PRC_Min_Pitch + LocalVarOutData(100) = LocalVar%PS_Min_Pitch + LocalVarOutData(101) = LocalVar%OL_Index + LocalVarOutData(102) = LocalVar%SD_Trigger + LocalVarOutData(103) = LocalVar%GenTq_SD + LocalVarOutData(104) = LocalVar%Fl_PitCom + LocalVarOutData(105) = LocalVar%NACIMU_FA_AccF + LocalVarOutData(106) = LocalVar%FA_AccF + LocalVarOutData(107) = LocalVar%FA_Hist + LocalVarOutData(108) = LocalVar%TRA_LastRefSpd + LocalVarOutData(109) = LocalVar%VS_RefSpeed + LocalVarOutData(110) = LocalVar%PtfmTDX + LocalVarOutData(111) = LocalVar%PtfmTDY + LocalVarOutData(112) = LocalVar%PtfmTDZ + LocalVarOutData(113) = LocalVar%PtfmRDX + LocalVarOutData(114) = LocalVar%PtfmRDY + LocalVarOutData(115) = LocalVar%PtfmRDZ + LocalVarOutData(116) = LocalVar%PtfmTVX + LocalVarOutData(117) = LocalVar%PtfmTVY + LocalVarOutData(118) = LocalVar%PtfmTVZ + LocalVarOutData(119) = LocalVar%PtfmRVX + LocalVarOutData(120) = LocalVar%PtfmRVY + LocalVarOutData(121) = LocalVar%PtfmRVZ + LocalVarOutData(122) = LocalVar%PtfmTAX + LocalVarOutData(123) = LocalVar%PtfmTAY + LocalVarOutData(124) = LocalVar%PtfmTAZ + LocalVarOutData(125) = LocalVar%PtfmRAX + LocalVarOutData(126) = LocalVar%PtfmRAY + LocalVarOutData(127) = LocalVar%PtfmRAZ + LocalVarOutData(128) = LocalVar%CC_DesiredL(1) + LocalVarOutData(129) = LocalVar%CC_ActuatedL(1) + LocalVarOutData(130) = LocalVar%CC_ActuatedDL(1) + LocalVarOutData(131) = LocalVar%StC_Input(1) + LocalVarOutData(132) = LocalVar%Flp_Angle(1) + LocalVarOutData(133) = LocalVar%RootMyb_Last(1) + LocalVarOutData(134) = LocalVar%ACC_INFILE_SIZE + LocalVarOutData(135) = LocalVar%AWC_complexangle(1) + LocalVarOutData(136) = LocalVar%ZMQ_ID + LocalVarOutData(137) = LocalVar%ZMQ_YawOffset + LocalVarOutData(138) = LocalVar%ZMQ_TorqueOffset + LocalVarOutData(139) = LocalVar%ZMQ_PitOffset(1) + LocalVarOutData(140) = LocalVar%ZMQ_R_Speed + LocalVarOutData(141) = LocalVar%ZMQ_R_Torque + LocalVarOutData(142) = LocalVar%ZMQ_R_Pitch LocalVarOutStrings = [CHARACTER(15) :: 'iStatus', 'RestartWSE', 'Time', 'DT', 'n_DT', & 'Time_Last', 'VS_GenPwr', 'VS_GenPwrF', 'GenSpeed', 'RotSpeed', & 'NacHeading', 'NacVane', 'NacVaneF', 'HorWindV', 'HorWindV_F', & @@ -879,21 +889,21 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av 'PC_PwrErr', 'PC_SpdErr', 'IPC_AxisTilt_1P', 'IPC_AxisYaw_1P', 'IPC_AxisTilt_2P', & 'IPC_AxisYaw_2P', 'axisTilt_1P', 'axisYaw_1P', 'axisYawF_1P', 'axisTilt_2P', & 'axisYaw_2P', 'axisYawF_2P', 'IPC_KI', 'IPC_KP', 'IPC_IntSat', & - 'PC_State', 'PitCom', 'PitComAct', 'SS_DelOmegaF', 'TestType', & - 'Kp_Float', 'VS_MaxTq', 'VS_LastGenTrq', 'VS_LastGenPwr', 'VS_MechGenPwr', & - 'VS_SpdErrAr', 'VS_SpdErrBr', 'VS_SpdErr', 'VS_State', 'VS_Rgn3Pitch', & - 'WE_Vw', 'WE_Vw_F', 'WE_VwI', 'WE_VwIdot', 'WE_Op', & - 'WE_Op_Last', 'VS_LastGenTrqF', 'PRC_WSE_F', 'PRC_R_Speed', 'PRC_R_Torque', & - 'PRC_R_Pitch', 'PRC_R_Total', 'PRC_Min_Pitch', 'PS_Min_Pitch', 'OL_Index', & - 'SD_Trigger', 'Fl_PitCom', 'NACIMU_FA_AccF', 'FA_AccF', 'FA_Hist', & - 'TRA_LastRefSpd', 'VS_RefSpeed', 'PtfmTDX', 'PtfmTDY', 'PtfmTDZ', & - 'PtfmRDX', 'PtfmRDY', 'PtfmRDZ', 'PtfmTVX', 'PtfmTVY', & - 'PtfmTVZ', 'PtfmRVX', 'PtfmRVY', 'PtfmRVZ', 'PtfmTAX', & - 'PtfmTAY', 'PtfmTAZ', 'PtfmRAX', 'PtfmRAY', 'PtfmRAZ', & - 'CC_DesiredL', 'CC_ActuatedL', 'CC_ActuatedDL', 'StC_Input', 'Flp_Angle', & - 'RootMyb_Last', 'ACC_INFILE_SIZE', 'AWC_complexangle', 'ZMQ_ID', 'ZMQ_YawOffset', & - 'ZMQ_TorqueOffset', 'ZMQ_PitOffset', 'ZMQ_R_Speed', 'ZMQ_R_Torque', 'ZMQ_R_Pitch' & - ] + 'PC_State', 'PitCom', 'PitCom_SD', 'PitComAct', 'SS_DelOmegaF', & + 'TestType', 'Kp_Float', 'VS_MaxTq', 'VS_LastGenTrq', 'VS_LastGenPwr', & + 'VS_MechGenPwr', 'VS_SpdErrAr', 'VS_SpdErrBr', 'VS_SpdErr', 'VS_State', & + 'VS_Rgn3Pitch', 'WE_Vw', 'WE_Vw_F', 'WE_VwI', 'WE_VwIdot', & + 'WE_Op', 'WE_Op_Last', 'VS_LastGenTrqF', 'PRC_WSE_F', 'PRC_R_Speed', & + 'PRC_R_Torque', 'PRC_R_Pitch', 'PRC_R_Total', 'PRC_Min_Pitch', 'PS_Min_Pitch', & + 'OL_Index', 'SD_Trigger', 'GenTq_SD', 'Fl_PitCom', 'NACIMU_FA_AccF', & + 'FA_AccF', 'FA_Hist', 'TRA_LastRefSpd', 'VS_RefSpeed', 'PtfmTDX', & + 'PtfmTDY', 'PtfmTDZ', 'PtfmRDX', 'PtfmRDY', 'PtfmRDZ', & + 'PtfmTVX', 'PtfmTVY', 'PtfmTVZ', 'PtfmRVX', 'PtfmRVY', & + 'PtfmRVZ', 'PtfmTAX', 'PtfmTAY', 'PtfmTAZ', 'PtfmRAX', & + 'PtfmRAY', 'PtfmRAZ', 'CC_DesiredL', 'CC_ActuatedL', 'CC_ActuatedDL', & + 'StC_Input', 'Flp_Angle', 'RootMyb_Last', 'ACC_INFILE_SIZE', 'AWC_complexangle', & + 'ZMQ_ID', 'ZMQ_YawOffset', 'ZMQ_TorqueOffset', 'ZMQ_PitOffset', 'ZMQ_R_Speed', & + 'ZMQ_R_Torque', 'ZMQ_R_Pitch'] ! Initialize debug file IF ((LocalVar%iStatus == 0) .OR. (LocalVar%iStatus == -9)) THEN ! .TRUE. if we're on the first call to the DLL IF (CntrPar%LoggingLevel > 0) THEN @@ -908,8 +918,8 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av CALL GetNewUnit(UnDb2, ErrVar) OPEN(unit=UnDb2, FILE=TRIM(RootName)//'.RO.dbg2') WRITE(UnDb2, *) 'Generated on '//CurDate()//' at '//CurTime()//' using ROSCO-'//TRIM(rosco_version) - WRITE(UnDb2, '(141(a20,TR5:))') 'Time', LocalVarOutStrings - WRITE(UnDb2, '(141(a20,TR5:))') + WRITE(UnDb2, '(143(a20,TR5:))') 'Time', LocalVarOutStrings + WRITE(UnDb2, '(143(a20,TR5:))') END IF IF (CntrPar%LoggingLevel > 2) THEN @@ -972,7 +982,7 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av END DO ! Write debug files - FmtDat = "(F20.5,TR5,140(ES20.5E2,TR5:))" ! The format of the debugging data + FmtDat = "(F20.5,TR5,142(ES20.5E2,TR5:))" ! The format of the debugging data IF ( MOD(LocalVar%n_DT, CntrPar%n_DT_Out) == 0) THEN IF(CntrPar%LoggingLevel > 0) THEN WRITE (UnDb, TRIM(FmtDat)) LocalVar%Time, DebugOutData diff --git a/rosco/controller/src/ROSCO_Types.f90 b/rosco/controller/src/ROSCO_Types.f90 index 8ec65cbd..5125d190 100644 --- a/rosco/controller/src/ROSCO_Types.f90 +++ b/rosco/controller/src/ROSCO_Types.f90 @@ -347,6 +347,7 @@ MODULE ROSCO_Types REAL(DbKi) :: IPC_IntSat ! Integrator saturation (maximum signal amplitude contrbution to pitch from IPC) INTEGER(IntKi) :: PC_State ! State of the pitch control system REAL(DbKi) :: PitCom(3) ! Commanded pitch of each blade the last time the controller was called [rad]. + REAL(DbKi) :: PitCom_SD(3) ! Commanded pitch of each blade due to shutdown [rad]. REAL(DbKi) :: PitComAct(3) ! Actuated pitch command of each blade [rad]. REAL(DbKi) :: SS_DelOmegaF ! Filtered setpoint shifting term defined in setpoint smoother [rad/s]. REAL(DbKi) :: TestType ! Test variable, no use @@ -376,6 +377,7 @@ MODULE ROSCO_Types REAL(DbKi) :: PS_Min_Pitch ! Instantaneous peak shaving REAL(DbKi) :: OL_Index ! Open loop indexing variable (time or wind speed) INTEGER(IntKi) :: SD_Trigger ! Shutdown trigger (1 - shutdown due to pitch, 2 - shutdown due to yaw error, 3 - shutdown due to generator speed, 4 - shutdown due to time) + REAL(DbKi) :: GenTq_SD ! Electrical generator torque command for shutdown, [Nm]. REAL(DbKi) :: Fl_PitCom ! Shutdown, .FALSE. if inactive, .TRUE. if active REAL(DbKi) :: NACIMU_FA_AccF ! None REAL(DbKi) :: FA_AccF ! None diff --git a/rosco/controller/src/ReadSetParameters.f90 b/rosco/controller/src/ReadSetParameters.f90 index be8a885a..a06ba6dd 100644 --- a/rosco/controller/src/ReadSetParameters.f90 +++ b/rosco/controller/src/ReadSetParameters.f90 @@ -1422,6 +1422,12 @@ SUBROUTINE CheckInputs(LocalVar, CntrPar, avrSWAP, ErrVar, size_avcMSG) ErrVar%ErrMsg = 'SD_MaxPitchRate should be less or equal to PC_MaxRat.' ENDIF + ! SD_MaxTorqueRate + IF (CntrPar%SD_MaxTorqueRate > CntrPar%VS_MaxRat) THEN + ErrVar%aviFAIL = -1 + ErrVar%ErrMsg = 'SD_MaxTorqueRate should be less or equal to VS_MaxRat.' + ENDIF + ! --- Open loop control --- IF (CntrPar%OL_Mode > 0) THEN ! Get all open loop indices From e5ba2279c9faf355ec6f42904a5d61a54f16495d Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Fri, 15 Nov 2024 21:16:42 -0700 Subject: [PATCH 07/33] Shutdown: Modify DISCON.IN files for test cases --- Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN | 16 ++++++++++++++-- .../DISCON-UMaineSemi.IN | 16 ++++++++++++++-- Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN | 16 ++++++++++++++-- Examples/Test_Cases/NREL-5MW/DISCON.IN | 16 ++++++++++++++-- .../NREL_2p8_127/NREL-2p8-127_DISCON.IN | 16 ++++++++++++++-- rosco/toolbox/utilities.py | 10 +++++----- 6 files changed, 75 insertions(+), 15 deletions(-) diff --git a/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN b/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN index d79e7b4e..88bc00d3 100644 --- a/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN +++ b/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN @@ -145,8 +145,20 @@ -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.012 0.000 0.011 0.020 0.029 0.041 0.056 0.069 0.082 0.095 0.108 0.120 0.132 0.143 0.155 0.166 0.178 0.189 0.200 0.211 0.222 0.232 0.243 0.254 0.264 0.274 0.285 0.295 0.305 0.315 0.325 0.335 0.344 0.354 0.364 0.373 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0.698100000000 ! 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] +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]​ +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]​ +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]​ +0 ! SD_EnableTime - Shutdown at a predefined time, [-]​ +0.5236 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​ +0.4189 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​ +0.5236 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ +0.4189 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​ +0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ +9999.00 ! SD_Time - Shutdown time, [s]​ +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch},​ [-]​ +4500000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ +0.03480 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN b/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN index ed348ab9..af75b858 100644 --- a/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN +++ b/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN @@ -145,8 +145,20 @@ 0.060 0.060 0.060 0.060 0.060 0.060 0.056 0.052 0.047 0.041 0.036 0.029 0.022 0.015 0.008 0.001 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.006 0.021 0.033 0.044 0.053 0.064 0.074 0.084 0.093 0.103 0.112 0.121 0.130 0.138 0.147 0.155 0.163 0.172 0.180 0.188 0.196 0.203 0.211 0.219 0.227 0.234 0.242 0.250 0.257 0.265 0.272 0.279 0.287 0.294 0.301 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0.698100000000 ! 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] +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]​ +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]​ +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]​ +0 ! SD_EnableTime - Shutdown at a predefined time, [-]​ +0.5236 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​ +0.4189 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​ +0.5236 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ +0.4189 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​ +0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ +9999.00 ! SD_Time - Shutdown time, [s]​ +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch},​ [-]​ +4500000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ +0.03480 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN b/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN index 89395380..e6c9c657 100644 --- a/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN +++ b/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN @@ -145,8 +145,20 @@ 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0.436300000000 ! 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] +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]​ +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]​ +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]​ +0 ! SD_EnableTime - Shutdown at a predefined time, [-]​ +0.5236 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​ +0.4189 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​ +0.5236 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ +0.4189 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​ +0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ +9999.00 ! SD_Time - Shutdown time, [s]​ +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch},​ [-]​ +4500000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ +0.03480 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/Examples/Test_Cases/NREL-5MW/DISCON.IN b/Examples/Test_Cases/NREL-5MW/DISCON.IN index 185c4126..b477013f 100644 --- a/Examples/Test_Cases/NREL-5MW/DISCON.IN +++ b/Examples/Test_Cases/NREL-5MW/DISCON.IN @@ -145,8 +145,20 @@ 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.011 0.023 0.032 0.040 0.047 0.059 0.070 0.081 0.091 0.102 0.112 0.122 0.131 0.141 0.150 0.160 0.169 0.178 0.187 0.196 0.205 0.214 0.223 0.232 0.240 0.249 0.257 0.266 0.274 0.282 0.290 0.299 0.307 0.315 0.323 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0.436300000000 ! 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] +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]​ +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]​ +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]​ +0 ! SD_EnableTime - Shutdown at a predefined time, [-]​ +0.5236 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​ +0.4189 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​ +0.5236 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ +0.4189 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​ +0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ +9999.00 ! SD_Time - Shutdown time, [s]​ +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch},​ [-]​ +4500000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ +0.03480 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN b/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN index a73c2829..e3c844b7 100644 --- a/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN +++ b/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN @@ -145,8 +145,20 @@ 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.019 0.031 0.041 0.050 0.058 0.066 0.074 0.086 0.096 0.107 0.117 0.127 0.137 0.147 0.156 0.165 0.174 0.183 0.192 0.201 0.210 0.218 0.227 0.236 0.244 0.253 0.262 0.270 0.279 0.287 0.295 0.303 0.312 0.320 0.328 0.337 0.345 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0.436300000000 ! 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] +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]​ +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]​ +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]​ +0 ! SD_EnableTime - Shutdown at a predefined time, [-]​ +0.5236 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​ +0.4189 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​ +0.5236 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ +0.4189 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​ +0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ +9999.00 ! SD_Time - Shutdown time, [s]​ +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch},​ [-]​ +4500000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ +0.03480 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/rosco/toolbox/utilities.py b/rosco/toolbox/utilities.py index dac1a27a..f0950891 100644 --- a/rosco/toolbox/utilities.py +++ b/rosco/toolbox/utilities.py @@ -233,10 +233,10 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('{} ! PS_BldPitchMin - Minimum blade pitch angles [rad]\n'.format(''.join('{:<10.3f} '.format(rosco_vt['PS_BldPitchMin'][i]) for i in range(len(rosco_vt['PS_BldPitchMin']))))) file.write('\n') file.write('!------- SHUTDOWN -----------------------------------------------------------\n') - file.write('{:<12d} ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]​\n'.format(rosco_vt['SD_EnablePitch'])) - file.write('{:<12d} ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]​\n'.format(rosco_vt['SD_EnableYawError'])) - file.write('{:<12d} ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]​\n'.format(rosco_vt['SD_EnableGenSpeed'])) - file.write('{:<12d} ! SD_EnableTime - Shutdown at a predefined time, [-]​\n'.format(rosco_vt['SD_EnableTime'])) + file.write('{0:<12d} ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]​\n'.format(int(rosco_vt['SD_EnablePitch']))) + file.write('{0:<12d} ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]​\n'.format(int(rosco_vt['SD_EnableYawError']))) + file.write('{0:<12d} ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]​\n'.format(int(rosco_vt['SD_EnableGenSpeed']))) + file.write('{0:<12d} ! SD_EnableTime - Shutdown at a predefined time, [-]​\n'.format(int(rosco_vt['SD_EnableTime']))) file.write('{:<014.5f} ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​\n'.format(rosco_vt['SD_MaxPit'])) file.write('{:<014.5f} ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​\n'.format(rosco_vt['SD_PitchCornerFreq'])) file.write('{:<014.5f} ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​\n'.format(rosco_vt['SD_MaxYawError'])) @@ -244,7 +244,7 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('{:<014.5f} ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​\n'.format(rosco_vt['SD_MaxGenSpd'])) file.write('{:<014.5f} ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​\n'.format(rosco_vt['SD_GenSpdCornerFreq'])) file.write('{:<014.5f} ! SD_Time - Shutdown time, [s]​\n'.format(rosco_vt['SD_Time'])) - file.write('{:<12d} ! SD_Method - Shutdown method {{1: Reduce generator torque and increase blade pitch}},​ [-]​\n'.format(rosco_vt['SD_Method'])) + file.write('{0:<12d} ! SD_Method - Shutdown method {{1: Reduce generator torque and increase blade pitch}},​ [-]​\n'.format(int(rosco_vt['SD_Method']))) file.write('{:<014.5f} ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​\n'.format(rosco_vt['SD_MaxTorqueRate'])) file.write('{:<014.5f} ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​\n'.format(rosco_vt['SD_MaxPitchRate'])) file.write('\n') From 55b2fbf31486e54b22f427ee6dbd203deaf631c0 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Sat, 16 Nov 2024 10:02:37 -0700 Subject: [PATCH 08/33] Shutdown: Fix utilities.py to remove unknown character --- rosco/toolbox/utilities.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/rosco/toolbox/utilities.py b/rosco/toolbox/utilities.py index f0950891..942ccc99 100644 --- a/rosco/toolbox/utilities.py +++ b/rosco/toolbox/utilities.py @@ -233,20 +233,20 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('{} ! PS_BldPitchMin - Minimum blade pitch angles [rad]\n'.format(''.join('{:<10.3f} '.format(rosco_vt['PS_BldPitchMin'][i]) for i in range(len(rosco_vt['PS_BldPitchMin']))))) file.write('\n') file.write('!------- SHUTDOWN -----------------------------------------------------------\n') - file.write('{0:<12d} ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]​\n'.format(int(rosco_vt['SD_EnablePitch']))) - file.write('{0:<12d} ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]​\n'.format(int(rosco_vt['SD_EnableYawError']))) - file.write('{0:<12d} ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]​\n'.format(int(rosco_vt['SD_EnableGenSpeed']))) - file.write('{0:<12d} ! SD_EnableTime - Shutdown at a predefined time, [-]​\n'.format(int(rosco_vt['SD_EnableTime']))) - file.write('{:<014.5f} ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​\n'.format(rosco_vt['SD_MaxPit'])) - file.write('{:<014.5f} ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​\n'.format(rosco_vt['SD_PitchCornerFreq'])) - file.write('{:<014.5f} ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​\n'.format(rosco_vt['SD_MaxYawError'])) + file.write('{0:<12d} ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]\n'.format(int(rosco_vt['SD_EnablePitch']))) + file.write('{0:<12d} ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]\n'.format(int(rosco_vt['SD_EnableYawError']))) + file.write('{0:<12d} ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]\n'.format(int(rosco_vt['SD_EnableGenSpeed']))) + file.write('{0:<12d} ! SD_EnableTime - Shutdown at a predefined time, [-]\n'.format(int(rosco_vt['SD_EnableTime']))) + file.write('{:<014.5f} ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]\n'.format(rosco_vt['SD_MaxPit'])) + file.write('{:<014.5f} ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]\n'.format(rosco_vt['SD_PitchCornerFreq'])) + file.write('{:<014.5f} ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]\n'.format(rosco_vt['SD_MaxYawError'])) file.write('{:<014.5f} ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s]\n'.format(rosco_vt['SD_YawErrorCornerFreq'])) - file.write('{:<014.5f} ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​\n'.format(rosco_vt['SD_MaxGenSpd'])) - file.write('{:<014.5f} ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​\n'.format(rosco_vt['SD_GenSpdCornerFreq'])) - file.write('{:<014.5f} ! SD_Time - Shutdown time, [s]​\n'.format(rosco_vt['SD_Time'])) - file.write('{0:<12d} ! SD_Method - Shutdown method {{1: Reduce generator torque and increase blade pitch}},​ [-]​\n'.format(int(rosco_vt['SD_Method']))) - file.write('{:<014.5f} ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​\n'.format(rosco_vt['SD_MaxTorqueRate'])) - file.write('{:<014.5f} ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​\n'.format(rosco_vt['SD_MaxPitchRate'])) + file.write('{:<014.5f} ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]\n'.format(rosco_vt['SD_MaxGenSpd'])) + file.write('{:<014.5f} ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] \n'.format(rosco_vt['SD_GenSpdCornerFreq'])) + file.write('{:<014.5f} ! SD_Time - Shutdown time, [s]\n'.format(rosco_vt['SD_Time'])) + file.write('{0:<12d} ! SD_Method - Shutdown method {{1: Reduce generator torque and increase blade pitch}}, [-]\n'.format(int(rosco_vt['SD_Method']))) + file.write('{:<014.5f} ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]\n'.format(rosco_vt['SD_MaxTorqueRate'])) + file.write('{:<014.5f} ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]\n'.format(rosco_vt['SD_MaxPitchRate'])) file.write('\n') file.write('!------- Floating -----------------------------------------------------------\n') if rosco_vt['Fl_Mode'] == 2: From 5dc3817a0d151295713a8711be86e1d11f88ddad Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Sat, 16 Nov 2024 20:05:13 -0700 Subject: [PATCH 09/33] Shutdown: Fix issue where SD_MaxPit was named SD_MaxPitch in some places and reduce default SD_MaxTorqueRate --- rosco/toolbox/controller.py | 2 +- rosco/toolbox/inputs/toolbox_schema.yaml | 6 +++--- rosco/toolbox/utilities.py | 4 +--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/rosco/toolbox/controller.py b/rosco/toolbox/controller.py index 68c68fe2..e8d45e73 100644 --- a/rosco/toolbox/controller.py +++ b/rosco/toolbox/controller.py @@ -102,7 +102,7 @@ def __init__(self, controller_params): self.sd_enableyawerror = controller_params['sd_enableyawerror'] self.sd_enablegenspeed = controller_params['sd_enablegenspeed'] self.sd_enabletime = controller_params['sd_enabletime'] - self.sd_maxpitch = controller_params['sd_maxpitch'] + self.sd_maxpit = controller_params['sd_maxpit'] self.sd_maxyawerror = controller_params['sd_maxyawerror'] self.sd_maxgenspd = controller_params['sd_maxgenspd'] self.sd_time = controller_params['sd_time'] diff --git a/rosco/toolbox/inputs/toolbox_schema.yaml b/rosco/toolbox/inputs/toolbox_schema.yaml index 87f86d89..ac82a1ae 100644 --- a/rosco/toolbox/inputs/toolbox_schema.yaml +++ b/rosco/toolbox/inputs/toolbox_schema.yaml @@ -345,7 +345,7 @@ properties: description: Shutdown at a predefined time, [-] {default = 0} type: number default: 0 - sd_maxpitch: + sd_maxpit: description: Maximum blade pitch angle to initiate shutdown [rad], {default = 40 deg.} type: number default: 0.6981 @@ -370,9 +370,9 @@ properties: type: number default: 1 sd_maxtorquerate: - description: Maximum torque rate for shutdown, [Nm/s], {default = 99999 Nm/s., High value to simulate instant cuttoff} + description: Maximum torque rate for shutdown, [Nm/s], {default = 10000 Nm/s., High value to simulate instant cuttoff} type: number - default: 99999 + default: 10000 unit: Nm/s sd_maxpitchrate: description: Maximum pitch rate used for shutdown, [rad/s], {default = 1 rad/s.} diff --git a/rosco/toolbox/utilities.py b/rosco/toolbox/utilities.py index 942ccc99..6f7d5b85 100644 --- a/rosco/toolbox/utilities.py +++ b/rosco/toolbox/utilities.py @@ -337,10 +337,8 @@ def read_DISCON(DISCON_filename): DISCON_in = {} with open(DISCON_filename) as discon: for line in discon: - # Skip whitespace and comment lines if (line[0] != '!') == (len(line.strip()) != 0): - if (line.split()[1] != '!'): # Array valued entries array_length = line.split().index('!') param = line.split()[array_length+1] @@ -618,7 +616,7 @@ def DISCON_dict(turbine, controller, txt_filename=None): DISCON_dict['SD_EnableYawError'] = controller.sd_enableyawerror DISCON_dict['SD_EnableGenSpeed'] = controller.sd_enablegenspeed DISCON_dict['SD_EnableTime'] = controller.sd_enabletime - DISCON_dict['SD_MaxPitch'] = controller.sd_maxpitch + DISCON_dict['SD_MaxPit'] = controller.sd_maxpit DISCON_dict['SD_PitchCornerFreq'] = controller.f_sd_pitchcornerfreq DISCON_dict['SD_MaxYawError'] = controller.sd_maxyawerror DISCON_dict['SD_YawErrorCornerFreq'] = controller.f_sd_yawerrorcornerfreq From d185bfab1d5014ff8f22c59bd7a72d3d9e523abb Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Sun, 17 Nov 2024 09:17:06 -0700 Subject: [PATCH 10/33] Shutdown: Fix DISCON.IN files in example_inputs --- Examples/example_inputs/DISCON_v2.2.0.IN | 16 ++++++++++++++-- Examples/example_inputs/minimal_DISCON.IN | 16 ++++++++++++++-- Examples/example_inputs/minimal_DISCON_err.IN | 16 ++++++++++++++-- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/Examples/example_inputs/DISCON_v2.2.0.IN b/Examples/example_inputs/DISCON_v2.2.0.IN index 81cbc148..7dae6e8d 100644 --- a/Examples/example_inputs/DISCON_v2.2.0.IN +++ b/Examples/example_inputs/DISCON_v2.2.0.IN @@ -106,8 +106,20 @@ 0.06108652 0.06108652 0.06108652 0.05672320 0.04799655 0.03926991 0.02617994 0.01308997 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0.393240000000 ! 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] +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] +0 ! SD_EnableTime - Shutdown at a predefined time, [-] +0.436300000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] +0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] +0.523600000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad] +0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] +0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] +9999.000000000 ! SD_Time - Shutdown time, [s] +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] +22000.00000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] +0.174500000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] !------- Floating ----------------------------------------------------------- -9.32196000000 ! Fl_Kp - Nacelle velocity proportional feedback gain [s] diff --git a/Examples/example_inputs/minimal_DISCON.IN b/Examples/example_inputs/minimal_DISCON.IN index 305379fd..2d80a6d3 100644 --- a/Examples/example_inputs/minimal_DISCON.IN +++ b/Examples/example_inputs/minimal_DISCON.IN @@ -92,8 +92,20 @@ Extra lines that ROSCO doesn't care about anymore 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.01116187 0.02310060 0.03164156 0.03968639 0.04741131 0.05899071 0.07019329 0.08090119 0.09141661 0.10169361 0.11174124 0.12170066 0.13137494 0.14103377 0.15048120 0.15989580 0.16913227 0.17831010 0.18739638 0.19643591 0.20537011 0.21419674 0.22293719 0.23161365 0.24025975 0.24885012 0.25735704 0.26578040 0.27407178 0.28233051 0.29047594 0.29867838 0.30674517 0.31490089 0.32284411 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0.436300000000 ! 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] +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] +0 ! SD_EnableTime - Shutdown at a predefined time, [-] +0.436300000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] +0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] +0.523600000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad] +0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] +0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] +9999.000000000 ! SD_Time - Shutdown time, [s] +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] +22000.00000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] +0.174500000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] !------- Floating ----------------------------------------------------------- 0.000000000000 ! Fl_Kp - Nacelle velocity proportional feedback gain [s] diff --git a/Examples/example_inputs/minimal_DISCON_err.IN b/Examples/example_inputs/minimal_DISCON_err.IN index 269736e0..a8229dc9 100644 --- a/Examples/example_inputs/minimal_DISCON_err.IN +++ b/Examples/example_inputs/minimal_DISCON_err.IN @@ -94,8 +94,20 @@ Extra lines that ROSCO doesn't care about anymore 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.01116187 0.02310060 0.03164156 0.03968639 0.04741131 0.05899071 0.07019329 0.08090119 0.09141661 0.10169361 0.11174124 0.12170066 0.13137494 0.14103377 0.15048120 0.15989580 0.16913227 0.17831010 0.18739638 0.19643591 0.20537011 0.21419674 0.22293719 0.23161365 0.24025975 0.24885012 0.25735704 0.26578040 0.27407178 0.28233051 0.29047594 0.29867838 0.30674517 0.31490089 0.32284411 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0.436300000000 ! 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] +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] +0 ! SD_EnableTime - Shutdown at a predefined time, [-] +0.436300000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] +0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] +0.523600000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad] +0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] +0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] +9999.000000000 ! SD_Time - Shutdown time, [s] +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] +22000.00000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] +0.174500000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] !------- Floating ----------------------------------------------------------- 0.000000000000 ! Fl_Kp - Nacelle velocity proportional feedback gain [s] From 02c4e317c38ad78dd1164e159f6f531c50395107 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Sun, 17 Nov 2024 09:18:36 -0700 Subject: [PATCH 11/33] Shutdown: Set defaults values SD_MaxPitchRate and SD_MaxTorqeRate based on turbine properties --- rosco/toolbox/controller.py | 4 ++-- rosco/toolbox/inputs/toolbox_schema.yaml | 10 ---------- rosco/toolbox/utilities.py | 4 ++-- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/rosco/toolbox/controller.py b/rosco/toolbox/controller.py index e8d45e73..b8266bd3 100644 --- a/rosco/toolbox/controller.py +++ b/rosco/toolbox/controller.py @@ -107,8 +107,8 @@ def __init__(self, controller_params): self.sd_maxgenspd = controller_params['sd_maxgenspd'] self.sd_time = controller_params['sd_time'] self.sd_method = controller_params['sd_method'] - self.sd_maxtorquerate = controller_params['sd_maxtorquerate'] - self.sd_maxpitchrate = controller_params['sd_maxpitchrate'] + #self.sd_maxtorquerate = controller_params['sd_maxtorquerate'] + #self.sd_maxpitchrate = controller_params['sd_maxpitchrate'] # Optional parameters without defaults diff --git a/rosco/toolbox/inputs/toolbox_schema.yaml b/rosco/toolbox/inputs/toolbox_schema.yaml index ac82a1ae..12e40a24 100644 --- a/rosco/toolbox/inputs/toolbox_schema.yaml +++ b/rosco/toolbox/inputs/toolbox_schema.yaml @@ -369,16 +369,6 @@ properties: description: Shutdown method {Only 1 supported for now} type: number default: 1 - sd_maxtorquerate: - description: Maximum torque rate for shutdown, [Nm/s], {default = 10000 Nm/s., High value to simulate instant cuttoff} - type: number - default: 10000 - unit: Nm/s - sd_maxpitchrate: - description: Maximum pitch rate used for shutdown, [rad/s], {default = 1 rad/s.} - type: number - default: 1.0 - unit: s flp_maxpit: description: Maximum (and minimum) flap pitch angle [rad] type: number diff --git a/rosco/toolbox/utilities.py b/rosco/toolbox/utilities.py index 6f7d5b85..57c07d4f 100644 --- a/rosco/toolbox/utilities.py +++ b/rosco/toolbox/utilities.py @@ -624,8 +624,8 @@ def DISCON_dict(turbine, controller, txt_filename=None): DISCON_dict['SD_GenSpdCornerFreq'] = controller.f_sd_genspdcornerfreq DISCON_dict['SD_Time'] = controller.sd_time DISCON_dict['SD_Method'] = controller.sd_method - DISCON_dict['SD_MaxTorqueRate'] = controller.sd_maxtorquerate - DISCON_dict['SD_MaxPitchRate'] = controller.sd_maxpitchrate + DISCON_dict['SD_MaxTorqueRate'] = turbine.max_torque_rate + DISCON_dict['SD_MaxPitchRate'] = turbine.max_pitch_rate # ------- Floating ------- DISCON_dict['Fl_n'] = len(controller.Kp_float) DISCON_dict['Fl_Kp'] = controller.Kp_float From 173eb47e1cd4a10ef87bd613c870b9c6894a2223 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Sun, 17 Nov 2024 12:17:51 -0700 Subject: [PATCH 12/33] Shutdown: Fix DISCON.IN files in Test_Cases --- Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN | 4 ++-- .../Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN | 2 +- Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN | 4 ++-- Examples/Test_Cases/NREL-5MW/DISCON.IN | 2 +- Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN b/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN index 88bc00d3..b7c95aae 100644 --- a/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN +++ b/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN @@ -157,8 +157,8 @@ 0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ 9999.00 ! SD_Time - Shutdown time, [s]​ 1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch},​ [-]​ -4500000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ -0.03480 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ +62000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ +2.00 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN b/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN index af75b858..1b6063a0 100644 --- a/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN +++ b/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN @@ -158,7 +158,7 @@ 9999.00 ! SD_Time - Shutdown time, [s]​ 1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch},​ [-]​ 4500000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ -0.03480 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ +0.03490 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN b/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN index e6c9c657..5b47c8df 100644 --- a/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN +++ b/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN @@ -157,8 +157,8 @@ 0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ 9999.00 ! SD_Time - Shutdown time, [s]​ 1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch},​ [-]​ -4500000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ -0.03480 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ +7800 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ +0.1745 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/Examples/Test_Cases/NREL-5MW/DISCON.IN b/Examples/Test_Cases/NREL-5MW/DISCON.IN index b477013f..7a9d9fbb 100644 --- a/Examples/Test_Cases/NREL-5MW/DISCON.IN +++ b/Examples/Test_Cases/NREL-5MW/DISCON.IN @@ -158,7 +158,7 @@ 9999.00 ! SD_Time - Shutdown time, [s]​ 1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch},​ [-]​ 4500000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ -0.03480 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ +0.03490 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN b/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN index e3c844b7..70c515c2 100644 --- a/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN +++ b/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN @@ -157,8 +157,8 @@ 0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ 9999.00 ! SD_Time - Shutdown time, [s]​ 1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch},​ [-]​ -4500000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ -0.03480 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ +22000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ +0.1745 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 From b57df54ef3bfe842d8617bfae723220d5f54e5f9 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Sat, 23 Nov 2024 17:57:44 -0700 Subject: [PATCH 13/33] Shutdown: Convert some filtered signals to local variables --- .../rosco_registry/rosco_types.yaml | 9 ++ rosco/controller/src/ControllerBlocks.f90 | 15 +-- rosco/controller/src/ROSCO_IO.f90 | 116 ++++++++++-------- rosco/controller/src/ROSCO_Types.f90 | 3 + 4 files changed, 81 insertions(+), 62 deletions(-) diff --git a/rosco/controller/rosco_registry/rosco_types.yaml b/rosco/controller/rosco_registry/rosco_types.yaml index 0ae13670..71b65b9b 100644 --- a/rosco/controller/rosco_registry/rosco_types.yaml +++ b/rosco/controller/rosco_registry/rosco_types.yaml @@ -1329,6 +1329,15 @@ LocalVariables: SD_Trigger: <<: *integer description: Shutdown trigger (1 - shutdown due to pitch, 2 - shutdown due to yaw error, 3 - shutdown due to generator speed, 4 - shutdown due to time) + SD_BlPitchF: + <<: *real + description: Blade pitch signal filtered for shutdown + SD_NacVaneF: + <<: *real + description: Nacelle vane signal filtered for shutdown + SD_GenSpeedF: + <<: *real + description: Generator speed signal filtered for shutdown GenTq_SD: <<: *real description: Electrical generator torque command for shutdown, [Nm]. diff --git a/rosco/controller/src/ControllerBlocks.f90 b/rosco/controller/src/ControllerBlocks.f90 index fbb82bcc..a3cce6c1 100644 --- a/rosco/controller/src/ControllerBlocks.f90 +++ b/rosco/controller/src/ControllerBlocks.f90 @@ -523,9 +523,6 @@ SUBROUTINE Shutdown(LocalVar, CntrPar, objInst,ErrVar) TYPE(ErrorVariables), INTENT(INOUT) :: ErrVar ! Local Variables - REAL(DbKi) :: SD_BlPitchF - REAL(DbKi) :: SD_NacVaneF - REAL(DbKi) :: SD_GenSpeedF CHARACTER(*), PARAMETER :: RoutineName = 'VariableSpeedControl' !Initialize shutdown trigger variable @@ -535,22 +532,22 @@ SUBROUTINE Shutdown(LocalVar, CntrPar, objInst,ErrVar) ! Filter pitch signal - SD_BlPitchF = LPFilter(LocalVar%PC_PitComT, LocalVar%DT, CntrPar%SD_PitchCornerFreq, LocalVar%FP,LocalVar%iStatus, LocalVar%restart, objInst%instLPF) + LocalVar%SD_BlPitchF = LPFilter(LocalVar%PC_PitComT, LocalVar%DT, CntrPar%SD_PitchCornerFreq, LocalVar%FP,LocalVar%iStatus, LocalVar%restart, objInst%instLPF) ! Filter yaw error signal (NacVane) - SD_NacVaneF = LPFilter(LocalVar%NacVane, LocalVar%DT, CntrPar%SD_YawErrorCornerFreq, LocalVar%FP,LocalVar%iStatus, LocalVar%restart, objInst%instLPF) + LocalVar%SD_NacVaneF = LPFilter(LocalVar%NacVane, LocalVar%DT, CntrPar%SD_YawErrorCornerFreq, LocalVar%FP,LocalVar%iStatus, LocalVar%restart, objInst%instLPF) ! Filter yaw generator speed - SD_GenSpeedF = LPFilter(LocalVar%Genspeed, LocalVar%DT, CntrPar%SD_GenSpdCornerFreq, LocalVar%FP,LocalVar%iStatus, LocalVar%restart, objInst%instLPF) + LocalVar%SD_GenSpeedF = LPFilter(LocalVar%Genspeed, LocalVar%DT, CntrPar%SD_GenSpdCornerFreq, LocalVar%FP,LocalVar%iStatus, LocalVar%restart, objInst%instLPF) ! See if we should shutdown IF (LocalVar%SD_Trigger == 0) THEN - IF (CntrPar%SD_EnablePitch==1 .AND. SD_BlPitchF > CntrPar%SD_MaxPit) THEN + IF (CntrPar%SD_EnablePitch==1 .AND. LocalVar%SD_BlPitchF > CntrPar%SD_MaxPit) THEN ! Shutdown if above pitch exceeds shutdown threshold LocalVar%SD_Trigger = 1 ENDIF - IF (CntrPar%SD_EnableYawError==1 .AND. SD_NacVaneF > CntrPar%SD_MaxYawError) THEN + IF (CntrPar%SD_EnableYawError==1 .AND. LocalVar%SD_NacVaneF > CntrPar%SD_MaxYawError) THEN LocalVar%SD_Trigger = 2 ENDIF - IF (CntrPar%SD_EnableGenSpeed==1 .AND. SD_GenSpeedF > CntrPar%SD_MaxGenSpd) THEN + IF (CntrPar%SD_EnableGenSpeed==1 .AND. LocalVar%SD_GenSpeedF > CntrPar%SD_MaxGenSpd) THEN LocalVar%SD_Trigger = 3 ENDIF IF (CntrPar%SD_EnableTime==1 .AND. LocalVar%Time > CntrPar%SD_Time) THEN diff --git a/rosco/controller/src/ROSCO_IO.f90 b/rosco/controller/src/ROSCO_IO.f90 index dda16e1f..ffa5c552 100644 --- a/rosco/controller/src/ROSCO_IO.f90 +++ b/rosco/controller/src/ROSCO_IO.f90 @@ -160,6 +160,9 @@ SUBROUTINE WriteRestartFile(LocalVar, CntrPar, ErrVar, objInst, RootName, size_a WRITE( Un, IOSTAT=ErrStat) LocalVar%PS_Min_Pitch WRITE( Un, IOSTAT=ErrStat) LocalVar%OL_Index WRITE( Un, IOSTAT=ErrStat) LocalVar%SD_Trigger + WRITE( Un, IOSTAT=ErrStat) LocalVar%SD_BlPitchF + WRITE( Un, IOSTAT=ErrStat) LocalVar%SD_NacVaneF + WRITE( Un, IOSTAT=ErrStat) LocalVar%SD_GenSpeedF WRITE( Un, IOSTAT=ErrStat) LocalVar%GenTq_SD WRITE( Un, IOSTAT=ErrStat) LocalVar%Fl_PitCom WRITE( Un, IOSTAT=ErrStat) LocalVar%NACIMU_FA_AccF @@ -481,6 +484,9 @@ SUBROUTINE ReadRestartFile(avrSWAP, LocalVar, CntrPar, objInst, PerfData, RootNa READ( Un, IOSTAT=ErrStat) LocalVar%PS_Min_Pitch READ( Un, IOSTAT=ErrStat) LocalVar%OL_Index READ( Un, IOSTAT=ErrStat) LocalVar%SD_Trigger + READ( Un, IOSTAT=ErrStat) LocalVar%SD_BlPitchF + READ( Un, IOSTAT=ErrStat) LocalVar%SD_NacVaneF + READ( Un, IOSTAT=ErrStat) LocalVar%SD_GenSpeedF READ( Un, IOSTAT=ErrStat) LocalVar%GenTq_SD READ( Un, IOSTAT=ErrStat) LocalVar%Fl_PitCom READ( Un, IOSTAT=ErrStat) LocalVar%NACIMU_FA_AccF @@ -730,7 +736,7 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av '[N/A]', '[N/A]', '[N/A]', '[N/A]', '[rad/s]', & '[deg]', '[deg]', '[deg]', '[N/A]', '[rad/s]', & '[rad/s]'] - nLocalVars = 142 + nLocalVars = 145 Allocate(LocalVarOutData(nLocalVars)) Allocate(LocalVarOutStrings(nLocalVars)) LocalVarOutData(1) = LocalVar%iStatus @@ -835,46 +841,49 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av LocalVarOutData(100) = LocalVar%PS_Min_Pitch LocalVarOutData(101) = LocalVar%OL_Index LocalVarOutData(102) = LocalVar%SD_Trigger - LocalVarOutData(103) = LocalVar%GenTq_SD - LocalVarOutData(104) = LocalVar%Fl_PitCom - LocalVarOutData(105) = LocalVar%NACIMU_FA_AccF - LocalVarOutData(106) = LocalVar%FA_AccF - LocalVarOutData(107) = LocalVar%FA_Hist - LocalVarOutData(108) = LocalVar%TRA_LastRefSpd - LocalVarOutData(109) = LocalVar%VS_RefSpeed - LocalVarOutData(110) = LocalVar%PtfmTDX - LocalVarOutData(111) = LocalVar%PtfmTDY - LocalVarOutData(112) = LocalVar%PtfmTDZ - LocalVarOutData(113) = LocalVar%PtfmRDX - LocalVarOutData(114) = LocalVar%PtfmRDY - LocalVarOutData(115) = LocalVar%PtfmRDZ - LocalVarOutData(116) = LocalVar%PtfmTVX - LocalVarOutData(117) = LocalVar%PtfmTVY - LocalVarOutData(118) = LocalVar%PtfmTVZ - LocalVarOutData(119) = LocalVar%PtfmRVX - LocalVarOutData(120) = LocalVar%PtfmRVY - LocalVarOutData(121) = LocalVar%PtfmRVZ - LocalVarOutData(122) = LocalVar%PtfmTAX - LocalVarOutData(123) = LocalVar%PtfmTAY - LocalVarOutData(124) = LocalVar%PtfmTAZ - LocalVarOutData(125) = LocalVar%PtfmRAX - LocalVarOutData(126) = LocalVar%PtfmRAY - LocalVarOutData(127) = LocalVar%PtfmRAZ - LocalVarOutData(128) = LocalVar%CC_DesiredL(1) - LocalVarOutData(129) = LocalVar%CC_ActuatedL(1) - LocalVarOutData(130) = LocalVar%CC_ActuatedDL(1) - LocalVarOutData(131) = LocalVar%StC_Input(1) - LocalVarOutData(132) = LocalVar%Flp_Angle(1) - LocalVarOutData(133) = LocalVar%RootMyb_Last(1) - LocalVarOutData(134) = LocalVar%ACC_INFILE_SIZE - LocalVarOutData(135) = LocalVar%AWC_complexangle(1) - LocalVarOutData(136) = LocalVar%ZMQ_ID - LocalVarOutData(137) = LocalVar%ZMQ_YawOffset - LocalVarOutData(138) = LocalVar%ZMQ_TorqueOffset - LocalVarOutData(139) = LocalVar%ZMQ_PitOffset(1) - LocalVarOutData(140) = LocalVar%ZMQ_R_Speed - LocalVarOutData(141) = LocalVar%ZMQ_R_Torque - LocalVarOutData(142) = LocalVar%ZMQ_R_Pitch + LocalVarOutData(103) = LocalVar%SD_BlPitchF + LocalVarOutData(104) = LocalVar%SD_NacVaneF + LocalVarOutData(105) = LocalVar%SD_GenSpeedF + LocalVarOutData(106) = LocalVar%GenTq_SD + LocalVarOutData(107) = LocalVar%Fl_PitCom + LocalVarOutData(108) = LocalVar%NACIMU_FA_AccF + LocalVarOutData(109) = LocalVar%FA_AccF + LocalVarOutData(110) = LocalVar%FA_Hist + LocalVarOutData(111) = LocalVar%TRA_LastRefSpd + LocalVarOutData(112) = LocalVar%VS_RefSpeed + LocalVarOutData(113) = LocalVar%PtfmTDX + LocalVarOutData(114) = LocalVar%PtfmTDY + LocalVarOutData(115) = LocalVar%PtfmTDZ + LocalVarOutData(116) = LocalVar%PtfmRDX + LocalVarOutData(117) = LocalVar%PtfmRDY + LocalVarOutData(118) = LocalVar%PtfmRDZ + LocalVarOutData(119) = LocalVar%PtfmTVX + LocalVarOutData(120) = LocalVar%PtfmTVY + LocalVarOutData(121) = LocalVar%PtfmTVZ + LocalVarOutData(122) = LocalVar%PtfmRVX + LocalVarOutData(123) = LocalVar%PtfmRVY + LocalVarOutData(124) = LocalVar%PtfmRVZ + LocalVarOutData(125) = LocalVar%PtfmTAX + LocalVarOutData(126) = LocalVar%PtfmTAY + LocalVarOutData(127) = LocalVar%PtfmTAZ + LocalVarOutData(128) = LocalVar%PtfmRAX + LocalVarOutData(129) = LocalVar%PtfmRAY + LocalVarOutData(130) = LocalVar%PtfmRAZ + LocalVarOutData(131) = LocalVar%CC_DesiredL(1) + LocalVarOutData(132) = LocalVar%CC_ActuatedL(1) + LocalVarOutData(133) = LocalVar%CC_ActuatedDL(1) + LocalVarOutData(134) = LocalVar%StC_Input(1) + LocalVarOutData(135) = LocalVar%Flp_Angle(1) + LocalVarOutData(136) = LocalVar%RootMyb_Last(1) + LocalVarOutData(137) = LocalVar%ACC_INFILE_SIZE + LocalVarOutData(138) = LocalVar%AWC_complexangle(1) + LocalVarOutData(139) = LocalVar%ZMQ_ID + LocalVarOutData(140) = LocalVar%ZMQ_YawOffset + LocalVarOutData(141) = LocalVar%ZMQ_TorqueOffset + LocalVarOutData(142) = LocalVar%ZMQ_PitOffset(1) + LocalVarOutData(143) = LocalVar%ZMQ_R_Speed + LocalVarOutData(144) = LocalVar%ZMQ_R_Torque + LocalVarOutData(145) = LocalVar%ZMQ_R_Pitch LocalVarOutStrings = [CHARACTER(15) :: 'iStatus', 'RestartWSE', 'Time', 'DT', 'n_DT', & 'Time_Last', 'VS_GenPwr', 'VS_GenPwrF', 'GenSpeed', 'RotSpeed', & 'NacHeading', 'NacVane', 'NacVaneF', 'HorWindV', 'HorWindV_F', & @@ -895,15 +904,16 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av 'VS_Rgn3Pitch', 'WE_Vw', 'WE_Vw_F', 'WE_VwI', 'WE_VwIdot', & 'WE_Op', 'WE_Op_Last', 'VS_LastGenTrqF', 'PRC_WSE_F', 'PRC_R_Speed', & 'PRC_R_Torque', 'PRC_R_Pitch', 'PRC_R_Total', 'PRC_Min_Pitch', 'PS_Min_Pitch', & - 'OL_Index', 'SD_Trigger', 'GenTq_SD', 'Fl_PitCom', 'NACIMU_FA_AccF', & - 'FA_AccF', 'FA_Hist', 'TRA_LastRefSpd', 'VS_RefSpeed', 'PtfmTDX', & - 'PtfmTDY', 'PtfmTDZ', 'PtfmRDX', 'PtfmRDY', 'PtfmRDZ', & - 'PtfmTVX', 'PtfmTVY', 'PtfmTVZ', 'PtfmRVX', 'PtfmRVY', & - 'PtfmRVZ', 'PtfmTAX', 'PtfmTAY', 'PtfmTAZ', 'PtfmRAX', & - 'PtfmRAY', 'PtfmRAZ', 'CC_DesiredL', 'CC_ActuatedL', 'CC_ActuatedDL', & - 'StC_Input', 'Flp_Angle', 'RootMyb_Last', 'ACC_INFILE_SIZE', 'AWC_complexangle', & - 'ZMQ_ID', 'ZMQ_YawOffset', 'ZMQ_TorqueOffset', 'ZMQ_PitOffset', 'ZMQ_R_Speed', & - 'ZMQ_R_Torque', 'ZMQ_R_Pitch'] + 'OL_Index', 'SD_Trigger', 'SD_BlPitchF', 'SD_NacVaneF', 'SD_GenSpeedF', & + 'GenTq_SD', 'Fl_PitCom', 'NACIMU_FA_AccF', 'FA_AccF', 'FA_Hist', & + 'TRA_LastRefSpd', 'VS_RefSpeed', 'PtfmTDX', 'PtfmTDY', 'PtfmTDZ', & + 'PtfmRDX', 'PtfmRDY', 'PtfmRDZ', 'PtfmTVX', 'PtfmTVY', & + 'PtfmTVZ', 'PtfmRVX', 'PtfmRVY', 'PtfmRVZ', 'PtfmTAX', & + 'PtfmTAY', 'PtfmTAZ', 'PtfmRAX', 'PtfmRAY', 'PtfmRAZ', & + 'CC_DesiredL', 'CC_ActuatedL', 'CC_ActuatedDL', 'StC_Input', 'Flp_Angle', & + 'RootMyb_Last', 'ACC_INFILE_SIZE', 'AWC_complexangle', 'ZMQ_ID', 'ZMQ_YawOffset', & + 'ZMQ_TorqueOffset', 'ZMQ_PitOffset', 'ZMQ_R_Speed', 'ZMQ_R_Torque', 'ZMQ_R_Pitch' & + ] ! Initialize debug file IF ((LocalVar%iStatus == 0) .OR. (LocalVar%iStatus == -9)) THEN ! .TRUE. if we're on the first call to the DLL IF (CntrPar%LoggingLevel > 0) THEN @@ -918,8 +928,8 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av CALL GetNewUnit(UnDb2, ErrVar) OPEN(unit=UnDb2, FILE=TRIM(RootName)//'.RO.dbg2') WRITE(UnDb2, *) 'Generated on '//CurDate()//' at '//CurTime()//' using ROSCO-'//TRIM(rosco_version) - WRITE(UnDb2, '(143(a20,TR5:))') 'Time', LocalVarOutStrings - WRITE(UnDb2, '(143(a20,TR5:))') + WRITE(UnDb2, '(146(a20,TR5:))') 'Time', LocalVarOutStrings + WRITE(UnDb2, '(146(a20,TR5:))') END IF IF (CntrPar%LoggingLevel > 2) THEN @@ -982,7 +992,7 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av END DO ! Write debug files - FmtDat = "(F20.5,TR5,142(ES20.5E2,TR5:))" ! The format of the debugging data + FmtDat = "(F20.5,TR5,145(ES20.5E2,TR5:))" ! The format of the debugging data IF ( MOD(LocalVar%n_DT, CntrPar%n_DT_Out) == 0) THEN IF(CntrPar%LoggingLevel > 0) THEN WRITE (UnDb, TRIM(FmtDat)) LocalVar%Time, DebugOutData diff --git a/rosco/controller/src/ROSCO_Types.f90 b/rosco/controller/src/ROSCO_Types.f90 index 5125d190..a6b2b9d6 100644 --- a/rosco/controller/src/ROSCO_Types.f90 +++ b/rosco/controller/src/ROSCO_Types.f90 @@ -377,6 +377,9 @@ MODULE ROSCO_Types REAL(DbKi) :: PS_Min_Pitch ! Instantaneous peak shaving REAL(DbKi) :: OL_Index ! Open loop indexing variable (time or wind speed) INTEGER(IntKi) :: SD_Trigger ! Shutdown trigger (1 - shutdown due to pitch, 2 - shutdown due to yaw error, 3 - shutdown due to generator speed, 4 - shutdown due to time) + REAL(DbKi) :: SD_BlPitchF ! Blade pitch signal filtered for shutdown + REAL(DbKi) :: SD_NacVaneF ! Nacelle vane signal filtered for shutdown + REAL(DbKi) :: SD_GenSpeedF ! Generator speed signal filtered for shutdown REAL(DbKi) :: GenTq_SD ! Electrical generator torque command for shutdown, [Nm]. REAL(DbKi) :: Fl_PitCom ! Shutdown, .FALSE. if inactive, .TRUE. if active REAL(DbKi) :: NACIMU_FA_AccF ! None From 96f1f54586a17824adab4828a70d55e6693753b2 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Sat, 23 Nov 2024 18:39:08 -0700 Subject: [PATCH 14/33] Shutdown: Add comments and minor code edit --- rosco/controller/src/Controllers.f90 | 3 +++ rosco/controller/src/DISCON.F90 | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/rosco/controller/src/Controllers.f90 b/rosco/controller/src/Controllers.f90 index 36d5593a..9a8f20f7 100644 --- a/rosco/controller/src/Controllers.f90 +++ b/rosco/controller/src/Controllers.f90 @@ -138,6 +138,7 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst, DebugVar, ErrVar) ! Shutdown IF (LocalVar%SD_Trigger == 0) THEN LocalVar%PitCom_SD = LocalVar%PitCom + ! If shutdown is not triggered, PitCom_SD tracks PitCom. ELSE IF (CntrPar%SD_Method == 1) THEN !Only SD_Method==1 supported for now DO K = 1,LocalVar%NumBl @@ -145,6 +146,8 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst, DebugVar, ErrVar) END DO ENDIF LocalVar%PitCom = LocalVar%PitCom_SD + ! When shutdown is triggered (SD_Trigger \=0), pitch to feather. + ! Note that in some instances (like a downwind rotor), we may want to pitch to a stall angle. ENDIF diff --git a/rosco/controller/src/DISCON.F90 b/rosco/controller/src/DISCON.F90 index 32a04ea4..4fb6477e 100644 --- a/rosco/controller/src/DISCON.F90 +++ b/rosco/controller/src/DISCON.F90 @@ -100,7 +100,9 @@ SUBROUTINE DISCON(avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAME CALL UpdateZeroMQ(LocalVar, CntrPar, ErrVar) ENDIF - CALL Shutdown(LocalVar, CntrPar, objInst,ErrVar) + IF (CntrPar%SD_Mode \= 0) THEN + CALL Shutdown(LocalVar, CntrPar, objInst,ErrVar) + ENDIF CALL WindSpeedEstimator(LocalVar, CntrPar, objInst, PerfData, DebugVar, ErrVar) CALL ComputeVariablesSetpoints(CntrPar, LocalVar, objInst, DebugVar, ErrVar) CALL StateMachine(CntrPar, LocalVar) From 809e632b36450d80e3c5e86b93fec3a42e0b6cde Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Sat, 23 Nov 2024 21:51:42 -0700 Subject: [PATCH 15/33] Shutdown: Use wrapping for filtering nacelle vane signal --- rosco/controller/src/ControllerBlocks.f90 | 9 +++++++-- rosco/controller/src/DISCON.F90 | 2 +- rosco/toolbox/controller.py | 6 ------ 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/rosco/controller/src/ControllerBlocks.f90 b/rosco/controller/src/ControllerBlocks.f90 index a3cce6c1..be29339f 100644 --- a/rosco/controller/src/ControllerBlocks.f90 +++ b/rosco/controller/src/ControllerBlocks.f90 @@ -524,6 +524,8 @@ SUBROUTINE Shutdown(LocalVar, CntrPar, objInst,ErrVar) ! Local Variables CHARACTER(*), PARAMETER :: RoutineName = 'VariableSpeedControl' + REAL(DbKi) :: SD_NacVaneCosF ! Time-filtered x-component of NacVane (deg) + REAL(DbKi) :: SD_NacVaneSinF ! Time-filtered y-component of NacVane (deg) !Initialize shutdown trigger variable IF (LocalVar%iStatus == 0) THEN @@ -533,10 +535,13 @@ SUBROUTINE Shutdown(LocalVar, CntrPar, objInst,ErrVar) ! Filter pitch signal LocalVar%SD_BlPitchF = LPFilter(LocalVar%PC_PitComT, LocalVar%DT, CntrPar%SD_PitchCornerFreq, LocalVar%FP,LocalVar%iStatus, LocalVar%restart, objInst%instLPF) - ! Filter yaw error signal (NacVane) - LocalVar%SD_NacVaneF = LPFilter(LocalVar%NacVane, LocalVar%DT, CntrPar%SD_YawErrorCornerFreq, LocalVar%FP,LocalVar%iStatus, LocalVar%restart, objInst%instLPF) ! Filter yaw generator speed LocalVar%SD_GenSpeedF = LPFilter(LocalVar%Genspeed, LocalVar%DT, CntrPar%SD_GenSpdCornerFreq, LocalVar%FP,LocalVar%iStatus, LocalVar%restart, objInst%instLPF) + + ! Filter yaw error signal (NacVane) + SD_NacVaneCosF = LPFilter(cos(LocalVar%NacVane*D2R), LocalVar%DT, CntrPar%SD_YawErrorCornerFreq, LocalVar%FP,LocalVar%iStatus, LocalVar%restart, objInst%instLPF) + SD_NacVaneSinF = LPFilter(sin(LocalVar%NacVane*D2R), LocalVar%DT, CntrPar%SD_YawErrorCornerFreq, LocalVar%FP,LocalVar%iStatus, LocalVar%restart, objInst%instLPF) + LocalVar%SD_NacVaneF = wrap_180(atan2(SD_NacVaneSinF, SD_NacVaneCosF) * R2D) ! (in deg) ! See if we should shutdown IF (LocalVar%SD_Trigger == 0) THEN diff --git a/rosco/controller/src/DISCON.F90 b/rosco/controller/src/DISCON.F90 index 4fb6477e..6f5cdfe4 100644 --- a/rosco/controller/src/DISCON.F90 +++ b/rosco/controller/src/DISCON.F90 @@ -100,7 +100,7 @@ SUBROUTINE DISCON(avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAME CALL UpdateZeroMQ(LocalVar, CntrPar, ErrVar) ENDIF - IF (CntrPar%SD_Mode \= 0) THEN + IF (CntrPar%SD_Mode /= 0) THEN CALL Shutdown(LocalVar, CntrPar, objInst,ErrVar) ENDIF CALL WindSpeedEstimator(LocalVar, CntrPar, objInst, PerfData, DebugVar, ErrVar) diff --git a/rosco/toolbox/controller.py b/rosco/toolbox/controller.py index b8266bd3..e23eaf12 100644 --- a/rosco/toolbox/controller.py +++ b/rosco/toolbox/controller.py @@ -362,12 +362,6 @@ def tune_controller(self, turbine): self.vs_minspd = (turbine.TSR_operational * turbine.v_min / turbine.rotor_radius) self.pc_minspd = self.vs_minspd - # max pitch angle for shutdown - # if self.sd_maxpit: - # self.sd_maxpit = self.sd_maxpit - # else: - # self.sd_maxpit = pitch_op[-1] - # Set IPC ramp inputs if not already defined if max(self.IPC_Vramp) == 0.0: self.IPC_Vramp = [turbine.v_rated*0.8, turbine.v_rated] From f674adcf0c1ab42a2a260513a442961565b66f24 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Sat, 23 Nov 2024 23:54:11 -0700 Subject: [PATCH 16/33] Shutdown: Remove optional shutdown inputs from minimal_discon.in --- Examples/example_inputs/minimal_DISCON.IN | 18 +------------ rosco/controller/src/ReadSetParameters.f90 | 30 ++++++++++++---------- 2 files changed, 17 insertions(+), 31 deletions(-) diff --git a/Examples/example_inputs/minimal_DISCON.IN b/Examples/example_inputs/minimal_DISCON.IN index 2d80a6d3..1b972078 100644 --- a/Examples/example_inputs/minimal_DISCON.IN +++ b/Examples/example_inputs/minimal_DISCON.IN @@ -91,23 +91,7 @@ Extra lines that ROSCO doesn't care about anymore 3.0000 3.2897 3.5793 3.8690 4.1586 4.4483 4.7379 5.0276 5.3172 5.6069 5.8966 6.1862 6.4759 6.7655 7.0552 7.3448 7.6345 7.9241 8.2138 8.5034 8.7931 9.0828 9.3724 9.6621 9.9517 10.2414 10.5310 10.8207 11.1103 11.4000 11.8533 12.3067 12.7600 13.2133 13.6667 14.1200 14.5733 15.0267 15.4800 15.9333 16.3867 16.8400 17.2933 17.7467 18.2000 18.6533 19.1067 19.5600 20.0133 20.4667 20.9200 21.3733 21.8267 22.2800 22.7333 23.1867 23.6400 24.0933 24.5467 25.0000 ! PS_WindSpeeds - Wind speeds corresponding to minimum blade pitch angles [m/s] 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.00088027 0.01116187 0.02310060 0.03164156 0.03968639 0.04741131 0.05899071 0.07019329 0.08090119 0.09141661 0.10169361 0.11174124 0.12170066 0.13137494 0.14103377 0.15048120 0.15989580 0.16913227 0.17831010 0.18739638 0.19643591 0.20537011 0.21419674 0.22293719 0.23161365 0.24025975 0.24885012 0.25735704 0.26578040 0.27407178 0.28233051 0.29047594 0.29867838 0.30674517 0.31490089 0.32284411 ! PS_BldPitchMin - Minimum blade pitch angles [rad] -!------- SHUTDOWN ----------------------------------------------------------- -0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] -0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] -0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] -0 ! SD_EnableTime - Shutdown at a predefined time, [-] -0.436300000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] -0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] -0.523600000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad] -0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] -10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] -0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] -9999.000000000 ! SD_Time - Shutdown time, [s] -1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] -22000.00000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] -0.174500000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] - !------- Floating ----------------------------------------------------------- 0.000000000000 ! Fl_Kp - Nacelle velocity proportional feedback gain [s] -Extra lines that ROSCO doesn't care about anymore \ No newline at end of file +Extra lines that ROSCO doesn't care about anymore diff --git a/rosco/controller/src/ReadSetParameters.f90 b/rosco/controller/src/ReadSetParameters.f90 index a06ba6dd..ac97bc9a 100644 --- a/rosco/controller/src/ReadSetParameters.f90 +++ b/rosco/controller/src/ReadSetParameters.f90 @@ -1409,23 +1409,25 @@ SUBROUTINE CheckInputs(LocalVar, CntrPar, avrSWAP, ErrVar, size_avcMSG) ENDIF ! --- Shutdown --- + IF (CntrPar%SD_Mode > 0) THEN - ! SD_Method - IF (CntrPar%SD_Method /= 1) THEN - ErrVar%aviFAIL = -1 - ErrVar%ErrMsg = 'SD_Method must be 1.' - ENDIF + ! SD_Method + IF (CntrPar%SD_Method /= 1) THEN + ErrVar%aviFAIL = -1 + ErrVar%ErrMsg = 'SD_Method must be 1.' + ENDIF - ! SD_MaxPitchRate - IF (CntrPar%SD_MaxPitchRate > CntrPar%PC_MaxRat) THEN - ErrVar%aviFAIL = -1 - ErrVar%ErrMsg = 'SD_MaxPitchRate should be less or equal to PC_MaxRat.' - ENDIF + ! SD_MaxPitchRate + IF (CntrPar%SD_MaxPitchRate > CntrPar%PC_MaxRat) THEN + ErrVar%aviFAIL = -1 + ErrVar%ErrMsg = 'SD_MaxPitchRate should be less or equal to PC_MaxRat.' + ENDIF - ! SD_MaxTorqueRate - IF (CntrPar%SD_MaxTorqueRate > CntrPar%VS_MaxRat) THEN - ErrVar%aviFAIL = -1 - ErrVar%ErrMsg = 'SD_MaxTorqueRate should be less or equal to VS_MaxRat.' + ! SD_MaxTorqueRate + IF (CntrPar%SD_MaxTorqueRate > CntrPar%VS_MaxRat) THEN + ErrVar%aviFAIL = -1 + ErrVar%ErrMsg = 'SD_MaxTorqueRate should be less or equal to VS_MaxRat.' + ENDIF ENDIF ! --- Open loop control --- From cca0117c316d6df1da4fa340a58f5760b663b1b7 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Sun, 24 Nov 2024 01:11:04 -0700 Subject: [PATCH 17/33] Shutdown: Set defaults for various shutdown parameters --- rosco/toolbox/controller.py | 13 ------------- rosco/toolbox/inputs/toolbox_schema.yaml | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/rosco/toolbox/controller.py b/rosco/toolbox/controller.py index e23eaf12..8ccfd0fc 100644 --- a/rosco/toolbox/controller.py +++ b/rosco/toolbox/controller.py @@ -97,19 +97,6 @@ def __init__(self, controller_params): self.Ki_ipc2p = controller_params['IPC_Kp2p'] self.IPC_Vramp = controller_params['IPC_Vramp'] self.ZMQ_UpdatePeriod = controller_params['ZMQ_UpdatePeriod'] - ## shutdownparameters - self.sd_enablepitch = controller_params['sd_enablepitch'] - self.sd_enableyawerror = controller_params['sd_enableyawerror'] - self.sd_enablegenspeed = controller_params['sd_enablegenspeed'] - self.sd_enabletime = controller_params['sd_enabletime'] - self.sd_maxpit = controller_params['sd_maxpit'] - self.sd_maxyawerror = controller_params['sd_maxyawerror'] - self.sd_maxgenspd = controller_params['sd_maxgenspd'] - self.sd_time = controller_params['sd_time'] - self.sd_method = controller_params['sd_method'] - #self.sd_maxtorquerate = controller_params['sd_maxtorquerate'] - #self.sd_maxpitchrate = controller_params['sd_maxpitchrate'] - # Optional parameters without defaults if self.Flp_Mode > 0: diff --git a/rosco/toolbox/inputs/toolbox_schema.yaml b/rosco/toolbox/inputs/toolbox_schema.yaml index 12e40a24..3befd612 100644 --- a/rosco/toolbox/inputs/toolbox_schema.yaml +++ b/rosco/toolbox/inputs/toolbox_schema.yaml @@ -1077,46 +1077,68 @@ properties: SD_EnablePitch: type: number description: Shutdown when collective blade pitch exceeds a threshold + minimum: 0 + maximum: 1 + default: 0 SD_EnableYawError: type: number description: Shutdown when yaw error exceeds a threshold + minimum: 0 + maximum: 1 + default: 0 SD_EnableGenSpeed: type: number description: Shutdown when generator speed exceeds a threshold + minimum: 0 + maximum: 1 + default: 0 SD_EnableTime: type: number description: Shutdown at a predefined time + minimum: 0 + maximum: 1 + default: 0 SD_MaxPit: type: number description: Maximum blade pitch angle to initiate shutdown units: rad + default: 0.6981 SD_PitchCornerFreq: type: number description: Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, units: rad/s + default: 0.41888 SD_MaxYawError: type: number description: Maximum yaw error to initiate shutdown units: rad + default: 0.5236 SD_YawErrorCornerFreq: type: number description: Cutoff Frequency for first order low-pass filter for yaw error for shutdown units: rad/s + default: 0.41888 SD_MaxGenSpd: type: number description: Maximum generator speed to initiate shutdown units: rad/s + default: 10 SD_GenSpdCornerFreq: type: number description: Cutoff Frequency for first order low-pass filter for generator speed for shutdown units: rad/s + default: 0.41888 SD_Time: type: number description: Shutdown time units: s + default: 9999 SD_Method: type: number description: Shutdown method {1- Reduce generator torque and increase blade pitch} + minimum: 1 + maximum: 1 + default: 1 SD_MaxTorqueRate: type: number description: Maximum torque rate for shutdown From e36bffbc2fbd7d976f846a5c3ad9c3c90135bbea Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Sun, 24 Nov 2024 01:44:55 -0700 Subject: [PATCH 18/33] Shutdown: Cleanup --- rosco/controller/src/ControllerBlocks.f90 | 5 ----- rosco/controller/src/DISCON.F90 | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/rosco/controller/src/ControllerBlocks.f90 b/rosco/controller/src/ControllerBlocks.f90 index be29339f..47612759 100644 --- a/rosco/controller/src/ControllerBlocks.f90 +++ b/rosco/controller/src/ControllerBlocks.f90 @@ -136,11 +136,6 @@ SUBROUTINE ComputeVariablesSetpoints(CntrPar, LocalVar, objInst, DebugVar, ErrVa LocalVar%VS_RefSpd = LocalVar%VS_RefSpd - LocalVar%SS_DelOmegaF ENDIF - ! Force zero torque in shutdown mode - !IF (LocalVar%SD_Trigger) THEN - ! LocalVar%VS_RefSpd = CntrPar%VS_MinOMSpd - !ENDIF - ! Force minimum rotor speed LocalVar%VS_RefSpd = max(LocalVar%VS_RefSpd, CntrPar%VS_MinOmSpd) diff --git a/rosco/controller/src/DISCON.F90 b/rosco/controller/src/DISCON.F90 index 6f5cdfe4..90f34317 100644 --- a/rosco/controller/src/DISCON.F90 +++ b/rosco/controller/src/DISCON.F90 @@ -100,7 +100,7 @@ SUBROUTINE DISCON(avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAME CALL UpdateZeroMQ(LocalVar, CntrPar, ErrVar) ENDIF - IF (CntrPar%SD_Mode /= 0) THEN + IF (CntrPar%SD_Mode > 0) THEN CALL Shutdown(LocalVar, CntrPar, objInst,ErrVar) ENDIF CALL WindSpeedEstimator(LocalVar, CntrPar, objInst, PerfData, DebugVar, ErrVar) From ad24b832cb3726f6b71836dea854e2986cf9d013 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Sun, 24 Nov 2024 17:23:57 -0700 Subject: [PATCH 19/33] Shutdown: Specify defaults for shutdown parameters in toolbox --- rosco/toolbox/utilities.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/rosco/toolbox/utilities.py b/rosco/toolbox/utilities.py index 57c07d4f..74a7a903 100644 --- a/rosco/toolbox/utilities.py +++ b/rosco/toolbox/utilities.py @@ -612,20 +612,20 @@ def DISCON_dict(turbine, controller, txt_filename=None): DISCON_dict['PS_WindSpeeds'] = controller.v DISCON_dict['PS_BldPitchMin'] = controller.ps_min_bld_pitch # ------- SHUTDOWN ------- - DISCON_dict['SD_EnablePitch'] = controller.sd_enablepitch - DISCON_dict['SD_EnableYawError'] = controller.sd_enableyawerror - DISCON_dict['SD_EnableGenSpeed'] = controller.sd_enablegenspeed - DISCON_dict['SD_EnableTime'] = controller.sd_enabletime - DISCON_dict['SD_MaxPit'] = controller.sd_maxpit - DISCON_dict['SD_PitchCornerFreq'] = controller.f_sd_pitchcornerfreq - DISCON_dict['SD_MaxYawError'] = controller.sd_maxyawerror - DISCON_dict['SD_YawErrorCornerFreq'] = controller.f_sd_yawerrorcornerfreq - DISCON_dict['SD_MaxGenSpd'] = controller.sd_maxgenspd - DISCON_dict['SD_GenSpdCornerFreq'] = controller.f_sd_genspdcornerfreq - DISCON_dict['SD_Time'] = controller.sd_time - DISCON_dict['SD_Method'] = controller.sd_method - DISCON_dict['SD_MaxTorqueRate'] = turbine.max_torque_rate - DISCON_dict['SD_MaxPitchRate'] = turbine.max_pitch_rate + DISCON_dict['SD_EnablePitch'] = 0 + DISCON_dict['SD_EnableYawError'] = 0 + DISCON_dict['SD_EnableGenSpeed'] = 0 + DISCON_dict['SD_EnableTime'] = 0 + DISCON_dict['SD_MaxPit'] = 0.6981 + DISCON_dict['SD_PitchCornerFreq'] = controller.f_sd_pitchcornerfreq + DISCON_dict['SD_MaxYawError'] = 0.5236 + DISCON_dict['SD_YawErrorCornerFreq']= controller.f_sd_yawerrorcornerfreq + DISCON_dict['SD_MaxGenSpd'] = 10 + DISCON_dict['SD_GenSpdCornerFreq'] = controller.f_sd_genspdcornerfreq + DISCON_dict['SD_Time'] = 9999 + DISCON_dict['SD_Method'] = 1 + DISCON_dict['SD_MaxTorqueRate'] = turbine.max_torque_rate + DISCON_dict['SD_MaxPitchRate'] = turbine.max_pitch_rate # ------- Floating ------- DISCON_dict['Fl_n'] = len(controller.Kp_float) DISCON_dict['Fl_Kp'] = controller.Kp_float From 651cb0178c215681981bad03e950f3bf23361879 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Wed, 4 Dec 2024 08:11:25 -0700 Subject: [PATCH 20/33] Shutdown: Add example 30_shutdown.py to regression test list --- rosco/test/test_examples.py | 1 + 1 file changed, 1 insertion(+) diff --git a/rosco/test/test_examples.py b/rosco/test/test_examples.py index 38539bdf..e7994007 100644 --- a/rosco/test/test_examples.py +++ b/rosco/test/test_examples.py @@ -33,6 +33,7 @@ '27_soft_cut_out', '28_tower_resonance', '29_power_control', + '30_shutdown', 'update_rosco_discons', ] From e1d51cf41075e194f302576a46e7fffd8e43803c Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Wed, 4 Dec 2024 08:13:42 -0700 Subject: [PATCH 21/33] Shutdown: Correced the unit of SD_MaxYawError from rad to deg --- Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN | 2 +- .../Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN | 2 +- Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN | 2 +- Examples/Test_Cases/NREL-5MW/DISCON.IN | 2 +- Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN | 2 +- Examples/example_inputs/DISCON_v2.2.0.IN | 4 ++-- Examples/example_inputs/minimal_DISCON_err.IN | 4 ++-- rosco/controller/rosco_registry/rosco_types.yaml | 2 +- rosco/controller/src/ROSCO_Types.f90 | 2 +- rosco/toolbox/inputs/toolbox_schema.yaml | 4 ++-- rosco/toolbox/utilities.py | 4 ++-- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN b/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN index b7c95aae..ca936e92 100644 --- a/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN +++ b/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN @@ -151,7 +151,7 @@ 0 ! SD_EnableTime - Shutdown at a predefined time, [-]​ 0.5236 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​ 0.4189 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​ -0.5236 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ +30.000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ 0.4189 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] 10.000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​ 0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ diff --git a/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN b/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN index 1b6063a0..dc0d2c34 100644 --- a/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN +++ b/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN @@ -151,7 +151,7 @@ 0 ! SD_EnableTime - Shutdown at a predefined time, [-]​ 0.5236 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​ 0.4189 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​ -0.5236 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ +30.000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ 0.4189 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] 10.000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​ 0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ diff --git a/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN b/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN index 5b47c8df..1c24b780 100644 --- a/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN +++ b/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN @@ -151,7 +151,7 @@ 0 ! SD_EnableTime - Shutdown at a predefined time, [-]​ 0.5236 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​ 0.4189 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​ -0.5236 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ +30.000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ 0.4189 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] 10.000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​ 0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ diff --git a/Examples/Test_Cases/NREL-5MW/DISCON.IN b/Examples/Test_Cases/NREL-5MW/DISCON.IN index 7a9d9fbb..99d86597 100644 --- a/Examples/Test_Cases/NREL-5MW/DISCON.IN +++ b/Examples/Test_Cases/NREL-5MW/DISCON.IN @@ -151,7 +151,7 @@ 0 ! SD_EnableTime - Shutdown at a predefined time, [-]​ 0.5236 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​ 0.4189 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​ -0.5236 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ +30.000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ 0.4189 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] 10.000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​ 0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ diff --git a/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN b/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN index 70c515c2..d442a141 100644 --- a/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN +++ b/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN @@ -151,7 +151,7 @@ 0 ! SD_EnableTime - Shutdown at a predefined time, [-]​ 0.5236 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​ 0.4189 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​ -0.5236 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ +30.000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ 0.4189 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] 10.000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​ 0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ diff --git a/Examples/example_inputs/DISCON_v2.2.0.IN b/Examples/example_inputs/DISCON_v2.2.0.IN index 7dae6e8d..8e9ffd0d 100644 --- a/Examples/example_inputs/DISCON_v2.2.0.IN +++ b/Examples/example_inputs/DISCON_v2.2.0.IN @@ -112,7 +112,7 @@ 0 ! SD_EnableTime - Shutdown at a predefined time, [-] 0.436300000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] 0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] -0.523600000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad] +30.00000000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad] 0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] 10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] 0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] @@ -128,4 +128,4 @@ 0.000000000000 ! Flp_Angle - Initial or steady state flap angle [rad] 0.00000000e+00 ! Flp_Kp - Blade root bending moment proportional gain for flap control [s] 0.00000000e+00 ! Flp_Ki - Flap displacement integral gain for flap control [s] -0.000000000000 ! Flp_MaxPit - Maximum (and minimum) flap pitch angle [rad] \ No newline at end of file +0.000000000000 ! Flp_MaxPit - Maximum (and minimum) flap pitch angle [rad] diff --git a/Examples/example_inputs/minimal_DISCON_err.IN b/Examples/example_inputs/minimal_DISCON_err.IN index a8229dc9..a103ae6e 100644 --- a/Examples/example_inputs/minimal_DISCON_err.IN +++ b/Examples/example_inputs/minimal_DISCON_err.IN @@ -100,7 +100,7 @@ Extra lines that ROSCO doesn't care about anymore 0 ! SD_EnableTime - Shutdown at a predefined time, [-] 0.436300000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] 0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] -0.523600000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad] +30.00000000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad] 0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] 10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] 0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] @@ -112,4 +112,4 @@ Extra lines that ROSCO doesn't care about anymore !------- Floating ----------------------------------------------------------- 0.000000000000 ! Fl_Kp - Nacelle velocity proportional feedback gain [s] -Extra lines that ROSCO doesn't care about anymore \ No newline at end of file +Extra lines that ROSCO doesn't care about anymore diff --git a/rosco/controller/rosco_registry/rosco_types.yaml b/rosco/controller/rosco_registry/rosco_types.yaml index 71b65b9b..50c4c39f 100644 --- a/rosco/controller/rosco_registry/rosco_types.yaml +++ b/rosco/controller/rosco_registry/rosco_types.yaml @@ -485,7 +485,7 @@ ControlParameters: description: Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] SD_MaxYawError: <<: *real - description: Maximum yaw error to initiate shutdown, [rad] + description: Maximum yaw error to initiate shutdown, [deg] SD_YawErrorCornerFreq: <<: *real description: Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] diff --git a/rosco/controller/src/ROSCO_Types.f90 b/rosco/controller/src/ROSCO_Types.f90 index a6b2b9d6..bad16b43 100644 --- a/rosco/controller/src/ROSCO_Types.f90 +++ b/rosco/controller/src/ROSCO_Types.f90 @@ -126,7 +126,7 @@ MODULE ROSCO_Types INTEGER(IntKi) :: SD_EnableTime ! Shutdown at a predefined time, [-] REAL(DbKi) :: SD_MaxPit ! Maximum blade pitch angle to initiate shutdown, [rad] REAL(DbKi) :: SD_PitchCornerFreq ! Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] - REAL(DbKi) :: SD_MaxYawError ! Maximum yaw error to initiate shutdown, [rad] + REAL(DbKi) :: SD_MaxYawError ! Maximum yaw error to initiate shutdown, [deg] REAL(DbKi) :: SD_YawErrorCornerFreq ! Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] REAL(DbKi) :: SD_MaxGenSpd ! Maximum generator speed to initiate shutdown, [rad/s] REAL(DbKi) :: SD_GenSpdCornerFreq ! Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] diff --git a/rosco/toolbox/inputs/toolbox_schema.yaml b/rosco/toolbox/inputs/toolbox_schema.yaml index 3befd612..02093132 100644 --- a/rosco/toolbox/inputs/toolbox_schema.yaml +++ b/rosco/toolbox/inputs/toolbox_schema.yaml @@ -1111,8 +1111,8 @@ properties: SD_MaxYawError: type: number description: Maximum yaw error to initiate shutdown - units: rad - default: 0.5236 + units: deg + default: 30.0 SD_YawErrorCornerFreq: type: number description: Cutoff Frequency for first order low-pass filter for yaw error for shutdown diff --git a/rosco/toolbox/utilities.py b/rosco/toolbox/utilities.py index 74a7a903..e00f7ef3 100644 --- a/rosco/toolbox/utilities.py +++ b/rosco/toolbox/utilities.py @@ -239,7 +239,7 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('{0:<12d} ! SD_EnableTime - Shutdown at a predefined time, [-]\n'.format(int(rosco_vt['SD_EnableTime']))) file.write('{:<014.5f} ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]\n'.format(rosco_vt['SD_MaxPit'])) file.write('{:<014.5f} ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]\n'.format(rosco_vt['SD_PitchCornerFreq'])) - file.write('{:<014.5f} ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]\n'.format(rosco_vt['SD_MaxYawError'])) + file.write('{:<014.5f} ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg]\n'.format(rosco_vt['SD_MaxYawError'])) file.write('{:<014.5f} ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s]\n'.format(rosco_vt['SD_YawErrorCornerFreq'])) file.write('{:<014.5f} ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]\n'.format(rosco_vt['SD_MaxGenSpd'])) file.write('{:<014.5f} ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] \n'.format(rosco_vt['SD_GenSpdCornerFreq'])) @@ -618,7 +618,7 @@ def DISCON_dict(turbine, controller, txt_filename=None): DISCON_dict['SD_EnableTime'] = 0 DISCON_dict['SD_MaxPit'] = 0.6981 DISCON_dict['SD_PitchCornerFreq'] = controller.f_sd_pitchcornerfreq - DISCON_dict['SD_MaxYawError'] = 0.5236 + DISCON_dict['SD_MaxYawError'] = 30 DISCON_dict['SD_YawErrorCornerFreq']= controller.f_sd_yawerrorcornerfreq DISCON_dict['SD_MaxGenSpd'] = 10 DISCON_dict['SD_GenSpdCornerFreq'] = controller.f_sd_genspdcornerfreq From 5de5cd38ff23241c45bb56d55154b250e5be89c7 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Wed, 4 Dec 2024 09:44:01 -0700 Subject: [PATCH 22/33] Shutdown: Run update_rosco_discons.py to update the DISCON.IN files in Examples/Test_Cases --- Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN | 34 +++++++++---------- .../DISCON-UMaineSemi.IN | 34 +++++++++---------- Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN | 34 +++++++++---------- Examples/Test_Cases/NREL-5MW/DISCON.IN | 34 +++++++++---------- .../NREL_2p8_127/NREL-2p8-127_DISCON.IN | 34 +++++++++---------- 5 files changed, 85 insertions(+), 85 deletions(-) diff --git a/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN b/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN index ca936e92..e9f99885 100644 --- a/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN +++ b/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the BAR_10 wind turbine -! - File written using ROSCO version 2.9.4 controller tuning logic on 09/03/24 +! - File written using ROSCO version 2.9.4 controller tuning logic on 12/04/24 !------- SIMULATION CONTROL ------------------------------------------------------------ 1 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -18,7 +18,7 @@ 0 ! PRC_Mode - Power reference tracking mode{0: power control disabled, 1: lookup table from wind speed to generator speed setpoints, 2: change speed, torque, pitch to control power} 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 - Pitch saturation mode {0: no pitch saturation, 1: implement pitch saturation} -0 ! SD_Mode - Shutdown mode {0: no shutdown procedure, 1: pitch to max pitch at shutdown} +0 ! SD_Mode - Shutdown mode {0: no shutdown procedure, 1: shutdown enabled} 0 ! Fl_Mode - Floating specific feedback mode {0: no nacelle velocity feedback, 1: feed back translational velocity, 2: feed back rotational veloicty} 0 ! TD_Mode - Tower damper mode (0- no tower damper, 1- feed back translational nacelle accelleration to pitch angle 0 ! TRA_Mode - Tower resonance avoidance mode (0- no tower resonsnace avoidance, 1- use torque control setpoints to avoid a specific frequency @@ -81,7 +81,7 @@ 70282.09458000 ! VS_MaxTq - Maximum generator torque in Region 3 (HSS side), [Nm]. 0.000000000000 ! VS_MinTq - Minimum generator torque (HSS side), [Nm]. 27.49717000000 ! VS_MinOMSpd - Minimum generator speed [rad/s] -11.20801000000 ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side). Only used in VS_ControlMode = 1,3 +11.43674000000 ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side). Only used in VS_ControlMode = 1,3 5000000.000000 ! VS_RtPwr - Wind turbine rated power [W] 63892.81326000 ! VS_RtTq - Rated torque, [Nm]. 75.83317000000 ! VS_RefSpd - Rated generator speed [rad/s] @@ -145,20 +145,20 @@ -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.012 0.000 0.011 0.020 0.029 0.041 0.056 0.069 0.082 0.095 0.108 0.120 0.132 0.143 0.155 0.166 0.178 0.189 0.200 0.211 0.222 0.232 0.243 0.254 0.264 0.274 0.285 0.295 0.305 0.315 0.325 0.335 0.344 0.354 0.364 0.373 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]​ -0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]​ -0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]​ -0 ! SD_EnableTime - Shutdown at a predefined time, [-]​ -0.5236 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​ -0.4189 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​ -30.000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ -0.4189 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] -10.000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​ -0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ -9999.00 ! SD_Time - Shutdown time, [s]​ -1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch},​ [-]​ -62000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ -2.00 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] +0 ! SD_EnableTime - Shutdown at a predefined time, [-] +0.698100000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] +0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] +30.00000000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg] +0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] +0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] +9999.000000000 ! SD_Time - Shutdown time, [s] +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] +62000.00000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] +2.000000000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN b/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN index dc0d2c34..efa83986 100644 --- a/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN +++ b/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the IEA-15-240-RWT-UMaineSemi wind turbine -! - File written using ROSCO version 2.9.4 controller tuning logic on 09/03/24 +! - File written using ROSCO version 2.9.4 controller tuning logic on 12/04/24 !------- SIMULATION CONTROL ------------------------------------------------------------ 2 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -18,7 +18,7 @@ 0 ! PRC_Mode - Power reference tracking mode{0: power control disabled, 1: lookup table from wind speed to generator speed setpoints, 2: change speed, torque, pitch to control power} 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 - Pitch saturation mode {0: no pitch saturation, 1: implement pitch saturation} -0 ! SD_Mode - Shutdown mode {0: no shutdown procedure, 1: pitch to max pitch at shutdown} +0 ! SD_Mode - Shutdown mode {0: no shutdown procedure, 1: shutdown enabled} 2 ! Fl_Mode - Floating specific feedback mode {0: no nacelle velocity feedback, 1: feed back translational velocity, 2: feed back rotational veloicty} 0 ! TD_Mode - Tower damper mode (0- no tower damper, 1- feed back translational nacelle accelleration to pitch angle 0 ! TRA_Mode - Tower resonance avoidance mode (0- no tower resonsnace avoidance, 1- use torque control setpoints to avoid a specific frequency @@ -81,7 +81,7 @@ 21765444.21450 ! VS_MaxTq - Maximum generator torque in Region 3 (HSS side), [Nm]. 0.000000000000 ! VS_MinTq - Minimum generator torque (HSS side), [Nm]. 0.523600000000 ! VS_MinOMSpd - Minimum generator speed [rad/s] -32413847.90763 ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side). Only used in VS_ControlMode = 1,3 +33850461.49341 ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side). Only used in VS_ControlMode = 1,3 15000000.00000 ! VS_RtPwr - Wind turbine rated power [W] 19786767.46773 ! VS_RtTq - Rated torque, [Nm]. 0.791680000000 ! VS_RefSpd - Rated generator speed [rad/s] @@ -145,20 +145,20 @@ 0.060 0.060 0.060 0.060 0.060 0.060 0.056 0.052 0.047 0.041 0.036 0.029 0.022 0.015 0.008 0.001 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.006 0.021 0.033 0.044 0.053 0.064 0.074 0.084 0.093 0.103 0.112 0.121 0.130 0.138 0.147 0.155 0.163 0.172 0.180 0.188 0.196 0.203 0.211 0.219 0.227 0.234 0.242 0.250 0.257 0.265 0.272 0.279 0.287 0.294 0.301 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]​ -0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]​ -0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]​ -0 ! SD_EnableTime - Shutdown at a predefined time, [-]​ -0.5236 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​ -0.4189 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​ -30.000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ -0.4189 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] -10.000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​ -0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ -9999.00 ! SD_Time - Shutdown time, [s]​ -1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch},​ [-]​ -4500000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ -0.03490 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] +0 ! SD_EnableTime - Shutdown at a predefined time, [-] +0.698100000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] +0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] +30.00000000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg] +0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] +0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] +9999.000000000 ! SD_Time - Shutdown time, [s] +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] +4500000.000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] +0.034900000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN b/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN index 1c24b780..a0914eb6 100644 --- a/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN +++ b/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the MHK_RM1_Floating wind turbine -! - File written using ROSCO version 2.9.4 controller tuning logic on 09/03/24 +! - File written using ROSCO version 2.9.4 controller tuning logic on 12/04/24 !------- SIMULATION CONTROL ------------------------------------------------------------ 2 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -18,7 +18,7 @@ 0 ! PRC_Mode - Power reference tracking mode{0: power control disabled, 1: lookup table from wind speed to generator speed setpoints, 2: change speed, torque, pitch to control power} 0 ! 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 - Pitch saturation mode {0: no pitch saturation, 1: implement pitch saturation} -0 ! SD_Mode - Shutdown mode {0: no shutdown procedure, 1: pitch to max pitch at shutdown} +0 ! SD_Mode - Shutdown mode {0: no shutdown procedure, 1: shutdown enabled} 1 ! Fl_Mode - Floating specific feedback mode {0: no nacelle velocity feedback, 1: feed back translational velocity, 2: feed back rotational veloicty} 0 ! TD_Mode - Tower damper mode (0- no tower damper, 1- feed back translational nacelle accelleration to pitch angle 0 ! TRA_Mode - Tower resonance avoidance mode (0- no tower resonsnace avoidance, 1- use torque control setpoints to avoid a specific frequency @@ -81,7 +81,7 @@ 12450.50344000 ! VS_MaxTq - Maximum generator torque in Region 3 (HSS side), [Nm]. 0.000000000000 ! VS_MinTq - Minimum generator torque (HSS side), [Nm]. 19.00309000000 ! VS_MinOMSpd - Minimum generator speed [rad/s] -1.142870000000 ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side). Only used in VS_ControlMode = 1,3 +1.210670000000 ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side). Only used in VS_ControlMode = 1,3 500000.0000000 ! VS_RtPwr - Wind turbine rated power [W] 8300.335630000 ! VS_RtTq - Rated torque, [Nm]. 63.81200000000 ! VS_RefSpd - Rated generator speed [rad/s] @@ -145,20 +145,20 @@ 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]​ -0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]​ -0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]​ -0 ! SD_EnableTime - Shutdown at a predefined time, [-]​ -0.5236 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​ -0.4189 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​ -30.000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ -0.4189 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] -10.000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​ -0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ -9999.00 ! SD_Time - Shutdown time, [s]​ -1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch},​ [-]​ -7800 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ -0.1745 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] +0 ! SD_EnableTime - Shutdown at a predefined time, [-] +0.698100000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] +0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] +30.00000000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg] +0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] +0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] +9999.000000000 ! SD_Time - Shutdown time, [s] +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] +7800.000000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] +0.174500000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/Examples/Test_Cases/NREL-5MW/DISCON.IN b/Examples/Test_Cases/NREL-5MW/DISCON.IN index 99d86597..c543845d 100644 --- a/Examples/Test_Cases/NREL-5MW/DISCON.IN +++ b/Examples/Test_Cases/NREL-5MW/DISCON.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the NREL-5MW wind turbine -! - File written using ROSCO version 2.9.4 controller tuning logic on 09/03/24 +! - File written using ROSCO version 2.9.4 controller tuning logic on 12/04/24 !------- SIMULATION CONTROL ------------------------------------------------------------ 1 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -18,7 +18,7 @@ 0 ! PRC_Mode - Power reference tracking mode{0: power control disabled, 1: lookup table from wind speed to generator speed setpoints, 2: change speed, torque, pitch to control power} 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 - Pitch saturation mode {0: no pitch saturation, 1: implement pitch saturation} -0 ! SD_Mode - Shutdown mode {0: no shutdown procedure, 1: pitch to max pitch at shutdown} +0 ! SD_Mode - Shutdown mode {0: no shutdown procedure, 1: shutdown enabled} 0 ! Fl_Mode - Floating specific feedback mode {0: no nacelle velocity feedback, 1: feed back translational velocity, 2: feed back rotational veloicty} 0 ! TD_Mode - Tower damper mode (0- no tower damper, 1- feed back translational nacelle accelleration to pitch angle 0 ! TRA_Mode - Tower resonance avoidance mode (0- no tower resonsnace avoidance, 1- use torque control setpoints to avoid a specific frequency @@ -81,7 +81,7 @@ 47402.87063000 ! VS_MaxTq - Maximum generator torque in Region 3 (HSS side), [Nm]. 0.000000000000 ! VS_MinTq - Minimum generator torque (HSS side), [Nm]. 35.29006000000 ! VS_MinOMSpd - Minimum generator speed [rad/s] -2.063350000000 ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side). Only used in VS_ControlMode = 1,3 +2.185750000000 ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side). Only used in VS_ControlMode = 1,3 5000000.000000 ! VS_RtPwr - Wind turbine rated power [W] 43093.51876000 ! VS_RtTq - Rated torque, [Nm]. 122.9096700000 ! VS_RefSpd - Rated generator speed [rad/s] @@ -145,20 +145,20 @@ 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.011 0.023 0.032 0.040 0.047 0.059 0.070 0.081 0.091 0.102 0.112 0.122 0.131 0.141 0.150 0.160 0.169 0.178 0.187 0.196 0.205 0.214 0.223 0.232 0.240 0.249 0.257 0.266 0.274 0.282 0.290 0.299 0.307 0.315 0.323 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]​ -0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]​ -0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]​ -0 ! SD_EnableTime - Shutdown at a predefined time, [-]​ -0.5236 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​ -0.4189 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​ -30.000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ -0.4189 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] -10.000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​ -0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ -9999.00 ! SD_Time - Shutdown time, [s]​ -1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch},​ [-]​ -4500000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ -0.03490 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] +0 ! SD_EnableTime - Shutdown at a predefined time, [-] +0.698100000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] +0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] +30.00000000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg] +0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] +0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] +9999.000000000 ! SD_Time - Shutdown time, [s] +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] +40000.00000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] +0.174500000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN b/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN index d442a141..319beb00 100644 --- a/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN +++ b/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the NREL-2p8-127 wind turbine -! - File written using ROSCO version 2.9.4 controller tuning logic on 09/03/24 +! - File written using ROSCO version 2.9.4 controller tuning logic on 12/04/24 !------- SIMULATION CONTROL ------------------------------------------------------------ 2 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -18,7 +18,7 @@ 0 ! PRC_Mode - Power reference tracking mode{0: power control disabled, 1: lookup table from wind speed to generator speed setpoints, 2: change speed, torque, pitch to control power} 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 - Pitch saturation mode {0: no pitch saturation, 1: implement pitch saturation} -0 ! SD_Mode - Shutdown mode {0: no shutdown procedure, 1: pitch to max pitch at shutdown} +0 ! SD_Mode - Shutdown mode {0: no shutdown procedure, 1: shutdown enabled} 0 ! Fl_Mode - Floating specific feedback mode {0: no nacelle velocity feedback, 1: feed back translational velocity, 2: feed back rotational veloicty} 0 ! TD_Mode - Tower damper mode (0- no tower damper, 1- feed back translational nacelle accelleration to pitch angle 0 ! TRA_Mode - Tower resonance avoidance mode (0- no tower resonsnace avoidance, 1- use torque control setpoints to avoid a specific frequency @@ -81,7 +81,7 @@ 26673.40024000 ! VS_MaxTq - Maximum generator torque in Region 3 (HSS side), [Nm]. 0.000000000000 ! VS_MinTq - Minimum generator torque (HSS side), [Nm]. 37.81562000000 ! VS_MinOMSpd - Minimum generator speed [rad/s] -1.654680000000 ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side). Only used in VS_ControlMode = 1,3 +1.761280000000 ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side). Only used in VS_ControlMode = 1,3 2800000.000000 ! VS_RtPwr - Wind turbine rated power [W] 24248.54567000 ! VS_RtTq - Rated torque, [Nm]. 122.9096700000 ! VS_RefSpd - Rated generator speed [rad/s] @@ -145,20 +145,20 @@ 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.019 0.031 0.041 0.050 0.058 0.066 0.074 0.086 0.096 0.107 0.117 0.127 0.137 0.147 0.156 0.165 0.174 0.183 0.192 0.201 0.210 0.218 0.227 0.236 0.244 0.253 0.262 0.270 0.279 0.287 0.295 0.303 0.312 0.320 0.328 0.337 0.345 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]​ -0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]​ -0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]​ -0 ! SD_EnableTime - Shutdown at a predefined time, [-]​ -0.5236 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]​ -0.4189 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]​ -30.000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [rad]​ -0.4189 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] -10.000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]​ -0.4189 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] ​ -9999.00 ! SD_Time - Shutdown time, [s]​ -1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch},​ [-]​ -22000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]​ -0.1745 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]​ +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] +0 ! SD_EnableTime - Shutdown at a predefined time, [-] +0.698100000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] +0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] +30.00000000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg] +0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] +0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] +9999.000000000 ! SD_Time - Shutdown time, [s] +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] +22000.00000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] +0.174500000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 From 20f383d7a4d01559508865ae60257e1fead36b52 Mon Sep 17 00:00:00 2001 From: dzalkind Date: Wed, 4 Dec 2024 10:02:35 -0700 Subject: [PATCH 23/33] Add mpi_tools to rosco --- rosco/toolbox/ofTools/case_gen/run_FAST.py | 6 +- rosco/toolbox/ofTools/util/mpi_tools.py | 139 +++++++++++++++++++++ 2 files changed, 142 insertions(+), 3 deletions(-) create mode 100644 rosco/toolbox/ofTools/util/mpi_tools.py diff --git a/rosco/toolbox/ofTools/case_gen/run_FAST.py b/rosco/toolbox/ofTools/case_gen/run_FAST.py index 49061f5b..160a4d40 100644 --- a/rosco/toolbox/ofTools/case_gen/run_FAST.py +++ b/rosco/toolbox/ofTools/case_gen/run_FAST.py @@ -22,13 +22,13 @@ try: from weis.aeroelasticse.runFAST_pywrapper import runFAST_pywrapper_batch in_weis = True -except Exception: +except Exception as e: from rosco.toolbox.ofTools.case_gen.runFAST_pywrapper import runFAST_pywrapper_batch in_weis = False #from rosco.toolbox.ofTools.case_gen.CaseGen_IEC import CaseGen_IEC from rosco.toolbox.ofTools.case_gen.CaseGen_General import CaseGen_General from rosco.toolbox.ofTools.case_gen import CaseLibrary as cl -from wisdem.commonse.mpi_tools import MPI +from openmdao.utils.mpi import MPI # Globals this_dir = os.path.dirname(os.path.abspath(__file__)) @@ -160,7 +160,7 @@ def run_FAST(self): # Management of parallelization, leave in for now if MPI: - from wisdem.commonse.mpi_tools import map_comm_heirarchical, subprocessor_loop, subprocessor_stop + from rosco.toolbox.ofTools.util.mpi_tools import map_comm_heirarchical, subprocessor_loop, subprocessor_stop n_OF_runs = len(case_list) available_cores = MPI.COMM_WORLD.Get_size() diff --git a/rosco/toolbox/ofTools/util/mpi_tools.py b/rosco/toolbox/ofTools/util/mpi_tools.py new file mode 100644 index 00000000..e53fcc85 --- /dev/null +++ b/rosco/toolbox/ofTools/util/mpi_tools.py @@ -0,0 +1,139 @@ +import os +import sys + +from openmdao.utils.mpi import MPI + + +def under_mpirun(): + """Return True if we're being executed under mpirun.""" + # this is a bit of a hack, but there appears to be + # no consistent set of environment vars between MPI + # implementations. + for name in os.environ.keys(): + if ( + name == "OMPI_COMM_WORLD_RANK" + or name == "MPIEXEC_HOSTNAME" + or name.startswith("MPIR_") + or name.startswith("MPICH_") + or name.startswith("INTEL_ONEAPI_MPI_") + or name.startswith("I_MPI_") + ): + return True + return False + + +if under_mpirun(): + + def debug(*msg): # pragma: no cover + newmsg = ["%d: " % MPI.COMM_WORLD.rank] + list(msg) + for m in newmsg: + sys.stdout.write("%s " % m) + sys.stdout.write("\n") + sys.stdout.flush() + +else: + MPI = None + + +def map_comm_heirarchical(n_DV, n_OF, openmp=False): + """ + Heirarchical parallelization communicator mapping. Assumes a number of top level processes + equal to the number of design variables (x2 if central finite differencing is used), each + with its associated number of openfast simulations. + When openmp flag is turned on, the code spreads the openfast simulations across nodes to + lavereage the opnemp parallelization of OpenFAST. The cores that will run under openmp, are marked + in the color map as 1000000. The ones handling python and the DV are marked as 0, and + finally the master ones for each openfast run are marked with a 1. + """ + if openmp: + n_procs_per_node = 36 # Number of + num_procs = MPI.COMM_WORLD.Get_size() + n_nodes = num_procs / n_procs_per_node + + comm_map_down = {} + comm_map_up = {} + color_map = [1000000] * num_procs + + n_DV_per_node = n_DV / n_nodes + + # for m in range(n_DV_per_node): + for nn in range(int(n_nodes)): + for n_dv in range(int(n_DV_per_node)): + comm_map_down[nn * n_procs_per_node + n_dv] = [ + int(n_DV_per_node) + n_dv * n_OF + nn * (n_procs_per_node) + j for j in range(n_OF) + ] + + # This core handles python, so in the colormap the entry is 0 + color_map[nn * n_procs_per_node + n_dv] = int(0) + # These cores handles openfast, so in the colormap the entry is 1 + for k in comm_map_down[nn * n_procs_per_node + n_dv]: + color_map[k] = int(1) + + for j in comm_map_down[nn * n_procs_per_node + n_dv]: + comm_map_up[j] = nn * n_procs_per_node + n_dv + else: + N = n_DV + n_DV * n_OF + comm_map_down = {} + comm_map_up = {} + color_map = [0] * n_DV + + for i in range(n_DV): + comm_map_down[i] = [n_DV + j + i * n_OF for j in range(n_OF)] + color_map.extend([i + 1] * n_OF) + + for j in comm_map_down[i]: + comm_map_up[j] = i + + return comm_map_down, comm_map_up, color_map + + +def subprocessor_loop(comm_map_up): + """ + Subprocessors loop, waiting to receive a function and its arguements to evaluate. + Output of the function is returned. Loops until a stop signal is received + + Input data format: + data[0] = function to be evaluated + data[1] = [list of arguments] + If the function to be evaluated does not fit this format, then a wrapper function + should be created and passed, that handles the setup, argument assignment, etc + for the actual function. + + Stop sigal: + data[0] = False + """ + # comm = impl.world_comm() + rank = MPI.COMM_WORLD.Get_rank() + rank_target = comm_map_up[rank] + + keep_running = True + while keep_running: + data = MPI.COMM_WORLD.recv(source=(rank_target), tag=0) + if data[0] == False: + break + else: + func_execution = data[0] + args = data[1] + output = func_execution(args) + MPI.COMM_WORLD.send(output, dest=(rank_target), tag=1) + + +def subprocessor_stop(comm_map_down): + """ + Send stop signal to subprocessors + """ + # comm = MPI.COMM_WORLD + for rank in comm_map_down.keys(): + subranks = comm_map_down[rank] + for subrank_i in subranks: + MPI.COMM_WORLD.send([False], dest=subrank_i, tag=0) + print("All MPI subranks closed.") + + +if __name__ == "__main__": + + ( + _, + _, + _, + ) = map_comm_heirarchical(2, 4) From b419f9de69c2b64f8938511ecfbd1d33733a8250 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Mon, 9 Dec 2024 22:23:10 -0700 Subject: [PATCH 24/33] Shutdown: Add SD_TimeActivate to enable delaying activate of shutdown --- Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN | 31 ++++++++++--------- .../DISCON-UMaineSemi.IN | 31 ++++++++++--------- Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN | 31 ++++++++++--------- Examples/Test_Cases/NREL-5MW/DISCON.IN | 31 ++++++++++--------- .../NREL_2p8_127/NREL-2p8-127_DISCON.IN | 31 ++++++++++--------- Examples/example_inputs/DISCON_v2.2.0.IN | 1 + .../rosco_registry/rosco_types.yaml | 3 ++ rosco/controller/src/DISCON.F90 | 2 +- rosco/controller/src/ROSCO_Types.f90 | 1 + rosco/controller/src/ReadSetParameters.f90 | 25 ++++++++------- rosco/toolbox/inputs/toolbox_schema.yaml | 5 +++ rosco/toolbox/utilities.py | 29 ++++++++--------- 12 files changed, 119 insertions(+), 102 deletions(-) diff --git a/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN b/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN index e9f99885..4fcf58c8 100644 --- a/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN +++ b/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the BAR_10 wind turbine -! - File written using ROSCO version 2.9.4 controller tuning logic on 12/04/24 +! - File written using ROSCO version 2.9.4 controller tuning logic on 12/09/24 !------- SIMULATION CONTROL ------------------------------------------------------------ 1 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -145,20 +145,21 @@ -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.012 0.000 0.011 0.020 0.029 0.041 0.056 0.069 0.082 0.095 0.108 0.120 0.132 0.143 0.155 0.166 0.178 0.189 0.200 0.211 0.222 0.232 0.243 0.254 0.264 0.274 0.285 0.295 0.305 0.315 0.325 0.335 0.344 0.354 0.364 0.373 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] -0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] -0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] -0 ! SD_EnableTime - Shutdown at a predefined time, [-] -0.698100000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] -0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] -30.00000000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg] -0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] -10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] -0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] -9999.000000000 ! SD_Time - Shutdown time, [s] -1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] -62000.00000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] -2.000000000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] +0 ! SD_TimeActivate - Time to acitvate shutdown modes, [-] +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] +0 ! SD_EnableTime - Shutdown at a predefined time, [-] +0.698100000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] +0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] +30.00000000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg] +0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] +0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] +9999.000000000 ! SD_Time - Shutdown time, [s] +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] +62000.00000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] +2.000000000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN b/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN index efa83986..68fa5bc7 100644 --- a/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN +++ b/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the IEA-15-240-RWT-UMaineSemi wind turbine -! - File written using ROSCO version 2.9.4 controller tuning logic on 12/04/24 +! - File written using ROSCO version 2.9.4 controller tuning logic on 12/09/24 !------- SIMULATION CONTROL ------------------------------------------------------------ 2 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -145,20 +145,21 @@ 0.060 0.060 0.060 0.060 0.060 0.060 0.056 0.052 0.047 0.041 0.036 0.029 0.022 0.015 0.008 0.001 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.006 0.021 0.033 0.044 0.053 0.064 0.074 0.084 0.093 0.103 0.112 0.121 0.130 0.138 0.147 0.155 0.163 0.172 0.180 0.188 0.196 0.203 0.211 0.219 0.227 0.234 0.242 0.250 0.257 0.265 0.272 0.279 0.287 0.294 0.301 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] -0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] -0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] -0 ! SD_EnableTime - Shutdown at a predefined time, [-] -0.698100000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] -0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] -30.00000000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg] -0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] -10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] -0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] -9999.000000000 ! SD_Time - Shutdown time, [s] -1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] -4500000.000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] -0.034900000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] +0 ! SD_TimeActivate - Time to acitvate shutdown modes, [-] +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] +0 ! SD_EnableTime - Shutdown at a predefined time, [-] +0.698100000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] +0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] +30.00000000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg] +0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] +0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] +9999.000000000 ! SD_Time - Shutdown time, [s] +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] +4500000.000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] +0.034900000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN b/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN index a0914eb6..600772ca 100644 --- a/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN +++ b/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the MHK_RM1_Floating wind turbine -! - File written using ROSCO version 2.9.4 controller tuning logic on 12/04/24 +! - File written using ROSCO version 2.9.4 controller tuning logic on 12/09/24 !------- SIMULATION CONTROL ------------------------------------------------------------ 2 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -145,20 +145,21 @@ 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] -0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] -0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] -0 ! SD_EnableTime - Shutdown at a predefined time, [-] -0.698100000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] -0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] -30.00000000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg] -0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] -10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] -0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] -9999.000000000 ! SD_Time - Shutdown time, [s] -1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] -7800.000000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] -0.174500000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] +0 ! SD_TimeActivate - Time to acitvate shutdown modes, [-] +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] +0 ! SD_EnableTime - Shutdown at a predefined time, [-] +0.698100000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] +0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] +30.00000000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg] +0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] +0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] +9999.000000000 ! SD_Time - Shutdown time, [s] +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] +7800.000000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] +0.174500000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/Examples/Test_Cases/NREL-5MW/DISCON.IN b/Examples/Test_Cases/NREL-5MW/DISCON.IN index c543845d..b8675448 100644 --- a/Examples/Test_Cases/NREL-5MW/DISCON.IN +++ b/Examples/Test_Cases/NREL-5MW/DISCON.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the NREL-5MW wind turbine -! - File written using ROSCO version 2.9.4 controller tuning logic on 12/04/24 +! - File written using ROSCO version 2.9.4 controller tuning logic on 12/09/24 !------- SIMULATION CONTROL ------------------------------------------------------------ 1 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -145,20 +145,21 @@ 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.011 0.023 0.032 0.040 0.047 0.059 0.070 0.081 0.091 0.102 0.112 0.122 0.131 0.141 0.150 0.160 0.169 0.178 0.187 0.196 0.205 0.214 0.223 0.232 0.240 0.249 0.257 0.266 0.274 0.282 0.290 0.299 0.307 0.315 0.323 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] -0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] -0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] -0 ! SD_EnableTime - Shutdown at a predefined time, [-] -0.698100000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] -0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] -30.00000000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg] -0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] -10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] -0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] -9999.000000000 ! SD_Time - Shutdown time, [s] -1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] -40000.00000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] -0.174500000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] +0 ! SD_TimeActivate - Time to acitvate shutdown modes, [-] +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] +0 ! SD_EnableTime - Shutdown at a predefined time, [-] +0.698100000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] +0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] +30.00000000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg] +0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] +0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] +9999.000000000 ! SD_Time - Shutdown time, [s] +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] +40000.00000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] +0.174500000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN b/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN index 319beb00..83a50d9c 100644 --- a/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN +++ b/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the NREL-2p8-127 wind turbine -! - File written using ROSCO version 2.9.4 controller tuning logic on 12/04/24 +! - File written using ROSCO version 2.9.4 controller tuning logic on 12/09/24 !------- SIMULATION CONTROL ------------------------------------------------------------ 2 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -145,20 +145,21 @@ 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.019 0.031 0.041 0.050 0.058 0.066 0.074 0.086 0.096 0.107 0.117 0.127 0.137 0.147 0.156 0.165 0.174 0.183 0.192 0.201 0.210 0.218 0.227 0.236 0.244 0.253 0.262 0.270 0.279 0.287 0.295 0.303 0.312 0.320 0.328 0.337 0.345 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] -0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] -0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] -0 ! SD_EnableTime - Shutdown at a predefined time, [-] -0.698100000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] -0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] -30.00000000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg] -0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] -10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] -0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] -9999.000000000 ! SD_Time - Shutdown time, [s] -1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] -22000.00000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] -0.174500000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] +0 ! SD_TimeActivate - Time to acitvate shutdown modes, [-] +0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] +0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] +0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] +0 ! SD_EnableTime - Shutdown at a predefined time, [-] +0.698100000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] +0.418880000000 ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] +30.00000000000 ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg] +0.418880000000 ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] +10.00000000000 ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s] +0.418880000000 ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] +9999.000000000 ! SD_Time - Shutdown time, [s] +1 ! SD_Method - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] +22000.00000000 ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s] +0.174500000000 ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s] !------- Floating ----------------------------------------------------------- 1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1 diff --git a/Examples/example_inputs/DISCON_v2.2.0.IN b/Examples/example_inputs/DISCON_v2.2.0.IN index 8e9ffd0d..6aac9ab7 100644 --- a/Examples/example_inputs/DISCON_v2.2.0.IN +++ b/Examples/example_inputs/DISCON_v2.2.0.IN @@ -106,6 +106,7 @@ 0.06108652 0.06108652 0.06108652 0.05672320 0.04799655 0.03926991 0.02617994 0.01308997 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- +0 ! SD_TimeActivate - Time to acitvate shutdown modes, [-] 0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] 0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] 0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] diff --git a/rosco/controller/rosco_registry/rosco_types.yaml b/rosco/controller/rosco_registry/rosco_types.yaml index 50c4c39f..f02d29c9 100644 --- a/rosco/controller/rosco_registry/rosco_types.yaml +++ b/rosco/controller/rosco_registry/rosco_types.yaml @@ -465,6 +465,9 @@ ControlParameters: SD_Mode: <<: *integer description: Shutdown mode {0 - no shutdown procedure, 1 - enable shutdown} + SD_TimeActivate: + <<: *real + description: Time to acitvate shutdown modes, [s] SD_EnablePitch: <<: *integer description: Shutdown when collective blade pitch exceeds a threshold, [-] diff --git a/rosco/controller/src/DISCON.F90 b/rosco/controller/src/DISCON.F90 index 90f34317..85874853 100644 --- a/rosco/controller/src/DISCON.F90 +++ b/rosco/controller/src/DISCON.F90 @@ -100,7 +100,7 @@ SUBROUTINE DISCON(avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAME CALL UpdateZeroMQ(LocalVar, CntrPar, ErrVar) ENDIF - IF (CntrPar%SD_Mode > 0) THEN + IF ((CntrPar%SD_Mode > 0) .AND. (LocalVar%Time>=CntrPar%SD_TimeActivate)) THEN CALL Shutdown(LocalVar, CntrPar, objInst,ErrVar) ENDIF CALL WindSpeedEstimator(LocalVar, CntrPar, objInst, PerfData, DebugVar, ErrVar) diff --git a/rosco/controller/src/ROSCO_Types.f90 b/rosco/controller/src/ROSCO_Types.f90 index bad16b43..c7bd7ebb 100644 --- a/rosco/controller/src/ROSCO_Types.f90 +++ b/rosco/controller/src/ROSCO_Types.f90 @@ -120,6 +120,7 @@ MODULE ROSCO_Types REAL(DbKi), DIMENSION(:), ALLOCATABLE :: PS_WindSpeeds ! Wind speeds corresponding to minimum blade pitch angles [m/s] REAL(DbKi), DIMENSION(:), ALLOCATABLE :: PS_BldPitchMin ! Minimum blade pitch angles [rad] INTEGER(IntKi) :: SD_Mode ! Shutdown mode {0 - no shutdown procedure, 1 - enable shutdown} + REAL(DbKi) :: SD_TimeActivate ! Time to acitvate shutdown modes, [s] INTEGER(IntKi) :: SD_EnablePitch ! Shutdown when collective blade pitch exceeds a threshold, [-] INTEGER(IntKi) :: SD_EnableYawError ! Shutdown when yaw error exceeds a threshold, [-] INTEGER(IntKi) :: SD_EnableGenSpeed ! Shutdown when generator speed exceeds a threshold, [-] diff --git a/rosco/controller/src/ReadSetParameters.f90 b/rosco/controller/src/ReadSetParameters.f90 index ac97bc9a..e3399afa 100644 --- a/rosco/controller/src/ReadSetParameters.f90 +++ b/rosco/controller/src/ReadSetParameters.f90 @@ -514,20 +514,21 @@ SUBROUTINE ReadControlParameterFileSub(CntrPar, LocalVar, accINFILE, accINFILE_s IF (ErrVar%aviFAIL < 0) RETURN !------------ SHUTDOWN ------------ - CALL ParseInput(FileLines, 'SD_EnablePitch', CntrPar%SD_EnablePitch, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) - CALL ParseInput(FileLines, 'SD_EnableYawError', CntrPar%SD_EnableYawError, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) - CALL ParseInput(FileLines, 'SD_EnableGenSpeed', CntrPar%SD_EnableGenSpeed, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) - CALL ParseInput(FileLines, 'SD_EnableTime', CntrPar%SD_EnableTime, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) - CALL ParseInput(FileLines, 'SD_MaxPit', CntrPar%SD_MaxPit, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) - CALL ParseInput(FileLines, 'SD_PitchCornerFreq', CntrPar%SD_PitchCornerFreq, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) - CALL ParseInput(FileLines, 'SD_MaxYawError', CntrPar%SD_MaxYawError, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) - CALL ParseInput(FileLines, 'SD_YawErrorCornerFreq', CntrPar%SD_YawErrorCornerFreq, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_TimeActivate', CntrPar%SD_TimeActivate, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_EnablePitch', CntrPar%SD_EnablePitch, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_EnableYawError', CntrPar%SD_EnableYawError,accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_EnableGenSpeed', CntrPar%SD_EnableGenSpeed,accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_EnableTime', CntrPar%SD_EnableTime, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_MaxPit', CntrPar%SD_MaxPit, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_PitchCornerFreq', CntrPar%SD_PitchCornerFreq, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_MaxYawError', CntrPar%SD_MaxYawError, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_YawErrorCornerFreq', CntrPar%SD_YawErrorCornerFreq,accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) CALL ParseInput(FileLines, 'SD_MaxGenSpd', CntrPar%SD_MaxGenSpd, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) - CALL ParseInput(FileLines, 'SD_GenSpdCornerFreq', CntrPar%SD_GenSpdCornerFreq, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_GenSpdCornerFreq', CntrPar%SD_GenSpdCornerFreq, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) CALL ParseInput(FileLines, 'SD_Time', CntrPar%SD_Time, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) - CALL ParseInput(FileLines, 'SD_Method', CntrPar%SD_Method, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) - CALL ParseInput(FileLines, 'SD_MaxTorqueRate', CntrPar%SD_MaxTorqueRate, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) - CALL ParseInput(FileLines, 'SD_MaxPitchRate', CntrPar%SD_MaxPitchRate, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_Method', CntrPar%SD_Method, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_MaxTorqueRate', CntrPar%SD_MaxTorqueRate, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) + CALL ParseInput(FileLines, 'SD_MaxPitchRate', CntrPar%SD_MaxPitchRate, accINFILE(1), ErrVar, CntrPar%SD_Mode == 0, UnEc) IF (ErrVar%aviFAIL < 0) RETURN !------------ FLOATING ------------ diff --git a/rosco/toolbox/inputs/toolbox_schema.yaml b/rosco/toolbox/inputs/toolbox_schema.yaml index 02093132..c68d7a88 100644 --- a/rosco/toolbox/inputs/toolbox_schema.yaml +++ b/rosco/toolbox/inputs/toolbox_schema.yaml @@ -1074,6 +1074,11 @@ properties: type: number description: Minimum blade pitch angles units: rad + SD_TimeActivate: + type: number + description: Time to acitvate shutdown modes + units: s + default: 0 SD_EnablePitch: type: number description: Shutdown when collective blade pitch exceeds a threshold diff --git a/rosco/toolbox/utilities.py b/rosco/toolbox/utilities.py index e00f7ef3..8e2e396c 100644 --- a/rosco/toolbox/utilities.py +++ b/rosco/toolbox/utilities.py @@ -233,20 +233,21 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('{} ! PS_BldPitchMin - Minimum blade pitch angles [rad]\n'.format(''.join('{:<10.3f} '.format(rosco_vt['PS_BldPitchMin'][i]) for i in range(len(rosco_vt['PS_BldPitchMin']))))) file.write('\n') file.write('!------- SHUTDOWN -----------------------------------------------------------\n') - file.write('{0:<12d} ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]\n'.format(int(rosco_vt['SD_EnablePitch']))) - file.write('{0:<12d} ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]\n'.format(int(rosco_vt['SD_EnableYawError']))) - file.write('{0:<12d} ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]\n'.format(int(rosco_vt['SD_EnableGenSpeed']))) - file.write('{0:<12d} ! SD_EnableTime - Shutdown at a predefined time, [-]\n'.format(int(rosco_vt['SD_EnableTime']))) - file.write('{:<014.5f} ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]\n'.format(rosco_vt['SD_MaxPit'])) - file.write('{:<014.5f} ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]\n'.format(rosco_vt['SD_PitchCornerFreq'])) - file.write('{:<014.5f} ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg]\n'.format(rosco_vt['SD_MaxYawError'])) - file.write('{:<014.5f} ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s]\n'.format(rosco_vt['SD_YawErrorCornerFreq'])) - file.write('{:<014.5f} ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]\n'.format(rosco_vt['SD_MaxGenSpd'])) - file.write('{:<014.5f} ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] \n'.format(rosco_vt['SD_GenSpdCornerFreq'])) - file.write('{:<014.5f} ! SD_Time - Shutdown time, [s]\n'.format(rosco_vt['SD_Time'])) - file.write('{0:<12d} ! SD_Method - Shutdown method {{1: Reduce generator torque and increase blade pitch}}, [-]\n'.format(int(rosco_vt['SD_Method']))) - file.write('{:<014.5f} ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]\n'.format(rosco_vt['SD_MaxTorqueRate'])) - file.write('{:<014.5f} ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]\n'.format(rosco_vt['SD_MaxPitchRate'])) + file.write('{0:<12d} ! SD_TimeActivate - Time to acitvate shutdown modes, [-]\n'.format(int(rosco_vt['SD_TimeActivate']))) + file.write('{0:<12d} ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]\n'.format(int(rosco_vt['SD_EnablePitch']))) + file.write('{0:<12d} ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]\n'.format(int(rosco_vt['SD_EnableYawError']))) + file.write('{0:<12d} ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]\n'.format(int(rosco_vt['SD_EnableGenSpeed']))) + file.write('{0:<12d} ! SD_EnableTime - Shutdown at a predefined time, [-]\n'.format(int(rosco_vt['SD_EnableTime']))) + file.write('{:<014.5f} ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad]\n'.format(rosco_vt['SD_MaxPit'])) + file.write('{:<014.5f} ! SD_PitchCornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s]\n'.format(rosco_vt['SD_PitchCornerFreq'])) + file.write('{:<014.5f} ! SD_MaxYawError - Maximum yaw error to initiate shutdown, [deg]\n'.format(rosco_vt['SD_MaxYawError'])) + file.write('{:<014.5f} ! SD_YawErrorCornerFreq - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s]\n'.format(rosco_vt['SD_YawErrorCornerFreq'])) + file.write('{:<014.5f} ! SD_MaxGenSpd - Maximum generator speed to initiate shutdown, [rad/s]\n'.format(rosco_vt['SD_MaxGenSpd'])) + file.write('{:<014.5f} ! SD_GenSpdCornerFreq - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] \n'.format(rosco_vt['SD_GenSpdCornerFreq'])) + file.write('{:<014.5f} ! SD_Time - Shutdown time, [s]\n'.format(rosco_vt['SD_Time'])) + file.write('{0:<12d} ! SD_Method - Shutdown method {{1: Reduce generator torque and increase blade pitch}}, [-]\n'.format(int(rosco_vt['SD_Method']))) + file.write('{:<014.5f} ! SD_MaxTorqueRate - Maximum torque rate for shutdown, [Nm/s]\n'.format(rosco_vt['SD_MaxTorqueRate'])) + file.write('{:<014.5f} ! SD_MaxPitchRate - Maximum pitch rate used for shutdown, [rad/s]\n'.format(rosco_vt['SD_MaxPitchRate'])) file.write('\n') file.write('!------- Floating -----------------------------------------------------------\n') if rosco_vt['Fl_Mode'] == 2: From 8709b8b9f5a3e9e08af99f24b8d51c94fdbdd722 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Wed, 11 Dec 2024 00:17:46 -0700 Subject: [PATCH 25/33] Shutdown: Add docstring to example 30_shutdown and remove time mode of shutdown --- Examples/30_shutdown.py | 43 +++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/Examples/30_shutdown.py b/Examples/30_shutdown.py index d319ec83..44554d4b 100644 --- a/Examples/30_shutdown.py +++ b/Examples/30_shutdown.py @@ -1,7 +1,43 @@ """ 30_shutdown ---------------- -This example demonstrates turbine shutdown. +This example demonstrates turbine shutdown using collective blade pitch threshold mode. + +ROSCO allows for four shutdown trigger options: + +- collective blade pitch exceeds a threshold +- yaw error exceeds a threshold +- generator speed exceeds a threshold +- Shutdown at a predefined time + + +Pitch Threshold Demo +```````````````````` +The following plot demonstrates turbine shutdown when blade pitch exceeds a threshold of 30 degrees. +This shutdown mode can provide protection against high wind speeds. + +.. image:: ../images/30_shutdown_pitch_demo.png + +Yaw Error Threshold Demo +```````````````````````` +The following plot demonstrates turbine shutdown when turbine yaw error pitch exceeds a threshold of 25 degrees. +This demonstration uses the extreme coherent gust with direction change wind inflow used in DLC 1.4. + +.. image:: ../images/30_shutdown_yaw_demo.png + +Generator Speed Threshold Demo +`````````````````````````````` +The following plot demonstrates turbine shutdown when generator speed exceeds a threshold of 8.5 rpm. +This also compares the use of `SD_TimeActive` to enable shutdown at 0 seconds and 10 seconds. + +.. image:: ../images/30_shutdown_gen_demo.png + +Time Demo +````````` +The following plot demonstrates turbine shutdown at 20 second time. + +.. image:: ../images/30_shutdown_time_demo.png + """ import os @@ -21,9 +57,6 @@ def main(): - # Test Config - FULL_TEST = False # FULL_TEST for local testing, otherwise shorter for CI - # Input yaml and output directory parameter_filename = os.path.join(this_dir, "Tune_Cases/IEA15MW.yaml") @@ -37,8 +70,6 @@ def main(): controller_params["DISCON"]["SD_MaxPit"] = 30*deg2rad controller_params["DISCON"]["SD_MaxPitchRate"] = 0.0348 controller_params["DISCON"]["SD_MaxTorqueRate"] = 4500000 - controller_params["DISCON"]["SD_EnableTime"] = 1 - controller_params["DISCON"]["SD_Time"] = 20 # simulation set up r = run_FAST_ROSCO() From 11a264a417b3cc29e54e2c47eb9d4ee9a1f34323 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Wed, 11 Dec 2024 00:20:41 -0700 Subject: [PATCH 26/33] Shutdown: Add example 30 documentation to docs --- docs/source/examples.rst | 1 + docs/source/rosco.rst | 58 +++++++++++++++++++++++++++++++++-- docs/source/toolbox_input.rst | 47 ++++++++++++++++++++++++++-- 3 files changed, 100 insertions(+), 6 deletions(-) diff --git a/docs/source/examples.rst b/docs/source/examples.rst index da451271..37d5891e 100644 --- a/docs/source/examples.rst +++ b/docs/source/examples.rst @@ -132,3 +132,4 @@ A complete list of examples is given below: .. automodule:: 27_soft_cut_out .. automodule:: 28_tower_resonance .. automodule:: 29_power_control +.. automodule:: 30_shutdown diff --git a/docs/source/rosco.rst b/docs/source/rosco.rst index 167e7fff..1b1907cd 100644 --- a/docs/source/rosco.rst +++ b/docs/source/rosco.rst @@ -378,13 +378,65 @@ Examples of the DISCON.IN file are found in each of the Test Cases in the ROSCO - Float array, length = :code:`PS_BldPitchMin_n` - Minimum blade pitch angles [rad] * - SHUTDOWN + - :code:`SD_TimeActivate` + - Float + - Time to acitvate shutdown modes ,[s] + * - + - :code:`SD_EnablePitch` + - Int + - Shutdown when collective blade pitch exceeds a threshold, [-] + * - + - :code:`SD_EnableYawError` + - Int + - Shutdown when yaw error exceeds a threshold, [-] + * - + - :code:`SD_EnableGenSpeed` + - Int + - Shutdown when generator speed exceeds a threshold, [-] + * - + - :code:`SD_EnableTime` + - Int + - Shutdown at a predefined time, [-] + * - - :code:`SD_MaxPit` - Float - Maximum blade pitch angle to initiate shutdown, [rad] * - - - :code:`SD_CornerFreq` - - Float - - Cutoff Frequency for first order low-pass filter for blade pitch angle, [rad/s] + - :code:`SD_PitchCornerFreq` + - Float + - Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, [rad/s] + * - + - :code:`SD_MaxYawError` + - Float + - Maximum yaw error to initiate shutdown, [deg] + * - + - :code:`SD_YawErrorCornerFreq` + - Float + - Cutoff Frequency for first order low-pass filter for yaw error for shutdown, [rad/s] + * - + - :code:`SD_MaxGenSpd` + - Float + - Maximum generator speed to initiate shutdown, [rad/s] + * - + - :code:`SD_GenSpdCornerFreq` + - Float + - Cutoff Frequency for first order low-pass filter for generator speed for shutdown, [rad/s] + * - + - :code:`SD_Time` + - Float + - Shutdown time, [s] + * - + - :code:`SD_Method` + - Int + - - Shutdown method {1: Reduce generator torque and increase blade pitch}, [-] + * - + - :code:`SD_MaxTorqueRate` + - Float + - Maximum torque rate for shutdown, [Nm/s] + * - + - :code:`SD_MaxPitchRate` + - Float + - Maximum pitch rate used for shutdown, [rad/s] * - FLOATING - :code:`Fl_Kp` - Float diff --git a/docs/source/toolbox_input.rst b/docs/source/toolbox_input.rst index 7aa7f007..a04f8d7c 100644 --- a/docs/source/toolbox_input.rst +++ b/docs/source/toolbox_input.rst @@ -1067,12 +1067,53 @@ These are pass-through parameters for the DISCON.IN file. Use with caution. Do :code:`PS_BldPitchMin` : Array of Floats Minimum blade pitch angles +:code:`SD_TimeActivate` : Float, s + Time to acitvate shutdown modes + +:code:`SD_EnablePitch` : Int + Shutdown when collective blade pitch exceeds a threshold + +:code:`SD_EnablePitch` : Int + Shutdown when collective blade pitch exceeds a threshold + +:code:`SD_EnableYawError` : Int + Shutdown when yaw error exceeds a threshold + +:code:`SD_EnableGenSpeed` : Int + Shutdown when generator speed exceeds a threshold + +:code:`SD_EnableTime` : Int + Shutdown at a predefined time + :code:`SD_MaxPit` : Float, rad Maximum blade pitch angle to initiate shutdown -:code:`SD_CornerFreq` : Float, rad/s - Cutoff Frequency for first order low-pass filter for blade pitch - angle +:code:`SD_PitchCornerFreq` : Float, rad/s + Cutoff Frequency for first order low-pass filter for blade pitch angle for shutdown, + +:code:`SD_MaxYawError` : Float, deg + Maximum yaw error to initiate shutdown + +:code:`SD_YawErrorCornerFreq` : Float, rad/s + Cutoff Frequency for first order low-pass filter for yaw error for shutdown + +:code:`SD_MaxGenSpd` : Float, rad/s + Maximum generator speed to initiate shutdown + +:code:`SD_GenSpdCornerFreq` : Float, rad/s + Cutoff Frequency for first order low-pass filter for generator speed for shutdown + +:code:`SD_Time` : Float, s + Shutdown time + +:code:`SD_Method` : Int + Shutdown method {1- Reduce generator torque and increase blade pitch} + +:code:`SD_MaxTorqueRate` : Float, Nm/s + Maximum torque rate for shutdown + +:code:`SD_MaxPitchRate` : Float, rad/s + Maximum pitch rate used for shutdown :code:`Fl_n` : Float, s Number of Fl_Kp gains in gain scheduling, optional with default of From 13287ddd6b705ec3925c4fb3980c3ea31e17381f Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Wed, 11 Dec 2024 00:30:07 -0700 Subject: [PATCH 27/33] Shutdown: Fix unit of SD_TimeActivate in toolbox --- rosco/toolbox/utilities.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rosco/toolbox/utilities.py b/rosco/toolbox/utilities.py index 8e2e396c..8027186c 100644 --- a/rosco/toolbox/utilities.py +++ b/rosco/toolbox/utilities.py @@ -233,7 +233,7 @@ def write_DISCON(turbine, controller, param_file='DISCON.IN', txt_filename='Cp_C file.write('{} ! PS_BldPitchMin - Minimum blade pitch angles [rad]\n'.format(''.join('{:<10.3f} '.format(rosco_vt['PS_BldPitchMin'][i]) for i in range(len(rosco_vt['PS_BldPitchMin']))))) file.write('\n') file.write('!------- SHUTDOWN -----------------------------------------------------------\n') - file.write('{0:<12d} ! SD_TimeActivate - Time to acitvate shutdown modes, [-]\n'.format(int(rosco_vt['SD_TimeActivate']))) + file.write('{0:<12d} ! SD_TimeActivate - Time to acitvate shutdown modes, [s]\n'.format(int(rosco_vt['SD_TimeActivate']))) file.write('{0:<12d} ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-]\n'.format(int(rosco_vt['SD_EnablePitch']))) file.write('{0:<12d} ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-]\n'.format(int(rosco_vt['SD_EnableYawError']))) file.write('{0:<12d} ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-]\n'.format(int(rosco_vt['SD_EnableGenSpeed']))) From fdd3079127a2665debed97d22766731722785e12 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Wed, 11 Dec 2024 00:32:05 -0700 Subject: [PATCH 28/33] Shutdown: Fix some bugs in shutdown logic --- rosco/controller/src/ControllerBlocks.f90 | 4 ++-- rosco/controller/src/DISCON.F90 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rosco/controller/src/ControllerBlocks.f90 b/rosco/controller/src/ControllerBlocks.f90 index 47612759..1ac1b68b 100644 --- a/rosco/controller/src/ControllerBlocks.f90 +++ b/rosco/controller/src/ControllerBlocks.f90 @@ -539,12 +539,12 @@ SUBROUTINE Shutdown(LocalVar, CntrPar, objInst,ErrVar) LocalVar%SD_NacVaneF = wrap_180(atan2(SD_NacVaneSinF, SD_NacVaneCosF) * R2D) ! (in deg) ! See if we should shutdown - IF (LocalVar%SD_Trigger == 0) THEN + IF ((LocalVar%SD_Trigger == 0) .AND. (LocalVar%Time>=CntrPar%SD_TimeActivate)) THEN IF (CntrPar%SD_EnablePitch==1 .AND. LocalVar%SD_BlPitchF > CntrPar%SD_MaxPit) THEN ! Shutdown if above pitch exceeds shutdown threshold LocalVar%SD_Trigger = 1 ENDIF - IF (CntrPar%SD_EnableYawError==1 .AND. LocalVar%SD_NacVaneF > CntrPar%SD_MaxYawError) THEN + IF (CntrPar%SD_EnableYawError==1 .AND. ABS(LocalVar%SD_NacVaneF) > CntrPar%SD_MaxYawError) THEN LocalVar%SD_Trigger = 2 ENDIF IF (CntrPar%SD_EnableGenSpeed==1 .AND. LocalVar%SD_GenSpeedF > CntrPar%SD_MaxGenSpd) THEN diff --git a/rosco/controller/src/DISCON.F90 b/rosco/controller/src/DISCON.F90 index 85874853..90f34317 100644 --- a/rosco/controller/src/DISCON.F90 +++ b/rosco/controller/src/DISCON.F90 @@ -100,7 +100,7 @@ SUBROUTINE DISCON(avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAME CALL UpdateZeroMQ(LocalVar, CntrPar, ErrVar) ENDIF - IF ((CntrPar%SD_Mode > 0) .AND. (LocalVar%Time>=CntrPar%SD_TimeActivate)) THEN + IF (CntrPar%SD_Mode > 0) THEN CALL Shutdown(LocalVar, CntrPar, objInst,ErrVar) ENDIF CALL WindSpeedEstimator(LocalVar, CntrPar, objInst, PerfData, DebugVar, ErrVar) From 17af62de1fce6c0345e3a493c3d3282b086b9057 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Wed, 11 Dec 2024 00:33:20 -0700 Subject: [PATCH 29/33] Shutdown: Add images in docs for example 30_shutdown --- docs/images/30_shutdown_gen_demo.png | Bin 0 -> 95098 bytes docs/images/30_shutdown_pitch_demo.png | Bin 0 -> 80063 bytes docs/images/30_shutdown_time_demo.png | Bin 0 -> 75862 bytes docs/images/30_shutdown_yaw_demo.png | Bin 0 -> 96451 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/images/30_shutdown_gen_demo.png create mode 100644 docs/images/30_shutdown_pitch_demo.png create mode 100644 docs/images/30_shutdown_time_demo.png create mode 100644 docs/images/30_shutdown_yaw_demo.png diff --git a/docs/images/30_shutdown_gen_demo.png b/docs/images/30_shutdown_gen_demo.png new file mode 100644 index 0000000000000000000000000000000000000000..43bd274bc26626471823100e98b1c62643ecf91a GIT binary patch literal 95098 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

!--I^;6aK^m%=4?|7s$V>YzPUm1URc+(fHxCLV1 zQ!PcGEz3$X{4GKRASg)CP?45>chRmD=bs(mV+Q1eQ-6q0Vp`lQ| zg2}cn$?x|Ogk=DgHqh_#D!Qd84j&|bG^pk5peLDz)dwZJ(Oe1$7Q(Q$?M%isrk7YJ2PmGXvL9~ zI-)aU$A;Vgq{LBnr`P3<729mu%K4ee-_dHS<6`xxEi{zfCI0sG{!6R~1P))6yfnPg z^-kwoBe2OD{Q^no;m$$C(SxRy&d!|-fGDJ4jzB26q&BxF0|)jWIIy7B-n*B}we%CW zFR-*eeotx)0I(gL>-$`;f_w8At*hF8P-9?tUypggXA%8s>g$&PK&Xc=e%t%XK*^_O zk~OCbL;8}I#n^rOWdTz3`O3wo6O?lWUhU<(U~G6cVoOHJK&$2pOp>UnjC@ZY5(JiLF5Wg zs*$Qih{o?6hfv=Ad8p3#E{i4glkWAARVx(yYy@6)wD&@Hp_%l&F16M--AEBC3qp4n z-b4=(s76YTQ0s$7y=8?=6V4?ulBnFhCKfGRw@3sC!yDg@CGl@e8 zuJ}pv_TD=CDt!4B&x59$*F&7b?zLrQLu|wXB!5w>pGC!C{Emb1orm61Q19&6v8n3P zSB8!o%mat^3Ji_?RJe8b=kOk+xZ97#uXwX{EpNk>4}n}VOKe<@Im&yy(}eJ0Tg~^y zHt7O@v2jpT{xk#DP0F6=D$rY?CRsmbN_k6YZPHlOKr#w>ls9E=&RKx6kVqCvzi zK;Yx`CpWtoCY%os;!PGc#?zC}IU1a7lKmPJkpi@qgG}G(om6%H@&i7VUlP(QW#k2` z>aK4-Y{KX}ImN!;SMS)mJJTKM5BUebP#JNYT3m7^iPo;8o_M!mX0^NTv}SKrt>CGj zaMvzMU9rqhFevs&ox&N(Ge?EmM@qv&=R5?<#A%6m;`ttX>CEB>EHarbJ8VVkq>@8+ z9<#f2vQrcZ{Q=2XekD-xfUd~*_?RT$uR4@On(O`)>7C>>kN=7tI&+KDreJ?7d-CG1SKM(;K;W z`+G2c`fV0Dm|YbUQE&5Bc#8E|qEc+?`{)aeYo4sn)iyKAD1A*h8BSN8Mx0zsN7qBl zM*xPSO_^$(9T~mJ>QPDarPXCgD1fF%&l_ExN$%g#w4ouAMQ3b~SFKy1k7earb7@KF zqpTY;`wP?8ugjL*CK+qXbUi@1jW6W*)aANZ~zwd;oZh#990F zM|IEF0F!{joL3I<5y3srv+ls{8e0CbSNiY0itI^E~xqO+^1TD&QrB z^e8p5O%fBiFFtu)wFFf^Ok7$Q|1>m9&A+BXLanB*^x7BX9Y)xHFLFfwKwwatW5;4( zT}%)9c@WYJBDurR%DZ(9a7X6AXo`B2OzzMj6LGBGm5o)-`Q;%*UJZpY#sm^B3K`%# zIFXqzp{?24u6{~>qm*A@yd|pMi;Fj(Jl6t7AtAsnOiX$Vxz88`c>M&e#TbGhG)iS> zO3+0ne%dHV=wV{$UWI)W8~3I#b8Xot8)hQpr6WQs@@z3I*-D5jk4agBXe zR?+A=^y4DK!o%UEwutaO;r6p?>()ng4WeRV>Zyj^V}DTJAV)$%7?lmSQc>xJBo^y! zHyXvY4(^h0;S#GnN{aL%fmpQ!4Cquxih;hH5BgBjaHq;@8xl}8NHy#M?TxsDwEeiB z`D?X^)3GF0`7uND)q4A)upgoLlJnLj%T*-yTPkP*{9u5N!7-j3{S5%*G1My9ROJDz zR7g(?9D;L1>4!lnnW`%6Mxjh|XD&-h2LF9<2c=6>yD%aO<^-f00)>GMPXcLB_tPe{r&?;XCR82|vEfpRi z53uKhKv`^dT~-c{aI9|Abv!+GBU-FnvXn3=td=ZMkhz%oHq&7VlkOgbBOOCOo_sov zZZ<34na=+GyhLwD%1;O?q~%0K(oVE>G_wL7JowuTx<(B(@6!Oq@I%)l#$N_)GzU8O z4UbO#Ad6S}FhH!NKlzj@)9&WsxSnFV24t59+Ga zdR;iSka0L*2asZwbV;{wKf7}`w~!DE`hkRvOn4EP%+}cip%PnPm(=Tn8y(9?7oF+V zP{=5aHEDU;y6{!)VwrGQHM+e#ZLa zz`!-n3T*XWcmrT~DLujqCKVs_v|yuy?c^dLG?*z}1!oQS(e5qjyzmCVE`YKdq-tA8 z=fU=t3SSQr6^Icjra35_NzVq1N!~ilo?iG+-3)Z1>p-(9Ra7$K*$j1!F~fxe#=(M? zMSny8A{%uLtd$SFxL{&;Fg`c)jnI{W3-Mq@naw&taX~N@m~ls8&=SlMY~apB?g%=Q zo==~GQ&Lh)lk@+bj8%bwf@GKp@o~X)cZgevp>X=0JNl6a{*NTBD60@Uo+-d+4bn6Ie-D8fqbL#u5t5|{!zp%c^eT}?PSjtp(^0%= z9Qh?^>tBk5(Xas8ze?*k8T;wY52S(<-nQEm1SYVr2|u3f5SWz)hKDm^>Dr+qO-8}O zsO?<4qrcE!o)~F(GCnlPfldrx*aZ`DH|A;quY&>+Id{=%fu-(!rdRq|$cQJF@wVb{ME!|k76422l5(GedCv}yY)0GD7o6!bm1 z-QMMOb)W$f(I`qs%*t6os16vP9e{{fBp+qki0*iRSZp2|~wLf$jP2GH6ES9B*vd;WNLM07h z$Xj#z%-+3dzM)+Fv;qg_-3dOL{SQw_kV}JW$JL)DmFOt)9%TxA;qW1Oc1vdI^tJQ9 z3ja?KgmvbT|LBTqNXB22;~5ex(`)wioM5}>+2;0jWjK0hO%Ut1TRMfjW&MX=ODM2b z<=(4vT?c`2#$GeXdHUy= z;i%}ays{lU#2@hmUQXZTPqJdhB&aHUEb;BFt-|8sx-RWVHNpRkvb$GU z=#Kulv>3R`*l8dK@<63zm-6~cq#bN=BSuDCqz{1(g0%w9vukXJhUS%3Hyvx@)vkXb zJ=cxfb94sz_nMg4V6qV5Hv%3qw6;Fxxpn>eFChbDK)YMl(c)D&VKHcpo_aLVZtnB7 zr~{K>MokBdk#Z0rMi({>Vo!i}`q`M6WrRsXl+9?X6LSxA*%?6Ohi$3=g>X9#Y@!c% zatH{yvivLrhk)N~c%jwgaK|zdF%eBeiCm8wdt)DC3rjF?N$4n?d@26(a|CE6Y}T|i z5z?2(At5u95v$qyAn=R;e_8Ai@Y!(+Tg`L0;*d$3bU3at732Sh7BoHbn}8gS`KXzB z%t3*h4oNOTAL06(7YX5Z>51c#N z&L5sSY#w=EE?1Mvic`0GBe zJp@qT{t|O!iF(i(K5gTl5Wfn3g?xQqsRWZiqB|eH4V}I8Lb}LNn`C}1e*%fa z_*l&{dn6>nn+!>cP|nrVtoM&GP81#h=`2a9`hO$ zRSBYdckI|ub@jdPJlSf|j>k24;FFEt&wA>Ij1B6H`$K{dHxsfsPTgH+PNCXjfAyL@ zfno1|uCwZorw4(a!8`4(!#o5cJtHICVmr}LU9zg;FW%PF_%UQOT6y#_a&Jah2c+2E zmw>S%F>4*g+*kSC7s8$x2mf>d!lYWnTjVuys0A*+VP&h4f+LC732=q4MK-bgAkgNftGTykzX~ zSs%ZYrR?OTu`p>G3yf2s4D5azh|ZDdf~@k$2PC}}(*tVrovH~O><3a-sj{NEL!@ncz?t^u^^xI-&XmB~FK)Qa6$)Dr!SS>yo2%xIT)HWD60mXml zA<5N;cHrCu?>!P{byyeZJ{NT7eWt_MSA&iG>p^pLSl05TpHGoKvV$1@C0I;%?#z{_ z%c!ZXL|)2SJUl!cHJT0U56O_(_b=*hE%08`qT7Z-S{fUfu)mLvPeVN2`{`5L!kZV1 zTJ4F}uMwf7xGdcI5kSc}g?h=5OG8V`cOUoTZCaiD#D(peyDJtS&Ahd>-L0@#`)GN< zYd+C`p7TXKXVlC(fV)XI4^sU<-~8um2+Lp2xm{RFiVeYhe}(VK)1P%U9WJinc)D`x z<@h~3d6A)QxmFJzqh3ey=Yy%)bAC`cO0T3_Z(_`g$ic$ zBYvdr+u82g)iL_`_`q^*38@*OMvH90aw`CF5JIXf6LClz zXraW?md4{C$0V{?`~f#C2xbk@KIb(ZRt27!D_KClvsQcl!VO~FX8>}G@d30H`U>zg zd%(ygni6>BGohV?Dd>F2`|O%7iR#_;7%(6uNa(Va+Gu!S$w!x!sd2MGuO`pI!9gAr zaiL^jV8E9fgjN`cY|gJ|FKaCQ^kOgH-vY&pUO{fXuA@CZQdYbJ>WTmF$g?N9BSb|C zUrrjrS5U&3aRdB(c>8HB|8f_++~1|8>gnslAC4Yj$gm;a3t3QBB6DiKd3 zlZnP|6;@E-fm&M$Gt+~KBg5LY^i<-;uu%w6T3b!1ZU5@U3SFy}RaM3Rm6Y67dEVRI zo!vgM5Ne6Po~z&9J>)?Rm0AAc1jj$r*Ds@Tt2f0_7gl}$$o2E3wY;~|4R!B)zRg1a zO1RaVfyg}&&udihM5V|zzZE(RI25PC`+G;Z5ROGP{-7H?Qa6J;v~Fdb%qn zGEw`!z1tCgY;aB=g+I9dJM{Hyv0iCpBkz_zd>A23__0|x{&#-t222!rI{2aJzjg?p zTsofGlKQYiUv0O}oAtSdnfY4AwsOBuU!7`9Xi0h4!JGh5!r#Vm>LIh4Kkw|WG&-a1 zBb;s6eiOABW`w`I;DnYenCi8MBo?}v-Rs2Q^MGi`We+Ad5_n>dBn_455~Ujkk*m^1 zx1;$J7DG!3M-RUwHM{cgcb0d^1KFUe{`k=W4cwk%{xbr)dV11GTOnB^QZ!`ewa6q$ zjX+99fYBf6aQquVZ^Tn8@Gi|@_bop&xiO;ScIEB#1Qja z+q{11Ny=>AOlBgbL+%7uEm8_Y5VXYF+M0SyNUYEhZ-p9ious7p;lt}NbDRl>@VFo$ zu|lxx1}bVAOd(+A%A`8`bI*T}SOLJ)bxJulT|JBA&T|ACGlGywDYk3It+!7fUmy#b z;srx8<@b&lsgTwwhIN`n7J%dm_>(l{xa|>K0R)~ZJi-Air?r6{rgNYOJXx0)SX{sP zP%ii*X?eFAt&i{2Y<&qUIWX2}spuaI=YW&Wf^A@xTV+V2 zYPR~3W>Ha)jWx>}4&l<2MJEq}O}KEg;1nSCF1W(XxgA?r_d$ zrDf`ZzB4V4`0N=eA8{G9Q

T|7Q8$e>44!Dbo6xL{Q!whK27pxc>F>n78S6 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%0Dd~#7^Qo$RA6i;!K#*|z`H7h{eO?-7=7BkjAP_n> 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/images/30_shutdown_yaw_demo.png b/docs/images/30_shutdown_yaw_demo.png new file mode 100644 index 0000000000000000000000000000000000000000..6b02aa8d5264da1d22f5292fdd0ebc798b9c5990 GIT binary patch literal 96451 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 literal 0 HcmV?d00001 From a4b4892c09cb8ac706964f280bb12714a035deb2 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Wed, 11 Dec 2024 00:37:15 -0700 Subject: [PATCH 30/33] Shutdown: Run update_rosco_discons.py --- Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN | 4 ++-- .../Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN | 4 ++-- Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN | 4 ++-- Examples/Test_Cases/NREL-5MW/DISCON.IN | 4 ++-- Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN b/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN index 4fcf58c8..a1de2b31 100644 --- a/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN +++ b/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the BAR_10 wind turbine -! - File written using ROSCO version 2.9.4 controller tuning logic on 12/09/24 +! - File written using ROSCO version 2.9.4 controller tuning logic on 12/11/24 !------- SIMULATION CONTROL ------------------------------------------------------------ 1 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -145,7 +145,7 @@ -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.015 -0.012 0.000 0.011 0.020 0.029 0.041 0.056 0.069 0.082 0.095 0.108 0.120 0.132 0.143 0.155 0.166 0.178 0.189 0.200 0.211 0.222 0.232 0.243 0.254 0.264 0.274 0.285 0.295 0.305 0.315 0.325 0.335 0.344 0.354 0.364 0.373 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0 ! SD_TimeActivate - Time to acitvate shutdown modes, [-] +0 ! SD_TimeActivate - Time to acitvate shutdown modes, [s] 0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] 0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] 0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] diff --git a/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN b/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN index 68fa5bc7..82138a4e 100644 --- a/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN +++ b/Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the IEA-15-240-RWT-UMaineSemi wind turbine -! - File written using ROSCO version 2.9.4 controller tuning logic on 12/09/24 +! - File written using ROSCO version 2.9.4 controller tuning logic on 12/11/24 !------- SIMULATION CONTROL ------------------------------------------------------------ 2 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -145,7 +145,7 @@ 0.060 0.060 0.060 0.060 0.060 0.060 0.056 0.052 0.047 0.041 0.036 0.029 0.022 0.015 0.008 0.001 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.006 0.021 0.033 0.044 0.053 0.064 0.074 0.084 0.093 0.103 0.112 0.121 0.130 0.138 0.147 0.155 0.163 0.172 0.180 0.188 0.196 0.203 0.211 0.219 0.227 0.234 0.242 0.250 0.257 0.265 0.272 0.279 0.287 0.294 0.301 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0 ! SD_TimeActivate - Time to acitvate shutdown modes, [-] +0 ! SD_TimeActivate - Time to acitvate shutdown modes, [s] 0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] 0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] 0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] diff --git a/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN b/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN index 600772ca..8b6e8b25 100644 --- a/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN +++ b/Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the MHK_RM1_Floating wind turbine -! - File written using ROSCO version 2.9.4 controller tuning logic on 12/09/24 +! - File written using ROSCO version 2.9.4 controller tuning logic on 12/11/24 !------- SIMULATION CONTROL ------------------------------------------------------------ 2 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -145,7 +145,7 @@ 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0 ! SD_TimeActivate - Time to acitvate shutdown modes, [-] +0 ! SD_TimeActivate - Time to acitvate shutdown modes, [s] 0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] 0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] 0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] diff --git a/Examples/Test_Cases/NREL-5MW/DISCON.IN b/Examples/Test_Cases/NREL-5MW/DISCON.IN index b8675448..5a03d7b6 100644 --- a/Examples/Test_Cases/NREL-5MW/DISCON.IN +++ b/Examples/Test_Cases/NREL-5MW/DISCON.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the NREL-5MW wind turbine -! - File written using ROSCO version 2.9.4 controller tuning logic on 12/09/24 +! - File written using ROSCO version 2.9.4 controller tuning logic on 12/11/24 !------- SIMULATION CONTROL ------------------------------------------------------------ 1 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -145,7 +145,7 @@ 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.011 0.023 0.032 0.040 0.047 0.059 0.070 0.081 0.091 0.102 0.112 0.122 0.131 0.141 0.150 0.160 0.169 0.178 0.187 0.196 0.205 0.214 0.223 0.232 0.240 0.249 0.257 0.266 0.274 0.282 0.290 0.299 0.307 0.315 0.323 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0 ! SD_TimeActivate - Time to acitvate shutdown modes, [-] +0 ! SD_TimeActivate - Time to acitvate shutdown modes, [s] 0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] 0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] 0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] diff --git a/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN b/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN index 83a50d9c..c7808254 100644 --- a/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN +++ b/Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN @@ -1,5 +1,5 @@ ! Controller parameter input file for the NREL-2p8-127 wind turbine -! - File written using ROSCO version 2.9.4 controller tuning logic on 12/09/24 +! - File written using ROSCO version 2.9.4 controller tuning logic on 12/11/24 !------- SIMULATION CONTROL ------------------------------------------------------------ 2 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: LoggingLevel 1 + ROSCO LocalVars (.dbg2) 3: LoggingLevel 2 + complete avrSWAP-array (.dbg3)} @@ -145,7 +145,7 @@ 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.019 0.031 0.041 0.050 0.058 0.066 0.074 0.086 0.096 0.107 0.117 0.127 0.137 0.147 0.156 0.165 0.174 0.183 0.192 0.201 0.210 0.218 0.227 0.236 0.244 0.253 0.262 0.270 0.279 0.287 0.295 0.303 0.312 0.320 0.328 0.337 0.345 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0 ! SD_TimeActivate - Time to acitvate shutdown modes, [-] +0 ! SD_TimeActivate - Time to acitvate shutdown modes, [s] 0 ! SD_EnablePitch - Shutdown when collective blade pitch exceeds a threshold, [-] 0 ! SD_EnableYawError - Shutdown when yaw error exceeds a threshold, [-] 0 ! SD_EnableGenSpeed - Shutdown when generator speed exceeds a threshold, [-] From 2290c242d78a3a5c9f901002d83dfd74a8dc2da9 Mon Sep 17 00:00:00 2001 From: AbhineetGupta Date: Wed, 11 Dec 2024 09:08:56 -0700 Subject: [PATCH 31/33] Shutdown: quick edit in example 30_shutdown --- Examples/30_shutdown.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/30_shutdown.py b/Examples/30_shutdown.py index 44554d4b..46a8e10d 100644 --- a/Examples/30_shutdown.py +++ b/Examples/30_shutdown.py @@ -28,7 +28,7 @@ Generator Speed Threshold Demo `````````````````````````````` The following plot demonstrates turbine shutdown when generator speed exceeds a threshold of 8.5 rpm. -This also compares the use of `SD_TimeActive` to enable shutdown at 0 seconds and 10 seconds. +This also compares the use of :code:`SD_TimeActive` to enable shutdown at 0 seconds and 10 seconds. .. image:: ../images/30_shutdown_gen_demo.png From 76b19d92cefebb308659db81be7d88b818da9903 Mon Sep 17 00:00:00 2001 From: dzalkind Date: Thu, 12 Dec 2024 11:50:04 -0700 Subject: [PATCH 32/33] Fix duplicated main call --- Examples/04_simple_sim.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/Examples/04_simple_sim.py b/Examples/04_simple_sim.py index 46ff3dea..5c022733 100644 --- a/Examples/04_simple_sim.py +++ b/Examples/04_simple_sim.py @@ -112,6 +112,3 @@ def main(): if __name__ == "__main__": main() -if __name__=='__main__': - main() - From 79786f5ef63dd7a9876769b78edefa2fbaaffce5 Mon Sep 17 00:00:00 2001 From: dzalkind Date: Thu, 12 Dec 2024 12:10:46 -0700 Subject: [PATCH 33/33] Change some minor formatting --- rosco/controller/src/ControllerBlocks.f90 | 2 +- rosco/controller/src/Controllers.f90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rosco/controller/src/ControllerBlocks.f90 b/rosco/controller/src/ControllerBlocks.f90 index 1ac1b68b..3f11dc99 100644 --- a/rosco/controller/src/ControllerBlocks.f90 +++ b/rosco/controller/src/ControllerBlocks.f90 @@ -530,7 +530,7 @@ SUBROUTINE Shutdown(LocalVar, CntrPar, objInst,ErrVar) ! Filter pitch signal LocalVar%SD_BlPitchF = LPFilter(LocalVar%PC_PitComT, LocalVar%DT, CntrPar%SD_PitchCornerFreq, LocalVar%FP,LocalVar%iStatus, LocalVar%restart, objInst%instLPF) - ! Filter yaw generator speed + ! Filter generator speed LocalVar%SD_GenSpeedF = LPFilter(LocalVar%Genspeed, LocalVar%DT, CntrPar%SD_GenSpdCornerFreq, LocalVar%FP,LocalVar%iStatus, LocalVar%restart, objInst%instLPF) ! Filter yaw error signal (NacVane) diff --git a/rosco/controller/src/Controllers.f90 b/rosco/controller/src/Controllers.f90 index 9a8f20f7..0be00e62 100644 --- a/rosco/controller/src/Controllers.f90 +++ b/rosco/controller/src/Controllers.f90 @@ -217,7 +217,7 @@ SUBROUTINE VariableSpeedControl(avrSWAP, CntrPar, LocalVar, objInst, ErrVar) ! -------- Variable-Speed Torque Controller -------- ! Define max torque IF (LocalVar%VS_State == 4) THEN - LocalVar%VS_MaxTq = CntrPar%VS_RtTq * LocalVar%PRC_R_Torque + LocalVar%VS_MaxTq = CntrPar%VS_RtTq * LocalVar%PRC_R_Torque ELSE LocalVar%VS_MaxTq = CntrPar%VS_RtTq * LocalVar%PRC_R_Torque ENDIF