From 0fd984b7c4fbf288b9572efe1f576a4208d1a1e1 Mon Sep 17 00:00:00 2001 From: dzalkind Date: Fri, 19 Jan 2024 10:49:08 -0700 Subject: [PATCH] Squashed 'ROSCO/' changes from 6c2807a9e..b994e4de6 b994e4de6 ROSCO v2.9.0 (#304) REVERT: 6c2807a9e Merge remote-tracking branch 'upstream/develop' into v2.9.0_prep REVERT: 7fa1ae25e Don't check ZMQ period if no ZMQ_Mode REVERT: 4cdef25d4 Merge pull request #300 from NREL/smart_lib_path REVERT: b1c943ea0 fixes for windows REVERT: 8c39105a3 hopefully caught everything REVERT: 2d0525830 switch to cmake-build-extension and logic for finding rosco library path REVERT: 45aad140c Add more error checking in checkpoint file I/O REVERT: c5de22f59 Modernize setup and CI (#297) REVERT: 92e2ac5ab Reorganize Repo (#294) REVERT: 6a3b194ac Merge pull request #164 from dzalkind/f/exclusion_zone REVERT: fb5c43de3 Skip upload of artifacts REVERT: eed259db9 Update toolbox input rst REVERT: 9d97bc285 Revert IEA yaml REVERT: 173a91580 Remove extra update_discons REVERT: 4f7d27376 Separate TD and TRA control modes REVERT: 77255d15a Rename TRA example, add to CI testing REVERT: 2decc8166 Add ZMQ_ID to api change REVERT: 1e455a0e8 Merge remote-tracking branch 'upstream/develop' into f/exclusion_zone REVERT: f93f28162 Add clarification on fastcall REVERT: 69da72105 Change guidance in api reference REVERT: ef5aa138c Add signals to IO and Types REVERT: 3c9e00fb0 Add PC_RefSpd interim signals REVERT: b2acd3efb Clean up PRC example REVERT: 2b0f88223 Set up TRA example REVERT: 05ed0f4df Wind Farm Control Interface (#280) REVERT: 47dd2d61e Update API docs REVERT: be4753b5f Revert PC_PitComC to T REVERT: 7d6b45a03 Try apt-get update REVERT: a681eb7ef Update toolbox docs REVERT: 5b38681c1 Clean up inputs further REVERT: 9d5e21a7e Clean up Twr_ variables and names names REVERT: f71b8ec04 Rate limit set point, needs clean up REVERT: c75738eee Modified ZeroMQ interface to include pitch offsets (#261) REVERT: a610e55eb Better Open Loop Control Error Catching (#273) REVERT: dd01047c5 Update .readthedocs.yaml remove old python version REVERT: 8693d4ba4 Update .readthedocs.yaml REVERT: 328d29e7d Update .readthedocs.yaml with version key REVERT: c4790340d Update .readthedocs.yaml with another python version REVERT: 04d3f5284 Update .readthedocs.yaml with new python version REVERT: 80973fe16 Update .readthedocs.yaml with python 3.9 REVERT: 6f1ccfa33 Update .readthedocs.yaml with other build options REVERT: f2a624db1 Update .readthedocs.yaml with build.os REVERT: 0e800947d Update api_change.rst formatting REVERT: b66cd1170 Add types to scalars (#264) REVERT: 31b7cc823 Update API docs REVERT: 9ca681b3c Clean up more old TD_Modes REVERT: 3c0c800ca Add Twr_Mode error catching and warnings REVERT: 93b16623f Remove TD_Mode, regen inputs, docs REVERT: 2c76747fa Increase max file unit (#253) REVERT: 4ebd1350f Clean up types, make band total width of band REVERT: b10ec71b2 Merge remote-tracking branch 'upstream/develop' into f/exclusion_zone REVERT: 25cf21977 Re-work exclusion zone with simpler implementation REVERT: 989ce5ba9 Merge pull request #170 from dzalkind/power_ref_tracking REVERT: e75baa29a Remove pCrunch notebook REVERT: 3b0bde0fa Update PRC example with PRC_GenSpeeds REVERT: 32292e588 Bring back saturation of torque reference speed REVERT: d9a31fb76 Document API changes REVERT: 38f27def4 Add LPF on WSE for speed selection, use gen speed rather than rotor REVERT: b817a5ca8 Bring back new VS_ControlMode that merge lost REVERT: 3092e387b Tidy example documentation, output REVERT: 24052dc20 Revert run_FAST cases REVERT: b5eb5c0ad Use updated DISCON writing functions for PRC inputs REVERT: ea55560f7 Shorten PRC example REVERT: b27629b3d Rename power ref example REVERT: 716b2e46d Merge remote-tracking branch 'upstream/develop' into power_ref_tracking REVERT: 63bcb0d4b Extend ROSCO for MHK (#257) REVERT: 31332d923 Update .readthedocs.yaml to remove use of 'system_packages' as it is being depreciated by readthedocs (#258) REVERT: c641b54a6 Rotor Position Control (#255) REVERT: 178217bb1 Regenerate registry, inputs REVERT: d9547ddcd Fix relative Cp filepaths REVERT: 9de385b3c Merge remote-tracking branch 'upstream/develop' into power_ref_tracking REVERT: 273af277d Regen registry, discons REVERT: fef92431b Fix relative Cp filepaths REVERT: d4d4cb261 Merge remote-tracking branch 'upstream/develop' into f/exclusion_zone REVERT: 2f069daec Floating Feedback Gain Scheduling (#241) REVERT: c701f6776 OpenFAST 3.5.0 (#246) REVERT: e5b1af538 Yaw Rate Bug Fix (#239) REVERT: 5fd97e254 Increment version number REVERT: 12f8fdb4b Merge remote-tracking branch 'upstream/main' into develop REVERT: 90357a2cd Merge remote-tracking branch 'upstream/develop' into power_ref_tracking REVERT: 23879c815 Remove old TD_Mode references REVERT: 1c644ecde Update TRA example REVERT: 0dc1ad0c1 Merge remote-tracking branch 'upstream/develop' into f/exclusion_zone REVERT: 79426f799 Increment version number REVERT: 339ad5391 Tidy example output REVERT: 585e2c8b1 Open loop platform control (#236) REVERT: 24bded08f Add note about offset REVERT: 60b366d0a Revert openfast changes REVERT: ac14b174d Init PC_RefSpeed if no PRC REVERT: de15e52d4 Various bug fixes (#233) REVERT: 766941943 Merge remote-tracking branch 'upstream/develop' into power_ref_tracking REVERT: 8a39f3cc7 Update example with ramp, reference REVERT: 5a7046f70 Active Wake Control (#230) REVERT: 099532bc7 Finish merge with awc inputs and registry REVERT: f1037ec6e Merge remote-tracking branch 'origin/awc' into power_ref_tracking REVERT: 9e5fd58cd Add PRC example REVERT: e49f3837d Add latest plot_FAST notebook REVERT: 1e38c90d7 Update IPC example for testing sat modes REVERT: 52e370867 Finish merge with inputs and registry REVERT: fe2470475 Merge remote-tracking branch 'upstream/develop' into power_ref_tracking REVERT: fbb44c4b2 Add IPC gain to NREL2p8 REVERT: 5afb385bd Parallelize output processing REVERT: 90c40416b Add optimized NREL2p8 controller input REVERT: 820aa6630 Merge pull request #2 from kbrown1snl/patch-2 REVERT: 728c61da3 Update 20_active_wake_control.py REVERT: 17ce1a5c4 Merge remote-tracking branch 'jfred/patch-1' into awc REVERT: bc3341760 Update api_change.rst REVERT: 8e4cf8b24 Allow more than 99 local variables in dbg2 REVERT: 7f12c9c92 Clean up comments REVERT: 9d7e18de4 Tidy file writing REVERT: 3851a6baf Remove lingering comment REVERT: e02379d93 Remove AWC references from IPC REVERT: 50bd08c19 Tidy up IPC, allow AWC and IPC with warning REVERT: 50f419119 Update error message REVERT: 1e25c88ae Fixed bug in added AWC input checks. REVERT: bd4d7d5d9 Added checks for AWC inputs. REVERT: cae3f1733 Updated AWC input parameters. REVERT: 2947b4f10 Dylib -> so in Test_Cases REVERT: e1379de0a Run ROSCO_testing from anywhere REVERT: de8d228a6 Fix input file writing, force into int in write_array REVERT: 5e75601ca Make AWC_n a list, too REVERT: c1e4be785 Force AWC_n into int better REVERT: 4194da43f Force AWC_n into int REVERT: e4d7ec259 Tidy input writing, remove `future` references REVERT: 74c7fcbfe Rename methods in readme REVERT: 4e2a77833 Remove duplicate PF_Offsets input read REVERT: ca7c44d8e Tidy print statements, file writing REVERT: daf77e943 Merge remote-tracking branch 'ndev/rosco_awc_merge' into awc REVERT: 8ea0a4c97 Merge remote-tracking branch 'jfred/AWC_NREL' into awc REVERT: 87cde8c52 Merge remote-tracking branch 'upstream/develop' into awc REVERT: 1ccc1b36b Platform control and Optional Inputs (#227) REVERT: e8996003c Updated Coleman Transformation based AWC REVERT: b2fdfbcf9 Update AWC_Mode descriptions REVERT: b17f35005 Add 2.8 to update_discons, regenerate DISCON Should match closely to original DISCON REVERT: 4604ebbee Add 20_awc to test_examples REVERT: a9ec14e98 Update all DISCONs REVERT: b24f07b6f Merge remote-tracking branch 'upstream/develop' into awc REVERT: 70d5771c8 Fix file writing in AWC section REVERT: 687b7603e Undo unintentional changes to wrie_registry.py REVERT: 3bc2185ce Added NREL-developed AWC-implementation REVERT: ff0ce39cf Update rosco_types.yaml REVERT: 797e5544e Update utilities.py REVERT: 826ca01fb Update toolbox_schema.yaml REVERT: b141c4e04 Update 20_active_wake_control.py REVERT: baaa8db06 Update ReadSetParameters.f90 REVERT: 5c878add4 Update ROSCO_Types.f90 REVERT: ae5090b5c Update Controllers.f90 REVERT: 32dc9fd8a Update NREL-2p8-127_DISCON.IN REVERT: 46e7168d8 Update 20_active_wake_control.py REVERT: 87b3f09c5 Revert setup directory REVERT: de3a6fe44 Tidy up DISCON file writing REVERT: de16ecdda Test all AWC cases in example 20 REVERT: cabbb2adc Merge pull request #1 from kbrown1snl/patch-1 REVERT: 1824f991a Fix units in schema REVERT: f6d061f87 Update 20_active_wake_control.py REVERT: a7d33035f Merge remote-tracking branch 'upstream/main' into develop REVERT: 83022e586 Prep for more modes REVERT: 3c40565ea Formatting fixes REVERT: d93d44321 Update AWC example with instructions/theory REVERT: 2bb01760d Tidy example REVERT: 1693602fb Add AWC to toolbox schema REVERT: 1201a6672 Update other DISCONs REVERT: cc4080d03 Tidy up input additions REVERT: da46fac31 Set min pitch for AWC REVERT: 5c5333b12 Remove LocalVar%PC_MinPit = CntrPar%PC_MinPit, breaking setpoint smoother REVERT: b102b34d2 Update example to point to correct inputs REVERT: 80bd691ac Add AWC_Mode and move AWC into subroutine REVERT: d05ef6c7a Merge branch 'develop' into rosco_awc_merge REVERT: 2f941e38f Merge remote-tracking branch 'upstream/main' into develop REVERT: a4717839d Add initial AWC example, needs OF3.4 REVERT: f5c3c1e5d Add case generation updates REVERT: 42525a98a V270 prep (#218) REVERT: a1cf97bbe Rename examples (#215) REVERT: 20c9c9d1d Adding NREL 2.8 127 for AWC testing REVERT: 0c0e466a8 Fixes to readsetparams and awc location REVERT: 3155b63dd Add script for updating DISCON versions (#214) REVERT: c51ed30ac Removed duplicate pitch assignment and removed MinPitch mods for AWC REVERT: e554c1da0 IPC Saturation Fix [RAAW] (#210) REVERT: be28641f1 Allow PA_Mode 1 (#213) REVERT: 515da1797 Make AWC_complexangle a LocalVar for logging REVERT: 974e271c7 Separate contribution to PitCom from mode calculation REVERT: 0575d7527 Re-organize AWC pitch contribution, before actuator REVERT: 1e802638f Apply DbKi to COMPLEX REVERT: 0be88d47e Add AWC parameters to registry, regenerate types REVERT: f5428de80 Merge remote-tracking branch 'upstream/develop' into rosco_awc_merge REVERT: 721fbf5d1 Use new numpy REVERT: 15c0603fb Merge remote-tracking branch 'upstream/develop' into f/exclusion_zone REVERT: 05d7b3b94 Compatibility with Numpy v1.24 (#208) REVERT: 75a648cdf AWC First Version, collected changes REVERT: b3a8b1cbf Try compilers in macOS build REVERT: b5c65bdb5 Add example_19 to CI REVERT: c8d08c11d Fix default Twr_GainTau REVERT: b1e122985 Allow Twr_Mode of 3 in tuning yaml REVERT: 591571e76 Add Twr_GainFactor and Twr_GainTau REVERT: 6881ac098 Add TRA example REVERT: f7bae0009 Tidy input writer REVERT: a3aa81fac Separate collective pitch command from total, use in SS REVERT: b1f78e088 Add VS_RefSpd and PC_RefSpd to LocalVars REVERT: f2db21273 Tidy up merge with develop REVERT: a2741f20a Merge remote-tracking branch 'upstream/develop' into f/exclusion_zone REVERT: 9d27a333b OpenFAST v3.3.0 (#202) REVERT: 5ad1d4109 Doc fix (#200) REVERT: 827b2814f Update sim.py (#196) REVERT: 602332eac Various Bug Fixes (#188) REVERT: 9384f0307 Added feature to read AeroDyn 14 files also for the case without tower influence. (#177) REVERT: decd69470 Various Bug Fixes (#167) REVERT: 2efac8480 Adding pitch actuator fault (#163) REVERT: 34ca985ef Update discons REVERT: b933b3bab Add rotor speed tracking, test case REVERT: 86c8acfb2 Update Windows install instructions REVERT: 778822b5d Add generator efficiency to power output of simple simulation REVERT: ae7b26748 Update example 05 units REVERT: 16bd05c66 Clean up TwrControl_Mode REVERT: 2da1a16ab Change TD_Mode to Twr_Mode REVERT: eec3d5f23 Merge branch 'develop' into f/exclusion_zone REVERT: 772e36f96 update discons REVERT: df919635b Update registry REVERT: 9bc45ce27 Merge remote-tracking branch 'upstream/develop' into f/exclusion_zone REVERT: 40a4edc9f F/zmq (#145) REVERT: b45fb4300 External Control Interface (#141) REVERT: 9ca75e1e2 Robust control updates (#139) REVERT: 0bf504ee3 Pass through (#136) REVERT: 75e7fb8dc RAAW Updates (#133) REVERT: 50a2f90e3 Add OpenFAST channels that Simulink reads (#135) REVERT: 5cdb0b5fb Pitch Actuator and IPC updates (#123) REVERT: e035a7d95 Flip Ct and Cq table allocation (#130) REVERT: bd0562cd4 sigma + ipc (#125) REVERT: d52019231 Update docs to reflect CI process REVERT: e9c9378e3 Merge remote-tracking branch 'upstream/develop' into develop REVERT: 4126adbfd Bladed readthedocs (#117) REVERT: d7d15b044 Update version in API change docs REVERT: 8c312875c Bladed docs (#116) REVERT: 5f18bf8c1 Increment version number REVERT: 9b5499d76 ipc (#105) REVERT: a857211fa Allow default inputs (#110) REVERT: 1be503c03 Fix print var type for WE_CP REVERT: 2d8a9451b Update DISCONs REVERT: 7e30c4d64 Add exclusion zone to example REVERT: eb9b901b8 Add exclusion zone mode to REVERT: a5eb72c35 fix units for exclusion zone REVERT: d50e23a00 Add twr frequency exclusion zone REVERT: 38a13da46 add control packageg REVERT: a9f43b948 Print when finished with ROSCO REVERT: 58b4e1b5d Update discons - resolve conflict REVERT: c8b23371f Merge remote-tracking branch 'upstream/develop' into f/ipc REVERT: 480c7c4ad Disable logging level REVERT: 3beca3eb9 Clean up, hone in on debug call REVERT: 5692ab844 Add more debugging lines 2 REVERT: a568be6a5 Add more debugging lines REVERT: e119569f4 Debug OL reading REVERT: 0971f300c Set wind speed, rotor speed IC in example 14 REVERT: a362dc473 Fix OL_Input reading REVERT: 41e0dc6e2 Fix ccrotor inputs (#104) REVERT: b4c755844 Update DISCONs again REVERT: db919993c Fix Material parameter path REVERT: 1dc03765f shorten simulation time REVERT: 5cb3725e3 Allow IPC to command pitch value below peak shaving saturation limit REVERT: 07753d8ca Add IPC tuning vars REVERT: 6caf61ed4 cleanup and streaamline run_examples REVERT: 1e5398f9f add examples to readme REVERT: 26bd784e9 Update cp surfaces and DISCONS REVERT: 7f3d89a3d Add example 13 for IPC REVERT: e35f20a13 expand pitch_initial to 30 degrees REVERT: 7760bcd77 update coord reader/writer REVERT: c1d7908dc Add IEA15MW_OL.yaml REVERT: 9a75c7114 ignore dbg2 files REVERT: 280996714 Update Polars to point to coord files REVERT: b6ba25358 make sure IPC_KP is positive REVERT: 03f2b761c fix ipc gain printing bug REVERT: 9bc06254d fix variable names REVERT: 02e08f7d0 add IPC gains to schema for pass-through ability REVERT: 86f3a9c4c numerical qualifiers for error handling REVERT: abd83d731 Add IPC_KP to api changes REVERT: 844b0693d add CMakeFiles to gitignore REVERT: 2ade01535 add mutichannel plotting with tuples REVERT: 7e5e2a3d7 Error checking foro flp or ipc REVERT: 79e5d5400 Addd IPC_KP to DISCON.IN REVERT: 0111087a8 Fix comments in ColemanTransformInverse REVERT: fded9d422 Add cyclic flap conrol REVERT: dbd81afda Better logic for filtering RootMOOP and fix notch filter slopes bug REVERT: 5e40ac40f Add IPC and filtered RootMyc to registry REVERT: 823f5f00f Add proportional control and cleanup IPC REVERT: 065befa76 Fix performance table paths REVERT: afca92fce Update surface and DISCON.INs REVERT: 262d3f6fe rename aerodynblade inputs REVERT: ee00f6786 remove interpolation of blade chord and twist REVERT: aad739652 Merge pull request #103 from nikhar-abbas/hf/robust REVERT: 5d5a9ba82 add bld edgewise freq to robust dict_inputs REVERT: 93dceb7ed Break up if statement in open loop pitch (#100) REVERT: 6c1e4dbf1 Restart & registry (#99) REVERT: 50f686dd2 Open Loop Control (#98) REVERT: f57ee4553 Merge pull request #97 from nikhar-abbas/b/listcheck REVERT: 6f16a9da6 update listcheck method for numpy arrays REVERT: aa888a1fc FOCAL Updates (#64) git-subtree-dir: ROSCO git-subtree-split: b994e4de67c423ff598a4bb354657b62ff61a50d --- .readthedocs.yaml | 8 +- docs/conf.py | 3 +- docs/index.rst | 79 ++++------- docs/requirements.txt | 2 +- docs/source/api_change.rst | 4 +- docs/source/examples.rst | 100 ++++++++++++++ docs/source/figures/ROSCOFramework.svg | 4 + docs/source/figures/ROSCO_toolbox.svg | 58 +++++--- docs/source/how_to_contribute_code.rst | 45 +++++++ docs/source/install.rst | 177 +++++++------------------ docs/source/rosco.rst | 9 +- docs/source/rosco_toolbox.rst | 24 ++-- docs/source/standard_use.rst | 111 +++------------- environment.yml | 2 + pyproject.toml | 1 + 15 files changed, 315 insertions(+), 312 deletions(-) create mode 100644 docs/source/examples.rst create mode 100644 docs/source/figures/ROSCOFramework.svg create mode 100644 docs/source/how_to_contribute_code.rst diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 66971b94f..061090c27 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -9,10 +9,10 @@ version: 2 build: os: ubuntu-22.04 tools: - python: "3.8" - # nodejs: "18" - # rust: "1.64" - # golang: "1.19" + python: "mambaforge-22.9" + +conda: + environment: environment.yml # Build documentation in the docs/ directory with Sphinx sphinx: diff --git a/docs/conf.py b/docs/conf.py index 27397c02b..952f69369 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -52,6 +52,7 @@ def __getattr__(cls, name): "sphinx.ext.intersphinx", "sphinx.ext.graphviz", "sphinx.ext.autosectionlabel", + "sphinx_rtd_theme", # "sphinxcontrib.bibtex", ] @@ -84,7 +85,7 @@ def __getattr__(cls, name): # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = "furo" +html_theme = "sphinx_rtd_theme" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, diff --git a/docs/index.rst b/docs/index.rst index 1e60107e7..e763859eb 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,54 +3,39 @@ ROSCO Documentation :Version: |release| :Date: |today| -NREL's Reference OpenSource Controller (ROSCO) tool-set for wind turbine applications designed to ease controller implementation for the wind turbine researcher. The purpose of these documents is to provide information for the use of the tool-set. +NREL's "Reference Open Source Controller" (ROSCO) is a reference controller framework that facilitates design and implementation of wind turbine and wind farm controllers for fixed and floating offshore wind turbines. -:numref:`fig-RT` shows the general workflow for the ROSCO tool-chain. with OpenFAST +ROSCO frameworks includes a large set of available controllers and advanced functionalities that can be combined in a modular fashion based on the intended application and can be easily adapted to a wide variety wind turbines. +For example, ROSCO can be used to design turbine yaw controller along with an individual blade pitch controller with floating platform feedback for an offshore turbine while simulating a pitch actuator fault and running a user-defined torque controller. -.. _fig-RT: -.. figure:: /source/figures/ROSCO_toolbox.svg - :align: center - :width: 80% +ROSCO provides a single framework for designing controllers for onshore and offshore turbines of varying sizes. +It can be used to run representative dynamic simulations using OpenFAST. +This helps researchers perform 'apples-to-apples' comparison of controller capabilities across turbines. +Control engineers can also design their own controllers and compare them with reference controller design using ROSCO for existing and new turbines. +ROSCO has been used to provide reference controllers for many recent reference turbines including the `IEA 3.4-MW `_ , `IEA 10-MW `_ , `IEA 15-MW `_ and the upcoming `IEA 22-MW `_ turbines. - ROSCO toolchain general workflow +The ROSCO framework also includes a python based toolbox that primarily enables tuning the controllers. +The tuning process is extemely simple where only a tuning parameters need to be provided. +It is not necessary to run aeroelastic simulations or provide linearized state-space models to tune the controller to tune the controllers. +The toolbox has other capabilities like simple 1-DOF turbine simulations for quick controller capability verifications, linear model analysis, and parsing of input and output files. +Source code for ROSCO toolset can be found in this `github repository `_ and it can be installed following the instructions provided in :ref:`install`. -**ROSCO Toolbox** -The python-based toolbox primarily used for tuning the controller and writing the DISCON.IN. +**Documentation Directory** -* Generic tuning of NREL's ROSCO controller -* Simple 1-DOF turbine simulations for quick controller capability verifications -* Parsing of OpenFAST input and output files -* Linear model analysis capability - -**ROSCO Controller** -The controller implementation itself. This is compiled to :code:`libdiscon.*` file, reads the DISCON.IN file, and interfaces with OpenFAST using the Bladed-style interface. - -* Fortran based -* Follows Bladed-style control interface -* Modular - -Standard Use ------------- - -For the standard use case in OpenFAST (or similar), ROSCO will need to be compiled. This is made possible via the instructions found in :ref:`install`. Once the controller is compiled, the turbine model needs to point to the compiled binary. In OpenFAST, this is ensured by changing the :code:`DLL_FileName` parameter in the ServoDyn input file. - -Additionally, an additional input file is needed for the ROSCO controller. Though the controller only needs to be compiled once, each individual turbine/controller tuning requires an input file. This input file is generically dubbed "DISCON.IN''. In OpenFAST, the :code:`DLL_InFile` parameter should be set to point to the desired input file. The ROSCO toolbox is used to automatically generate the input file. These instructions are provided in the instructions for :ref:`standard_use`. - -Technical Documentation ------------------------ -A publication highlighting much of the theory behind the controller tuning and implementation methods can be found at: -https://wes.copernicus.org/preprints/wes-2021-19/ - -Survey ------- -Please help us better understand the ROSCO user-base and how we can improve ROSCO through this brief survey: - -.. raw:: html - - +.. toctree:: + :maxdepth: 3 + :numbered: - + source/standard_use.rst + source/install.rst + source/examples.rst + source/rosco.rst + source/rosco_toolbox.rst + source/api_change.rst + source/toolbox_input.rst + source/how_to_contribute_code.rst + source/ROSCO_instructions_for_Bladed.rst License ------- @@ -67,15 +52,3 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - -.. toctree:: - :maxdepth: 3 - :numbered: - - source/install.rst - source/standard_use.rst - source/rosco_toolbox.rst - source/rosco.rst - source/api_change.rst - source/toolbox_input.rst - source/ROSCO_instructions_for_Bladed.rst diff --git a/docs/requirements.txt b/docs/requirements.txt index 6ff6c653e..5b42fa1eb 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,4 @@ # File: docs/requirements.txt sphinx>4.0.0 -furo \ No newline at end of file +sphinx_rtd_theme diff --git a/docs/source/api_change.rst b/docs/source/api_change.rst index 1e85bcad6..0127cd079 100644 --- a/docs/source/api_change.rst +++ b/docs/source/api_change.rst @@ -42,7 +42,7 @@ Thus, be sure to implement each in order so that subsequent line numbers are cor * Each turbine is assigned a `ZMQ_ID` by the controller, which is tracked by a farm-level controller -**Tower resonance avoidance +**Tower resonance avoidance** * When `TRA_Mode` is 1, change the torque control generator speed setpoint to avoid TRA_ExclSpeed +/- TRA_ExclBand. * The set point is changed at a slow rate `TRA_RateLimit` to avoid generator power spikes. `VS_RefSpd`/100 is recommended. @@ -89,7 +89,7 @@ Line Input Name Example Value 161 Ind_Azimuth 0 ! Ind_Azimuth - The column in OL_Filename that contains the desired azimuth position in rad (used if OL_Mode = 2) 162 RP_Gains 0.0000 0.0000 0.0000 0.0000 ! RP_Gains - PID gains and Tf of derivative for rotor position control (used if OL_Mode = 2) 186 ZMQ_ID 0 ! ZMQ_ID - Integer identifier of turbine -====== ================= ====================================================================================================================================================================================================== +====== ======================= =============================================================================================================================================================================================================================================================== ====== ================= ====================================================================================================================================================================================================== Changed in ROSCO develop diff --git a/docs/source/examples.rst b/docs/source/examples.rst new file mode 100644 index 000000000..5302c1c0d --- /dev/null +++ b/docs/source/examples.rst @@ -0,0 +1,100 @@ + +.. toctree:: + +.. _examplepage: + +ROSCO Examples +============== +Methods for reading turbine models, generating the control parameters of a :code:`DISCON.IN`: file, and running aeroelastic simulations to test controllers +Reading Turbine Models +---------------------- +Control parameters depend on the turbine model. +The rosco.toolbox uses OpenFAST inputs and an additional :code:`.yaml` formatted file to set up a :code:`turbine` object in python. +Several OpenFAST inputs are located in `Test_Cases/ `_. +The controller tuning :code:`.yaml` are located in `Tune_Cases/ `_. +A detailed description of the ROSCO control inputs and tuning :code:`.yaml` are provided in :ref:`discon_in` and :ref:`rt_tuning_yaml`, respectively. + +* :code:`01_turbine_model.py` loads an OpenFAST turbine model and displays a summary of its information + +ROSCO requires the power and thrust coefficients for tuning control inputs and running the extended Kalman filter wind speed estimator. + +* :code:`02_ccblade.py` runs cc-blade, a blade element momentum solver from WISDEM, to generate a :math:`C_p` surface. + +The :code:`Cp_Cq_Ct.txt` (or similar) file contains the rotor performance tables that are necessary to run the ROSCO controller. +This file can be located wherever you desire, just be sure to point to it properly with the :code:`PerfFileName` parameter in :code:`DISCON.IN`. + + +Tuning Controllers and Generating DISCON.IN +------------------------------------------- +The ROSCO :code:`turbine` object, which contains turbine information required for controller tuning, along with control parameters in the tuning yaml and the :math:`C_p` surface are used to generate control parameters and :code:`DISCON.IN` files. +To tune the PI gains of the torque control, set :code:`omega_vs` and :code:`zeta_vs` in the yaml. +Similarly, set :code:`omega_pc` and :code:`zeta_pc` to tune the PI pitch controller; gain scheduling is automatically handled using turbine information. +Generally :code:`omega_*` increases the responsiveness of the controller, reducing generator speed variations, but an also increases loading on the turbine. +:code:`zeta_*` changes the damping of the controller and is generally less important of a tuning parameter, but could also help with loading. +The default parameters in `Tune_Cases/ `_ are known to work well with the turbines in this repository. + +* :code:`03_tune_controller.py` loads a turbine and tunes the PI control gains +* :code:`04_simple_sim.py` tunes a controller and runs a simple simualtion (not using OpenFAST) +* :code:`05_openfast_sim.py` loads a turbine, tunes a controller, and runs an OpenFAST simulation + +Each of these examples generates a :code:`DISCON.IN` file, which is an input to libdiscon.*. +When running the controller in OpenFAST, :code:`DISCON.IN` must be appropriately named using the :code:`DLL_FileName` parameter in ServoDyn. + +OpenFAST can be installed from `source `_ or in a conda environment using: + +.. code-block:: bash + + conda install -c conda-forge openfast + +ROSCO can implement peak shaving (or thrust clipping) by changing the minimum pitch angle based on the estimated wind speed: + +* :code:`06_peak_shaving.py` loads a turbine and tunes a controller with peak shaving. + +By setting the :code:`ps_percent` value in the tuning yaml, the minimum pitch versus wind speed table changes and is updated in the :code:`DISCON.IN` file. + +ROSCO also contains a method for distributed aerodynamic control (e.g., via trailing edge flaps): + +* :code:`09_distributed_aero.py` tunes a controller for distributed aerodynamic control + +The ROSCO toolbox also contains methods for working with OpenFAST linear models +* :code:`10_linear_params.py` exports a file of the parameters used for the simplified linear models used to tune ROSCO +* :code:`11_robust_tuning.py` shows how linear models generated using OpenFAST can be used to tune controllers with robust stability properties. +* :code:`12_tune_ipc.py` shows the tuning procedure for IPC + +Running OpenFAST Simulations +---------------------------- + +To run an aeroelastic simulation with ROSCO, the ROSCO input (:code:`DISCON.IN`) must point to a properly formatted :code:`Cp_Cq_Ct.txt` file using the :code:`PerfFileName` parameter. +If called from OpenFAST, the main OpenFAST input points to the ServoDyn input, which points to the :code:`DISCON.IN` file and the :code:`libdiscon.*` dynamic library. + +For example in `Test_Cases/NREL-5MW`: + +* :code:`NREL-5MW.fst` has :code:`"NRELOffshrBsline5MW_Onshore_ServoDyn.dat"` as the :code:`ServoFile` input +* :code:`NRELOffshrBsline5MW_Onshore_ServoDyn.dat` has :code:`"../../ROSCO/build/libdiscon.dylib"` as the :code:`DLL_FileName` input and :code:`"DISCON.IN"` as the :code:`DLL_InFile` input. + Note that these file paths are relative to the path of the main fast input (:code:`NREL-5MW.fst`) +* :code:`DISCON.IN` has :code:`"Cp_Ct_Cq.NREL5MW.txt"` as the :code:`PerfFileName` input + +The rosco.toolbox has methods for running OpenFAST (and other) binary executables using system calls, as well as post-processing tools in `ofTools/ `_. + +Several example scripts are set up to quickly simulate ROSCO with OpenFAST: + +* :code:`05_openfast_sim.py` loads a turbine, tunes a controller, and runs an OpenFAST simulation +* :code:`07_openfast_outputs.py` loads the OpenFAST output files and plots the results +* :code:`08_run_turbsim.py` runs TurbSim, for generating turbulent wind inputs +* :code:`14_open_loop_control.py` runs an OpenFAST simulation with ROSCO providing open loop control inputs + + +Testing ROSCO +------------- + +The rosco.toolbox also contains tools for testing ROSCO in IEC design load cases (DLCs), located in `ROSCO_testing/ `_. +The script :code:`run_Testing.py` allows the user to set up their own set of tests. +By setting :code:`testtype`, the user can run a variety of tests: + +* :code:`lite`, which runs DLC 1.1 simulations at 5 wind speed from cut-in to cut-out, in 330 second simulations +* :code:`heavy`, which runs DLC 1.3 from cut-in to cut-out in 2 m/s steps and 2 seeds for each, in 630 seconds, as well as DLC 1.4 simulations +* :code:`binary-comp`, where the user can compare :code:`libdiscon.*` dynamic libraries (compiled ROSCO source code), with either a lite or heavy set of simulations +* :code:`discon-comp`, where the user can compare :code:`DISCON.IN` controller tunings (and the complied ROSCO source is constant) + +Setting the :code:`turbine2test` allows the user to test either the IEA-15MW with the UMaine floating semisubmersible or the NREL-5MW reference onshore turbine. + diff --git a/docs/source/figures/ROSCOFramework.svg b/docs/source/figures/ROSCOFramework.svg new file mode 100644 index 000000000..9ef35b0cb --- /dev/null +++ b/docs/source/figures/ROSCOFramework.svg @@ -0,0 +1,4 @@ + + + +
Tuning.yaml
Tuning.yaml
ROSCO
Toolbox
ROSCO...
OpenFAST
Model
OpenFAST...
DISCON.IN
DISCON.IN
ROSCO
Controller
ROSCO...
OpenFAST
OpenFAST
Text is not SVG - cannot display
\ No newline at end of file diff --git a/docs/source/figures/ROSCO_toolbox.svg b/docs/source/figures/ROSCO_toolbox.svg index 8bbc55870..2ba1daf56 100644 --- a/docs/source/figures/ROSCO_toolbox.svg +++ b/docs/source/figures/ROSCO_toolbox.svg @@ -1,13 +1,5 @@ image/svg+xmlROSCOControllerROSCO`_. +If any example fails, this information is passed on to GitHub and a red X will be shown next to the commit. +Otherwise, if all tests pass, a green check mark appears to signify the code changes are valid. + +The examples that are covered are shown in :code:`ROSCO/rosco/test/test_examples.py`. +If you add an example to ROSCO, make sure to add a call to it in the :code:`run_examples.py` script as well. + + +Pull requests +------------- +Once you have added or modified code, submit a pull request via the GitHub interface. +This will automatically go through all of the tests in the repo to make sure everything is functioning properly. +The main developers of ROSCO will then merge in the request or provide feedback on how to improve the contribution. + diff --git a/docs/source/install.rst b/docs/source/install.rst index 023da03cd..40734441b 100644 --- a/docs/source/install.rst +++ b/docs/source/install.rst @@ -2,11 +2,44 @@ .. _install: -Installing the ROSCO tools -=========================== -As a reminder, the ROSCO toolbox is a python-based tool used to write the DISCON.IN file, which is read by the ROSCO controller (a compiled binary file). If you only wish to run the controller, you *do not* need to install the ROSCO toolbox. +Installing ROSCO toolset +======================== +ROSCO toolsets can be utilized either to run an existing controller or to design and tune a controller from scratch. +We recommend using the instructions provided in the :ref:`full_rosco` to install the full ROSCO toolset. +This allows for full use of the provided functionalities including the controller and toolbox to facilitate controller tuning. +However, if only the ROSCO binary is needed (to run an existing controller, for example), then users should follow the instructions provided in :ref:`rosco_controller` -Depending on what is needed, a user can choose to use just the ROSCO controller or to use both the ROSCO controller and the toolbox. Both the controller and the toolbox should be installed if one wishes to leverage the full ROSCO tool-chain. :numref:`rosco_table` provides an overview of the primary methods available for :ref:`rosco_controller`. Additionally, :numref:`roscotoolbox_table` provides an overview of the primary methods available to acquire the ROSCO toolbox. Finally, if you wish to install and use both the controller and toolbox, the section about :ref:`full_rosco` provides the best methods of doing so. +.. _full_rosco: + +Complete ROSCO Installation +--------------------------- +Steps for the installation of the complete rosco toolset are: + +1. Create a conda environment for ROSCO + +.. code-block:: bash + + conda config --add channels conda-forge # (Enable Conda-forge Channel For Conda Package Manager) + conda create -y --name rosco-env python=3.10 # (Create a new environment named "rosco-env" that contains Python 3.8) + conda activate rosco-env # (Activate your "rosco-env" environment) + +2. Clone and Install the ROSCO toolbox with ROSCO controller + +.. code-block:: bash + + git clone https://github.com/NREL/ROSCO.git + cd ROSCO + pip install -e . + +This step creates the rosco controller binary (:code:`libdiscon.so` (Linux), :code:`libdiscon.dylib` (Mac), or :code:`libdisscon.dll` (Windows)`) in the directory :code:`ROSCO/rosco/lib` and installs the python toolbox in the conda environment in the develop mode. + + + +.. _rosco_controller: + +Installing only the ROSCO controller +------------------------------------ +:numref:`rosco_table` provides an overview of the primary methods available for installing only the ROSCO controller binary. .. _rosco_table: .. list-table:: Methods for Installing the ROSCO Controller @@ -16,34 +49,18 @@ Depending on what is needed, a user can choose to use just the ROSCO controller * - Method - Use Case * - :ref:`rosco_direct_download` - - Best for users who simply want to use a released version of the controller without working through the compilation procedures. + - Best for users who simply want to use a released version of the controller binary without working through the compilation procedures. * - :ref:`rosco_anaconda_download` - - Best for users who just want to use the controller but prefer to download using the Anaconda package man age Full ROSCO Installation. - * - :ref:`full_rosco` - - Best for users who wish to both use the controller and leverage the tools in the ROSCO toolbox + - Best for users who just want to use the controller binary but prefer to download using the Anaconda package manager. * - :ref:`cmake_compile` - - Best for users who need to re-compile the source code often, plan to use non-released versions of ROSCO (including modified source code), or who simply want to compile the controller themselves so they have the full code available locally. This is necessary for users who wish to use the :ref:`zmq_build`. - -.. _roscotoolbox_table: -.. list-table:: Methods for Installing the ROSCO Toolbox - :widths: 30 70 - :header-rows: 1 - - * - Method - - Use Case - * - :ref:`roscotoolbox_anaconda_download` - - Best for users who simply want to use the primary ROSCO toolbox functions - * - :ref:`full_rosco` - - (Recommended) Best for users who wish to both use the primary ROSCO toolbox functions, as well run and use the many example and testing scripts available. This process can be done with or without compiling ROSCO. - -For many of the methods used to install both ROSCO and the ROSCO toolbox, both Anaconda_ and CMake_ are necessary. Anaconda is a popular package manager used to distribute software packages of various types. Anaconda is used to download requisite packages and distribute pre-compiled versions of the ROSCO tools. CMake is a build configuration system that creates files as input to a build tool like GNU Make, Visual Studio, or Ninja. CMake does not compile code or run compilers directly, but rather creates the environment needed for another tool to run compilers and create binaries. CMake is used to ease the processes of compiling the ROSCO controller locally. For more information on CMake, please see `understanding CMake `_ in the OpenFAST documentation. + - Best for users who need to re-compile the source code often, plan to use non-released versions of ROSCO (including modified source code), or who simply want to compile the controller themselves so they have the full code available locally. - -.. _rosco_controller: - -Installing the ROSCO controller --------------------------------- -The standard ROSCO controller is based in Fortran and must be compiled; the source code can be found at: https://github.com/NREL/ROSCO/ROSCO. +Anaconda is a popular package manager used to distribute software packages of various types. +Anaconda is used to download requisite packages and distribute pre-compiled versions of the ROSCO tools. +CMake is a build configuration system that creates files as input to a build tool like GNU Make, Visual Studio, or Ninja. +CMake does not compile code or run compilers directly, but rather creates the environment needed for another tool to run compilers and create binaries. +CMake is used to ease the processes of compiling the ROSCO controller locally. +For more information on CMake, please see `understanding CMake `_ in the OpenFAST documentation. .. _rosco_direct_download: @@ -53,15 +70,15 @@ The most recent tagged version releases of the controller are `available for dow .. _rosco_anaconda_download: -Anaconda Download - ROSCO -.......................... +Anaconda Download +................. Using the popular package manager, Anaconda_, the tagged 64-bit versions of ROSCO are available through the conda-forge channel. In order to download the most recently compiled version release, from an anaconda powershell (Windows) or terminal (Mac/Linux) window, create a new anaconda virtual environment: .. code-block:: bash conda config --add channels conda-forge - conda create -y --name rosco-env python=3.9 + conda create -y --name rosco-env python=3.10 conda activate rosco-env navigate to your desired folder to save the compiled binary using: @@ -114,108 +131,16 @@ Once the CMake and the required compilers are downloaded, the following code can git clone https://github.com/NREL/ROSCO.git # Compile ROSCO - cd ROSCO/ROSCO + cd ROSCO/rosco/controller mkdir build cd build cmake .. # Mac/linux only cmake .. -G "MinGW Makefiles" # Windows only make install -This will generate a file called :code:`libdiscon.so` (Linux), :code:`libdiscon.dylib` (Mac), or :code:`libdisscon.dll` (Windows) in the :code:`/ROSCO/install/lib` directory. - -.. _zmq_build: - -ZeroMQ Interface -..................... -There is an option to interface ROSCO with external inputs using `ZeroMQ `_. Currently, only externally commanded yaw offset inputs are supported, though this could easily be expanded if the need arises. - -To use the ZeroMQ interface, the software must be downloaded following the `ZeroMQ download instructions `_. Using CMake, ROSCO can then be compiled to enable this interface by using the :code:`ZMQ_CLIENT:ON` flag with the :code:`cmake` command in :ref:`cmake_compile`: - -.. code-block:: bash - - cmake -DZMQ_CLIENT:ON .. - -.. _rosco_toolbox_install: - -Installing the ROSCO toolbox ----------------------------- -The ROSCO toolbox is based in python and contains all relevant ROSCO tools; the source code can be found at: https://github.com/NREL/ROSCO/. In addition to tuning procedures, the ROSCO toolbox also contains example scripts, a Simulink Model of ROSCO, OpenFAST pre-and post-processing functions, linearized systems analysis tools, and a testing suite. - -.. _roscotoolbox_anaconda_download: - -Anaconda Download - ROSCO Toolbox -.................................. -If one wishes to simply use the modules provided in the ROSCO toolbox through scripts of their own, the ROSCO toolbox can be installed via the conda-forge channel of Anaconda. They can then be accessed using the standard methods of loading modules in python, e.g: - -.. code-block:: python - - from ROSCO_toolbox import controller as ROSCO_controller - from ROSCO_toolbox import turbine as ROSCO_turbine - -Note that the install procedures for the ROSCO toolbox are the same as in :ref:`rosco_anaconda_download`, but do not involve moving the controller binary file. -In order to download the most recently compiled version release, from an anaconda powershell (Windows) or terminal (Mac/Linux) window, create a new anaconda virtual environment: - -.. code-block:: bash - - conda config --add channels conda-forge - conda create -y --name rosco-env python=3.8 - conda activate rosco-env - -navigate to your desired folder to save the compiled binary using: - -.. code-block:: bash - - cd - -and download the controller: - -.. code-block:: bash - - conda install -y ROSCO - - - -.. _full_rosco: - -Full ROSCO Installation ------------------------ - -We recommend using the full ROSCO tool-chain. This allows for full use of the provided functions along with the developed python packages and controller code, - -Please follow the following steps to install the ROSCO tool-chain. You should do step 2 *or* 3. If you simply want to install the ROSCO toolbox without the controller, do step 3. If you would like to install the ROSCO toolbox and compile the controller simultaneously, do step 2. - -1. Create a conda environment for ROSCO - -.. code-block:: bash - - conda config --add channels conda-forge # (Enable Conda-forge Channel For Conda Package Manager) - conda create -y --name rosco-env python=3.8 # (Create a new environment named "rosco-env" that contains Python 3.8) - conda activate rosco-env # (Activate your "rosco-env" environment) - -2. Clone and Install the ROSCO toolbox with ROSCO controller - -.. code-block:: bash - - git clone https://github.com/NREL/ROSCO.git - cd ROSCO - conda install compilers # (Mac/Linux only) - conda install m2w64-toolchain libpython # (Windows only) - conda env config vars set FC=gfortran # Sometimes needed for Windows - conda install -y wisdem>3.7 - python setup.py install --compile-rosco - -3. Clone and Install the ROSCO toolbox without ROSCO controller - -.. code-block:: bash - - git clone https://github.com/NREL/ROSCO.git - cd ROSCO - python setup.py install +This will generate a file called :code:`libdiscon.so` (Linux), :code:`libdiscon.dylib` (Mac), or :code:`libdisscon.dll` (Windows). -Getting Started ----------------- -Please see :ref:`standard_use` for several example scripts using ROSCO and the ROSCO_toolbox. .. _Anaconda: https://www.anaconda.com/ diff --git a/docs/source/rosco.rst b/docs/source/rosco.rst index cb6e75a93..167e7fffe 100644 --- a/docs/source/rosco.rst +++ b/docs/source/rosco.rst @@ -2,8 +2,8 @@ .. _rosco: -ROSCO Controller Structure -========================== +ROSCO Structure: Controller +=========================== Here, we give an overview of the structure of the ROSCO controller and how the code is implemented. ----- @@ -14,12 +14,15 @@ The primary functions of the ROSCO toolbox are separated into several files. The * :code:`DISCON.f90` is the primary driver function. * :code:`ReadSetParameters.f90` primarily handles file I/O and the Bladed Interface. -* :code:`ROSCO_Types.f90` allocates variables in memory. +* :code:`ROSCO_Types.f90` allocates variables in memory; it is procedurally generated from :code:`rosco_registry` * :code:`Constants.f90` establishes some global constants. * :code:`Controllers.f90` contains the primary controller algorithms (e.g. blade pitch control) * :code:`ControllerBlocks.f90` contains additional control features that are not necessarily primary controllers (e.g. wind speed estimator) * :code:`Filters.f90` contains the various filter implementations. * :code:`Functions.f90` contains various functions used in the controller. +* :code:`ExtControl.f90` contains subroutines for calling external dynamic libraries +* :code:`ROSCO_Helpers.f90` contains subroutines for file I/O and other helpful routines, borrowed heavily from NWTC.IO in OpenFAST +* :code:`ROSCO_IO.f90` is procedurally generated using the :code:`rosco_registry` for writing debug and checkpoint files .. _discon_in: diff --git a/docs/source/rosco_toolbox.rst b/docs/source/rosco_toolbox.rst index a61b31312..637c0f8fa 100644 --- a/docs/source/rosco_toolbox.rst +++ b/docs/source/rosco_toolbox.rst @@ -2,7 +2,7 @@ .. _rosco_toolbox_main: -ROSCO Toolbox Structure +ROSCO Structure: Toolbox ======================== Here, we give an overview of the structure of the ROSCO toolbox and how the code is implemented. @@ -25,28 +25,30 @@ The source code for the ROSCO toolbox generic tuning implementations lives here. Examples ......... -A number of examples are included to showcase the numerous capabilities of the ROSCO toolbox; they are described in the :ref:`standard_use`. - -Matlab_Toolbox -............... -A simulink implementation of the ROSCO controller is included in the Matlab Toolbox. Some requisite MATLAB utility scripts are also included. +A number of examples are included to showcase the numerous capabilities of the ROSCO toolbox; they are described in the :ref:`examplepage`. ROSCO_testing ............. Testing scripts for the ROSCO toolbox are held here and showcased with :code:`run_testing.py`. These can be used to compare different controller tunings or different controllers all together. -Test_Cases -.......... +Examples/Test_Cases +................... Example OpenFAST models consistent with the latest release of OpenFAST are provided here for simple testing and simulation cases. -Tune_Cases -.......... +Examples/Tune_Cases +................... Some example tuning scripts and tuning input files are provided here. The code found in :code:`tune_ROSCO.py` can be modified by the user to easily enable tuning of their own wind turbine model. The ROSCO Toolbox Tuning File ------------------------------ A yaml_ formatted input file is used for the standard ROSCO toolbox tuning process. This file contains the necessary inputs for the ROSCO toolbox to load an OpenFAST input file deck and tune the ROSCO controller. It can be found here: :ref:`rt_tuning_yaml`. - + +Matlab_Toolbox +............... +A simulink implementation of the ROSCO controller is included in the Matlab Toolbox. Some requisite MATLAB utility scripts are also included. +These scripts are not maintained by NREL as of ROSCO v2.5.0. +The Simulink controller there should not be used and referenenced as "ROSCO" because it has never been validated against the official ROSCO dynamic library and has drifted away from the official implementation. +We will leave the implementation in place to be used only as a learning tool. .. _OpenFAST: https://github.com/openfast/openfast .. _yaml: https://yaml.org/ diff --git a/docs/source/standard_use.rst b/docs/source/standard_use.rst index 528efac9e..08cc8caad 100644 --- a/docs/source/standard_use.rst +++ b/docs/source/standard_use.rst @@ -4,99 +4,30 @@ Standard ROSCO Workflow ======================= -This page outlines methods for reading turbine models, generating the control parameters of a :code:`DISCON.IN`: file, and running aeroelastic simulations to test controllers. -A set of `example scripts `_ demonstrate the functionality of the ROSCO toolbox and controller. -Reading Turbine Models ----------------------- -Control parameters depend on the turbine model. -The rosco.toolbox uses OpenFAST inputs and an additional :code:`.yaml` formatted file to set up a :code:`turbine` object in python. -Several OpenFAST inputs are located in `Test_Cases/ `_. -The controller tuning :code:`.yaml` are located in `Tune_Cases/ `_. -A detailed description of the ROSCO control inputs and tuning :code:`.yaml` are provided in :ref:`discon_in` and :ref:`rt_tuning_yaml`, respectively. +.. _fig-RT: +.. figure:: /source/figures/ROSCOFramework.svg + :align: center + :width: 90% -* :code:`01_turbine_model.py` loads an OpenFAST turbine model and displays a summary of its information + ROSCO toolchain general workflow -ROSCO requires the power and thrust coefficients for tuning control inputs and running the extended Kalman filter wind speed estimator. +:numref:`fig-RT` shows the general workflow for the ROSCO tool-chain with OpenFAST. +For the standard use case in OpenFAST (or similar), ROSCO controller needs to be compiled. +The controller is a fortran based module that follows the bladed-style control interface. +Compiling the controller ouputs a dynamic-link library (or equivalent) called :code:`libdiscon.dll` for windows, :code:`libdiscon.so` for linux and, :code:`libdiscon.dylib` for mac-os. +Instructions for the compilation are provided in :ref:`install`. +Once the controller is compiled the turbine simulation tool must point to the compiled library. +In OpenFAST, this is ensured by changing the :code:`DLL_FileName` parameter in the ServoDyn input file. +This step enables communication between the ROSCO controller and OpenFAST. -* :code:`02_ccblade.py` runs cc-blade, a blade element momentum solver from WISDEM, to generate a :math:`C_p` surface. - -The :code:`Cp_Cq_Ct.txt` (or similar) file contains the rotor performance tables that are necessary to run the ROSCO controller. -This file can be located wherever you desire, just be sure to point to it properly with the :code:`PerfFileName` parameter in :code:`DISCON.IN`. - - -Tuning Controllers and Generating DISCON.IN -------------------------------------------- -The ROSCO :code:`turbine` object, which contains turbine information required for controller tuning, along with control parameters in the tuning yaml and the :math:`C_p` surface are used to generate control parameters and :code:`DISCON.IN` files. -To tune the PI gains of the torque control, set :code:`omega_vs` and :code:`zeta_vs` in the yaml. -Similarly, set :code:`omega_pc` and :code:`zeta_pc` to tune the PI pitch controller; gain scheduling is automatically handled using turbine information. -Generally :code:`omega_*` increases the responsiveness of the controller, reducing generator speed variations, but an also increases loading on the turbine. -:code:`zeta_*` changes the damping of the controller and is generally less important of a tuning parameter, but could also help with loading. -The default parameters in `Tune_Cases/ `_ are known to work well with the turbines in this repository. - -* :code:`03_tune_controller.py` loads a turbine and tunes the PI control gains -* :code:`04_simple_sim.py` tunes a controller and runs a simple simualtion (not using OpenFAST) -* :code:`05_openfast_sim.py` loads a turbine, tunes a controller, and runs an OpenFAST simulation - -Each of these examples generates a :code:`DISCON.IN` file, which is an input to libdiscon.*. -When running the controller in OpenFAST, :code:`DISCON.IN` must be appropriately named using the :code:`DLL_FileName` parameter in ServoDyn. - -OpenFAST can be installed from `source `_ or in a conda environment using: - -.. code-block:: bash - - conda install -c conda-forge openfast - -ROSCO can implement peak shaving (or thrust clipping) by changing the minimum pitch angle based on the estimated wind speed: - -* :code:`06_peak_shaving.py` loads a turbine and tunes a controller with peak shaving. - -By setting the :code:`ps_percent` value in the tuning yaml, the minimum pitch versus wind speed table changes and is updated in the :code:`DISCON.IN` file. - -ROSCO also contains a method for distributed aerodynamic control (e.g., via trailing edge flaps): - -* :code:`09_distributed_aero.py` tunes a controller for distributed aerodynamic control - -The ROSCO toolbox also contains methods for working with OpenFAST linear models -* :code:`10_linear_params.py` exports a file of the parameters used for the simplified linear models used to tune ROSCO -* :code:`11_robust_tuning.py` shows how linear models generated using OpenFAST can be used to tune controllers with robust stability properties. -* :code:`12_tune_ipc.py` shows the tuning procedure for IPC - -Running OpenFAST Simulations ----------------------------- - -To run an aeroelastic simulation with ROSCO, the ROSCO input (:code:`DISCON.IN`) must point to a properly formatted :code:`Cp_Cq_Ct.txt` file using the :code:`PerfFileName` parameter. -If called from OpenFAST, the main OpenFAST input points to the ServoDyn input, which points to the :code:`DISCON.IN` file and the :code:`libdiscon.*` dynamic library. - -For example in `Test_Cases/NREL-5MW`: - -* :code:`NREL-5MW.fst` has :code:`"NRELOffshrBsline5MW_Onshore_ServoDyn.dat"` as the :code:`ServoFile` input -* :code:`NRELOffshrBsline5MW_Onshore_ServoDyn.dat` has :code:`"../../ROSCO/build/libdiscon.dylib"` as the :code:`DLL_FileName` input and :code:`"DISCON.IN"` as the :code:`DLL_InFile` input. - Note that these file paths are relative to the path of the main fast input (:code:`NREL-5MW.fst`) -* :code:`DISCON.IN` has :code:`"Cp_Ct_Cq.NREL5MW.txt"` as the :code:`PerfFileName` input - -The rosco.toolbox has methods for running OpenFAST (and other) binary executables using system calls, as well as post-processing tools in `ofTools/ `_. - -Several example scripts are set up to quickly simulate ROSCO with OpenFAST: - -* :code:`05_openfast_sim.py` loads a turbine, tunes a controller, and runs an OpenFAST simulation -* :code:`07_openfast_outputs.py` loads the OpenFAST output files and plots the results -* :code:`08_run_turbsim.py` runs TurbSim, for generating turbulent wind inputs -* :code:`14_open_loop_control.py` runs an OpenFAST simulation with ROSCO providing open loop control inputs - - -Testing ROSCO -------------- - -The rosco.toolbox also contains tools for testing ROSCO in IEC design load cases (DLCs), located in `ROSCO_testing/ `_. -The script :code:`run_Testing.py` allows the user to set up their own set of tests. -By setting :code:`testtype`, the user can run a variety of tests: - -* :code:`lite`, which runs DLC 1.1 simulations at 5 wind speed from cut-in to cut-out, in 330 second simulations -* :code:`heavy`, which runs DLC 1.3 from cut-in to cut-out in 2 m/s steps and 2 seeds for each, in 630 seconds, as well as DLC 1.4 simulations -* :code:`binary-comp`, where the user can compare :code:`libdiscon.*` dynamic libraries (compiled ROSCO source code), with either a lite or heavy set of simulations -* :code:`discon-comp`, where the user can compare :code:`DISCON.IN` controller tunings (and the complied ROSCO source is constant) - -Setting the :code:`turbine2test` allows the user to test either the IEA-15MW with the UMaine floating semisubmersible or the NREL-5MW reference onshore turbine. +The compiled ROSCO controller library requires an input file (generally called :code:`DISCON.IN`). +It stores several flags and parameters needed by the controller and is read by the compiled dynamic-link library. +Several different :code:`DISCON.IN` files, for varous turbines and controller tunings, can use the same dynamic-link library. +In OpenFAST, the :code:`DLL_InFile` parameter in the ServoDyn input file determines the desired input file. +The ROSCO toolbox is used to tune the ROSCO controller and generate a :code:`DISCON.IN` input file. +To tune the controller, ROSCO toolbox needs the OpenFAST model of the turbine and some user inputs in the form of a :code:`tuning.yaml` file. +The functionality of ROSCO toolset can be best understood by following the set of included example scripts in :ref:`examplepage`. +ROSCO toolset can be installed using the instructions provided in :ref:`install`. diff --git a/environment.yml b/environment.yml index ddc350064..fdec1ba39 100644 --- a/environment.yml +++ b/environment.yml @@ -18,3 +18,5 @@ dependencies: - scipy - treon - wisdem + - compilers + - sphinx_rtd_theme diff --git a/pyproject.toml b/pyproject.toml index 3260258eb..ce80267c8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,6 +51,7 @@ dependencies = [ "pyzmq", "treon", "wisdem", + "ruamel.yaml", ] # List additional groups of dependencies here (e.g. development