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() - diff --git a/Examples/30_shutdown.py b/Examples/30_shutdown.py new file mode 100644 index 00000000..46a8e10d --- /dev/null +++ b/Examples/30_shutdown.py @@ -0,0 +1,123 @@ +""" +30_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 :code:`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 +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.ofTools.fast_io import output_processing + +rpm2RadSec = 2.0 * (np.pi) / 60.0 +deg2rad = np.pi/180.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(): + # 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["LoggingLevel"] = 3 + controller_params["SD_Mode"] = 1 + controller_params["DISCON"]["SD_EnablePitch"] = 1 + controller_params["DISCON"]["SD_MaxPit"] = 30*deg2rad + controller_params["DISCON"]["SD_MaxPitchRate"] = 0.0348 + controller_params["DISCON"]["SD_MaxTorqueRate"] = 4500000 + + # 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} + + + 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() + + # 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.png")) + + +if __name__ == "__main__": + main() diff --git a/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN b/Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN index d79e7b4e..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 09/03/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)} @@ -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,8 +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.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_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, [-] +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 ed348ab9..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 09/03/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)} @@ -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,8 +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.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_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, [-] +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 89395380..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 09/03/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)} @@ -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,8 +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.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_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, [-] +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 185c4126..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 09/03/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)} @@ -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,8 +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.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_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, [-] +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 a73c2829..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 09/03/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)} @@ -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,8 +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.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_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, [-] +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/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/Examples/example_inputs/DISCON_v2.2.0.IN b/Examples/example_inputs/DISCON_v2.2.0.IN index 81cbc148..6aac9ab7 100644 --- a/Examples/example_inputs/DISCON_v2.2.0.IN +++ b/Examples/example_inputs/DISCON_v2.2.0.IN @@ -106,8 +106,21 @@ 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_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.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] +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] +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] @@ -116,4 +129,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.IN b/Examples/example_inputs/minimal_DISCON.IN index 305379fd..1b972078 100644 --- a/Examples/example_inputs/minimal_DISCON.IN +++ b/Examples/example_inputs/minimal_DISCON.IN @@ -91,11 +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.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] - !------- 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/Examples/example_inputs/minimal_DISCON_err.IN b/Examples/example_inputs/minimal_DISCON_err.IN index 269736e0..a103ae6e 100644 --- a/Examples/example_inputs/minimal_DISCON_err.IN +++ b/Examples/example_inputs/minimal_DISCON_err.IN @@ -94,10 +94,22 @@ 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] +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] +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/docs/images/30_shutdown_gen_demo.png b/docs/images/30_shutdown_gen_demo.png new file mode 100644 index 00000000..43bd274b Binary files /dev/null and b/docs/images/30_shutdown_gen_demo.png differ diff --git a/docs/images/30_shutdown_pitch_demo.png b/docs/images/30_shutdown_pitch_demo.png new file mode 100644 index 00000000..6e463552 Binary files /dev/null and b/docs/images/30_shutdown_pitch_demo.png differ diff --git a/docs/images/30_shutdown_time_demo.png b/docs/images/30_shutdown_time_demo.png new file mode 100644 index 00000000..82b64a01 Binary files /dev/null and b/docs/images/30_shutdown_time_demo.png differ diff --git a/docs/images/30_shutdown_yaw_demo.png b/docs/images/30_shutdown_yaw_demo.png new file mode 100644 index 00000000..6b02aa8d Binary files /dev/null and b/docs/images/30_shutdown_yaw_demo.png differ 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 diff --git a/rosco/controller/rosco_registry/rosco_types.yaml b/rosco/controller/rosco_registry/rosco_types.yaml index e0bd5dc3..1142bdba 100644 --- a/rosco/controller/rosco_registry/rosco_types.yaml +++ b/rosco/controller/rosco_registry/rosco_types.yaml @@ -461,17 +461,55 @@ ControlParameters: <<: *real description: Minimum blade pitch angles [rad] allocatable: True - # 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_TimeActivate: + <<: *real + description: Time to acitvate shutdown modes, [s] + 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, [deg] + 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_GenSpdCornerFreq: + <<: *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: @@ -1206,6 +1244,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]. @@ -1291,9 +1333,21 @@ LocalVariables: OL_Index: <<: *real description: Open loop indexing variable (time or wind speed) - SD: - <<: *logical - description: Shutdown, .FALSE. if inactive, .TRUE. if active + 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]. Fl_PitCom: <<: *real description: Shutdown, .FALSE. if inactive, .TRUE. if active @@ -1458,7 +1512,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..3f11dc99 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) THEN - LocalVar%VS_RefSpd = CntrPar%VS_MinOMSpd - ENDIF - ! Force minimum rotor speed LocalVar%VS_RefSpd = max(LocalVar%VS_RefSpd, CntrPar%VS_MinOmSpd) @@ -512,47 +507,60 @@ REAL(DbKi) FUNCTION PitchSaturation(LocalVar, CntrPar, objInst, DebugVar, ErrVar END FUNCTION PitchSaturation !------------------------------------------------------------------------------------------------------------------------------- - REAL(DbKi) FUNCTION Shutdown(LocalVar, CntrPar, objInst) - ! Shutdown controller + SUBROUTINE Shutdown(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 + 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 - LocalVar%SD = .FALSE. + LocalVar%SD_Trigger = 0 ENDIF + + ! Filter pitch signal + LocalVar%SD_BlPitchF = LPFilter(LocalVar%PC_PitComT, LocalVar%DT, CntrPar%SD_PitchCornerFreq, LocalVar%FP,LocalVar%iStatus, LocalVar%restart, objInst%instLPF) + ! 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) + 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 (.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) .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. 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 + 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 Shutdown !------------------------------------------------------------------------------------------------------------------------------- !------------------------------------------------------------------------------------------------------------------------------- SUBROUTINE RefSpeedExclusion(LocalVar, CntrPar, objInst, DebugVar) diff --git a/rosco/controller/src/Controllers.f90 b/rosco/controller/src/Controllers.f90 index 912a3706..0be00e62 100644 --- a/rosco/controller/src/Controllers.f90 +++ b/rosco/controller/src/Controllers.f90 @@ -89,11 +89,6 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst, DebugVar, ErrVar) LocalVar%PC_PitComT = LocalVar%PC_PitComT + LocalVar%Fl_PitCom ENDIF - ! Shutdown - IF (CntrPar%SD_Mode == 1) THEN - LocalVar%PC_PitComT = Shutdown(LocalVar, CntrPar, objInst) - 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 LocalVar%PC_PitComT = ratelimit(LocalVar%PC_PitComT, CntrPar%PC_MinRat, CntrPar%PC_MaxRat, LocalVar%DT, LocalVar%restart, LocalVar%rlP,objInst%instRL,LocalVar%BlPitchCMeas) ! Saturate the overall command of blade K using the pitch rate limit @@ -139,7 +134,23 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst, DebugVar, ErrVar) IF (CntrPar%AWC_Mode > 0) THEN CALL ActiveWakeControl(CntrPar, LocalVar, DebugVar) ENDIF - + + ! 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 + LocalVar%PitCom_SD(K) = LocalVar%PitCom_SD(K) + CntrPar%SD_MaxPitchRate*LocalVar%DT + 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 + + ! 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 @@ -180,7 +191,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) @@ -207,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 @@ -252,7 +262,19 @@ SUBROUTINE VariableSpeedControl(avrSWAP, CntrPar, LocalVar, objInst, ErrVar) 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_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: 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 e95c1580..ae4fd324 100644 --- a/rosco/controller/src/DISCON.F90 +++ b/rosco/controller/src/DISCON.F90 @@ -102,6 +102,9 @@ SUBROUTINE DISCON(avrSWAP, aviFAIL, accINFILE, avcOUTNAME, avcMSG) BIND (C, NAME CALL UpdateZeroMQ(LocalVar, CntrPar, ErrVar) ENDIF + 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) diff --git a/rosco/controller/src/ROSCO_IO.f90 b/rosco/controller/src/ROSCO_IO.f90 index 5deb4574..de2fc994 100644 --- a/rosco/controller/src/ROSCO_IO.f90 +++ b/rosco/controller/src/ROSCO_IO.f90 @@ -127,6 +127,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,7 +160,11 @@ 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%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 WRITE( Un, IOSTAT=ErrStat) LocalVar%FA_AccF @@ -445,6 +452,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) @@ -475,7 +485,11 @@ 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%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 READ( Un, IOSTAT=ErrStat) LocalVar%FA_AccF @@ -724,7 +738,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 = 146 Allocate(LocalVarOutData(nLocalVars)) Allocate(LocalVarOutStrings(nLocalVars)) LocalVarOutData(1) = LocalVar%iStatus @@ -800,73 +814,79 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av LocalVarOutData(71) = LocalVar%IPC_IntSat LocalVarOutData(72) = LocalVar%PC_State LocalVarOutData(73) = LocalVar%PitCom(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%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(74) = LocalVar%PitCom_SD(1) + LocalVarOutData(75) = LocalVar%PitComAct(1) + LocalVarOutData(76) = LocalVar%SS_DelOmegaF + LocalVarOutData(77) = LocalVar%TestType + LocalVarOutData(78) = LocalVar%Kp_Float + LocalVarOutData(79) = LocalVar%VS_MaxTq + LocalVarOutData(80) = LocalVar%VS_LastGenTrq + LocalVarOutData(81) = LocalVar%VS_LastGenPwr + LocalVarOutData(82) = LocalVar%VS_MechGenPwr + LocalVarOutData(83) = LocalVar%VS_SpdErrAr + LocalVarOutData(84) = LocalVar%VS_SpdErrBr + LocalVarOutData(85) = LocalVar%VS_SpdErr + LocalVarOutData(86) = LocalVar%VS_State + LocalVarOutData(87) = LocalVar%VS_Rgn3Pitch + LocalVarOutData(88) = LocalVar%WE_Vw + LocalVarOutData(89) = LocalVar%WE_Vw_F + LocalVarOutData(90) = LocalVar%WE_VwI + LocalVarOutData(91) = LocalVar%WE_VwIdot + LocalVarOutData(92) = LocalVar%WE_Op + LocalVarOutData(93) = LocalVar%WE_Op_Last + LocalVarOutData(94) = LocalVar%VS_LastGenTrqF + LocalVarOutData(95) = LocalVar%PRC_WSE_F + LocalVarOutData(96) = LocalVar%PRC_R_Speed + LocalVarOutData(97) = LocalVar%PRC_R_Torque + LocalVarOutData(98) = LocalVar%PRC_R_Pitch + LocalVarOutData(99) = LocalVar%PRC_R_Total + LocalVarOutData(100) = LocalVar%PRC_Min_Pitch + LocalVarOutData(101) = LocalVar%PS_Min_Pitch + LocalVarOutData(102) = LocalVar%OL_Index + LocalVarOutData(103) = LocalVar%SD_Trigger + LocalVarOutData(104) = LocalVar%SD_BlPitchF + LocalVarOutData(105) = LocalVar%SD_NacVaneF + LocalVarOutData(106) = LocalVar%SD_GenSpeedF + LocalVarOutData(107) = LocalVar%GenTq_SD + LocalVarOutData(108) = LocalVar%Fl_PitCom + LocalVarOutData(109) = LocalVar%NACIMU_FA_AccF + LocalVarOutData(110) = LocalVar%FA_AccF + LocalVarOutData(111) = LocalVar%FA_Hist + LocalVarOutData(112) = LocalVar%TRA_LastRefSpd + LocalVarOutData(113) = LocalVar%VS_RefSpeed + LocalVarOutData(114) = LocalVar%PtfmTDX + LocalVarOutData(115) = LocalVar%PtfmTDY + LocalVarOutData(116) = LocalVar%PtfmTDZ + LocalVarOutData(117) = LocalVar%PtfmRDX + LocalVarOutData(118) = LocalVar%PtfmRDY + LocalVarOutData(119) = LocalVar%PtfmRDZ + LocalVarOutData(120) = LocalVar%PtfmTVX + LocalVarOutData(121) = LocalVar%PtfmTVY + LocalVarOutData(122) = LocalVar%PtfmTVZ + LocalVarOutData(123) = LocalVar%PtfmRVX + LocalVarOutData(124) = LocalVar%PtfmRVY + LocalVarOutData(125) = LocalVar%PtfmRVZ + LocalVarOutData(126) = LocalVar%PtfmTAX + LocalVarOutData(127) = LocalVar%PtfmTAY + LocalVarOutData(128) = LocalVar%PtfmTAZ + LocalVarOutData(129) = LocalVar%PtfmRAX + LocalVarOutData(130) = LocalVar%PtfmRAY + LocalVarOutData(131) = LocalVar%PtfmRAZ + LocalVarOutData(132) = LocalVar%CC_DesiredL(1) + LocalVarOutData(133) = LocalVar%CC_ActuatedL(1) + LocalVarOutData(134) = LocalVar%CC_ActuatedDL(1) + LocalVarOutData(135) = LocalVar%StC_Input(1) + LocalVarOutData(136) = LocalVar%Flp_Angle(1) + LocalVarOutData(137) = LocalVar%RootMyb_Last(1) + LocalVarOutData(138) = LocalVar%ACC_INFILE_SIZE + LocalVarOutData(139) = LocalVar%AWC_complexangle(1) + LocalVarOutData(140) = LocalVar%ZMQ_ID + LocalVarOutData(141) = LocalVar%ZMQ_YawOffset + LocalVarOutData(142) = LocalVar%ZMQ_TorqueOffset + LocalVarOutData(143) = LocalVar%ZMQ_PitOffset(1) + LocalVarOutData(144) = LocalVar%ZMQ_R_Speed + LocalVarOutData(145) = LocalVar%ZMQ_R_Torque + LocalVarOutData(146) = LocalVar%ZMQ_R_Pitch LocalVarOutStrings = [CHARACTER(15) :: 'iStatus', 'AlreadyInitialized', 'RestartWSE', 'Time', 'DT', & 'n_DT', 'Time_Last', 'VS_GenPwr', 'VS_GenPwrF', 'GenSpeed', & 'RotSpeed', 'NacHeading', 'NacVane', 'NacVaneF', 'HorWindV', & @@ -881,21 +901,22 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, ErrVar, avrSWAP, RootName, size_av 'PC_PitComT_IPC', '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', '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' & - ] + 'IPC_IntSat', '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', '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 @@ -910,8 +931,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, '(147(a20,TR5:))') 'Time', LocalVarOutStrings + WRITE(UnDb2, '(147(a20,TR5:))') END IF IF (CntrPar%LoggingLevel > 2) THEN @@ -974,7 +995,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,146(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 8175d99d..c4fe19c1 100644 --- a/rosco/controller/src/ROSCO_Types.f90 +++ b/rosco/controller/src/ROSCO_Types.f90 @@ -119,9 +119,22 @@ 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 - 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, [-] + 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, [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] + 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] @@ -336,6 +349,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 @@ -364,7 +378,11 @@ 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 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 REAL(DbKi) :: FA_AccF ! None diff --git a/rosco/controller/src/ReadSetParameters.f90 b/rosco/controller/src/ReadSetParameters.f90 index 8a1d0080..ab1ec866 100644 --- a/rosco/controller/src/ReadSetParameters.f90 +++ b/rosco/controller/src/ReadSetParameters.f90 @@ -524,8 +524,21 @@ 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_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_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 ------------ @@ -1406,6 +1419,27 @@ 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_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.' + ENDIF + ENDIF ! --- Open loop control --- IF (CntrPar%OL_Mode > 0) THEN 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', ] diff --git a/rosco/toolbox/controller.py b/rosco/toolbox/controller.py index 9b8febd7..c954791e 100644 --- a/rosco/toolbox/controller.py +++ b/rosco/toolbox/controller.py @@ -89,7 +89,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'] @@ -140,8 +139,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_genspdcornerfreq = controller_params['filter_params']['f_sd_genspdcornerfreq'] # Open loop parameters: set up and error catching self.OL_Mode = controller_params['OL_Mode'] @@ -373,12 +373,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] diff --git a/rosco/toolbox/inputs/toolbox_schema.yaml b/rosco/toolbox/inputs/toolbox_schema.yaml index 414371f0..1c61105b 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,47 @@ properties: default: 0.8 maximum: 1 unit: rad + 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_maxpit: 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_method: + description: Shutdown method {Only 1 supported for now} + type: number + default: 1 + flp_maxpit: description: Maximum (and minimum) flap pitch angle [rad] type: number default: 0.1745 @@ -475,11 +510,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_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 + unit: rad/s open_loop: type: object default: {} @@ -621,7 +666,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 +1074,83 @@ 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 + 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 - SD_CornerFreq: + 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: deg + default: 30.0 + 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 + 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 8aef0200..435de1e4 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,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('{:<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('{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']))) + 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: @@ -325,10 +338,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] @@ -602,8 +613,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'] = 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'] = 30 + 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