Skip to content

Commit

Permalink
Pitch Actuator and IPC updates (#123)
Browse files Browse the repository at this point in the history
* Convert WE saved variables to WE type

* Put restart flag in localvars

* Use saved filter params from LocalVar

* save pitcomt last

* Move IPC saved variables to localvars

* Saved pi controller variables to localvar

* Save RootMyb_Last to localvar

* ROSCO_IO - initial commit. Include restart and debug functions

* Use ROSCO IO and call restart functions

* Remove debug from function.f90

* Save ACC Infile info

* update for restart capabilities

* add rosco_io with restart and debug functions

* cleanup debug call

* use registry generate types and IO

* delete DFController

* fix timestep mismatch

* remove unnecessaray istatus check

* close files

* add reg test for restart

* add restart option to run_openfast

* add testing to CI, ignore generate files

* fix fastcall

* remove extra commas

* specify gfortran-10

* testing flag cleanup

* Use lv_strings to generate debug output

* Revert "testing flag cleanup"

This reverts commit 6f29556.

* Revert "specify gfortran-10"

This reverts commit 4c31544.

* minor cleanup

* Use kind from constants

* Add some comments for clarity

* put debug in if statements

* separate reg tests from oother tests

* Fl_Mode>0

* Remove hard coded values

* Add filtered signals and WE_Vw to debug varrs

* cd for regtest

* Check logging level before calling debug

* add fl_pitcom and pc_minpit to debugvars

* Turn runFAST into a class

* Refactor/simplify CaseLibrary

* Implement initial pitch actuator

* Set up steps case

* Add actuator variable

* Print first time step in debug outs

* Fix FOCAL yaml

* Set actuator to 0.25 Hz bandwidth

* ROSCO 2.5.0 (#115)

* FOCAL Updates (#64)

* Update headers

* fix bullets

* make uppercase

* Update turbine.py (#56)

* Update turbine.py

This add several lines for fixing the problem of repeated maximum values in the performance tables. This will cause the error (' the length of x and y is different.') of 'interpolate.interp1d.'

* Add comments and catch when there are multiple optimal pitch angles

Co-authored-by: dzalkind <dzalkind@nrel.gov>

* increment version

* Update for OpenFAST v3.0.0

* Update for OpenFAST v3.0.0

* Install OF3.0.0 for tests

* update for OF v3.0.0

* add publish to pypi on release

* Update to ROSCO v2.3.0

* Update Testing (#58)

* Update scripts to run on eagle

* Update IEA-15MW semi example: use peak shaving w/ ps_percen=0.8

* Add comparison plots to testing scripts

* Update submit script for testing

* Update for latest eagle runs

* Add future to install dependencies

* add TMax to self, define tmin in print_results

* run tests in CI

* generic ROSCO path

* default to overwrite

* fix path

* import platform

* separate run_testing

* cleanup, specify lite test

* don't run testing in after examples, oops.

Co-authored-by: nikhar-abbas <40865984+nikhar-abbas@users.noreply.github.com>
Co-authored-by: Nikhar Abbas <nikhar.abbas@colorado.edu>

* increment version

* Update for OpenFAST v3.0.0

* Install OF3.0.0 for tests

* update for OF v3.0.0

* add publish to pypi on release

* Update to ROSCO v2.3.0

* Increment Version, OF3.0 (#57)

* increment version

* Update for OpenFAST v3.0.0

* Install OF3.0.0 for tests

* update for OF v3.0.0

* add publish to pypi on release

* Update to ROSCO v2.3.0

* increment version

* Update for OpenFAST v3.0.0

* Install OF3.0.0 for tests

* update for OF v3.0.0

* add publish to pypi on release

* Update to ROSCO v2.3.0

* add ROSCO without submodule

* move ROSCO source to ROSCO folder

* Move cmake-related files to ROSCO

* Add back pesky ErrVar

* Remove parameters_files

* Merge ROSCO and _toolbox gitignore

* Fix .gitignore

* Remove Examples/DISCON.IN from git

* Fix and point example_01 to Tune_Cases/

* Update verbiage around using ofTools vs. weis

* Fix and point example_04 to Tune_Cases/

* Clean up example_06

* Clean up example_07

* Only check FlpCornerFreq if using Flp control, fixes example 05

* Make example_04 consistent with others

* Let example_05 run independently from 04

* Clean up example_05, wind files

* Add schema and update empty tuning yaml inputs, not connected yet

* Integrate schema into turbine, controller, and examples

* Only check Fl filter parameters if Fl_Mode > 0, fix example_05

* bump version to 2.3

* Compile ROSCO from ROSCO dir

* Rename to CI_rosco

* Add omega vs. windspeed functionality

* Fix tests: 5MW U_pc and 06 example dir

* Make _Toolbox vs_minspeed in rotor frame to match ROSCO

* Revert ServoDyn change

* change rotor speed constraint to be epsilon

* rename for clarity

* docs major refresh

* fix FA_AccF units in debug file

* docs that build locally

* Deallocate arrays in ROSCO, check in example_05

* Clean up comments

* remove gitmodules

* furo theme

* furo in requirements

* move readthedocs config file, remove furo import in conf.py

* add docs requirements file

* typo

* move index out of source folder

* trying to get furo to work

* import date

* fix versions and titles, cleanup readthedocs requirements

* typo fix, remove extras

* more cleanup

* bump version

* no furo extension, "hack" to load RT version

* proper toctree paths

* specify method

* add mock modules

* fix typos

* update python install requirements

* running locally

* move index to main docs dir again

* update to build locally

* error during warnings

* automated version

* cleanup

* remove old docs

* re-add docs

* simplify

* fix figure path

* try alabaster

* remove archived docs

* Add omega vs. windspeed functionality

* Fix tests: 5MW U_pc and 06 example dir

* more detailed sp.optimize settings

* run MBC3 in parallel

* restructure driver, run initialization doe for tuning

* Try new dlclose function

* Update example_05 to run simple simulation twice and check result

* Revert deallocation stuff

* Close discon library after every sim run

* Test examples on macOS and windows

* Run examples instead of testing on other platforms

* Skip examples in windows for now

* update paths and yaml load funciton

* Skip mac testing of examples

* provide default U_pc for single omega/zeta case

* allow for float or list-like pc tuning inputs

* Change name in setup.py

* WE_Vw unit fix

* Pass through kp_float, if desired

* Minor fixes: schema error and InputReader defaults

* cleeanup for improved stability

* check for doe_logs as string in load_DOE

* major restructure for rsched_driver class

* cleanup verbosity

* run serial by default

* load_parallel as linturb_option

* specific IEA15MW yaml for multi omega

* remove unused module imports

* fix error message types

* lin_file as input

* add comments on inputs to LinearTurbineModel init method

* remove relative file paths

* provide OpenFAST linearizations for IEA15MW UMaineSemi

* put plotting in specific function

* fix WE_lambda units

* add self in on a few necessary variables

* creaete example 12 for robust scheduling

* try a few mbc3 locations for import

* allow list-like or numpy arrays for omega_pc and zeta_pc schedules

* create and use recorder setup function

* Pass Through Kp_float (#57)

* Pass through kp_float, if desired

* Minor fixes: schema error and InputReader defaults

* fix setup_recorder to work for optimization driver too

* Allow pass through of Kp_float = 0

* cleanup om problems, update om0 calc

* doe levels as input

* negative k_float to account for OF conventions

* cleanup print statements

* variable name cleanup, use calculated k_float

* Add defaults to omega_,zeta_ pc and vs, allow to be numbers

* use standard tuning k_float as IC

* formatting update

* update problem setup methods

* cleanup add_dv, enable adding design variables after problem is setup

* change optimization step size

* more setup restructure

* update verbosity

* use sphinx-rtd-theme

* master doc and sphinx rtd theme

* index back to root folder

* only ignore install folders

* remove hidden toctree

* furo theme

* update paths

* convert rt version to string

* update sphinx settings

* move conf

* furo theme

* Mostly a docs update (#61)

* rename for clarity

* docs major refresh

* fix FA_AccF units in debug file

* docs that build locally

* remove gitmodules

* furo theme

* furo in requirements

* move readthedocs config file, remove furo import in conf.py

* add docs requirements file

* typo

* move index out of source folder

* trying to get furo to work

* import date

* fix versions and titles, cleanup readthedocs requirements

* typo fix, remove extras

* more cleanup

* bump version

* no furo extension, "hack" to load RT version

* proper toctree paths

* specify method

* add mock modules

* fix typos

* update python install requirements

* running locally

* move index to main docs dir again

* update to build locally

* error during warnings

* automated version

* cleanup

* remove old docs

* re-add docs

* simplify

* fix figure path

* try alabaster

* remove archived docs

* use sphinx-rtd-theme

* master doc and sphinx rtd theme

* index back to root folder

* only ignore install folders

* remove hidden toctree

* furo theme

* update paths

* convert rt version to string

* update sphinx settings

* move conf

* furo theme

* Pass through Kp_float = 0 (#59)

* Pass through kp_float, if desired

* Minor fixes: schema error and InputReader defaults

* Allow pass through of Kp_float = 0

* Add flp parameters to schema

* Change Fl_Mode default to 0

* Add defaults to omega_,zeta_ pc and vs, allow to be numbers

* Allow single pitch tuning values in code, default U_pc to 0

* use nac acceleration for floating feedback

* Fix TSR saturation for region 2.5operation

* Modify system for constant power operation

* Only modify pole for constant power above-rated

* Remove GenEff from K calc

* Update tuning, use constant power

* use load_rosco_yaml

* constant power

* Fix broken tests

* Include Fl_Mode=2 for nacelle pitching feedback

* Add FOCAL inputs
- hpf on floating feedback
- lpf on wind speed estimator
- associated schema updates

* Set notch and check frequencies when Fl_Mode = 1 (fixes bug)

* Skip filter step if there's an error

* Update IEA-15MW test case DISCON with focal inputs

* Allow Fl_Mode = 2 in ROSCO

* Pass through lpf frequency

* Add FOCAL tuning yaml

* Set Cp contour number of levels

* Add FOCAL params to various writers

* Update/tune focal yaml

* Add scripts for running FAST, tuning various parameters and cases

* Add notebook for FAST plotting

* Set up step case for testing

* Change doubles to C_doubles

* Define real and integer kinds, assign to all of ROSCO

* Add ADJUSTL to DISCON error message

* Fix Fl_Mode == 2

* Fix Fl_Mode == 2 again

* Call yaw, flap, and debug only if enabled in DISOCN.IN

* Make avrSWAP a ReKi and set constant kinds

* Add DISCONs for testing - revert this later

* Fix DISCON comparison, before DISCON's were overwritten by model

* Rename DEBUG2.dbg to RootName.dbg2

* Update TestCase DISCONs to new input file

* Add API change page in docs

* Add link to API change on main page

* Fix table headers

* Fix title underlines

* Fix tables again

* Fix tables again

* Fix version numbering in docs

* Simplify FAST_directory in run_FAST

* Versioning (#65)

* use sphinx-rtd-theme

* master doc and sphinx rtd theme

* index back to root folder

* only ignore install folders

* remove hidden toctree

* furo theme

* update paths

* convert rt version to string

* update sphinx settings

* move conf

* furo theme

* remove git versioning from cmake

* use hard coded rosco_version

* update intro write method

* set nowrap for intel compilers

* Add transfer of error message and clear message after each call

* update install instructions

* Catch nans in ROSCO at end of WSE

* fix conda install typo

* cleanup docs

* Rename DEBUG2.dbg to RootName.dbg2

* Fix Fl_Mode == 2

* Fix Fl_Mode == 2 again

* Allow Fl_Mode = 2 in ROSCO

* Set notch and check frequencies when Fl_Mode = 1 (fixes bug)

* Update FOCAL tuning yaml

* Update TSR

* Clean up and doc fix

* Remove publish to pypi

* Define all constant inputs to functions with kind typing

* Generate Test_Case/ inputs automatically

* Fix IEA15 DISCON path

* Fix example 11 paths

* Auto-generate tuning input yaml using schema

* Add toolbox_input to doc index

* Add toctree

* Re-name title of toolbox_input

Co-authored-by: Nikhar Abbas <nikhar.abbas@colorado.edu>
Co-authored-by: Xianping Du <38188001+Seager1989@users.noreply.github.com>
Co-authored-by: nikhar-abbas <40865984+nikhar-abbas@users.noreply.github.com>

* update listcheck method for numpy arrays

* Open Loop Control (#98)

* create rosco types yaml

* Add more descriptions, add integer_c default, cleanup

* updates for allocatability and shapes

* python scripts to write ROSCO_types.f90

* reemove superfulous modules

* use types from ROSCO registry

* create rosco types yaml

* Add more descriptions, add integer_c default, cleanup

* updates for allocatability and shapes

* python scripts to write ROSCO_types.f90

* reemove superfulous modules

* use types from ROSCO registry

* Saturate inputs to WSE.  Needs some TLC, but seems to work

* Reduce saturation limits on speed, torque

* Re-organize, set saturation limits.  Working at 3 m/s

* Initial add of OL control to ROSCO: builds

* Update DISCONs with open loop inputs

* Fix file reading for OL_Filename

* Add open loop control generation and file writing

* Use DISCON_dict for more manageable DISCON file writing

* Add open loop example, fix constant timeseries

* Make open loop example generate power

* Handle relative paths and calling from outside the run directory:
- Some helper functions borrowed from OpenFAST, f/ext_control
- Updated file writing

* Clean up: versions, print statements

* Fix SysFiles paths in CMakeLists

* Tidy up Ext_DLL names

* More Ext_DLL name tidying

* Test write_registry.py

* Update for OL Control

* Move preprocessor lines

* add zenodo DOI

* Regenerated Types

* fix shape

* revert filepath change

* give all  types a size, ProcAddr size = 3

* update types

* test registry in compile step

* specify default shell

* update write_registry path

* remove default shell

* Document API changes, provide OL input example

* Fix example 14 (yaw input)

* Add error catching to yaw control

* Tidy up OL_Input Reading: error catching, generalize

* More yaw control fixes, to model

* Checkout develop CMakeLists for ROSCO

* Update DISCON.INs for TestCases/

* Revert "Checkout develop CMakeLists for ROSCO"

This reverts commit 87a4913.

* Revert windows cmake stuff to develop

* Fix CMake again

* Revert "Revert windows cmake stuff to develop"

This reverts commit 39df122.

* Make last cmake fix - hopefully

Co-authored-by: Nikhar Abbas <nikhar.abbas@colorado.edu>

* Restart & registry (#99)

* Convert WE saved variables to WE type

* Put restart flag in localvars

* Use saved filter params from LocalVar

* save pitcomt last

* Move IPC saved variables to localvars

* Saved pi controller variables to localvar

* Save RootMyb_Last to localvar

* ROSCO_IO - initial commit. Include restart and debug functions

* Use ROSCO IO and call restart functions

* Remove debug from function.f90

* Save ACC Infile info

* update for restart capabilities

* add rosco_io with restart and debug functions

* cleanup debug call

* use registry generate types and IO

* delete DFController

* fix timestep mismatch

* remove unnecessaray istatus check

* close files

* add reg test for restart

* add restart option to run_openfast

* add testing to CI, ignore generate files

* fix fastcall

* remove extra commas

* specify gfortran-10

* testing flag cleanup

* Use lv_strings to generate debug output

* Revert "testing flag cleanup"

This reverts commit 6f29556.

* Revert "specify gfortran-10"

This reverts commit 4c31544.

* minor cleanup

* Use kind from constants

* Add some comments for clarity

* put debug in if statements

* separate reg tests from oother tests

* Fl_Mode>0

* Remove hard coded values

* Add filtered signals and WE_Vw to debug varrs

* cd for regtest

* Check logging level before calling debug

* add fl_pitcom and pc_minpit to debugvars

Co-authored-by: dzalkind <dzalkind@nrel.gov>

* Break up if statement in open loop pitch (#100)

* Break up if statement in open loop pitch

* Make torque and yaw consistent with pitch: can start after some time

* add bld edgewise freq to robust dict_inputs

* Fix ccrotor inputs (#104)

* remove interpolation of blade chord and twist

* rename aerodynblade inputs

* Update surface and DISCON.INs

* Fix performance table paths

* Allow default inputs (#110)

* Allow defaults for AeroDyn inputs

* Allow AeroDyn inputs to be floats, too

* ipc (#105)

* remove interpolation of blade chord and twist

* rename aerodynblade inputs

* Update surface and DISCON.INs

* Fix performance table paths

* Add proportional control and cleanup IPC

* Add IPC and filtered RootMyc to registry

* Better logic for filtering RootMOOP and fix notch filter slopes bug

* Add cyclic flap conrol

* Fix comments in ColemanTransformInverse

* Addd IPC_KP to DISCON.IN

* Error checking foro flp or ipc

* add mutichannel plotting with tuples

* add CMakeFiles to gitignore

* Add IPC_KP to api changes

* numerical qualifiers for error handling

* add IPC gains to schema for pass-through ability

* fix variable names

* fix ipc gain printing bug

* make sure IPC_KP is positive

* Update Polars to point to coord files

* ignore dbg2 files

* Add IEA15MW_OL.yaml

* update coord reader/writer

* expand pitch_initial to 30 degrees

* Add example 13 for IPC

* Update cp surfaces and DISCONS

* add examples to readme

* cleanup and streaamline run_examples

* Add IPC tuning vars

* Allow IPC to command pitch value below peak shaving saturation limit

* shorten simulation time

* Fix Material parameter path

* Update DISCONs again

* Fix OL_Input reading

* Set wind speed, rotor speed IC in example 14

* Debug OL reading

* Add more debugging lines

* Add more debugging lines 2

* Clean up, hone in on debug call

* Disable logging level

* Update discons - resolve conflict

* Print when finished with ROSCO

* add control packageg

* Use PriPath and RootName to name dbg files

* Print AvrSWAP

* Revert "Use PriPath and RootName to name dbg files"

This reverts commit 062fcaa.

* Disable other examples

* Print OL inputs

* Allow logging level 3

* Print OL inputs

* Make example shorter

* Print more stuf

* Print shape

* Revert "Print OL inputs"

This reverts commit 8e2a642.

* Update ROSCO Simulink model with IPC example

* refactor flap tuning for normalization methods

* improved flap controller filtering

* delete extra F_FlpCornerFrerq

* Update inputs, reader, and writer for OF 3.1.0

* Make sigma default interp type for multi_sigma

* Use openfast 3.1.0 in CI

* Fix leak...maybe

* Use OF 3.1.0 in testing

* Use gfotran for compile

* Clean up print statements

* Re-enable all examples

* Update NREL-5MW AD file

* Only check airfoil controls if more than one table

* Update BAR models

* Revert "Use gfotran for compile"

This reverts commit 5a6e2b7.

* Install pyFAST for CI

* Fix some paths in ex12

* Disable example 12

* Fix example 12 linear path, re-enable

* Skip compilers install for mac

* Try gfortran-9, no compilers

* Try gfortran-10, no compilers

* Skip windows compile in pytools

* Re-enable windows, use gfortran as FC

* Unset FC in windows

* Set environment for windows when dependencies installed

* Try setting environment in installation

* Put conditional env setting in correct place

* Try in setup again

* Break up tasks: Windows vs. not

* Update DISCONs

* Update docs with new variables

* Add example documentation

* Update ROSCO Simulink model for 3.1.0

* Make IEA model float again

* Reduce IEA timestep

* Match DT to checkpoint time

Co-authored-by: dzalkind <dzalkind@nrel.gov>

* Increment version number

* Bladed docs (#116)

* Added image of Bladed control screen setup

* Delete Bladed control screen.png

* Adding image of Bladed control screen

* Add files via upload

* Minor edit 1

* Minor change 2

* Minor change 3

* Minor change 4

* Change 6

* Change 7

* Change 8

* Minor change 9

Co-authored-by: nikhar-abbas <40865984+nikhar-abbas@users.noreply.github.com>
Co-authored-by: WillC-DNV <100850534+WillC-DNV@users.noreply.github.com>

* Update version in API change docs

* Bladed readthedocs (#117)

* Added image of Bladed control screen setup

* Delete Bladed control screen.png

* Adding image of Bladed control screen

* Add files via upload

* Minor edit 1

* Minor change 2

* Minor change 3

* Minor change 4

* Change 6

* Change 7

* Change 8

* Minor change 9

* Tinker with characters in bladed instructions

* Add bladed instructions to index

* Change bladed toctree label

* Do underline stuff

* Make toctree label same as file

* Remove colons from headers

Co-authored-by: nikhar-abbas <40865984+nikhar-abbas@users.noreply.github.com>
Co-authored-by: WillC-DNV <100850534+WillC-DNV@users.noreply.github.com>

* Update docs to reflect CI process

Co-authored-by: Nikhar Abbas <nikhar.abbas@colorado.edu>
Co-authored-by: Xianping Du <38188001+Seager1989@users.noreply.github.com>
Co-authored-by: nikhar-abbas <40865984+nikhar-abbas@users.noreply.github.com>
Co-authored-by: WillC-DNV <100850534+WillC-DNV@users.noreply.github.com>

* Fixed wrong formatting of list items (#122)

extra newline required between list elements

* Regenerate types, IO with registry

* Update registry so first timestep is printed

* Update inverted notch to move frequency properly

* Saturate inv notch corner frequency at 0

* Add tower damper mode flag

* Flip Ct and Cq table allocation

* Regen types

* Remove print statements used for debugging

* Update input files: IEA model has pitch actuator

* Add back flap control (no idea when it was deleted)

* Update discons, docs with API change

Co-authored-by: nikhar-abbas <40865984+nikhar-abbas@users.noreply.github.com>
Co-authored-by: Nikhar Abbas <nikhar.abbas@colorado.edu>
Co-authored-by: Xianping Du <38188001+Seager1989@users.noreply.github.com>
Co-authored-by: WillC-DNV <100850534+WillC-DNV@users.noreply.github.com>
Co-authored-by: Gustavo Hylander <74593034+ghylander@users.noreply.github.com>
  • Loading branch information
6 people authored May 6, 2022
1 parent e035a7d commit 5cdb0b5
Show file tree
Hide file tree
Showing 19 changed files with 600 additions and 468 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,6 @@ ROSCO_testing/results/
*.autosave
*.mat

# OpenFAST outputs
outputs/

20 changes: 19 additions & 1 deletion ROSCO/rosco_registry/rosco_types.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ ControlParameters:
allocatable: True

# Tower fore-aft damping
TD_Mode:
<<: *integer
description: Tower damper mode (0- no tower damper, 1- feed back translational nacelle accelleration to pitch angle
FA_HPFCornerFreq:
<<: *real
description: Corner frequency (-3dB point) in the high-pass filter on the fore-aft acceleration signal [rad/s]
Expand Down Expand Up @@ -422,6 +425,17 @@ ControlParameters:
allocatable: True
dimension: (:,:)
description: Open loop channels in timeseries

# Pitch actuator
PA_Mode:
<<: *integer
description: Pitch actuator mode {0 - not used, 1 - first order filter, 2 - second order filter}
PA_CornerFreq:
<<: *real
description: Pitch actuator bandwidth/cut-off frequency [rad/s]
PA_Damping:
<<: *real
description: Pitch actuator damping ratio [-, unused if PA_Mode = 1]

# Calculated
PC_RtTq99:
Expand Down Expand Up @@ -769,6 +783,10 @@ LocalVariables:
<<: *real
description: Commanded pitch of each blade the last time the controller was called [rad].
size: 3
PitComAct:
<<: *real
description: Actuated pitch of each blade the last time the controller was called [rad].
size: 3
SS_DelOmegaF:
<<: *real
description: Filtered setpoint shifting term defined in setpoint smoother [rad/s].
Expand Down Expand Up @@ -1011,4 +1029,4 @@ ExtDLL_Type:
equals: '""'
size: 3
length: 1024
description: The name of the procedure in the DLL that will be called.
description: The name of the procedure in the DLL that will be called.
29 changes: 14 additions & 15 deletions ROSCO/rosco_registry/write_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,25 +278,24 @@ def write_roscoio(yfile):
file.write(" WRITE(UnDb3,'"+'(A,85("'+"'//Tab//'"+'AvrSWAP("'+',I2,")"'+"))') 'LocalVar%Time ', (i,i=1, 85)\n")
file.write(" WRITE(UnDb3,'"+'(A,85("'+"'//Tab//'"+'(-)"'+"))') '(s)'"+'\n')
file.write(" END IF\n")
file.write(" ELSE\n")
file.write(" END IF\n")
file.write(" ! Print simulation status, every 10 seconds\n")
file.write(" IF (MODULO(LocalVar%Time, 10.0_DbKi) == 0) THEN\n")
file.write(" WRITE(*, 100) LocalVar%GenSpeedF*RPS2RPM, LocalVar%BlPitch(1)*R2D, avrSWAP(15)/1000.0, LocalVar%WE_Vw\n")
file.write(" 100 FORMAT('Generator speed: ', f6.1, ' RPM, Pitch angle: ', f5.1, ' deg, Power: ', f7.1, ' kW, Est. wind Speed: ', f5.1, ' m/s')\n")
file.write(" END IF\n")
file.write(" IF (MODULO(LocalVar%Time, 10.0_DbKi) == 0) THEN\n")
file.write(" WRITE(*, 100) LocalVar%GenSpeedF*RPS2RPM, LocalVar%BlPitch(1)*R2D, avrSWAP(15)/1000.0, LocalVar%WE_Vw\n")
file.write(" 100 FORMAT('Generator speed: ', f6.1, ' RPM, Pitch angle: ', f5.1, ' deg, Power: ', f7.1, ' kW, Est. wind Speed: ', f5.1, ' m/s')\n")
file.write(" END IF\n")
file.write("\n")
file.write(" ! Write debug files\n")
file.write(" IF(CntrPar%LoggingLevel > 0) THEN\n")
file.write(" WRITE (UnDb, FmtDat) LocalVar%Time, DebugOutData\n")
file.write(" END IF\n")
file.write(" ! Write debug files\n")
file.write(" IF(CntrPar%LoggingLevel > 0) THEN\n")
file.write(" WRITE (UnDb, FmtDat) LocalVar%Time, DebugOutData\n")
file.write(" END IF\n")
file.write("\n")
file.write(" IF(CntrPar%LoggingLevel > 1) THEN\n")
file.write(" WRITE (UnDb2, FmtDat) LocalVar%Time, LocalVarOutData\n")
file.write(" END IF\n")
file.write(" IF(CntrPar%LoggingLevel > 1) THEN\n")
file.write(" WRITE (UnDb2, FmtDat) LocalVar%Time, LocalVarOutData\n")
file.write(" END IF\n")
file.write("\n")
file.write(" IF(CntrPar%LoggingLevel > 2) THEN\n")
file.write(" WRITE (UnDb3, FmtDat) LocalVar%Time, avrSWAP(1: 85)\n")
file.write(" END IF\n")
file.write(" IF(CntrPar%LoggingLevel > 2) THEN\n")
file.write(" WRITE (UnDb3, FmtDat) LocalVar%Time, avrSWAP(1: 85)\n")
file.write(" END IF\n")
file.write("\n")
file.write("END SUBROUTINE Debug\n")
Expand Down
38 changes: 29 additions & 9 deletions ROSCO/src/Controllers.f90
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst, DebugVar, ErrVar)
END IF

! Include tower fore-aft tower vibration damping control
IF ((CntrPar%FA_KI > 0.0) .OR. (CntrPar%Y_ControlMode == 2)) THEN
IF ((CntrPar%TD_Mode > 0) .OR. (CntrPar%Y_ControlMode == 2)) THEN
CALL ForeAftDamping(CntrPar, LocalVar, objInst)
ELSE
LocalVar%FA_PitCom = 0.0 ! THIS IS AN ARRAY!!
Expand Down Expand Up @@ -99,13 +99,12 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst, DebugVar, ErrVar)
LocalVar%PC_PitComT = ratelimit(LocalVar%PC_PitComT, LocalVar%PC_PitComT_Last, CntrPar%PC_MinRat, CntrPar%PC_MaxRat, LocalVar%DT) ! Saturate the overall command of blade K using the pitch rate limit
LocalVar%PC_PitComT_Last = LocalVar%PC_PitComT

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

Expand All @@ -119,12 +118,33 @@ SUBROUTINE PitchControl(avrSWAP, CntrPar, LocalVar, objInst, DebugVar, ErrVar)
ENDIF
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
IF (CntrPar%PA_Mode == 1) THEN
LocalVar%PitComAct(K) = LPFilter(LocalVar%PitCom(K), LocalVar%DT, CntrPar%PA_CornerFreq, LocalVar%FP, LocalVar%iStatus, LocalVar%restart, objInst%instLPF)
ELSE IF (CntrPar%PA_Mode == 2) THEN
LocalVar%PitComAct(K) = SecLPFilter(LocalVar%PitCom(K),LocalVar%DT,CntrPar%PA_CornerFreq,CntrPar%PA_Damping,LocalVar%FP,LocalVar%iStatus,LocalVar%restart,objInst%instSecLPF)
END IF
ELSE
LocalVar%PitComAct(K) = LocalVar%PitCom(K)
ENDIF
END DO

! Hardware saturation: using CntrPar%PC_MinPit
DO K = 1,LocalVar%NumBl ! Loop through all blades, add IPC contribution and limit pitch rate
! Saturate the pitch command using the overall (hardware) limit
LocalVar%PitComAct(K) = saturate(LocalVar%PitComAct(K), LocalVar%PC_MinPit, CntrPar%PC_MaxPit)
! Saturate the overall command of blade K using the pitch rate limit
LocalVar%PitComAct(K) = ratelimit(LocalVar%PitComAct(K), LocalVar%BlPitch(K), CntrPar%PC_MinRat, CntrPar%PC_MaxRat, LocalVar%DT) ! Saturate the overall command of blade K using the pitch rate limit
END DO

! Command the pitch demanded from the last
! call to the controller (See Appendix A of Bladed User's Guide):
avrSWAP(42) = LocalVar%PitCom(1) ! Use the command angles of all blades if using individual pitch
avrSWAP(43) = LocalVar%PitCom(2) ! "
avrSWAP(44) = LocalVar%PitCom(3) ! "
avrSWAP(45) = LocalVar%PitCom(1) ! Use the command angle of blade 1 if using collective pitch
avrSWAP(42) = LocalVar%PitComAct(1) ! Use the command angles of all blades if using individual pitch
avrSWAP(43) = LocalVar%PitComAct(2) ! "
avrSWAP(44) = LocalVar%PitComAct(3) ! "
avrSWAP(45) = LocalVar%PitComAct(1) ! Use the command angle of blade 1 if using collective pitch

! Add RoutineName to error message
IF (ErrVar%aviFAIL < 0) THEN
Expand Down
2 changes: 1 addition & 1 deletion ROSCO/src/Filters.f90
Original file line number Diff line number Diff line change
Expand Up @@ -310,4 +310,4 @@ SUBROUTINE PreFilterMeasuredSignals(CntrPar, LocalVar, DebugVar, objInst, ErrVar
DebugVar%NacIMU_FA_AccF = LocalVar%NacIMU_FA_AccF
DebugVar%FA_AccF = LocalVar%FA_AccF
END SUBROUTINE PreFilterMeasuredSignals
END MODULE Filters
END MODULE Filters
104 changes: 55 additions & 49 deletions ROSCO/src/ROSCO_IO.f90
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ SUBROUTINE WriteRestartFile(LocalVar, CntrPar, objInst, RootName, size_avcOUTNAM
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%PitComAct(1)
WRITE( Un, IOSTAT=ErrStat) LocalVar%PitComAct(2)
WRITE( Un, IOSTAT=ErrStat) LocalVar%PitComAct(3)
WRITE( Un, IOSTAT=ErrStat) LocalVar%SS_DelOmegaF
WRITE( Un, IOSTAT=ErrStat) LocalVar%TestType
WRITE( Un, IOSTAT=ErrStat) LocalVar%VS_MaxTq
Expand Down Expand Up @@ -272,6 +275,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%PitComAct(1)
READ( Un, IOSTAT=ErrStat) LocalVar%PitComAct(2)
READ( Un, IOSTAT=ErrStat) LocalVar%PitComAct(3)
READ( Un, IOSTAT=ErrStat) LocalVar%SS_DelOmegaF
READ( Un, IOSTAT=ErrStat) LocalVar%TestType
READ( Un, IOSTAT=ErrStat) LocalVar%VS_MaxTq
Expand Down Expand Up @@ -424,7 +430,7 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, avrSWAP, RootName, size_avcOUTNAME
'[m/s]', '[m/s]', '[rad]', '[rad]', '[rad/s]', &
'[rad/s]', '[rad/s]', '[m/s]', '[rad]', '[rad]', &
'', '', '', '']
nLocalVars = 72
nLocalVars = 73
Allocate(LocalVarOutData(nLocalVars))
Allocate(LocalVarOutStrings(nLocalVars))
LocalVarOutData(1) = LocalVar%iStatus
Expand Down Expand Up @@ -472,33 +478,34 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, avrSWAP, RootName, size_avcOUTNAME
LocalVarOutData(43) = LocalVar%IPC_KP(1)
LocalVarOutData(44) = LocalVar%PC_State
LocalVarOutData(45) = LocalVar%PitCom(1)
LocalVarOutData(46) = LocalVar%SS_DelOmegaF
LocalVarOutData(47) = LocalVar%TestType
LocalVarOutData(48) = LocalVar%VS_MaxTq
LocalVarOutData(49) = LocalVar%VS_LastGenTrq
LocalVarOutData(50) = LocalVar%VS_LastGenPwr
LocalVarOutData(51) = LocalVar%VS_MechGenPwr
LocalVarOutData(52) = LocalVar%VS_SpdErrAr
LocalVarOutData(53) = LocalVar%VS_SpdErrBr
LocalVarOutData(54) = LocalVar%VS_SpdErr
LocalVarOutData(55) = LocalVar%VS_State
LocalVarOutData(56) = LocalVar%VS_Rgn3Pitch
LocalVarOutData(57) = LocalVar%WE_Vw
LocalVarOutData(58) = LocalVar%WE_Vw_F
LocalVarOutData(59) = LocalVar%WE_VwI
LocalVarOutData(60) = LocalVar%WE_VwIdot
LocalVarOutData(61) = LocalVar%VS_LastGenTrqF
LocalVarOutData(62) = LocalVar%Y_AccErr
LocalVarOutData(63) = LocalVar%Y_ErrLPFFast
LocalVarOutData(64) = LocalVar%Y_ErrLPFSlow
LocalVarOutData(65) = LocalVar%Y_MErr
LocalVarOutData(66) = LocalVar%Y_YawEndT
LocalVarOutData(67) = LocalVar%Fl_PitCom
LocalVarOutData(68) = LocalVar%NACIMU_FA_AccF
LocalVarOutData(69) = LocalVar%FA_AccF
LocalVarOutData(70) = LocalVar%Flp_Angle(1)
LocalVarOutData(71) = LocalVar%RootMyb_Last(1)
LocalVarOutData(72) = LocalVar%ACC_INFILE_SIZE
LocalVarOutData(46) = LocalVar%PitComAct(1)
LocalVarOutData(47) = LocalVar%SS_DelOmegaF
LocalVarOutData(48) = LocalVar%TestType
LocalVarOutData(49) = LocalVar%VS_MaxTq
LocalVarOutData(50) = LocalVar%VS_LastGenTrq
LocalVarOutData(51) = LocalVar%VS_LastGenPwr
LocalVarOutData(52) = LocalVar%VS_MechGenPwr
LocalVarOutData(53) = LocalVar%VS_SpdErrAr
LocalVarOutData(54) = LocalVar%VS_SpdErrBr
LocalVarOutData(55) = LocalVar%VS_SpdErr
LocalVarOutData(56) = LocalVar%VS_State
LocalVarOutData(57) = LocalVar%VS_Rgn3Pitch
LocalVarOutData(58) = LocalVar%WE_Vw
LocalVarOutData(59) = LocalVar%WE_Vw_F
LocalVarOutData(60) = LocalVar%WE_VwI
LocalVarOutData(61) = LocalVar%WE_VwIdot
LocalVarOutData(62) = LocalVar%VS_LastGenTrqF
LocalVarOutData(63) = LocalVar%Y_AccErr
LocalVarOutData(64) = LocalVar%Y_ErrLPFFast
LocalVarOutData(65) = LocalVar%Y_ErrLPFSlow
LocalVarOutData(66) = LocalVar%Y_MErr
LocalVarOutData(67) = LocalVar%Y_YawEndT
LocalVarOutData(68) = LocalVar%Fl_PitCom
LocalVarOutData(69) = LocalVar%NACIMU_FA_AccF
LocalVarOutData(70) = LocalVar%FA_AccF
LocalVarOutData(71) = LocalVar%Flp_Angle(1)
LocalVarOutData(72) = LocalVar%RootMyb_Last(1)
LocalVarOutData(73) = LocalVar%ACC_INFILE_SIZE
LocalVarOutStrings = [CHARACTER(15) :: 'iStatus', 'Time', 'DT', 'VS_GenPwr', 'GenSpeed', &
'RotSpeed', 'Y_M', 'HorWindV', 'rootMOOP', 'rootMOOPF', &
'BlPitch', 'Azimuth', 'NumBl', 'FA_Acc', 'NacIMU_FA_Acc', &
Expand All @@ -508,12 +515,12 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, avrSWAP, RootName, size_avcOUTNAME
'PC_MinPit', 'PC_PitComT', 'PC_PitComT_Last', 'PC_PitComTF', 'PC_PitComT_IPC', &
'PC_PwrErr', 'PC_SpdErr', 'IPC_AxisTilt_1P', 'IPC_AxisYaw_1P', 'IPC_AxisTilt_2P', &
'IPC_AxisYaw_2P', 'IPC_KI', 'IPC_KP', 'PC_State', 'PitCom', &
'SS_DelOmegaF', 'TestType', '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', &
'VS_LastGenTrqF', 'Y_AccErr', 'Y_ErrLPFFast', 'Y_ErrLPFSlow', 'Y_MErr', &
'Y_YawEndT', 'Fl_PitCom', 'NACIMU_FA_AccF', 'FA_AccF', 'Flp_Angle', &
'RootMyb_Last', 'ACC_INFILE_SIZE']
'PitComAct', 'SS_DelOmegaF', 'TestType', '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', 'VS_LastGenTrqF', 'Y_AccErr', 'Y_ErrLPFFast', 'Y_ErrLPFSlow', &
'Y_MErr', 'Y_YawEndT', 'Fl_PitCom', 'NACIMU_FA_AccF', 'FA_AccF', &
'Flp_Angle', 'RootMyb_Last', 'ACC_INFILE_SIZE']
! 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
Expand All @@ -536,25 +543,24 @@ SUBROUTINE Debug(LocalVar, CntrPar, DebugVar, avrSWAP, RootName, size_avcOUTNAME
WRITE(UnDb3,'(A,85("'//Tab//'AvrSWAP(",I2,")"))') 'LocalVar%Time ', (i,i=1, 85)
WRITE(UnDb3,'(A,85("'//Tab//'(-)"))') '(s)'
END IF
ELSE
END IF
! Print simulation status, every 10 seconds
IF (MODULO(LocalVar%Time, 10.0_DbKi) == 0) THEN
WRITE(*, 100) LocalVar%GenSpeedF*RPS2RPM, LocalVar%BlPitch(1)*R2D, avrSWAP(15)/1000.0, LocalVar%WE_Vw
100 FORMAT('Generator speed: ', f6.1, ' RPM, Pitch angle: ', f5.1, ' deg, Power: ', f7.1, ' kW, Est. wind Speed: ', f5.1, ' m/s')
END IF
IF (MODULO(LocalVar%Time, 10.0_DbKi) == 0) THEN
WRITE(*, 100) LocalVar%GenSpeedF*RPS2RPM, LocalVar%BlPitch(1)*R2D, avrSWAP(15)/1000.0, LocalVar%WE_Vw
100 FORMAT('Generator speed: ', f6.1, ' RPM, Pitch angle: ', f5.1, ' deg, Power: ', f7.1, ' kW, Est. wind Speed: ', f5.1, ' m/s')
END IF

! Write debug files
IF(CntrPar%LoggingLevel > 0) THEN
WRITE (UnDb, FmtDat) LocalVar%Time, DebugOutData
END IF
! Write debug files
IF(CntrPar%LoggingLevel > 0) THEN
WRITE (UnDb, FmtDat) LocalVar%Time, DebugOutData
END IF

IF(CntrPar%LoggingLevel > 1) THEN
WRITE (UnDb2, FmtDat) LocalVar%Time, LocalVarOutData
END IF
IF(CntrPar%LoggingLevel > 1) THEN
WRITE (UnDb2, FmtDat) LocalVar%Time, LocalVarOutData
END IF

IF(CntrPar%LoggingLevel > 2) THEN
WRITE (UnDb3, FmtDat) LocalVar%Time, avrSWAP(1: 85)
END IF
IF(CntrPar%LoggingLevel > 2) THEN
WRITE (UnDb3, FmtDat) LocalVar%Time, avrSWAP(1: 85)
END IF

END SUBROUTINE Debug
Expand Down
Loading

0 comments on commit 5cdb0b5

Please sign in to comment.