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