Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Torque Floating Feedback Update #331

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ Examples/*.p
# Exclude testing results
ROSCO_testing/results/
ROSCO_testing/testing
rosco/test/testing

# Simulink/Matlab temp files
*.slxc
Expand Down
2 changes: 1 addition & 1 deletion Examples/24_floating_feedback.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'''
----------- 23_structural_control ------------------------
----------- 24_floating_feedback ------------------------
Run openfast with ROSCO and all the floating feedback methods
-----------------------------------------------

Expand Down
169 changes: 169 additions & 0 deletions Examples/29_floating_feedback_torque.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
'''
----------- 29_floating_feedback_torque ------------------------
Run openfast with ROSCO and torque floating feedback
-----------------------------------------------

Floating feedback methods available in ROSCO/ROSCO_Toolbox

1. Automated tuning, constant for all wind speeds
2. Automated tuning, varies with wind speed
3. Direct tuning, constant for all wind speeds
4. Direct tuning, varies with wind speeds

'''

import os
from rosco.toolbox.ofTools.case_gen.run_FAST import run_FAST_ROSCO
from rosco.toolbox.ofTools.case_gen import CaseLibrary as cl
import numpy as np
#from rosco.toolbox.ofTools.fast_io.FAST_reader import InputReader_OpenFAST
#from rosco.toolbox.inputs.validation import load_rosco_yaml
#from rosco.toolbox.controller import OpenLoopControl
from rosco.toolbox.tune import yaml_to_objs
from rosco.toolbox.utilities import write_DISCON, read_DISCON
from rosco.toolbox import controller as ROSCO_controller
from rosco.toolbox.ofTools.fast_io import output_processing
import matplotlib.pyplot as plt



#directories
this_dir = os.path.dirname(os.path.abspath(__file__))
rosco_dir = os.path.dirname(this_dir)
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')
run_dir = os.path.join(example_out_dir,'29_floating_feedback_torque')
os.makedirs(run_dir,exist_ok=True)

controller, turbine, path_params = yaml_to_objs(parameter_filename)

# First, let's write the DISCONs for each method
param_files = []

# Method 1: Automated tuning, constant for all wind speeds (default param = 0.5)
controller_params_1 = controller.controller_params # numbers correspond to methods above
controller_params_1['Fl_Mode'] = 0
controller_params_1['FlTq_Mode'] = 2
controller_params_1['U_Fl'] = 'all'
controller_params_1['tune_Fl'] = True
controller_params_1['tune_FlTq'] = True
controller_params_1['FlTq_param'] = [0.2] # Low tuning
controller = ROSCO_controller.Controller(controller_params_1)
controller.tune_controller(turbine)
# Reduce gain
# controller.Kp_floatTq = controller.Kp_floatTq/2
param_file = os.path.join(run_dir,'DISCON_Fl_1.IN')
param_files.append(param_file)
write_DISCON(turbine,controller,
param_file=param_file,
txt_filename=path_params['rotor_performance_filename'])

# Automated tuning, constant for all wind speeds, with smaller scaling param
controller_params_2 = controller.controller_params # numbers correspond to methods above
controller_params_2['Fl_Mode'] = 0
controller_params_2['FlTq_Mode'] = 2
controller_params_2['U_Fl'] = 'all'
controller_params_2['tune_Fl'] = True
controller_params_2['tune_FlTq'] = True
controller_params_2['FlTq_param'] = [0.5] # Moderate tuning
controller = ROSCO_controller.Controller(controller_params_1)
controller.tune_controller(turbine)
param_file = os.path.join(run_dir,'DISCON_Fl_2.IN')
param_files.append(param_file)
write_DISCON(turbine,controller,
param_file=param_file,
txt_filename=path_params['rotor_performance_filename'])


# Automated tuning, constant for all wind speeds, with smaller scaling param
controller_params_3 = controller.controller_params # numbers correspond to methods above
controller_params_3['Fl_Mode'] = 0
controller_params_3['FlTq_Mode'] = 2
controller_params_3['U_Fl'] = 'all'
controller_params_3['tune_Fl'] = True
controller_params_3['tune_FlTq'] = True
controller_params_3['FlTq_param'] = [0.8] # Aggressive tuning
controller = ROSCO_controller.Controller(controller_params_1)
controller.tune_controller(turbine)
param_file = os.path.join(run_dir,'DISCON_Fl_3.IN')
param_files.append(param_file)
write_DISCON(turbine,controller,
param_file=param_file,
txt_filename=path_params['rotor_performance_filename'])


# Read all DISCONs and make into case_inputs
case_inputs = {}
discon_lists = {}
for discon in param_files:
discon_vt = read_DISCON(discon)
for discon_input in discon_vt:
if discon_input not in discon_lists: # initialize
discon_lists[discon_input] = []
discon_lists[discon_input].append(discon_vt[discon_input])

for discon_input, input in discon_lists.items():
case_inputs[('DISCON_in',discon_input)] = {'vals': input, 'group': 2}


# Additional config for the torque controller
case_inputs[('DISCON_in', 'VS_MaxTq')] = {'vals': [turbine.rated_torque * 1.5], 'group': 0} # 29436069.9996
case_inputs[('ElastoDyn', 'RotSpeed')] = {'vals': [7.56], 'group': 0}
case_inputs[('ElastoDyn', 'BlPitch1')] = {'vals': [10], 'group': 0}
case_inputs[('ElastoDyn', 'BlPitch2')] = {'vals': [10], 'group': 0}
case_inputs[('ElastoDyn', 'BlPitch3')] = {'vals': [10], 'group': 0}

# simulation set up
r = run_FAST_ROSCO()
r.tuning_yaml = parameter_filename
r.wind_case_fcn = cl.simp_step # single step wind input
r.wind_case_opts = {
'U_start': [13],
'U_end': [16],
'TMax': 800,
'TStep': 400,
}
r.case_inputs = case_inputs
r.save_dir = run_dir
r.rosco_dir = rosco_dir
r.n_cores = 4
r.run_FAST()

op = output_processing.output_processing()
op_dbg = output_processing.output_processing()
op_dbg2 = output_processing.output_processing()

out_files = [os.path.join(run_dir,f'IEA15MW/simp_step/base/IEA15MW_{i_case}.outb') for i_case in range(len(param_files))]
dbg_files = [os.path.join(run_dir,f'IEA15MW/simp_step/base/IEA15MW_{i_case}.RO.dbg') for i_case in range(len(param_files))]
dbg2_files = [os.path.join(run_dir,f'IEA15MW/simp_step/base/IEA15MW_{i_case}.RO.dbg2') for i_case in range(len(param_files))]

fst_out = op.load_fast_out(out_files, tmin=0)
debug_vars = op_dbg.load_fast_out(dbg_files, tmin=0)
local_vars = op_dbg2.load_fast_out(dbg2_files, tmin=0)

comb_out = [None] * len(fst_out)
for i, (r_out, f_out) in enumerate(zip(debug_vars,fst_out)):
r_out.update(f_out)
comb_out[i] = r_out
for i, (r_out2, f_out) in enumerate(zip(local_vars,comb_out)):
r_out2.update(f_out)
comb_out[i] = r_out2

cases = {}
cases['Fl Sigs.'] = ['Wind1VelX', 'GenSpeed', 'BldPitch1', 'PtfmPitch', 'Fl_TqCom', 'GenTq'] # , 'NcIMURAys']#,'PtfmPitch','PtfmYaw','NacYaw']
fig, ax = op.plot_fast_out(comb_out,cases, showplot=False)

if False:
plt.show()
else:
plt.savefig(os.path.join(run_dir,'29_floating_feedback_torque.png'))

plt.show()

if __name__=="__main__":
main()
17 changes: 10 additions & 7 deletions Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
! Controller parameter input file for the BAR_10 wind turbine
! - File written using ROSCO version 2.8.0 controller tuning logic on 01/05/24
! - File written using ROSCO version 2.9.0 controller tuning logic on 04/08/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)}
0 ! DT_Out - {Time step to output .dbg* files, or 0 to match sampling period of OpenFAST}
1 ! Ext_Interface - (0 - use standard bladed interface, 1 - Use the extened DLL interface introduced in OpenFAST 3.5.0.)
1 ! Ext_Interface - (0 - use standard bladed interface, 1 - Use the extened DLL interface introduced in OpenFAST 3.5.0.)
0 ! Echo - (0 - no Echo, 1 - Echo input data to <RootName>.echo)

!------- CONTROLLER FLAGS -------------------------------------------------
Expand All @@ -19,9 +19,10 @@
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 ! 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
0 ! Fl_Mode - Floating specific feedback mode to blade pitch {0: no nacelle velocity feedback, 1: feed back translational velocity, 2: feed back rotational veloicty}
0 ! FlTq_Mode - Floating specific feedback mode to generator torque {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
2 ! Flp_Mode - Flap control mode {0: no flap control, 1: steady state flap angle, 2: Proportional flap control, 2: Cyclic (1P) flap control}
0 ! OL_Mode - Open loop control mode {0: no open loop control, 1: open loop control vs. time, 2: rotor position control}
0 ! PA_Mode - Pitch actuator mode {0 - not used, 1 - first order filter, 2 - second order filter}
Expand All @@ -46,7 +47,8 @@
0.62830 ! F_SSCornerFreq - Corner frequency (-3dB point) in the first order low pass filter for the setpoint smoother, [rad/s].
0.20944 ! F_WECornerFreq - Corner frequency (-3dB point) in the first order low pass filter for the wind speed estimate [rad/s].
0.17952 ! F_YawErr - Low pass filter corner frequency for yaw controller [rad/s].
0.000000 1.000000 ! F_FlCornerFreq - Natural frequency and damping in the second order low pass filter of the tower-top fore-aft motion for floating feedback control [rad/s, -].
0.000000 1.000000 ! F_FlCornerFreq - Natural frequency and damping in the second order low pass filter of the tower-top fore-aft motion for blade pitch floating feedback control [rad/s, -].
0.000000 1.000000 ! F_FlTqCornerFreq - Natural frequency and damping in the second order low pass filter of the tower-top fore-aft motion for generator torque floating feedback control [rad/s, -].
0.01042 ! F_FlHighPassFreq - Natural frequency of first-order high-pass filter for nacelle fore-aft motion [rad/s].
7.8480 1.0000 ! F_FlpCornerFreq - Corner frequency and damping in the second order low pass filter of the blade root bending moment for flap control

Expand Down Expand Up @@ -143,7 +145,8 @@

!------- Floating -----------------------------------------------------------
1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1
0.0000 ! Fl_Kp - Nacelle velocity proportional feedback gain [s]
0.0000 ! Fl_Kp - Nacelle velocity proportional feedback gain to blade pitch [s]
0.0000 ! FlTq_Kp - Nacelle velocity proportional feedback gain to generator torque [s]
0.0000 ! Fl_U - Wind speeds for scheduling Fl_Kp, optional if Fl_Kp is single value [m/s]

!------- FLAP ACTUATION -----------------------------------------------------
Expand Down
17 changes: 10 additions & 7 deletions Examples/Test_Cases/IEA-15-240-RWT-UMaineSemi/DISCON-UMaineSemi.IN
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
! Controller parameter input file for the IEA-15-240-RWT-UMaineSemi wind turbine
! - File written using ROSCO version 2.8.0 controller tuning logic on 01/05/24
! - File written using ROSCO version 2.9.0 controller tuning logic on 04/08/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)}
0 ! DT_Out - {Time step to output .dbg* files, or 0 to match sampling period of OpenFAST}
1 ! Ext_Interface - (0 - use standard bladed interface, 1 - Use the extened DLL interface introduced in OpenFAST 3.5.0.)
1 ! Ext_Interface - (0 - use standard bladed interface, 1 - Use the extened DLL interface introduced in OpenFAST 3.5.0.)
0 ! Echo - (0 - no Echo, 1 - Echo input data to <RootName>.echo)

!------- CONTROLLER FLAGS -------------------------------------------------
Expand All @@ -19,9 +19,10 @@
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}
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
2 ! Fl_Mode - Floating specific feedback mode to blade pitch {0: no nacelle velocity feedback, 1: feed back translational velocity, 2: feed back rotational veloicty}
0 ! FlTq_Mode - Floating specific feedback mode to generator torque {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
0 ! Flp_Mode - Flap control mode {0: no flap control, 1: steady state flap angle, 2: Proportional flap control, 2: Cyclic (1P) flap control}
0 ! OL_Mode - Open loop control mode {0: no open loop control, 1: open loop control vs. time, 2: rotor position control}
2 ! PA_Mode - Pitch actuator mode {0 - not used, 1 - first order filter, 2 - second order filter}
Expand All @@ -46,7 +47,8 @@
0.62830 ! F_SSCornerFreq - Corner frequency (-3dB point) in the first order low pass filter for the setpoint smoother, [rad/s].
0.20944 ! F_WECornerFreq - Corner frequency (-3dB point) in the first order low pass filter for the wind speed estimate [rad/s].
0.17952 ! F_YawErr - Low pass filter corner frequency for yaw controller [rad/s].
0.213000 1.000000 ! F_FlCornerFreq - Natural frequency and damping in the second order low pass filter of the tower-top fore-aft motion for floating feedback control [rad/s, -].
0.213000 1.000000 ! F_FlCornerFreq - Natural frequency and damping in the second order low pass filter of the tower-top fore-aft motion for blade pitch floating feedback control [rad/s, -].
0.639000 1.000000 ! F_FlTqCornerFreq - Natural frequency and damping in the second order low pass filter of the tower-top fore-aft motion for generator torque floating feedback control [rad/s, -].
0.01042 ! F_FlHighPassFreq - Natural frequency of first-order high-pass filter for nacelle fore-aft motion [rad/s].
10.4616 1.0000 ! F_FlpCornerFreq - Corner frequency and damping in the second order low pass filter of the blade root bending moment for flap control

Expand Down Expand Up @@ -143,7 +145,8 @@

!------- Floating -----------------------------------------------------------
1 ! Fl_n - Number of Fl_Kp gains in gain scheduling, optional with default of 1
-9.3465 ! Fl_Kp - Nacelle pitching proportional feedback gain [s]
-9.3465 ! Fl_Kp - Nacelle pitching proportional feedback gain to blade pitch [s]
0.0000 ! FlTq_Kp - Nacelle pitching proportional feedback gain to generator torque [s]
11.2770 ! Fl_U - Wind speeds for scheduling Fl_Kp, optional if Fl_Kp is single value [m/s]

!------- FLAP ACTUATION -----------------------------------------------------
Expand Down
Loading
Loading