From 59a1464a9cee284e95be9e1c864ae281f65eb962 Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Thu, 4 Feb 2021 11:27:17 -0700 Subject: [PATCH 01/34] initial commit --- docs/source/install.rst | 133 +++++++++++++++++++++++++++++++++++ docs/source/standard_use.rst | 14 ++++ 2 files changed, 147 insertions(+) create mode 100644 docs/source/install.rst create mode 100644 docs/source/standard_use.rst diff --git a/docs/source/install.rst b/docs/source/install.rst new file mode 100644 index 000000000..d7c8f70d8 --- /dev/null +++ b/docs/source/install.rst @@ -0,0 +1,133 @@ +.. _install:: +.. toctree:: + :max_depth: 3 + +Installing the ROSCO tools +=========================== +Both the ROSCO controller and ROSCO toolbox should be installed if one wishes to leverage the full ROSCO toolchain. Of course, some users may only wish to download and install only the controller or the toolbox. + +For users wishing to use just the ROSCO toolbox or the ROSCO toolbox and controller, please skip to the section on section :ref:`installing_rt`. Here you will provide the necessary steps to install the ROSCO toolbox and the ROSCO controller simultaneously. For users planning to only download and compile the ROSCO controller, please follow the instructions on :ref:`compiling_rosco`. For information on best practices to update to the most recent version of the ROSCO toolbox, see :ref:`updating_rt`. + + +.. _compiling_rosco: + +Compiling ROSCO +---------------- +The standard ROSCO controller is based in Fortran and must be compiled. This code can be found at: https://github.com/NREL/ROSCO. Of course, the advanced user can compile the downloaded code using their own desired methods (e.g. Visual Studio). Otherwise, a few of the more common compiling methods are detailed on this page. Additionally, the most recent tagged version releases are `available for download `_. + +If one wishes to download the code via the command line, we provide two supported options. For non-developers (those not interested in modifying the source code), the controller can be downloaded via Anaconda. For developers, CMake can be used to compile the Fortran code. + + +Anaconda for non-developers: +............................. + +For users familiar with Anaconda_, ROSCO is available through the conda-forge channel. In order to download the compiled, most recent version release, from an anaconda powershell (Windows) or terminal (Mac/Linux) window, one can create a new anaconda virtual environment: +:: + + conda config --add channels conda-forge + conda create -y --name ROSCO-env + conda activate ROSCO-env + +navigate to your desired folder to save the compiled binary using: +:: + + cd + +and download the controller: +:: + + conda install -y ROSCO + +This will download a compiled ROSCO binary file into the default filepath for any dynamic libraries downloaded via anaconda while in the ROSCO-env. This can be copied to your desired folder using: +:: + + cp $CONDA_PREFIX/lib/libdiscon.* . + + +CMake for developers: +..................... +CMake_ provides a straightforward option for many users, particularly those on a Mac or Linux. ROSCO can be compiled by first cloning the source code from git using: +:: + + git clone https://github.com/NREL/ROSCO.git + +And then compiling using CMake: +:: + + cd ROSCO + mkdir build + cd build + cmake .. # Mac/Linus + cmake .. -G "MinGW Makefiles" # Windows + make + +This will generate a file titled :code:`libdiscon.*` in the :code:`/ROSCO/install/lib` directory. + +Note: when compiling with MinGW on Windows, modifying the cmake line (4th commant) in the above code block to :code:`cmake .. -G "MinGWMakefiles" -DCMake_Fortran_COMPILER=gfortran` may solve compiler errors that may arise, depending on your local configuration. + +.. _installing_rt: + +Installing the ROSCO toolbox +---------------------------- +Installation of the complete ROSCO toolbox is made easy through `Anaconda `_. If you do not already have Anaconda installed on your machine, please install it. + +Then please follow the following steps: + +1. Create a conda environment for ROSCO + :: + + conda config --add channels conda-forge + conda create -y --name rosco-env python=3.8 + conda activate rosco-env + :: + +2. Install WISDEM + :: + + conda install -y wisdem + + +You should then do step three *or* four. If you do not want to compile the ROSCO controller within the installation of the ROSCO toolbox, please follow the instructions for :ref:`compiling_rosco`. + +3. Clone and Install the ROSCO toolbox with ROSCO + :: + + git clone https://github.com/NREL/ROSCO_toolbox.git + cd ROSCO_toolbox + git submodule init + git submodule update + conda install compilers # (Mac/Linux only) + conda install m2w64-toolchain libpython # (Windows only) + python setup.py install --compile-rosco + +4. Clone and Install the ROSCO toolbox *without* ROSCO + :: + + git clone https://github.com/NREL/ROSCO_toolbox.git + cd ROSCO_toolbox + python setup.py install + + +**Alternatively...** + +If you wish to write your own scripts to leverage the ROSCO toolbox tools, but do not necessarily need the source code or to run any of the examples, the ROSCO toolbox is available via PyPi: + + :: + + pip install rosco_toolbox + +Note that if you do choose to install the ROSCO Toolbox this way, you will not have the source code. Additionally, you will need to download WISDEM and the ROSCO controller separately if you wish to use any of the ROSCO toolbox functionalities that need those software packages. + +.. _updating_rt: + +Updating the ROSCO Toolbox +-------------------------- +Simple git commands should update the toolbox and controller as development continues: +``` +git pull +git submodule update +``` +and then recompile and reinstall as necessary... + +.. _Anaconda: https://www.anaconda.com/ +.. _CMake: https://cmake.org/ diff --git a/docs/source/standard_use.rst b/docs/source/standard_use.rst new file mode 100644 index 000000000..ac4fa831e --- /dev/null +++ b/docs/source/standard_use.rst @@ -0,0 +1,14 @@ +.. _standard-use: +.. toctree:: + + +Standard Uses +================= + + +Tuning a Controller +-------------------- + + +Generating DISCON.IN +-------------------- From ebc4dd2838628ce9b41d7583077c51887e3219e0 Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Thu, 4 Feb 2021 11:27:26 -0700 Subject: [PATCH 02/34] remove old docs --- docs/source/compiling.rst | 52 -------------------------------------- docs/source/generating.rst | 5 ---- 2 files changed, 57 deletions(-) delete mode 100644 docs/source/compiling.rst delete mode 100644 docs/source/generating.rst diff --git a/docs/source/compiling.rst b/docs/source/compiling.rst deleted file mode 100644 index 4b890b48a..000000000 --- a/docs/source/compiling.rst +++ /dev/null @@ -1,52 +0,0 @@ -.. _compiling: - -Compiling ROSCO -================= -The standard ROSCO controller is based in Fortran and must be compiled. This code can be found at: https://github.com/NREL/ROSCO. Of course, the advanced user can compile the downloaded code using their own desired methods (e.g. Visual Studio). Otherwise, a few of the more common compiling methods are detailed on this page. Additionally, the most recent tagged version releases are `available for download `_. - -If one wishes to download the code via the command line, we provide two supported options. For non-developers (those not interested in modifying the source code), the controller can be downloaded via Anaconda. For developers, CMake can be used to compile the Fortran code. Using CMake is generally a simple and straightforward process for Mac/Linux users, however, the process of compiling using CMake and MinGW is possible on Windows, but can produce complications if not done carefully. - -Anaconda for non-developers: ------------------------------------- -For users familiar with Anaconda_, ROSCO is available through the conda-forge channel. In order to download the compiled, most recent version release, from an anaconda powershell (Windows) or terminal (Mac/Linux) window, one can create a new anaconda virtual environment: -:: - - conda config --add channels conda-forge - conda create -y --name ROSCO-env - conda activate ROSCO-env - -navigate to your desired folder to save the compiled binary using: -:: - - cd - -and download the controller: -:: - - conda install -y ROSCO - -This will download a compiled ROSCO binary file into the default filepath for any dynamic libraries downloaded via anaconda while in the ROSCO-env. This can be copied to your desired folder using: -:: - - cp $CONDA_PREFIX/lib/libdiscon.* . - -CMake for developers: -------------------------------- -CMake_ provides a straightforward option for many users, particularly those on a Mac or Linux. ROSCO can be compiled by first cloning the source code from git using: -:: - - git clone https://github.com/NREL/ROSCO.git - -And then compiling using CMake: -:: - - cd ROSCO - mkdir build - cd build - cmake .. - make - -This will generate a file titled :code:`libdiscon.*` in the current directory. - -.. _Anaconda: https://www.anaconda.com/ -.. _CMake: https://cmake.org/ \ No newline at end of file diff --git a/docs/source/generating.rst b/docs/source/generating.rst deleted file mode 100644 index e523d0390..000000000 --- a/docs/source/generating.rst +++ /dev/null @@ -1,5 +0,0 @@ -.. _generate_discon: - -Generating DISCON.IN --------------------- -Instructions for generating the DISCON.IN file will be here soon... From 54ffd6f5e16e78fea87d369591886604a6906bc4 Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Thu, 4 Feb 2021 11:27:40 -0700 Subject: [PATCH 03/34] update themes --- docs/conf.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index a1ca4be1e..c90e6ed74 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -32,7 +32,14 @@ "sphinx.ext.napoleon", "sphinx.ext.autosummary", "sphinx.ext.intersphinx", - "sphinxcontrib.bibtex", + "sphinx_rtd_theme" + # "sphinxcontrib.bibtex", +] + +autodoc_default_flags = [ + 'members', + 'show-inheritance', + 'undoc-members' ] autosummary_generate = True @@ -55,7 +62,7 @@ # General information about the project. project = "ROSCO toolbox" -copyright = "2020, NREL" +copyright = "2021, NREL" author = "ROSCO developers" # The version info for the project you're documenting, acts as replacement for @@ -63,7 +70,7 @@ # built documents. # version = "2.1.1" -release = "2.1.1" +release = "2.3.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -86,7 +93,7 @@ # -- Options for HTML output ---------------------------------------------- -html_theme = "alabaster" +html_theme = "sphinx_rtd_theme" # html_static_path = ["_static/custom.css"] html_theme_options = { # "logo": "logo.png", From 268581c4aac7c31fcb4d67d94e8ec1d7c9d5a6a7 Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Thu, 4 Feb 2021 11:27:54 -0700 Subject: [PATCH 04/34] Edit for new docs format --- docs/index.rst | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 5ec032ea6..ac8eff196 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,11 +1,8 @@ .. toctree:: :hidden: - :glob: - :titlesonly: - - source/compiling.rst - source/generating.rst + source/standard_use.rst + source/install.rst ROSCO toolbox documentation =========================== @@ -16,15 +13,27 @@ ROSCO toolbox documentation NREL's Reference OpenSource Controller (ROSCO) toolbox for wind turbine applications is a toolbox designed to ease controller implementation for the wind turbine researcher. The purpose of these documents is to provide information for the use of the ROSCO related toolchain. -Standard Use -------------- +**ROSCO Toolbox** + +- Generic tuning of NREL's ROSCO controller +- Simple 1-DOF turbine simulations for quick controller capability verifications +- Parsing of OpenFAST input and output files +- Block diagrams of these capabilities can be seen in architecture.png. + +**ROSCO Controller** + +- Fortran based +- Follows Bladed-style control interface +- Modular + +**Standard Use** + For the standard use case in OpenFAST, ROSCO will need to be compiled. This is made possible via the instructions found in :ref:`compiling`. 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:`generate_discon`. -License -------- +**License** Copyright 2020 NREL Licensed under the Apache License, Version 2.0 (the "License"); From b6235f913aa9b38136d493a624915849df2b0784 Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Thu, 4 Feb 2021 11:28:04 -0700 Subject: [PATCH 05/34] Add sphinx_rtd_theme --- docs/requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 93b87dc12..c517da123 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -2,4 +2,5 @@ readthedocs-sphinx-ext Sphinx>=2.0 sphinxcontrib-napoleon -sphinxcontrib-bibtex \ No newline at end of file +sphinxcontrib-bibtex +sphinx_rtd_theme \ No newline at end of file From 33b7a03fb49b4f8e2b7d2e458bb1ad1dbb0af101 Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Thu, 4 Feb 2021 13:46:13 -0700 Subject: [PATCH 06/34] Fix cross references --- docs/index.rst | 4 ++-- docs/source/standard_use.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index ac8eff196..307caa7ee 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -28,9 +28,9 @@ NREL's Reference OpenSource Controller (ROSCO) toolbox for wind turbine applicat **Standard Use** -For the standard use case in OpenFAST, ROSCO will need to be compiled. This is made possible via the instructions found in :ref:`compiling`. 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. +For the standard use case in OpenFAST, 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:`generate_discon`. +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`. **License** diff --git a/docs/source/standard_use.rst b/docs/source/standard_use.rst index ac4fa831e..fe743d7bc 100644 --- a/docs/source/standard_use.rst +++ b/docs/source/standard_use.rst @@ -1,14 +1,14 @@ -.. _standard-use: .. toctree:: +.. _standard_use: Standard Uses ================= - Tuning a Controller -------------------- +.. _generate_discon: Generating DISCON.IN -------------------- From 78b274e466c1c3a13c90289e438ad38efe3e330a Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Thu, 4 Feb 2021 13:46:28 -0700 Subject: [PATCH 07/34] Include workflow image --- docs/conf.py | 31 ++++++++++++++++++------------- docs/figures/ROSCO_toolbox.png | Bin 0 -> 14071 bytes docs/index.rst | 11 +++++++++++ docs/source/install.rst | 3 ++- 4 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 docs/figures/ROSCO_toolbox.png diff --git a/docs/conf.py b/docs/conf.py index c90e6ed74..f3f45e0d5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -32,7 +32,9 @@ "sphinx.ext.napoleon", "sphinx.ext.autosummary", "sphinx.ext.intersphinx", - "sphinx_rtd_theme" + "sphinx_rtd_theme", + "sphinx.ext.graphviz", + "sphinx.ext.autosectionlabel", # "sphinxcontrib.bibtex", ] @@ -44,6 +46,9 @@ autosummary_generate = True +# enable numref +numfig = True + # Napoleon settings napoleon_google_docstring = True napoleon_include_init_with_doc = True @@ -95,18 +100,18 @@ html_theme = "sphinx_rtd_theme" # html_static_path = ["_static/custom.css"] -html_theme_options = { - # "logo": "logo.png", - # "logo_name": True, - "badge_branch": "develop", - "codecov_button": True, - "fixed_sidebar": True, - "github_user": "NREL", - "github_repo": "ROSCO toolbox", - "sidebar_width": "375px", - "page_width": "75%", - "show_relbars": True, -} +# html_theme_options = { +# # "logo": "logo.png", +# # "logo_name": True, +# "badge_branch": "develop", +# "codecov_button": True, +# "fixed_sidebar": True, +# "github_user": "NREL", +# "github_repo": "ROSCO toolbox", +# "sidebar_width": "375px", +# "page_width": "75%", +# "show_relbars": True, +# } # 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/figures/ROSCO_toolbox.png b/docs/figures/ROSCO_toolbox.png new file mode 100644 index 0000000000000000000000000000000000000000..cc48b4024d41fc249ad6798d6e4a47de2eea005b GIT binary patch literal 14071 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%0A$RV(crCioNgw{$ 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 BqQw9J literal 0 HcmV?d00001 diff --git a/docs/index.rst b/docs/index.rst index 307caa7ee..99e79d067 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -13,6 +13,17 @@ ROSCO toolbox documentation NREL's Reference OpenSource Controller (ROSCO) toolbox for wind turbine applications is a toolbox designed to ease controller implementation for the wind turbine researcher. The purpose of these documents is to provide information for the use of the ROSCO related toolchain. +Figure :numref:`fig-RT` shows the general workflow for the ROSCO toolchain. + +.. _fig-RT: +.. figure:: /figures/ROSCO_toolbox.png + :alt: ROSCO_toolbox + :align: center + :width: 400px + + ROSCO toolchain general workflow + + **ROSCO Toolbox** - Generic tuning of NREL's ROSCO controller diff --git a/docs/source/install.rst b/docs/source/install.rst index d7c8f70d8..829ffe2dd 100644 --- a/docs/source/install.rst +++ b/docs/source/install.rst @@ -1,7 +1,8 @@ -.. _install:: .. toctree:: :max_depth: 3 +.. _install: + Installing the ROSCO tools =========================== Both the ROSCO controller and ROSCO toolbox should be installed if one wishes to leverage the full ROSCO toolchain. Of course, some users may only wish to download and install only the controller or the toolbox. From 63d4d48c420d2385fcbd8aa200c2f61a231efa93 Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Thu, 4 Feb 2021 13:47:45 -0700 Subject: [PATCH 08/34] Remove old architecture images --- architecture.png | Bin 54457 -> 0 bytes architecture.svg | 459 ----------------------------------------------- 2 files changed, 459 deletions(-) delete mode 100644 architecture.png delete mode 100644 architecture.svg diff --git a/architecture.png b/architecture.png deleted file mode 100644 index 25a2facc8675923f01bad2deb971549cbdbc8d4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54457 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 LQzc!=)aQQyT5SvK diff --git a/architecture.svg b/architecture.svg deleted file mode 100644 index 389fc3bc3..000000000 --- a/architecture.svg +++ /dev/null @@ -1,459 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - ROSCO - - - ControllerParameters - - - ControllerTuning - - - TurbineModel - - - TinySim - - - FASTInterface - - - - Read Write OpenFAST Files - - Read Write - - - controller.py - turbine.py - sim.py - From cabcd34e9d3e1180bee09536537aaf22ffce2e1f Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Thu, 4 Feb 2021 13:55:25 -0700 Subject: [PATCH 09/34] Cleanup for readthedocs --- README.md | 77 ++----------------------------------------------------- 1 file changed, 2 insertions(+), 75 deletions(-) diff --git a/README.md b/README.md index 29478ff06..48df2db4f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ NREL's Reference OpenSource Controller (ROSCO) toolbox for wind turbine applicat * Simple 1-DOF turbine simulations for quick controller capability verifications * Parsing of OpenFAST input and output files -Block diagrams of these capabilities can be seen in [architecture.png](architecture.png). ## Introduction The NREL Reference OpenSource Controller (ROSCO) provides an open, modular and fully adaptable baseline wind turbine controller to the scientific community. The ROSCO toolbox leverages this architecture and implementation to provide a generic tuning process for the controller. Because of the open character and modular set-up, scientists are able to collaborate and contribute in making continuous improvements to the code for the controller and the toolbox. The ROSCO toolbox is a mostly-python code base with a number of functionalities. @@ -16,81 +15,9 @@ The NREL Reference OpenSource Controller (ROSCO) provides an open, modular and f * [Matlab_Toolbox](https://github.com/NREL/ROSCO_toolbox/tree/master/Matlab_Toolbox) - MATLAB scripts to parse and plot simulation output data. * [ofTools](https://github.com/NREL/ROSCO_toolbox/tree/master/ofTools) - A number of scripts to facilitate usage of OpenFAST and manage OpenFAST input and output files. -## Using the ROSCO Toolbox -Here is a short (but _hopefully_ sweet) installation and run process for basic controller tuning... -### Installing the complete ROSCO Toolbox -Installation of the complete ROSCO toolbox is made easy through [Anaconda](https://www.anaconda.com/). If you do not already have Anaconda installed on your machine, please install it. If you cannot install Anaconda, you can install the ROSCO toolbox without first initiating a conda environment (step 1), but will need to follow the detailed installatino instructions of [WISDEM](https://github.com/WISDEM/WISDEM) and [ROSCO](https://github.com/NREL/ROSCO.git) from their respective github pages. - -For users who have access to anaconda, please follow steps 1-3/4 below. - -1. #### Create a conda environment for ROSCO - ``` - conda config --add channels conda-forge - conda create -y --name rosco-env python=3.8 - conda activate rosco-env - ``` - -2. #### Install WISDEM - ``` - conda install -y wisdem - ``` - -You should then do step three _OR_ four. If you do not want to compile the ROSCO controller within the installation of the ROSCO toolbox, please follow the instruction on the controller's [github page]((https://github.com/NREL/ROSCO.git)). - -3. #### Clone and Install the ROSCO toolbox with ROSCO - ``` - git clone https://github.com/NREL/ROSCO_toolbox.git - cd ROSCO_toolbox - git submodule init - git submodule update - conda install compilers # (Mac/Linux only) - conda install m2w64-toolchain libpython # (Windows only) - python setup.py install --compile-rosco - ``` - -4. #### Clone and Install the ROSCO toolbox _without_ ROSCO - ``` - git clone https://github.com/NREL/ROSCO_toolbox.git - cd ROSCO_toolbox - python setup.py install - ``` - -### Alternatively... -If you wish to write your own scripts to leverage the ROSCO toolbox tools, but do not necessarily need the source code or to run any of the examples, the ROSCO toolbox is available via PyPi: -``` -pip install rosco_toolbox -``` -Note that if you do choose to install the ROSCO Toolbox this way, you will not have the source code. Additionally, you will need to download WISDEM and the ROSCO controller separately if you wish to use any of the ROSCO toolbox functionalities that need those software packages. - -#### Compiling ROSCO -The controller itself is installed as a submodule in the ROSCO toolbox. For further information on compiling and running ROSCO itself, or to download the release binaries directly, we point you to the [ROSCO github page](https://github.com/NREL/ROSCO_toolbox.git). If you wish to re-compile the ROSOCO toolbox, cmake provides easy to compiling on Unix based systems. In order to compile the controller, you should run the following commands from the ROSCO_toolbox folder. -``` -cd ROSCO -mkdir build -cd build -cmake .. -make -``` -Those familiar with mingw on windows can also compile ROSCO similarly. - -These commands will compile a binary titled `libdiscon.*` in the build folder, which is the binary necessary run the controller. This should only need to be compiled once. The extension should be `.dll`, `.so`, or `.dylib`, depending on the user operating system. - -### Running ROSCO with Generic Tuning -The [Tune_Cases](Tune_Cases) folder hosts examples on what needs to happen to write the input file to the ROSCO controller. See below on some details for compiling ROSCO: - -#### ROSCO Toolbox Generic Tuning -IF you would like to run the generic tuning process for ROSCO, examples are shown in the [Tune_Cases](Tune_Cases) folder. When you run your own version of [tune_ROSCO.py](Tune_Cases/tune_ROSCO.py), you will have two files that are necessary to run the controller. -1. `DISCON.IN` (or similar) - the input file to `libdiscon.*`. When running the controller in OpenFAST, `DISCON.IN` must be appropriately pointed to by the `DLL_FileName` parameter in ServoDyn. -2. `Cp_Cq_Ct.txt` (or similar) - This file contains rotor performance tables that are necessary to run the wind speed estimators in ROSCO. This can live wherever you desire, just be sure to point to it properly with the `PerfFileName` parameter in `DISCON.IN`. - -### Updating ROSCO Toolbox -Simple git commands should update the toolbox and controller as development continues: -``` -git pull -git submodule update -``` -and then recompile and reinstall as necessary... +## Documentation +All relevant documentation about the ROSCO toolbox and ROSCO controller can be found at through [ROSCO's readthedocs webpage](https://rosco-toolbox.readthedocs.io/en/latest/). Here, users can find the information on [installing the ROSCO toolbox](https://rosco-toolbox.readthedocs.io/en/latest/source/install.html#installing-the-rosco-toolbox) and [compiling ROSCO](https://rosco-toolbox.readthedocs.io/en/latest/source/install.html#compiling-rosco) for control purposes. Additionally, there is information on the standard workflow and uses cases for the ROSCO toolchain, and more. ## Referencing If the ROSCO Toolbox played a role in your research, please cite it. This software can be From 1c5c3632df9c818c5e953732f68a3a2b4df87830 Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Thu, 4 Feb 2021 13:55:31 -0700 Subject: [PATCH 10/34] Some placeholder info --- docs/source/standard_use.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/source/standard_use.rst b/docs/source/standard_use.rst index fe743d7bc..cabc488d6 100644 --- a/docs/source/standard_use.rst +++ b/docs/source/standard_use.rst @@ -4,11 +4,14 @@ Standard Uses ================= +TODO: This needs a lot of expansion Tuning a Controller -------------------- - .. _generate_discon: Generating DISCON.IN -------------------- +IF you would like to run the generic tuning process for ROSCO, examples are shown in the :code:`Tune_Cases` folder. When you run your own version of :code:`tune_ROSCO.py`, you will have two files that are necessary to run the controller. +1. `DISCON.IN` (or similar) - the input file to `libdiscon.*`. When running the controller in OpenFAST, `DISCON.IN` must be appropriately pointed to by the `DLL_FileName` parameter in ServoDyn. +2. `Cp_Cq_Ct.txt` (or similar) - This file contains rotor performance tables that are necessary to run the wind speed estimators in ROSCO. This can live wherever you desire, just be sure to point to it properly with the `PerfFileName` parameter in `DISCON.IN`. From e9c56eb61b1a5bd4b585c1b0e191603864586089 Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Thu, 4 Feb 2021 13:58:26 -0700 Subject: [PATCH 11/34] Update Version --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 48df2db4f..c754e5627 100644 --- a/README.md +++ b/README.md @@ -23,15 +23,15 @@ All relevant documentation about the ROSCO toolbox and ROSCO controller can be f If the ROSCO Toolbox played a role in your research, please cite it. This software can be cited as: - ROSCO. Version 1.0.0 (2020). Available at https://github.com/nrel/rosco_toolbox. + NREL: ROSCO Toolbox. Version 2.2.0, https://github.com/NREL/rosco_toolbox, 2021. For LaTeX users: ``` -@misc{ROSCO_toolbox_2019, +@misc{ROSCO_toolbox_2021, author = {NREL}, - title = {{ROSCO Toolbox. Version 0.1.0}}, - year = {2019}, + title = {{ROSCO Toolbox. Version 2.2.0}}, + year = {2021}, publisher = {GitHub}, journal = {GitHub repository}, url = {https://github.com/NREL/rosco_toolbox} From d4e46ffa0c348ec13f7b716cd988bb70ab0da481 Mon Sep 17 00:00:00 2001 From: dzalkind Date: Fri, 19 Feb 2021 10:58:11 -0700 Subject: [PATCH 12/34] Add draft of workflow/standard use --- docs/source/standard_use.rst | 112 +++++++++++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 13 deletions(-) diff --git a/docs/source/standard_use.rst b/docs/source/standard_use.rst index cabc488d6..40fbfda73 100644 --- a/docs/source/standard_use.rst +++ b/docs/source/standard_use.rst @@ -2,16 +2,102 @@ .. _standard_use: -Standard Uses -================= -TODO: This needs a lot of expansion - -Tuning a Controller --------------------- - -.. _generate_discon: -Generating DISCON.IN --------------------- -IF you would like to run the generic tuning process for ROSCO, examples are shown in the :code:`Tune_Cases` folder. When you run your own version of :code:`tune_ROSCO.py`, you will have two files that are necessary to run the controller. -1. `DISCON.IN` (or similar) - the input file to `libdiscon.*`. When running the controller in OpenFAST, `DISCON.IN` must be appropriately pointed to by the `DLL_FileName` parameter in ServoDyn. -2. `Cp_Cq_Ct.txt` (or similar) - This file contains rotor performance tables that are necessary to run the wind speed estimators in ROSCO. This can live wherever you desire, just be sure to point to it properly with the `PerfFileName` parameter in `DISCON.IN`. +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 ROSCO_toolbox and ROSCO 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:`ROSCO_turbine` object in python. +Several OpenFAST inputs are located in `Test_Cases/ `_. +The controller tuning .yaml are located in `Tune_Cases/ `_; a detailed description of these parameters is located here. **TODO: add link** + +* :code:`example_01.py` loads an OpenFAST turbine model and displays a summary of its information +* :code:`example_02.py` plots the C_p surface of a turbine + +ROSCO requires the power and thrust coefficients for tuning control parameters and running the extended Kalman filter wind speed estimator. + +* :code:`example_03.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_turbine object, which contains turbine information required for controller tuning, along with control parameters in the tuning yaml and the Cp surface are used to generate control parameters and 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 increase 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:`example_04.py` loads a turbine and tunes the PI control gains +* :code:`example_05.py` tunes a controller and runs a simple simualtion (not using OpenFAST) +* :code:`example_06.py` loads a turbine, tunes a controller, and runs an OpenFAST simulations + +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. + +ROSCO can implement peak shaving (or thrust clipping) by changing the minimum pitch angle based on the estimated wind speed: + +* :code:`example_07.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:`example_10.py` tunes a controller for distributed aerodynamic control + +.. This was incorported into the above +.. .. _generate_discon: +.. Generating DISCON.IN +.. -------------------- +.. IF you would like to run the generic tuning process for ROSCO, examples are shown in the :code:`Tune_Cases` folder. When you run your own version of :code:`tune_ROSCO.py`, you will have two files that are necessary to run the controller. +.. 1. `DISCON.IN` (or similar) - the input file to `libdiscon.*`. When running the controller in OpenFAST, `DISCON.IN` must be appropriately pointed to by the `DLL_FileName` parameter in ServoDyn. +.. 2. `Cp_Cq_Ct.txt` (or similar) - This file contains rotor performance tables that are necessary to run the wind speed estimators in ROSCO. This can live wherever you desire, just be sure to point to it properly with the `PerfFileName` parameter in `DISCON.IN`. + +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 "../../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 + +OpenFAST can be installed from `source `_ or from conda using:: + + conda install -c conda-forge openfast + +The ROSCO_toolbox has methods for running OpenFAST (and other) binary executables using system calls, as well as post-processing tools in `ofTools/ `_. +For more extensive post-processing tools, please see pCrunch (link). + +Several example scripts are set up to quickly simulate ROSCO with OpenFAST: + +* :code:`example_06.py` loads a turbine, tunes a controller, and runs an OpenFAST simulation +* :code:`example_08.py` loads the OpenFAST output files and plots the results +* :code:`example_09.py` runs TurbSim, for generating turbulent wind 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. + From 2825f74d482cb4cd918b15f4490fe703de032550 Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Fri, 19 Feb 2021 17:31:03 -0700 Subject: [PATCH 13/34] Add mingw, fix capitalization --- docs/source/install.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/source/install.rst b/docs/source/install.rst index 829ffe2dd..63bab7011 100644 --- a/docs/source/install.rst +++ b/docs/source/install.rst @@ -26,8 +26,8 @@ For users familiar with Anaconda_, ROSCO is available through the conda-forge ch :: conda config --add channels conda-forge - conda create -y --name ROSCO-env - conda activate ROSCO-env + conda create -y --name rosco-env python=3.8 + conda activate rosco-env navigate to your desired folder to save the compiled binary using: :: @@ -47,7 +47,7 @@ This will download a compiled ROSCO binary file into the default filepath for an CMake for developers: ..................... -CMake_ provides a straightforward option for many users, particularly those on a Mac or Linux. ROSCO can be compiled by first cloning the source code from git using: +CMake_ provides a straightforward option for many users, particularly those on a Mac or Linux. For windows users, we recommend using MinGW_ to compile similarly. ROSCO can be compiled by first cloning the source code from git using: :: git clone https://github.com/NREL/ROSCO.git @@ -132,3 +132,4 @@ and then recompile and reinstall as necessary... .. _Anaconda: https://www.anaconda.com/ .. _CMake: https://cmake.org/ +.. _MinGW: https://mingw-w64.org/ From 112b960f7504940ae214b85c54769542d9abc721 Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Fri, 19 Feb 2021 17:31:16 -0700 Subject: [PATCH 14/34] ROSCO toolbox specific intructions - initial commit --- docs/source/rosco_toolbox.rst | 280 ++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 docs/source/rosco_toolbox.rst diff --git a/docs/source/rosco_toolbox.rst b/docs/source/rosco_toolbox.rst new file mode 100644 index 000000000..6faa9eb18 --- /dev/null +++ b/docs/source/rosco_toolbox.rst @@ -0,0 +1,280 @@ +.. toctree:: + :max_depth: 2 + +.. _rosco_toolbox: + +ROSCO toolbox Structure +======================== +Here, we give an overview of the structure of the ROSCO toolbox and how the code is implemented. + +----- + +File Structure +--------------- +The primary tools of the ROSCO toolbox are separated into several folders. They include the following: + +*ROSCO_toolbox* +............... +The primary source code for the ROSCO toolbox generic tuning implementations lives here. + * :code:`turbine.py` loads a wind turbine model from OpenFAST_ input files. + * :code:`controller.py` contains the generic controller tuning scripts + * :code:`utilities.py` has most of the input/output file management scripts + * :code:`control_interface.py` enables a python interface to the ROSCO controller + * :code:`sim.py` is a simple 1-DOF model simulator + * **ofTools** is a folder containing a large set of tools to handle OpenFAST_ input files - this is primarily used to run large simulation sets and to handle reading and processing of OpenFAST input and output files. + +*Examples* +.......... +A number of examples are included to showcase the numerous capabilities of the ROSCO toolbox + +*Matlab_Toolbox* +................ +A simulink implementation of the ROSCO controller is included in the Matlab Toolbox. Some requisite MATLAB utility scripts are also included. + +*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* +........... +Example OpenFAST models consistent with OpenFAST's master branch are provided here for simple testing and simulation cases. + +*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. + +.. _rt_tuning_yaml: + +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 contains the following inputs: + +.. list-table:: ROSCO toolbox input yaml + :header-rows: 1 + :widths: 15 15 10 10 50 + :stub-columns: 1 + + * - Primary Section + - Variable + - Required + - Type + - Description + * - :code:`path_params` + - :code:`FAST_InputFile` + - Yes + - String + - Name of the primary (*.fst) OpenFAST input file + * - + - :code:`FAST_directory` + - Yes + - String + - Main OpenFAST model directory, where the *.fst lives + * - + - :code:`rotor_performance_filename` + - No + - String + - Filename for rotor performance text file. If this is not specified, and an existing rotor performance file cannot be found, cc-blade will be run + * - :code:`turbine_params` + - :code:`rotor_interia` + - Yes + - Float + - Rotor inertia [kg m^2], (Available in Elastodyn .sum file) + * - + - :code:`rated_rotor_speed` + - Yes + - Float + - Rated rotor speed of the turbine [rad/s] + * - + - :code:`v_min` + - Yes + - Float + - Cut-in wind speed [m/s] + * - + - :code:`v_max` + - Yes + - Float + - Cut-out wind speed [m/s] + * - + - :code:`max_pitch_rate` + - Yes + - Float + - Maximum blade pitch rate [rad/s] + * - + - :code:`max_torque_rate` + - Yes + - Float + - Maximum generator torque rate [Nm/s] + * - + - :code:`rated_power` + - Yes + - Float + - Rated Power [W]. + * - + - :code:`bld_edgewise_freq` + - Yes + - Float + - Blade edgewise first natural frequency [rad/s]. + * - + - :code:`TSR_operational` + - No + - Float + - Desired below-rated operation tip speed ratio [-]. If this is not specified, the Cp-maximizing TSR from the Cp surface is used. + * - + - :code:`twr_freq` + - No + - Float + - Tower first fore-aft natural frequency [rad/s]. Required for floating wind turbine control. + * - + - :code:`ptfm_freq` + - No + - Float + - Platform first fore-aft natural frequency [rad/s]. Required for floating wind turbine control. + * - :code:`controller_params` + - :code:`LoggingLevel` + - Yes + - Int + - 0: write no debug files, 1: write standard output .dbg-file, 2: write standard output .dbg-file and complete avrSWAP-array .dbg2-file + * - + - :code:`F_LPFType` + - Yes + - Int + - Type of Low pass filter for the generator speed feedback signal [rad/s]. 1: first-order low-pass filter, 2: second-order low-pass filter. + * - + - :code:`F_NotchType` + - Yes + - Int + - Notch filter on generator speed and/or tower fore-aft motion, used for floating wind turbine control. 0: disable, 1: generator speed, 2: tower-top fore-aft motion, 3: generator speed and tower-top fore-aft motion + * - + - :code:`IPC_ControlMode` + - Yes + - Int + - Turn Individual Pitch Control (IPC) for fatigue load reductions (pitch contribution). 0: off, 1: 1P reductions, 2: 1P+2P reductions. + * - + - :code:`VS_ControlMode` + - Yes + - Int + - Generator torque control mode. 0: :math:`k\omega^2` below rated, constant torque above rated, 1: :math:`k\omega^2` below rated, constant power above rated, 2: TSR tracking PI control below rated, constant torque above rated, 3: TSR tracking PI control below rated, constant power above rated. + * - + - :code:`PC_ControlMode` + - Yes + - Int + - Blade pitch control mode. 0: No pitch control, fix to fine pitch, 1: active PI blade pitch control + * - + - :code:`Y_ControlMode` + - Yes + - Int + - Yaw control mode. 0: no yaw control, 1: yaw rate control, 2: yaw-by-IPC + * - + - :code:`SS_Mode` + - Yes + - Int + - Setpoint Smoother mode. 0: no set point smoothing, 1: set point smoothing + * - + - :code:`WE_Mode` + - Yes + - Int + - Wind speed estimator mode. 0: One-second low pass filtered hub height wind speed, 1: Immersion and Invariance Estimator (Ortega et al.) + * - + - :code:`PS_Mode` + - Yes + - Int + - Pitch saturation mode. 0: no pitch saturation, 1: peak shaving, 2: Cp-maximizing pitch saturation, 3: peak shaving and Cp-maximizing pitch saturation + * - + - :code:`SD_Mode` + - Yes + - Int + - Shutdown mode. 0: no shutdown procedure, 1: pitch to max pitch at shutdown. + * - + - :code:`Fl_Mode` + - Yes + - Int + - Floating feedback mode. 0: no nacelle rotational velocity feedback, 1: nacelle rotational velocity feedback + * - + - :code:`Flp_Mode` + - Yes + - Int + - Flap control mode. 0: no flap control, 1: steady state flap angle, 2: Proportional flap control + * - + - :code:`zeta_pc` + - Yes + - Float + - Pitch controller desired damping ratio [-] + * - + - :code:`omega_pc` + - Yes + - Float + - Pitch controller desired natural frequency [rad/s] + * - + - :code:`zeta_vs` + - Yes + - Float + - Torque controller desired damping ratio [-] + * - + - :code:`omega_vs` + - Yes + - Float + - Torque controller desired natural frequency [rad/s] + * - + - :code:`zeta_flp` + - No + - Float + - Flap controller desired damping ratio [-]. Required if :code:`Flp_Mode`>0 + * - + - :code:`omega_flp` + - No + - Float + - Flap controller desired natural frequency [rad/s]. Required if :code:`Flp_Mode`>0 + * - + - :code:`max_pitch` + - No + - Float + - Maximum blade pitch angle [rad]. Default is 1.57 rad (90 degrees). + * - + - :code:`min_pitch` + - No + - Float + - Minimum blade pitch angle [rad]. Default is 0 degrees. + * - + - :code:`vs_minspd` + - No + - Float + - Minimum rotor speed [rad/s]. Default is 0 rad/s. + * - + - :code:`ss_cornerfreq` + - No + - Float + - First order low-pass filter cornering frequency for setpoint smoother [rad/s]. Default is .6283 rad/s. + * - + - :code:`ss_vsgain` + - No + - Float + - Torque controller set point smoother gain bias percentage [:math:`\leq` 1]. Default is 1. + * - + - :code:`ss_pcgain` + - No + - Float + - Pitch controller set point smoother gain bias percentage [:math:`\leq` 1]. Default is 0.001. + * - + - :code:`ps_percent` + - No + - Float + - Percent peak shaving [:math:`\leq` 1]. Default is 0.8. + * - + - :code:`sd_maxpit` + - No + - Float + - Maximum blade pitch angle to initiate shutdown [rad]. Default is the blade pitch angle at :code:`v_max`. + * - + - :code:`sd_cornerfreq` + - No + - Float + - Cutoff Frequency for first order low-pass filter for blade pitch angle [rad/s]. Default is 0.41888 rad/s. + * - + - :code:`flp_maxpit` + - No + - Float + - Maximum (and minimum) flap pitch angle [rad]. Default is 0.1745 rad (10 degrees). + + +.. _OpenFAST: https://github.com/openfast/openfast +.. _yaml: https://yaml.org/ \ No newline at end of file From 5a3db3efed6ea99d00122a8569287f4648f2a4e9 Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Fri, 19 Feb 2021 17:31:27 -0700 Subject: [PATCH 15/34] Add ROSCO toolbox instruction to contents --- docs/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/index.rst b/docs/index.rst index 99e79d067..85836e7a7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,6 +3,7 @@ source/standard_use.rst source/install.rst + source/rosco_toolbox.rst ROSCO toolbox documentation =========================== From 788173f1dd8d69c9ba55af47b05e8ac97a39fdd7 Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Fri, 26 Feb 2021 10:35:33 -0700 Subject: [PATCH 16/34] typo fix --- Examples/DISCON.IN | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/DISCON.IN b/Examples/DISCON.IN index 523448349..698181f5e 100644 --- a/Examples/DISCON.IN +++ b/Examples/DISCON.IN @@ -5,7 +5,7 @@ 1 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: write standard output .dbg-file and complete avrSWAP-array .dbg2-file} !------- CONTROLLER FLAGS ------------------------------------------------- -1 ! F_LPFType - {1: first-order low-pass filter, 2: second-order low-pass filter}, [rad/s] (currently filters generator speed and pitch control signals +1 ! F_LPFType - {1: first-order low-pass filter, 2: second-order low-pass filter} (currently filters generator speed and pitch control signals 0 ! F_NotchType - Notch on the measured generator speed and/or tower fore-aft motion (for floating) {0: disable, 1: generator speed, 2: tower-top fore-aft motion, 3: generator speed and tower-top fore-aft motion} 0 ! IPC_ControlMode - Turn Individual Pitch Control (IPC) for fatigue load reductions (pitch contribution) {0: off, 1: 1P reductions, 2: 1P+2P reductions} 2 ! VS_ControlMode - Generator torque control mode in above rated conditions {0: constant torque, 1: constant power, 2: TSR tracking PI control} From d1fee5a7da15cee4ac16986101d404fd5bbdb131 Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Fri, 26 Feb 2021 10:36:03 -0700 Subject: [PATCH 17/34] Toctree update, formatting --- docs/source/rosco_toolbox.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/source/rosco_toolbox.rst b/docs/source/rosco_toolbox.rst index 6faa9eb18..e7cadbab8 100644 --- a/docs/source/rosco_toolbox.rst +++ b/docs/source/rosco_toolbox.rst @@ -1,5 +1,5 @@ .. toctree:: - :max_depth: 2 + :max_depth: 1 .. _rosco_toolbox: @@ -15,7 +15,8 @@ The primary tools of the ROSCO toolbox are separated into several folders. They *ROSCO_toolbox* ............... -The primary source code for the ROSCO toolbox generic tuning implementations lives here. +The source code for the ROSCO toolbox generic tuning implementations lives here. + * :code:`turbine.py` loads a wind turbine model from OpenFAST_ input files. * :code:`controller.py` contains the generic controller tuning scripts * :code:`utilities.py` has most of the input/output file management scripts From 5900d635af1a170484e52dda5fd104d326867fe8 Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Fri, 26 Feb 2021 10:36:12 -0700 Subject: [PATCH 18/34] Add ROSCO inputs --- docs/source/rosco.rst | 398 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 398 insertions(+) create mode 100644 docs/source/rosco.rst diff --git a/docs/source/rosco.rst b/docs/source/rosco.rst new file mode 100644 index 000000000..5b7d5e6f9 --- /dev/null +++ b/docs/source/rosco.rst @@ -0,0 +1,398 @@ +.. toctree:: + :max_depth: 1 + +.. _rosco: + +ROSCO Controller Structure +======================== +Here, we give an overview of the structure of the ROSCO controller and how the code is implemented. + +----- + +File Structure +--------------- +The primary functions of the ROSCO toolbox are separated into several files. They include the following: + + * :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:`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. + +.. _discon_in: + +The DISCON.IN file +------------------------------ +A standard file structure is used as an input to the ROSCO controller. This is, generically, dubbed the DISCON.IN file, though it can be renamed (In OpenFAST_, this file is pointed to by :code:`DLL_InFile` in the ServoDyn file. Examples of the DISCON.IN file are found in each of the Test Cases in the ROSCO toolbox, and in the :code:`parameter_files` folder of ROSCO. + +.. list-table:: DISCON.IN + :header-rows: 1 + :widths: 15 15 10 60 + :stub-columns: 1 + + * - Primary Section + - Variable + - Type + - Description + * - DEBUG + - :code:`LoggingLevel` + - Int + - 0: write no debug files, 1: write standard output .dbg-file, 2: write standard output .dbg-file and complete avrSWAP-array .dbg2-file + * - CONTROLLER FLAGS + - :code:`F_LPFType` + - Int + - Filter type for generator speed feedback signal. 1: first-order low-pass filter, 2: second-order low-pass filter. + * - + - :code:`F_NotchType` + - Int + - Notch filter on the measured generator speed and/or tower fore-aft motion (used for floating). 0: disable, 1: generator speed, 2: tower-top fore-aft motion, 3: generator speed and tower-top fore-aft motion. + * - + - :code:`IPC_ControlMode` + - Int + - Individual Pitch Control (IPC) type for fatigue load reductions (pitch contribution). 0: off, 1: 1P reductions, 2: 1P+2P reductions. + * - + - :code:`VS_ControlMode` + - Int + - Generator torque control mode type. 0: :math:`k\omega^2` below rated, constant torque above rated, 1: :math:`k\omega^2` below rated, constant power above rated, 2: TSR tracking PI control below rated, constant torque above rated, 3: TSR tracking PI control below rated, constant torque above rated + * - + - :code:`PC_ControlMode` + - Int + - Blade pitch control mode. 0: No pitch, fix to fine pitch, 1: active PI blade pitch control. + * - + - :code:`Y_ControlMode` + - Int + - Yaw control mode. 0: no yaw control, 1: yaw rate control, 2: yaw-by-IPC. + * - + - :code:`SS_Mode` + - Int + - Setpoint Smoother mode. 0: no set point smoothing, 1: use set point smoothing. + * - + - :code:`WE_Mode` + - Int + - Wind speed estimator mode. 0: One-second low pass filtered hub height wind speed, 1: Immersion and Invariance Estimator, 2: Extended Kalman Filter. + * - + - :code:`PS_Mode` + - Int + - Pitch saturation mode. 0: no pitch saturation, 1: implement pitch saturation} + * - + - :code:`SD_Mode` + - Int + - Shutdown mode. 0: no shutdown procedure, 1: shutdown triggered by max blade pitch. + * - + - :code:`Fl_Mode` + - Int + - Floating feedback mode. 0: no nacelle velocity feedback, 1: nacelle velocity feedback (parallel compensation). + * - + - :code:`Flp_Mode` + - Int + - Flap control mode. 0: no flap control, 1: steady state flap angle, 2: PI flap control. + * - FILTERS + - :code:`F_LPFCornerFreq` + - Float + - Corner frequency (-3dB point) in the generator speed low-pass filter, [rad/s] + * - + - :code:`F_LPFDamping` + - Float + - Damping coefficient in the generator speed low-pass filter, [-]. Only used only when F_FilterType = 2 + * - + - :code:`F_NotchCornerFreq` + - Float + - Natural frequency of the notch filter, [rad/s] + * - + - :code:`F_NotchBetaNumDen` + - Float Float + - Notch damping values of numerator and denominator - determines the width and depth of the notch, [-] + * - + - :code:`F_SSCornerFreq` + - Float + - Corner frequency (-3dB point) in the first order low pass ..filter for the set point smoother, [rad/s]. + * - + - :code:`F_FlCornerFreq` + - Float Float + - Corner frequency and damping ratio for the second order low pass filter of the tower-top fore-aft motion for floating feedback control [rad/s, -]. + * - + - :code:`F_FlpCornerFreq` + - Float Float + - Corner frequency and damping ratio in the second order low pass filter of the blade root bending moment for flap control [rad/s, -]. + * - BLADE PITCH CONTROL + - :code:`PC_GS_n` + - Int + - Number of gain-scheduling table entries + * - + - :code:`PC_GS_angles` + - Float array with length = :code:`PC_GS_n` + - Gain-schedule table: pitch angles [rad]. + * - + - :code:`PC_GS_KP` + - Float array with length = :code:`PC_GS_n` + - Gain-schedule table: pitch controller proportional gains [s]. + * - + - :code:`PC_GS_KI` + - Float array with length = :code:`PC_GS_n` + - Gain-schedule table: pitch controller integral gains [-]. + * - + - :code:`PC_GS_KD` + - Float array with length = :code:`PC_GS_n` + - Gain-schedule table: pitch controller derivative gains [:math:`s^2`]. Currently unused! + * - + - :code:`PC_GS_TF` + - Float array with length = :code:`PC_GS_n` + - Gain-schedule table: transfer function gains [:math:`s^2`]. Currently unused! + * - + - :code:`PC_MaxPit` + - Float + - Maximum physical pitch limit, [rad]. + * - + - :code:`PC_MinPit` + - Float + - Minimum physical pitch limit, [rad]. + * - + - :code:`PC_MaxRat` + - Float + - Maximum pitch rate (in absolute value) of pitch controller, [rad/s]. + * - + - :code:`PC_MinRat` + - Float + - Minimum pitch rate (in absolute value) in pitch controller, [rad/s]. + * - + - :code:`PC_RefSpd` + - Float + - Desired (reference) HSS speed for pitch controller, [rad/s]. + * - + - :code:`PC_FinePit` + - Float + - Below-rated pitch angle set-point, [rad] + * - + - :code:`PC_Switch` + - Float + - Angle above lowest :code:`PC_MinPit` to switch to above rated torque control, [rad]. Used for :code:`VS_ControlMode`=0,1. + * - INDIVIDUAL PITCH CONTROL + - :code:`IPC_IntSat` + - Float + - Integrator saturation point (maximum signal amplitude contribution to pitch from IPC), [rad] + * - + - :code:`IPC_KI` + - Float Float + - Integral gain for the individual pitch controller: first parameter for 1P reductions, second for 2P reductions, [-, -]. + * - + - :code:`IPC_aziOffset` + - Float Float + - Phase offset added to the azimuth angle for the individual pitch controller: first parameter for 1P reductions, second for 2P reductions, [rad]. + * - + - :code:`IPC_CornerFreqAct` + - Float + - Corner frequency of the first-order actuators model, used to induce a phase lag in the IPC signal [rad/s]. 0: Disable. + * - VS TORQUE CONTROL + - :code:`VS_GenEff` + - Float + - Generator efficiency from mechanical power -> electrical power, [should match the efficiency defined in the generator properties!], [%] + * - + - :code:`VS_ArSatTq` + - Float + - Above rated generator torque PI control saturation limit, [Nm]. + * - + - :code:`VS_MaxRat` + - Float + - Maximum generator torque rate (in absolute value) [Nm/s]. + * - + - :code:`VS_MaxTq` + - Float + - Maximum generator torque (HSS), [Nm]. + * - + - :code:`VS_MinTq` + - Float + - Minimum generator torque (HSS) [Nm]. + * - + - :code:`VS_MinOMSpd` + - Float + - Cut-in speed towards optimal mode gain path, [rad/s]. Used if :code:`VS_ControlMode` = 0,1. + * - + - :code:`VS_Rgn2K` + - Float + - Generator torque constant in Region 2 (HSS side), [N-m/(rad/s)^2]. Used if :code:`VS_ControlMode` = 0,1. + * - + - :code:`VS_RtPwr` + - Float + - Rated power [W] + * - + - :code:`VS_RtTq` + - Float + - Rated torque, [Nm]. + * - + - :code:`VS_RefSpd` + - Float + - Rated generator speed used by torque controller [rad/s]. + * - + - :code:`VS_n` + - Int + - Number of generator PI torque controller gains. Only 1 is currently supported. + * - + - :code:`VS_KP` + - Float + - Proportional gain for generator PI torque controller [1/(rad/s) Nm]. (Used in the transition 2.5 region if :code:`VS_ControlMode` = 0,1. Always used if :code:`VS_ControlMode` = 2,3) + * - + - :code:`VS_KI` + - Float + - Integral gain for generator PI torque controller [1/rad Nm]. (Only used in the transition 2.5 region if :code:`VS_ControlMode` = 0,1. Always used if :code:`VS_ControlMode` = 2,3) + * - + - :code:`VS_TSRopt` + - Float + - Region 2 tip-speed-ratio [rad]. Generally, the power maximizing TSR. Can use non-optimal TSR for low axial induction rotors. + * - SETPOINT SMOOTHER + - :code:`SS_VSGain` + - Float + - Variable speed torque controller setpoint smoother gain, [-]. + * - + - :code:`SS_PCGain` + - Float + - Collective pitch controller setpoint smoother gain, [-]. + * - WIND SPEED ESTIMATOR + - :code:`WE_BladeRadius` + - Float + - Blade length (distance from hub center to blade tip), [m] + * - + - :code:`WE_CP_n` + - Int + - Number of parameters in the Cp array + * - + - :code:`WE_CP` + - Float Float Float Float + - Parameters that define the parameterized CP(lambda) function + * - + - :code:`WE_Gamma` + - Float + - Adaption gain for the I&I wind speed estimator algorithm [m/rad] + * - + - :code:`WE_GearboxRatio` + - Float + - Gearbox ratio [>=1], [-] + * - + - :code:`WE_Jtot` + - Float + - Total drivetrain inertia, including blades, hub and casted generator inertia to LSS, [kg m^2] + * - + - :code:`WE_RhoAir` + - Float + - Air density, [kg m^-3] + * - + - :code:`PerfFileName` + - String + - File containing rotor performance tables (Cp,Ct,Cq) + * - + - :code:`PerfTableSize` + - Int Int + - Size of rotor performance tables in :code:`PerfFileName`, first number refers to number of blade pitch angles (num columns), second number refers to number of tip-speed ratios (num rows) + * - + - :code:`WE_FOPoles_N` + - Int + - Number of first-order system poles used in the Extended Kalman Filter + * - + - :code:`WE_FOPoles_v` + - Float array, length = :code:`WE_FOPoles_N` + - Wind speeds for first-order system poles lookup table [m/s] + * - + - :code:`WE_FOPoles` + - Float array, length = :code:`WE_FOPoles_N` + - First order system poles [1/s] + * - YAW CONTROL + - :code:`Y_ErrThresh` + - Float + - Yaw error threshold. Turbine begins to yaw when it passes this. [rad^2 s] + * - + - :code:`Y_IPC_IntSat` + - Float + - Integrator saturation (maximum signal amplitude contribution to pitch from yaw-by-IPC), [rad] + * - + - :code:`Y_IPC_n` + - Int + - Number of controller gains for yaw-by-IPC + * - + - :code:`Y_IPC_KP` + - Float array, length = :code:`Y_IPC_n` + - Yaw-by-IPC proportional controller gains Kp [s] + * - + - :code:`Y_IPC_KI` + - Float array, length = :code:`Y_IPC_n` + - Yaw-by-IPC integral controller gain Ki [-] + * - + - :code:`Y_IPC_omegaLP` + - Float + - Low-pass filter corner frequency for the Yaw-by-IPC controller to filtering the yaw alignment error, [rad/s]. + * - + - :code:`Y_IPC_zetaLP` + - Float + - Low-pass filter damping factor for the Yaw-by-IPC controller to filtering the yaw alignment error, [-]. + * - + - :code:`Y_MErrSet` + - Float + - Yaw alignment error set point, [rad]. + * - + - :code:`Y_omegaLPFast` + - Float + - Corner frequency fast low pass filter, [rad/s]. + * - + - :code:`Y_omegaLPSlow` + - Float + - Corner frequency slow low pass filter, [rad/s]. + * - + - :code:`Y_Rate` + - Float + - Yaw rate, [rad/s]. + * - TOWER FORE-AFT DAMPING + - :code:`FA_KI` + - Float + - Integral gain for the fore-aft tower damper controller [rad*s/m]. -1 = off + * - + - :code:`FA_HPF_CornerFreq` + - Float + - Corner frequency (-3dB point) in the high-pass filter on the fore-aft acceleration signal [rad/s] + * - + - :code:`FA_IntSat` + - Float + - Integrator saturation (maximum signal amplitude contribution to pitch from FA damper), [rad] + * - MINIMUM PITCH SATURATION + - :code:`PS_BldPitchMin_N` + - Int + - Number of values in minimum blade pitch lookup table. + * - + - :code:`PS_WindSpeeds` + - Float array, length = :code:`PS_BldPitchMin_n` + - Wind speeds corresponding to minimum blade pitch angles [m/s] + * - + - :code:`PS_BldPitchMin` + - Float array, length = :code:`PS_BldPitchMin_n` + - Minimum blade pitch angles [rad] + * - SHUTDOWN + - :code:`SD_MaxPit` + - Float + - Maximum blade pitch angle to initiate shutdown, [rad] + * - + - :code:`SD_CornerFreq` + - Float + - Cutoff Frequency for first order low-pass filter for blade pitch angle, [rad/s] + * - FLOATING + - :code:`Fl_Kp` + - Float + - Nacelle velocity proportional feedback gain [s] + * - FLAP ACTUATION + - :code:`Flp_Angle` + - Float + - Initial or steady state flap angle [rad] + * - + - :code:`Flp_Kp` + - Float + - Trailing edge flap control proportional gain [s] + * - + - :code:`Flp_Ki` + - Float + - Trailing edge flap control integral gain [s] + * - + - :code:`Flp_MaxPit` + - Float + - Maximum (and minimum) flap angle [rad] + + +.. _OpenFAST: https://github.com/openfast/openfast +.. _yaml: https://yaml.org/ \ No newline at end of file From 667b2c166efc845d9baa302e245ac4c154874541 Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Fri, 26 Feb 2021 10:53:22 -0700 Subject: [PATCH 19/34] Table formatting --- docs/source/rosco.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/source/rosco.rst b/docs/source/rosco.rst index 5b7d5e6f9..e539680eb 100644 --- a/docs/source/rosco.rst +++ b/docs/source/rosco.rst @@ -29,7 +29,7 @@ A standard file structure is used as an input to the ROSCO controller. This is, .. list-table:: DISCON.IN :header-rows: 1 - :widths: 15 15 10 60 + :widths: 10 10 10 70 :stub-columns: 1 * - Primary Section @@ -122,23 +122,23 @@ A standard file structure is used as an input to the ROSCO controller. This is, - Number of gain-scheduling table entries * - - :code:`PC_GS_angles` - - Float array with length = :code:`PC_GS_n` + - Float array, length = :code:`PC_GS_n` - Gain-schedule table: pitch angles [rad]. * - - :code:`PC_GS_KP` - - Float array with length = :code:`PC_GS_n` + - Float array, length = :code:`PC_GS_n` - Gain-schedule table: pitch controller proportional gains [s]. * - - :code:`PC_GS_KI` - - Float array with length = :code:`PC_GS_n` + - Float array, length = :code:`PC_GS_n` - Gain-schedule table: pitch controller integral gains [-]. * - - :code:`PC_GS_KD` - - Float array with length = :code:`PC_GS_n` + - Float array, length = :code:`PC_GS_n` - Gain-schedule table: pitch controller derivative gains [:math:`s^2`]. Currently unused! * - - :code:`PC_GS_TF` - - Float array with length = :code:`PC_GS_n` + - Float array, length = :code:`PC_GS_n` - Gain-schedule table: transfer function gains [:math:`s^2`]. Currently unused! * - - :code:`PC_MaxPit` From b70ca27433130947e60c4da0951c4263d2d6cfc5 Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Fri, 26 Feb 2021 10:53:32 -0700 Subject: [PATCH 20/34] Add ROSCO page --- docs/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/index.rst b/docs/index.rst index 85836e7a7..d10cc29eb 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -4,6 +4,7 @@ source/standard_use.rst source/install.rst source/rosco_toolbox.rst + source/rosco.rst ROSCO toolbox documentation =========================== From d1ba1f1eba0f21298548878a9fffafb732e2e9db Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Fri, 26 Feb 2021 11:42:52 -0700 Subject: [PATCH 21/34] formatting --- docs/source/rosco_toolbox.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/rosco_toolbox.rst b/docs/source/rosco_toolbox.rst index e7cadbab8..86566b78c 100644 --- a/docs/source/rosco_toolbox.rst +++ b/docs/source/rosco_toolbox.rst @@ -3,7 +3,7 @@ .. _rosco_toolbox: -ROSCO toolbox Structure +ROSCO Toolbox Structure ======================== Here, we give an overview of the structure of the ROSCO toolbox and how the code is implemented. From fb1a122434cd62b0dafd095df4319165567aec4d Mon Sep 17 00:00:00 2001 From: dzalkind Date: Fri, 26 Feb 2021 16:08:54 -0700 Subject: [PATCH 22/34] Update simulink model input channel names, running --- Matlab_Toolbox/Simulink/ROSCO.mdl | 203 +++++++++--------- .../NRELOffshrBsline5MW_Onshore_ElastoDyn.dat | 2 +- 2 files changed, 97 insertions(+), 108 deletions(-) diff --git a/Matlab_Toolbox/Simulink/ROSCO.mdl b/Matlab_Toolbox/Simulink/ROSCO.mdl index 0eaa7c1a0..bcc8684b2 100644 --- a/Matlab_Toolbox/Simulink/ROSCO.mdl +++ b/Matlab_Toolbox/Simulink/ROSCO.mdl @@ -6,7 +6,7 @@ Model { NumRootInports 0 NumRootOutports 0 ParameterArgumentNames "" - ComputedModelVersion "1.1850" + ComputedModelVersion "1.1851" NumModelReferences 0 NumTestPointedSignals 19 TestPointedSignal { @@ -217,7 +217,7 @@ Model { $ObjectID 2 $ClassName "Simulink.WindowInfo" IsActive [1] - Location [0.0, 23.0, 1920.0, 977.0] + Location [0.0, 23.0, 1920.0, 984.0] Object { $PropName "ModelBrowserInfo" $ObjectID 3 @@ -251,34 +251,34 @@ Model { IsActive [0] ViewObjType "SimulinkTopLevel" LoadSaveID "0" - Extents [1882.0, 801.0] + Extents [1882.0, 808.0] ZoomFactor [1.0] - Offset [-948.93363095238146, 249.50952380952435] + Offset [-1120.3836309523813, -40.490476190475533] } Object { $ObjectID 7 IsActive [0] ViewObjType "SimulinkSubsys" LoadSaveID "20" - Extents [1882.0, 801.0] + Extents [1882.0, 808.0] ZoomFactor [1.0] Offset [-419.21718750000014, 14.173611111110858] } Object { $ObjectID 8 - IsActive [0] + IsActive [1] ViewObjType "SimulinkSubsys" LoadSaveID "766" - Extents [1882.0, 801.0] + Extents [1882.0, 808.0] ZoomFactor [1.0] Offset [-474.25281148867293, 377.65392394821993] } Object { $ObjectID 9 - IsActive [1] + IsActive [0] ViewObjType "SimulinkSubsys" LoadSaveID "3" - Extents [1882.0, 801.0] + Extents [1882.0, 808.0] ZoomFactor [1.25] Offset [-480.24140624999995, -154.2] } @@ -394,7 +394,7 @@ Model { "AAAAfwAAABGAAAC+AAAAAAA////+gAAAAECAAAAAvsAAABUAEcATABVAEUAMgA6AFAAcgBvAHAAZQByAHQAeQBJAG4AcwBwAGUAYwB0AG8AcgAvA" "FAAcgBvAHAAZQByAHQAeQAgAEkAbgBzAHAAZQBjAHQAbwByAAAAAAD/////AAAAOQD////7AAAAXgBHAEwAVQBFADIAOgBOAG8AdABlAHMAIABCA" "HIAbwB3AHMAZQByACAAQwBvAG0AcABvAG4AZQBuAHQALwBTAHkAcwBEAG8AYwBNAGkAeABlAGQARQBkAGkAdABvAHIAAAAAAP////8AAAAAAAAAA" - "AAAB4AAAANcAAAAAQAAAAIAAAABAAAAAvwAAAABAAAAAgAAAA//////AAAAAAD/////AAAAAAAAAAD/////AQAAAAD/////AAAAAAAAAAD/////A" + "AAAB4AAAANjAAAAAQAAAAIAAAABAAAAAvwAAAABAAAAAgAAAA//////AAAAAAD/////AAAAAAAAAAD/////AQAAAAD/////AAAAAAAAAAD/////A" "AAAAAD/////AAAAAAAAAAD/////AAAAAAD/////AAAAAAAAAAD/////AAAAAAD/////AAAAAAAAAAD/////AQAAAIT/////AAAAAAAAAAD/////A" "QAAAPb/////AAAAAAAAAAD/////AAAAAAD/////AAAAAAAAAAD/////AQAAAXr/////AAAAAAAAAAD/////AAAAAAD/////AAAAAAAAAAD/////A" "AAAAAD/////AAAAAAAAAAD/////AAAAAAD/////AAAAAAAAAAD/////AQAAA6D/////AAAAAAAAAAD/////AAAAAAD/////AAAAAAAAAAD/////A" @@ -408,9 +408,9 @@ Model { ModifiedByFormat "%" LastModifiedBy "dzalkind" ModifiedDateFormat "%" - LastModifiedDate "Fri Jul 17 17:08:03 2020" - RTWModifiedTimeStamp 516906481 - ModelVersionFormat "1.%" + LastModifiedDate "Wed Feb 24 15:00:35 2021" + RTWModifiedTimeStamp 536079624 + ModelVersionFormat "1.%" SampleTimeColors on SampleTimeAnnotations on LibraryLinkDisplay "disabled" @@ -14243,7 +14243,7 @@ Model { } System { Name "ROSCO" - Location [0, 23, 1920, 1000] + Location [0, 23, 1920, 1007] Open on PortBlocksUseCompactNotation off SetExecutionDomain off @@ -14396,7 +14396,7 @@ Model { ContentPreviewEnabled on System { Name "Integral" - Location [1920, 23, 3712, 1120] + Location [0, 23, 1920, 1000] Open on PortBlocksUseCompactNotation off SetExecutionDomain off @@ -15323,7 +15323,7 @@ Model { } System { Name "Extract Signals" - Location [0, 23, 1920, 1000] + Location [0, 23, 1920, 1007] Open on PortBlocksUseCompactNotation off SetExecutionDomain off @@ -15374,12 +15374,20 @@ Model { } Block { BlockType Fcn - Name "Extract NcIMUTAys" + Name "Extract NcIMURAys" SID "729" Position [245, 525, 305, 555] ZOrder 32 Expr "u(strmatch('NcIMURAys',OutList))" } + Block { + BlockType Fcn + Name "Extract NcIMUTAxs" + SID "824" + Position [245, 695, 305, 725] + ZOrder 38 + Expr "u(strmatch('NcIMUTAxs',OutList))" + } Block { BlockType Fcn Name "Extract RotSpeed" @@ -15405,14 +15413,6 @@ Model { ZOrder 12 Expr "u(strmatch('Wind1VelX',OutList))" } - Block { - BlockType Fcn - Name "Extract YawBrTAyt" - SID "824" - Position [245, 695, 305, 725] - ZOrder 38 - Expr "u(strmatch('NcIMUTAys',OutList))" - } Block { BlockType Gain Name "deg2rad" @@ -15573,7 +15573,7 @@ Model { Branch { ZOrder 232 Points [0, 80] - DstBlock "Extract YawBrTAyt" + DstBlock "Extract NcIMUTAxs" DstPort 1 } Branch { @@ -15584,7 +15584,7 @@ Model { } Branch { ZOrder 227 - DstBlock "Extract NcIMUTAys" + DstBlock "Extract NcIMURAys" DstPort 1 } } @@ -15647,7 +15647,7 @@ Model { } Line { ZOrder 216 - SrcBlock "Extract NcIMUTAys" + SrcBlock "Extract NcIMURAys" SrcPort 1 DstBlock "deg2rad1" DstPort 1 @@ -15675,7 +15675,7 @@ Model { } Line { ZOrder 234 - SrcBlock "Extract YawBrTAyt" + SrcBlock "Extract NcIMUTAxs" SrcPort 1 DstBlock "TwrFA Accel" DstPort 1 @@ -15710,7 +15710,7 @@ Model { } System { Name "FAST Nonlinear Wind Turbine" - Location [0, 23, 1920, 1000] + Location [0, 23, 1920, 1007] Open on PortBlocksUseCompactNotation off SetExecutionDomain off @@ -15935,15 +15935,15 @@ Model { "AxesTickColor',[0.686274509803922 0.686274509803922 0.686274509803922],'ColorOrder',[1 1 0.0666666666666667;0.07450" "98039215686 0.623529411764706 1;1 0.411764705882353 0.16078431372549;0.392156862745098 0.831372549019608 0.07450980" "39215686;0.717647058823529 0.274509803921569 1;0.0588235294117647 1 1;1 0.0745098039215686 0.650980392156863],'Titl" - "e','%','LinePropertiesCache',{{}},'UserDefinedChannelNames',{{}},'NumLines',2,'LineNames',{{'GenSpeed'" - ",'Discrete Filter'}},'ShowContent',true,'Placement',1)},'DisplayPropertyDefaults',struct('MinYLimReal','0.35212','M" - "axYLimReal','1.12256','YLabelReal','','MinYLimMag','0.35212','MaxYLimMag','1.12256','LegendVisibility','off','XGrid" - "',true,'YGrid',true,'PlotMagPhase',false,'AxesColor',[0 0 0],'AxesTickColor',[0.686274509803922 0.686274509803922 0" - ".686274509803922],'ColorOrder',[0.0745098039215686 0.623529411764706 1;1 0.411764705882353 0.16078431372549;1 1 0.0" - "666666666666667;0.717647058823529 0.274509803921569 1;0.392156862745098 0.831372549019608 0.0745098039215686;0.0588" - "235294117647 1 1;1 0.0745098039215686 0.650980392156863])),extmgr.Configuration('Tools','Plot Navigation',true,'Pre" - "viousAutoscale','XY'),extmgr.Configuration('Tools','Measurements',true,'Version','2018b')),'Version','2018b','Posit" - "ion',[1 1 895 596],'VisibleAtModelOpen','on')" + "e','%','LinePropertiesCache',{{}},'UserDefinedChannelNames',{{}},'NumLines',0,'LineNames',{{[]}},'Show" + "Content',true,'Placement',1)},'DisplayPropertyDefaults',struct('MinYLimReal','0.35212','MaxYLimReal','1.12256','YLa" + "belReal','','MinYLimMag','0.35212','MaxYLimMag','1.12256','LegendVisibility','off','XGrid',true,'YGrid',true,'PlotM" + "agPhase',false,'AxesColor',[0 0 0],'AxesTickColor',[0.686274509803922 0.686274509803922 0.686274509803922],'ColorOr" + "der',[0.0745098039215686 0.623529411764706 1;1 0.411764705882353 0.16078431372549;1 1 0.0666666666666667;0.71764705" + "8823529 0.274509803921569 1;0.392156862745098 0.831372549019608 0.0745098039215686;0.0588235294117647 1 1;1 0.07450" + "98039215686 0.650980392156863])),extmgr.Configuration('Tools','Plot Navigation',true,'PreviousAutoscale','XY'),extm" + "gr.Configuration('Tools','Measurements',true,'Version','2018b')),'Version','2018b','Position',[1 1 633 482],'Visibl" + "eAtModelOpen','on')" NumInputPorts "2" Floating off } @@ -16027,7 +16027,7 @@ Model { RequestExecContextInheritance off System { Name "Filter WindSpeed" - Location [1920, 23, 3712, 1120] + Location [0, 23, 1920, 1000] Open on PortBlocksUseCompactNotation off SetExecutionDomain off @@ -16351,15 +16351,14 @@ Model { "66666666666667;0.0745098039215686 0.623529411764706 1;1 0.411764705882353 0.16078431372549;0.392156862745098 0." "831372549019608 0.0745098039215686;0.717647058823529 0.274509803921569 1;0.0588235294117647 1 1;1 0.07450980392" "15686 0.650980392156863],'Title','%','LinePropertiesCache',{{}},'UserDefinedChannelNames',{{}},'Nu" - "mLines',2,'LineNames',{{'x','Saturate Integral Term'}},'ShowContent',true,'Placement',1)},'DisplayPropertyDefau" - "lts',struct('MinYLimReal','-0.01228','MaxYLimReal','0.01','YLabelReal','','MinYLimMag','0.00000','MaxYLimMag','" - "0.01228','LegendVisibility','Off','XGrid',true,'YGrid',true,'PlotMagPhase',false,'AxesColor',[0 0 0],'AxesTickC" - "olor',[0.686274509803922 0.686274509803922 0.686274509803922],'ColorOrder',[1 1 0.0666666666666667;0.0745098039" - "215686 0.623529411764706 1;1 0.411764705882353 0.16078431372549;0.392156862745098 0.831372549019608 0.074509803" - "9215686;0.717647058823529 0.274509803921569 1;0.0588235294117647 1 1;1 0.0745098039215686 0.650980392156863],'T" - "itle','%'),'DisplayContentCache',[]),extmgr.Configuration('Tools','Plot Navigation',true),extmgr.C" - "onfiguration('Tools','Measurements',true,'Version','2018b')),'Version','2018b','Position',[1 1 895 596],'Visibl" - "eAtModelOpen','on')" + "mLines',0,'LineNames',{{[]}},'ShowContent',true,'Placement',1)},'DisplayPropertyDefaults',struct('MinYLimReal'," + "'-0.01228','MaxYLimReal','0.01','YLabelReal','','MinYLimMag','0.00000','MaxYLimMag','0.01228','LegendVisibility" + "','Off','XGrid',true,'YGrid',true,'PlotMagPhase',false,'AxesColor',[0 0 0],'AxesTickColor',[0.686274509803922 0" + ".686274509803922 0.686274509803922],'ColorOrder',[1 1 0.0666666666666667;0.0745098039215686 0.623529411764706 1" + ";1 0.411764705882353 0.16078431372549;0.392156862745098 0.831372549019608 0.0745098039215686;0.717647058823529 " + "0.274509803921569 1;0.0588235294117647 1 1;1 0.0745098039215686 0.650980392156863],'Title','%'),'D" + "isplayContentCache',[]),extmgr.Configuration('Tools','Plot Navigation',true),extmgr.Configuration('Tools','Meas" + "urements',true,'Version','2018b')),'Version','2018b','Position',[1 1 633 482],'VisibleAtModelOpen','on')" NumInputPorts "2" Floating off } @@ -16894,7 +16893,7 @@ Model { ContentPreviewEnabled on System { Name "PitchSaturation" - Location [0, 23, 1920, 1000] + Location [0, 23, 1920, 1007] Open on PortBlocksUseCompactNotation off SetExecutionDomain off @@ -17128,15 +17127,14 @@ Model { ".0666666666666667;0.0745098039215686 0.623529411764706 1;1 0.411764705882353 0.16078431372549;0.392156862745098" " 0.831372549019608 0.0745098039215686;0.717647058823529 0.274509803921569 1;0.0588235294117647 1 1;1 0.07450980" "39215686 0.650980392156863],'Title','%','LinePropertiesCache',{{}},'UserDefinedChannelNames',{{}}," - "'NumLines',2,'LineNames',{{'x','Saturate Integral Term'}},'ShowContent',true,'Placement',1)},'DisplayPropertyDe" - "faults',struct('MinYLimReal','-2.01542','MaxYLimReal','0.83808','YLabelReal','','MinYLimMag','0.00000','MaxYLim" - "Mag','2.01542','LegendVisibility','Off','XGrid',true,'YGrid',true,'PlotMagPhase',false,'AxesColor',[0 0 0],'Axe" - "sTickColor',[0.686274509803922 0.686274509803922 0.686274509803922],'ColorOrder',[1 1 0.0666666666666667;0.0745" - "098039215686 0.623529411764706 1;1 0.411764705882353 0.16078431372549;0.392156862745098 0.831372549019608 0.074" - "5098039215686;0.717647058823529 0.274509803921569 1;0.0588235294117647 1 1;1 0.0745098039215686 0.6509803921568" - "63],'Title','%'),'DisplayContentCache',[]),extmgr.Configuration('Tools','Plot Navigation',true),ex" - "tmgr.Configuration('Tools','Measurements',true,'Version','2018b')),'Version','2018b','Position',[1 1 895 596],'" - "VisibleAtModelOpen','on')" + "'NumLines',0,'LineNames',{{[]}},'ShowContent',true,'Placement',1)},'DisplayPropertyDefaults',struct('MinYLimRea" + "l','-2.01542','MaxYLimReal','0.83808','YLabelReal','','MinYLimMag','0.00000','MaxYLimMag','2.01542','LegendVisi" + "bility','Off','XGrid',true,'YGrid',true,'PlotMagPhase',false,'AxesColor',[0 0 0],'AxesTickColor',[0.68627450980" + "3922 0.686274509803922 0.686274509803922],'ColorOrder',[1 1 0.0666666666666667;0.0745098039215686 0.62352941176" + "4706 1;1 0.411764705882353 0.16078431372549;0.392156862745098 0.831372549019608 0.0745098039215686;0.7176470588" + "23529 0.274509803921569 1;0.0588235294117647 1 1;1 0.0745098039215686 0.650980392156863],'Title','%'),'DisplayContentCache',[]),extmgr.Configuration('Tools','Plot Navigation',true),extmgr.Configuration('Tools'" + ",'Measurements',true,'Version','2018b')),'Version','2018b','Position',[1 1 633 482],'VisibleAtModelOpen','on')" NumInputPorts "2" Floating off } @@ -17796,15 +17794,15 @@ Model { "],'ColorOrder',[1 1 0.0666666666666667;0.0745098039215686 0.623529411764706 1;1 0.411764705882353 0.160784313725" "49;0.392156862745098 0.831372549019608 0.0745098039215686;0.717647058823529 0.274509803921569 1;0.05882352941176" "47 1 1;1 0.0745098039215686 0.650980392156863],'Title','%','LinePropertiesCache',{{}},'UserDefinedC" - "hannelNames',{{}},'NumLines',1,'LineNames',{{'Torque Controller'}},'ShowContent',true,'Placement',1)},'DisplayPr" - "opertyDefaults',struct('MinYLimReal','14040172.34833','MaxYLimReal','20244477.14617','YLabelReal','','MinYLimMag" - "','14040172.34833','MaxYLimMag','20244477.14617','LegendVisibility','off','XGrid',true,'YGrid',true,'PlotMagPhas" - "e',false,'AxesColor',[0 0 0],'AxesTickColor',[0.686274509803922 0.686274509803922 0.686274509803922],'ColorOrder" - "',[0.0745098039215686 0.623529411764706 1;1 0.411764705882353 0.16078431372549;1 1 0.0666666666666667;0.71764705" - "8823529 0.274509803921569 1;0.392156862745098 0.831372549019608 0.0745098039215686;0.0588235294117647 1 1;1 0.07" - "45098039215686 0.650980392156863])),extmgr.Configuration('Tools','Plot Navigation',true,'PreviousAutoscale','XY'" - "),extmgr.Configuration('Tools','Measurements',true,'Version','2018b')),'Version','2018b','Position',[1 1 895 596" - "],'VisibleAtModelOpen','on')" + "hannelNames',{{}},'NumLines',0,'LineNames',{{[]}},'ShowContent',true,'Placement',1)},'DisplayPropertyDefaults',s" + "truct('MinYLimReal','14040172.34833','MaxYLimReal','20244477.14617','YLabelReal','','MinYLimMag','14040172.34833" + "','MaxYLimMag','20244477.14617','LegendVisibility','off','XGrid',true,'YGrid',true,'PlotMagPhase',false,'AxesCol" + "or',[0 0 0],'AxesTickColor',[0.686274509803922 0.686274509803922 0.686274509803922],'ColorOrder',[0.074509803921" + "5686 0.623529411764706 1;1 0.411764705882353 0.16078431372549;1 1 0.0666666666666667;0.717647058823529 0.2745098" + "03921569 1;0.392156862745098 0.831372549019608 0.0745098039215686;0.0588235294117647 1 1;1 0.0745098039215686 0." + "650980392156863])),extmgr.Configuration('Tools','Plot Navigation',true,'PreviousAutoscale','XY'),extmgr.Configur" + "ation('Tools','Measurements',true,'Version','2018b')),'Version','2018b','Position',[1 1 633 482],'VisibleAtModel" + "Open','on')" NumInputPorts "1" Floating off } @@ -17820,7 +17818,7 @@ Model { ContentPreviewEnabled on System { Name "SetpointSmoother" - Location [1920, 23, 3712, 1120] + Location [0, 23, 1920, 1000] Open on PortBlocksUseCompactNotation off SetExecutionDomain off @@ -19427,14 +19425,14 @@ Model { "666666666667;0.0745098039215686 0.623529411764706 1;1 0.411764705882353 0.16078431372549;0.392156862745098 0.831" "372549019608 0.0745098039215686;0.717647058823529 0.274509803921569 1;0.0588235294117647 1 1;1 0.074509803921568" "6 0.650980392156863],'Title','%','LinePropertiesCache',{{}},'UserDefinedChannelNames',{{}},'NumLine" - "s',2,'LineNames',{{'Extract Signals/2','WE_Vw'}},'ShowContent',true,'Placement',1)},'DisplayPropertyDefaults',st" - "ruct('MinYLimReal','8.89309','MaxYLimReal','20.36941','YLabelReal','','MinYLimMag','8.89309','MaxYLimMag','20.36" - "941','LegendVisibility','Off','XGrid',true,'YGrid',true,'PlotMagPhase',false,'AxesColor',[0 0 0],'AxesTickColor'" - ",[0.686274509803922 0.686274509803922 0.686274509803922],'ColorOrder',[0.0745098039215686 0.623529411764706 1;1 " - "0.411764705882353 0.16078431372549;1 1 0.0666666666666667;0.717647058823529 0.274509803921569 1;0.39215686274509" - "8 0.831372549019608 0.0745098039215686;0.0588235294117647 1 1;1 0.0745098039215686 0.650980392156863])),extmgr.C" - "onfiguration('Tools','Plot Navigation',true,'PreviousAutoscale','XY'),extmgr.Configuration('Tools','Measurements" - "',true,'Version','2018b')),'Version','2018b','Position',[1 1 895 596],'VisibleAtModelOpen','on')" + "s',0,'LineNames',{{[]}},'ShowContent',true,'Placement',1)},'DisplayPropertyDefaults',struct('MinYLimReal','8.893" + "09','MaxYLimReal','20.36941','YLabelReal','','MinYLimMag','8.89309','MaxYLimMag','20.36941','LegendVisibility','" + "Off','XGrid',true,'YGrid',true,'PlotMagPhase',false,'AxesColor',[0 0 0],'AxesTickColor',[0.686274509803922 0.686" + "274509803922 0.686274509803922],'ColorOrder',[0.0745098039215686 0.623529411764706 1;1 0.411764705882353 0.16078" + "431372549;1 1 0.0666666666666667;0.717647058823529 0.274509803921569 1;0.392156862745098 0.831372549019608 0.074" + "5098039215686;0.0588235294117647 1 1;1 0.0745098039215686 0.650980392156863])),extmgr.Configuration('Tools','Plo" + "t Navigation',true,'PreviousAutoscale','XY'),extmgr.Configuration('Tools','Measurements',true,'Version','2018b')" + "),'Version','2018b','Position',[1 1 633 482],'VisibleAtModelOpen','on')" NumInputPorts "2" Floating off } @@ -20428,7 +20426,7 @@ Model { ContentPreviewEnabled on System { Name "WE_Params" - Location [1920, 23, 3712, 1120] + Location [0, 23, 1920, 1000] Open on PortBlocksUseCompactNotation off SetExecutionDomain off @@ -20551,26 +20549,26 @@ Model { "AxesTickColor',[0.686274509803922 0.686274509803922 0.686274509803922],'ColorOrder',[1 1 0.0666666666666667;0.07450" "98039215686 0.623529411764706 1;1 0.411764705882353 0.16078431372549;0.392156862745098 0.831372549019608 0.07450980" "39215686;0.717647058823529 0.274509803921569 1;0.0588235294117647 1 1;1 0.0745098039215686 0.650980392156863],'Titl" - "e','%','LinePropertiesCache',{{}},'UserDefinedChannelNames',{{}},'NumLines',1,'LineNames',{{'WE_w'}},'" - "ShowContent',true,'Placement',1),struct('MinYLimReal','14581185.40632','MaxYLimReal','20349315.3758','YLabelReal','" - "','MinYLimMag','0','MaxYLimMag','10','LegendVisibility','off','XGrid',true,'YGrid',true,'PlotMagPhase',false,'AxesC" - "olor',[0 0 0],'AxesTickColor',[0.686274509803922 0.686274509803922 0.686274509803922],'ColorOrder',[1 1 0.066666666" - "6666667;0.0745098039215686 0.623529411764706 1;1 0.411764705882353 0.16078431372549;0.392156862745098 0.83137254901" - "9608 0.0745098039215686;0.717647058823529 0.274509803921569 1;0.0588235294117647 1 1;1 0.0745098039215686 0.6509803" - "92156863],'Title','%','LinePropertiesCache',{{}},'UserDefinedChannelNames',{{}},'NumLines',1,'LineName" - "s',{{'WE_t'}},'ShowContent',true,'Placement',2),struct('MinYLimReal','-0.02807','MaxYLimReal','0.25267','YLabelReal" - "','','MinYLimMag','0','MaxYLimMag','10','LegendVisibility','off','XGrid',true,'YGrid',true,'PlotMagPhase',false,'Ax" - "esColor',[0 0 0],'AxesTickColor',[0.686274509803922 0.686274509803922 0.686274509803922],'ColorOrder',[1 1 0.066666" - "6666666667;0.0745098039215686 0.623529411764706 1;1 0.411764705882353 0.16078431372549;0.392156862745098 0.83137254" - "9019608 0.0745098039215686;0.717647058823529 0.274509803921569 1;0.0588235294117647 1 1;1 0.0745098039215686 0.6509" - "80392156863],'Title','%','LinePropertiesCache',{{}},'UserDefinedChannelNames',{{}},'NumLines',1,'LineN" - "ames',{{'WE_b'}},'ShowContent',true,'Placement',3)},'DisplayPropertyDefaults',struct('YLabelReal','','AxesColor',[0" - " 0 0],'AxesTickColor',[0.686274509803922 0.686274509803922 0.686274509803922],'ColorOrder',[0.0745098039215686 0.62" - "3529411764706 1;1 0.411764705882353 0.16078431372549;1 1 0.0666666666666667;0.717647058823529 0.274509803921569 1;0" - ".392156862745098 0.831372549019608 0.0745098039215686;0.0588235294117647 1 1;1 0.0745098039215686 0.650980392156863" - "]),'DisplayLayoutDimensions',[3 1],'DisplayContentCache',[]),extmgr.Configuration('Tools','Plot Navigation',true),e" - "xtmgr.Configuration('Tools','Measurements',true,'Version','2018b')),'Version','2018b','Position',[1 1 895 596],'Vis" - "ibleAtModelOpen','on')" + "e','%','LinePropertiesCache',{{}},'UserDefinedChannelNames',{{}},'NumLines',0,'LineNames',{{[]}},'Show" + "Content',true,'Placement',1),struct('MinYLimReal','14581185.40632','MaxYLimReal','20349315.3758','YLabelReal','','M" + "inYLimMag','0','MaxYLimMag','10','LegendVisibility','off','XGrid',true,'YGrid',true,'PlotMagPhase',false,'AxesColor" + "',[0 0 0],'AxesTickColor',[0.686274509803922 0.686274509803922 0.686274509803922],'ColorOrder',[1 1 0.0666666666666" + "667;0.0745098039215686 0.623529411764706 1;1 0.411764705882353 0.16078431372549;0.392156862745098 0.831372549019608" + " 0.0745098039215686;0.717647058823529 0.274509803921569 1;0.0588235294117647 1 1;1 0.0745098039215686 0.65098039215" + "6863],'Title','%','LinePropertiesCache',{{}},'UserDefinedChannelNames',{{}},'NumLines',0,'LineNames',{" + "{[]}},'ShowContent',true,'Placement',2),struct('MinYLimReal','-0.02807','MaxYLimReal','0.25267','YLabelReal','','Mi" + "nYLimMag','0','MaxYLimMag','10','LegendVisibility','off','XGrid',true,'YGrid',true,'PlotMagPhase',false,'AxesColor'" + ",[0 0 0],'AxesTickColor',[0.686274509803922 0.686274509803922 0.686274509803922],'ColorOrder',[1 1 0.06666666666666" + "67;0.0745098039215686 0.623529411764706 1;1 0.411764705882353 0.16078431372549;0.392156862745098 0.831372549019608 " + "0.0745098039215686;0.717647058823529 0.274509803921569 1;0.0588235294117647 1 1;1 0.0745098039215686 0.650980392156" + "863],'Title','%','LinePropertiesCache',{{}},'UserDefinedChannelNames',{{}},'NumLines',0,'LineNames',{{" + "[]}},'ShowContent',true,'Placement',3)},'DisplayPropertyDefaults',struct('YLabelReal','','AxesColor',[0 0 0],'AxesT" + "ickColor',[0.686274509803922 0.686274509803922 0.686274509803922],'ColorOrder',[0.0745098039215686 0.62352941176470" + "6 1;1 0.411764705882353 0.16078431372549;1 1 0.0666666666666667;0.717647058823529 0.274509803921569 1;0.39215686274" + "5098 0.831372549019608 0.0745098039215686;0.0588235294117647 1 1;1 0.0745098039215686 0.650980392156863]),'DisplayL" + "ayoutDimensions',[3 1],'DisplayContentCache',[]),extmgr.Configuration('Tools','Plot Navigation',true),extmgr.Config" + "uration('Tools','Measurements',true,'Version','2018b')),'Version','2018b','Position',[1 1 633 482],'VisibleAtModelO" + "pen','on')" NumInputPorts "3" Floating off } @@ -21323,9 +21321,6 @@ Stateflow { screen [1 1 3600 1200 1.180555555555556] treeNode [0 3 0 0] viewObj 2 - visible 1 - subviewS { - } ssIdHighWaterMark 5 decomposition CLUSTER_CHART type EML_CHART @@ -21449,9 +21444,6 @@ Stateflow { screen [1 1 3600 1200 1.180555555555556] treeNode [0 10 0 0] viewObj 9 - visible 1 - subviewS { - } ssIdHighWaterMark 24 decomposition CLUSTER_CHART type EML_CHART @@ -21978,9 +21970,6 @@ Stateflow { screen [1 1 3600 1200 1.180555555555556] treeNode [0 32 0 0] viewObj 31 - visible 1 - subviewS { - } ssIdHighWaterMark 9 decomposition CLUSTER_CHART type EML_CHART diff --git a/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_Onshore_ElastoDyn.dat b/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_Onshore_ElastoDyn.dat index 46c89f7d6..5c9eb6f36 100644 --- a/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_Onshore_ElastoDyn.dat +++ b/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_Onshore_ElastoDyn.dat @@ -154,6 +154,6 @@ True TabDelim - Use tab delimiters in text tabular output file? (fla "TwrBsMyt" - Side-to-side bending, fore-aft bending, and yaw moments at the base of the tower (mudline) "TwrBsMzt" - Side-to-side bending, fore-aft bending, and yaw moments at the base of the tower (mudline) "NcIMURAys" - Nacelle IMU rotational acceleration in the nodding direction -"NcIMUTAxs" - Nacelle IMU rotational acceleration in the streamwise direction +"NcIMUTAxs" - Nacelle IMU translational acceleration in the streamwise direction END of input file (the word "END" must appear in the first 3 columns of this last OutList line) --------------------------------------------------------------------------------------- From 0032cdc285700e83ba8d3649ef0dabf2bfc0bc1d Mon Sep 17 00:00:00 2001 From: dzalkind Date: Mon, 1 Mar 2021 11:32:53 -0700 Subject: [PATCH 23/34] Point submodule to main --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 34f458082..d9da4963b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "ROSCO"] path = ROSCO url = https://github.com/NREL/ROSCO - branch = develop \ No newline at end of file + branch = main \ No newline at end of file From 72bbaf812f1db0de51db74104c7a6ef3ac42e7b1 Mon Sep 17 00:00:00 2001 From: dzalkind Date: Mon, 1 Mar 2021 11:55:02 -0700 Subject: [PATCH 24/34] Update version and names in __init__.py --- ROSCO_toolbox/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ROSCO_toolbox/__init__.py b/ROSCO_toolbox/__init__.py index 6dfaca7ea..63c851566 100644 --- a/ROSCO_toolbox/__init__.py +++ b/ROSCO_toolbox/__init__.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """Top-level package for ROSCO_toolbox Repo.""" -__author__ = """Nikhar J. Abbas and Paul Fleming""" +__author__ = """Nikhar J. Abbas and Daniel S. Zalkind""" __email__ = 'nikhar.abbas@nrel.gov' -__version__ = '2.1.1' \ No newline at end of file +__version__ = '2.2.0' \ No newline at end of file From f46682270e6716066286b20a9f4c4b34d81a27fe Mon Sep 17 00:00:00 2001 From: dzalkind Date: Mon, 1 Mar 2021 15:05:38 -0700 Subject: [PATCH 25/34] Point Test_Cases/ to ROSCO in install/lib --- Test_Cases/BAR_10/BAR_10_ServoDyn.dat | 2 +- .../IEA-15-240-RWT-UMaineSemi_ServoDyn.dat | 2 +- Test_Cases/NREL-5MW/NRELOffshrBsline5MW_Onshore_ServoDyn.dat | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Test_Cases/BAR_10/BAR_10_ServoDyn.dat b/Test_Cases/BAR_10/BAR_10_ServoDyn.dat index 515796534..a429c67df 100644 --- a/Test_Cases/BAR_10/BAR_10_ServoDyn.dat +++ b/Test_Cases/BAR_10/BAR_10_ServoDyn.dat @@ -63,7 +63,7 @@ False CompNTMD - Compute nacelle tuned mass damper {true/fal False CompTTMD - Compute tower tuned mass damper {true/false} (flag) "b.dat" TTMDfile - Name of the file for tower tuned mass damper (quoted string) [unused when CompTTMD is false] ---------------------- BLADED INTERFACE ---------------------------------------- [used only with Bladed Interface] -"../../ROSCO/build/libdiscon.dylib" DLL_FileName - Name/location of the dynamic library {.dll [Windows] or .so [Linux]} in the Bladed-DLL format (-) [used only with Bladed Interface] +"../../ROSCO/install/lib/libdiscon.dylib" DLL_FileName - Name/location of the dynamic library {.dll [Windows] or .so [Linux]} in the Bladed-DLL format (-) [used only with Bladed Interface] "BAR_10_DISCON.IN" DLL_InFile - Name of input file sent to the DLL (-) [used only with Bladed Interface] "DISCON" DLL_ProcName - Name of procedure in DLL to be called (-) [case sensitive; used only with DLL Interface] "default" DLL_DT - Communication interval for dynamic library (s) (or "default") [used only with Bladed Interface] diff --git a/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_ServoDyn.dat b/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_ServoDyn.dat index 92c9b2fed..c86a078d0 100644 --- a/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_ServoDyn.dat +++ b/Test_Cases/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_ServoDyn.dat @@ -63,7 +63,7 @@ False CompNTMD - Compute nacelle tuned mass damper {true/fal False CompTTMD - Compute tower tuned mass damper {true/false} (flag) "unused" TTMDfile - Name of the file for tower tuned mass damper (quoted string) [unused when CompTTMD is false] ---------------------- BLADED INTERFACE ---------------------------------------- [used only with Bladed Interface] -"../../ROSCO/build/libdiscon.dylib" DLL_FileName - Name/location of the dynamic library {.dll [Windows] or .so [Linux]} in the Bladed-DLL format (-) [used only with Bladed Interface] +"../../ROSCO/install/lib/libdiscon.dylib" DLL_FileName - Name/location of the dynamic library {.dll [Windows] or .so [Linux]} in the Bladed-DLL format (-) [used only with Bladed Interface] "ServoData/DISCON-UMaineSemi.IN" DLL_InFile - Name of input file sent to the DLL (-) [used only with Bladed Interface] "DISCON" DLL_ProcName - Name of procedure in DLL to be called (-) [case sensitive; used only with DLL Interface] "default" DLL_DT - Communication interval for dynamic library (s) (or "default") [used only with Bladed Interface] diff --git a/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_Onshore_ServoDyn.dat b/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_Onshore_ServoDyn.dat index d55c09b7a..47961d9cd 100644 --- a/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_Onshore_ServoDyn.dat +++ b/Test_Cases/NREL-5MW/NRELOffshrBsline5MW_Onshore_ServoDyn.dat @@ -63,7 +63,7 @@ False CompNTMD - Compute nacelle tuned mass damper {true/false} (fla False CompTTMD - Compute tower tuned mass damper {true/false} (flag) "../5MW_Baseline/NRELOffshrBsline5MW_ServoDyn_TMD.dat" TTMDfile - Name of the file for tower tuned mass damper (quoted string) [unused when CompTTMD is false] ---------------------- BLADED INTERFACE ---------------------------------------- [used only with Bladed Interface] -"../../ROSCO/build/libdiscon.dylib" DLL_FileName - Name/location of the dynamic library {.dll [Windows] or .so [Linux]} in the Bladed-DLL format (-) [used only with Bladed Interface] +"../../ROSCO/install/lib/libdiscon.dylib" DLL_FileName - Name/location of the dynamic library {.dll [Windows] or .so [Linux]} in the Bladed-DLL format (-) [used only with Bladed Interface] "DISCON.IN" DLL_InFile - Name of input file sent to the DLL (-) [used only with Bladed Interface] "DISCON" DLL_ProcName - Name of procedure in DLL to be called (-) [case sensitive; used only with DLL Interface] "default" DLL_DT - Communication interval for dynamic library (s) (or "default") [used only with Bladed Interface] From 08d60446c1c877dfb7effae773eb4a3cd6b47fce Mon Sep 17 00:00:00 2001 From: dzalkind Date: Mon, 1 Mar 2021 15:37:38 -0700 Subject: [PATCH 26/34] Break lines up for readability, minor edits, re-organize TOC --- docs/index.rst | 3 +-- docs/source/install.rst | 45 +++++++++++++++++++++++++---------- docs/source/rosco.rst | 1 - docs/source/rosco_toolbox.rst | 3 +-- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index d10cc29eb..b6f6eaec4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,8 +1,7 @@ .. toctree:: - :hidden: - source/standard_use.rst source/install.rst + source/standard_use.rst source/rosco_toolbox.rst source/rosco.rst diff --git a/docs/source/install.rst b/docs/source/install.rst index 63bab7011..45b3e2fb0 100644 --- a/docs/source/install.rst +++ b/docs/source/install.rst @@ -1,28 +1,37 @@ .. toctree:: - :max_depth: 3 .. _install: Installing the ROSCO tools =========================== -Both the ROSCO controller and ROSCO toolbox should be installed if one wishes to leverage the full ROSCO toolchain. Of course, some users may only wish to download and install only the controller or the toolbox. +Both the ROSCO controller and ROSCO toolbox should be installed if one wishes to leverage the full ROSCO toolchain. +Of course, some users may only wish to download and install only the controller or the toolbox. -For users wishing to use just the ROSCO toolbox or the ROSCO toolbox and controller, please skip to the section on section :ref:`installing_rt`. Here you will provide the necessary steps to install the ROSCO toolbox and the ROSCO controller simultaneously. For users planning to only download and compile the ROSCO controller, please follow the instructions on :ref:`compiling_rosco`. For information on best practices to update to the most recent version of the ROSCO toolbox, see :ref:`updating_rt`. +For users wishing to use just the ROSCO toolbox or the ROSCO toolbox and controller, please skip to the section on section :ref:`installing_rt`. +Here we will provide the necessary steps to install the ROSCO toolbox and the ROSCO controller simultaneously. +For users planning to only download and compile the ROSCO controller, please follow the instructions on :ref:`compiling_rosco`. +For information on best practices to update to the most recent version of the ROSCO toolbox, see :ref:`updating_rt`. .. _compiling_rosco: Compiling ROSCO ---------------- -The standard ROSCO controller is based in Fortran and must be compiled. This code can be found at: https://github.com/NREL/ROSCO. Of course, the advanced user can compile the downloaded code using their own desired methods (e.g. Visual Studio). Otherwise, a few of the more common compiling methods are detailed on this page. Additionally, the most recent tagged version releases are `available for download `_. +The standard ROSCO controller is based in Fortran and must be compiled; this code can be found at: https://github.com/NREL/ROSCO. +Of course, the advanced user can compile the downloaded code using their own desired methods (e.g. Visual Studio). +Otherwise, a few of the more common compiling methods are detailed on this page. +Additionally, the most recent tagged version releases are `available for download `_. -If one wishes to download the code via the command line, we provide two supported options. For non-developers (those not interested in modifying the source code), the controller can be downloaded via Anaconda. For developers, CMake can be used to compile the Fortran code. +If one wishes to download the code via the command line, we provide two supported options. +For non-developers (those not interested in modifying the source code), the controller can be downloaded via Anaconda. +For developers, CMake can be used to compile the Fortran code. Anaconda for non-developers: ............................. -For users familiar with Anaconda_, ROSCO is available through the conda-forge channel. In order to download the compiled, most recent version release, from an anaconda powershell (Windows) or terminal (Mac/Linux) window, one can create a new anaconda virtual environment: +For users familiar with Anaconda_, ROSCO is 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: :: conda config --add channels conda-forge @@ -39,7 +48,8 @@ and download the controller: conda install -y ROSCO -This will download a compiled ROSCO binary file into the default filepath for any dynamic libraries downloaded via anaconda while in the ROSCO-env. This can be copied to your desired folder using: +This will download a compiled ROSCO binary file into the default filepath for any dynamic libraries downloaded via anaconda while in the ROSCO-env. +The ROSCO binary file can be copied to your desired folder using: :: cp $CONDA_PREFIX/lib/libdiscon.* . @@ -47,7 +57,9 @@ This will download a compiled ROSCO binary file into the default filepath for an CMake for developers: ..................... -CMake_ provides a straightforward option for many users, particularly those on a Mac or Linux. For windows users, we recommend using MinGW_ to compile similarly. ROSCO can be compiled by first cloning the source code from git using: +CMake_ provides a straightforward option for many users, particularly those on a Mac or Linux. +For windows users, we recommend using MinGW_ to compile similarly. +ROSCO can be compiled by first cloning the source code from git using: :: git clone https://github.com/NREL/ROSCO.git @@ -60,17 +72,18 @@ And then compiling using CMake: cd build cmake .. # Mac/Linus cmake .. -G "MinGW Makefiles" # Windows - make + make install -This will generate a file titled :code:`libdiscon.*` in the :code:`/ROSCO/install/lib` directory. +This will generate a file called :code:`libdiscon.*` in the :code:`/ROSCO/install/lib` directory. -Note: when compiling with MinGW on Windows, modifying the cmake line (4th commant) in the above code block to :code:`cmake .. -G "MinGWMakefiles" -DCMake_Fortran_COMPILER=gfortran` may solve compiler errors that may arise, depending on your local configuration. +Note: when compiling with MinGW on Windows, modifying the cmake line (4th command) in the above code block to :code:`cmake .. -G "MinGWMakefiles" -DCMake_Fortran_COMPILER=gfortran` may solve compiler errors that may arise, depending on your local configuration. .. _installing_rt: Installing the ROSCO toolbox ---------------------------- -Installation of the complete ROSCO toolbox is made easy through `Anaconda `_. If you do not already have Anaconda installed on your machine, please install it. +Installation of the complete ROSCO toolbox is made easy through `Anaconda `_. +If you do not already have Anaconda installed on your machine, please install it. Then please follow the following steps: @@ -88,7 +101,8 @@ Then please follow the following steps: conda install -y wisdem -You should then do step three *or* four. If you do not want to compile the ROSCO controller within the installation of the ROSCO toolbox, please follow the instructions for :ref:`compiling_rosco`. +You should then do step three *or* four. +If you do not want to compile the ROSCO controller within the installation of the ROSCO toolbox, please follow the instructions for :ref:`compiling_rosco`. 3. Clone and Install the ROSCO toolbox with ROSCO :: @@ -133,3 +147,8 @@ and then recompile and reinstall as necessary... .. _Anaconda: https://www.anaconda.com/ .. _CMake: https://cmake.org/ .. _MinGW: https://mingw-w64.org/ + + +Getting Started with the ROSCO Toolbox +-------------------------------------- +Please see a the :ref:`standard_use` for several example scripts using ROSCO and the ROSCO_toolbox. diff --git a/docs/source/rosco.rst b/docs/source/rosco.rst index e539680eb..30577e173 100644 --- a/docs/source/rosco.rst +++ b/docs/source/rosco.rst @@ -1,5 +1,4 @@ .. toctree:: - :max_depth: 1 .. _rosco: diff --git a/docs/source/rosco_toolbox.rst b/docs/source/rosco_toolbox.rst index 86566b78c..61a837957 100644 --- a/docs/source/rosco_toolbox.rst +++ b/docs/source/rosco_toolbox.rst @@ -1,5 +1,4 @@ .. toctree:: - :max_depth: 1 .. _rosco_toolbox: @@ -37,7 +36,7 @@ A simulink implementation of the ROSCO controller is included in the Matlab Tool 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* -........... +............ Example OpenFAST models consistent with OpenFAST's master branch are provided here for simple testing and simulation cases. *Tune_Cases* From 53ed6f0a9f71522c3cb3da6f219b3e24a0d822f4 Mon Sep 17 00:00:00 2001 From: dzalkind Date: Tue, 2 Mar 2021 17:32:10 -0700 Subject: [PATCH 27/34] Revise documentation --- docs/source/rosco.rst | 9 ++++++--- docs/source/rosco_toolbox.rst | 6 +++--- docs/source/standard_use.rst | 27 ++++++++++++++------------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/docs/source/rosco.rst b/docs/source/rosco.rst index 30577e173..2317c6ce5 100644 --- a/docs/source/rosco.rst +++ b/docs/source/rosco.rst @@ -9,7 +9,7 @@ Here, we give an overview of the structure of the ROSCO controller and how the c ----- File Structure ---------------- +-------------- The primary functions of the ROSCO toolbox are separated into several files. They include the following: * :code:`DISCON.f90` is the primary driver function. @@ -19,12 +19,15 @@ The primary functions of the ROSCO toolbox are separated into several files. The * :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. .. _discon_in: The DISCON.IN file ------------------------------ -A standard file structure is used as an input to the ROSCO controller. This is, generically, dubbed the DISCON.IN file, though it can be renamed (In OpenFAST_, this file is pointed to by :code:`DLL_InFile` in the ServoDyn file. Examples of the DISCON.IN file are found in each of the Test Cases in the ROSCO toolbox, and in the :code:`parameter_files` folder of ROSCO. +A standard file structure is used as an input to the ROSCO controller. +This is, generically, dubbed the DISCON.IN file, though it can be renamed (In OpenFAST_, this file is pointed to by :code:`DLL_InFile` in the ServoDyn file. +Examples of the DISCON.IN file are found in each of the Test Cases in the ROSCO toolbox, and in the :code:`parameter_files` folder of ROSCO. .. list-table:: DISCON.IN :header-rows: 1 @@ -74,7 +77,7 @@ A standard file structure is used as an input to the ROSCO controller. This is, * - - :code:`PS_Mode` - Int - - Pitch saturation mode. 0: no pitch saturation, 1: implement pitch saturation} + - Pitch saturation mode. 0: no pitch saturation, 1: implement pitch saturation * - - :code:`SD_Mode` - Int diff --git a/docs/source/rosco_toolbox.rst b/docs/source/rosco_toolbox.rst index 61a837957..d51d9b370 100644 --- a/docs/source/rosco_toolbox.rst +++ b/docs/source/rosco_toolbox.rst @@ -25,7 +25,7 @@ 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 +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* ................ @@ -37,7 +37,7 @@ Testing scripts for the ROSCO toolbox are held here and showcased with :code:`ru *Test_Cases* ............ -Example OpenFAST models consistent with OpenFAST's master branch are provided here for simple testing and simulation cases. +Example OpenFAST models consistent with the latest release of OpenFAST are provided here for simple testing and simulation cases. *Tune_Cases* ............ @@ -113,7 +113,7 @@ A yaml_ formatted input file is used for the standard ROSCO toolbox tuning proce - :code:`bld_edgewise_freq` - Yes - Float - - Blade edgewise first natural frequency [rad/s]. + - Blade edgewise first natural frequency [rad/s]. Set this even if you are using stiff blades. It becomes the generator speed LPF bandwidth. * - - :code:`TSR_operational` - No diff --git a/docs/source/standard_use.rst b/docs/source/standard_use.rst index 40fbfda73..829185e0a 100644 --- a/docs/source/standard_use.rst +++ b/docs/source/standard_use.rst @@ -11,14 +11,15 @@ A set of `example scripts `_. -The controller tuning .yaml are located in `Tune_Cases/ `_; a detailed description of these parameters is located here. **TODO: add link** +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:`example_01.py` loads an OpenFAST turbine model and displays a summary of its information -* :code:`example_02.py` plots the C_p surface of a turbine +* :code:`example_02.py` plots the :math:`C_p` surface of a turbine -ROSCO requires the power and thrust coefficients for tuning control parameters and running the extended Kalman filter wind speed estimator. +ROSCO requires the power and thrust coefficients for tuning control inputs and running the extended Kalman filter wind speed estimator. * :code:`example_03.py` runs cc-blade, a blade element momentum solver from WISDEM, to generate a :math:`C_p` surface. @@ -28,27 +29,31 @@ This file can be located wherever you desire, just be sure to point to it proper Tuning Controllers and Generating DISCON.IN ------------------------------------------- -The ROSCO_turbine object, which contains turbine information required for controller tuning, along with control parameters in the tuning yaml and the Cp surface are used to generate control parameters and DISCON.IN files. +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 increase loading on the turbine. +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:`example_04.py` loads a turbine and tunes the PI control gains * :code:`example_05.py` tunes a controller and runs a simple simualtion (not using OpenFAST) -* :code:`example_06.py` loads a turbine, tunes a controller, and runs an OpenFAST simulations +* :code:`example_06.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:: + + 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:`example_07.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): +ROSCO also contains a method for distributed aerodynamic control (e.g., via trailing edge flaps): * :code:`example_10.py` tunes a controller for distributed aerodynamic control @@ -69,14 +74,10 @@ If called from OpenFAST, the main OpenFAST input points to the ServoDyn input, w 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 "../../ROSCO/build/libdiscon.dylib" as the :code:`DLL_FileName` input and :code:`"DISCON.IN"` as the :code:`DLL_InFile` 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 -OpenFAST can be installed from `source `_ or from conda using:: - - conda install -c conda-forge openfast - The ROSCO_toolbox has methods for running OpenFAST (and other) binary executables using system calls, as well as post-processing tools in `ofTools/ `_. For more extensive post-processing tools, please see pCrunch (link). From d647d0aa5ec4a479f4d83ce4edcf91aa3e0af622 Mon Sep 17 00:00:00 2001 From: dzalkind Date: Tue, 2 Mar 2021 17:38:54 -0700 Subject: [PATCH 28/34] Revise documentation 2 --- docs/source/standard_use.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/source/standard_use.rst b/docs/source/standard_use.rst index 829185e0a..19f688dd7 100644 --- a/docs/source/standard_use.rst +++ b/docs/source/standard_use.rst @@ -79,7 +79,6 @@ For example in `Test_Cases/NREL-5MW`: * :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/ `_. -For more extensive post-processing tools, please see pCrunch (link). Several example scripts are set up to quickly simulate ROSCO with OpenFAST: From b3ab9c689ae100b866b091a11615f6e28b5b2aa5 Mon Sep 17 00:00:00 2001 From: dzalkind Date: Wed, 3 Mar 2021 17:53:35 -0700 Subject: [PATCH 29/34] Update gitignore, DISCON example --- .gitignore | 7 ++-- Examples/DISCON.IN | 86 +++++++++++++++++++++++----------------------- 2 files changed, 46 insertions(+), 47 deletions(-) diff --git a/.gitignore b/.gitignore index 3da1c9327..ad2f8c950 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ _build *.out *.outb *.dbg +*.vtp # ROSCO files *.85 @@ -48,13 +49,11 @@ examples/cp_ct_cq_lut.p Examples/DISCON.IN Examples/*.p -# Matlab Stuff -Matlab_Toolbox/*.slxc -*.mat - # Exclude testing results ROSCO_testing/results/ # Simulink/Matlab temp files *.slxc *.autosave +*.mat + diff --git a/Examples/DISCON.IN b/Examples/DISCON.IN index c9b428262..cd69e3701 100644 --- a/Examples/DISCON.IN +++ b/Examples/DISCON.IN @@ -1,45 +1,45 @@ -! Controller parameter input file for the IEA-15-240-RWT-UMaineSemi wind turbine -! - File written using ROSCO version 2.1.1 controller tuning logic on 02/08/21 +! Controller parameter input file for the NREL-5MW wind turbine +! - File written using ROSCO version 2.2.0 controller tuning logic on 03/02/21 !------- DEBUG ------------------------------------------------------------ 1 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: write standard output .dbg-file and complete avrSWAP-array .dbg2-file} !------- CONTROLLER FLAGS ------------------------------------------------- -2 ! F_LPFType - {1: first-order low-pass filter, 2: second-order low-pass filter}, [rad/s] (currently filters generator speed and pitch control signals -2 ! F_NotchType - Notch on the measured generator speed and/or tower fore-aft motion (for floating) {0: disable, 1: generator speed, 2: tower-top fore-aft motion, 3: generator speed and tower-top fore-aft motion} +1 ! F_LPFType - {1: first-order low-pass filter, 2: second-order low-pass filter}, [rad/s] (currently filters generator speed and pitch control signals +0 ! F_NotchType - Notch on the measured generator speed and/or tower fore-aft motion (for floating) {0: disable, 1: generator speed, 2: tower-top fore-aft motion, 3: generator speed and tower-top fore-aft motion} 0 ! IPC_ControlMode - Turn Individual Pitch Control (IPC) for fatigue load reductions (pitch contribution) {0: off, 1: 1P reductions, 2: 1P+2P reductions} 2 ! VS_ControlMode - Generator torque control mode in above rated conditions {0: constant torque, 1: constant power, 2: TSR tracking PI control} 1 ! PC_ControlMode - Blade pitch control mode {0: No pitch, fix to fine pitch, 1: active PI blade pitch control} 0 ! Y_ControlMode - Yaw control mode {0: no yaw control, 1: yaw rate control, 2: yaw-by-IPC} 1 ! SS_Mode - Setpoint Smoother mode {0: no setpoint smoothing, 1: introduce setpoint smoothing} -2 ! WE_Mode - Wind speed estimator mode {0: One-second low pass filtered hub height wind speed, 1: Immersion and Invariance Estimator, 2: Extended Kalman Filter} -1 ! PS_Mode - Pitch saturation mode {0: no pitch saturation, 1: implement pitch saturation} +0 ! WE_Mode - Wind speed estimator mode {0: One-second low pass filtered hub height wind speed, 1: Immersion and Invariance Estimator, 2: Extended Kalman Filter} +0 ! PS_Mode - Pitch saturation mode {0: no pitch saturation, 1: implement pitch saturation} 0 ! SD_Mode - Shutdown mode {0: no shutdown procedure, 1: pitch to max pitch at shutdown} -1 ! Fl_Mode - Floating specific feedback mode {0: no nacelle velocity feedback, 1: nacelle velocity feedback} +0 ! Fl_Mode - Floating specific feedback mode {0: no nacelle velocity feedback, 1: nacelle velocity feedback} 0 ! Flp_Mode - Flap control mode {0: no flap control, 1: steady state flap angle, 2: Proportional flap control} !------- FILTERS ---------------------------------------------------------- -1.00810 ! F_LPFCornerFreq - Corner frequency (-3dB point) in the low-pass filters, [rad/s] -0.70000 ! F_LPFDamping - Damping coefficient {used only when F_FilterType = 2} [-] -3.35500 ! F_NotchCornerFreq - Natural frequency of the notch filter, [rad/s] +1.57080 ! F_LPFCornerFreq - Corner frequency (-3dB point) in the low-pass filters, [rad/s] +0.00000 ! F_LPFDamping - Damping coefficient {used only when F_FilterType = 2} [-] +0.44990 ! F_NotchCornerFreq - Natural frequency of the notch filter, [rad/s] 0.00000 0.25000 ! F_NotchBetaNumDen - Two notch damping values (numerator and denominator, resp) - determines the width and depth of the notch, [-] 0.628320000000 ! F_SSCornerFreq - Corner frequency (-3dB point) in the first order low pass filter for the setpoint smoother, [rad/s]. -0.21300 1.00000 ! F_FlCornerFreq - Natural frequency and damping in the second order low pass filter of the tower-top fore-aft motion for floating feedback control [rad/s, -]. -1.16240 1.00000 ! F_FlpCornerFreq - Corner frequency and damping in the second order low pass filter of the blade root bending moment for flap control [rad/s, -]. +0.23250 1.00000 ! F_FlCornerFreq - Natural frequency and damping in the second order low pass filter of the tower-top fore-aft motion for floating feedback control [rad/s, -]. +0.00000 1.00000 ! F_FlpCornerFreq - Corner frequency and damping in the second order low pass filter of the blade root bending moment for flap control [rad/s, -]. !------- BLADE PITCH CONTROL ---------------------------------------------- 29 ! PC_GS_n - Amount of gain-scheduling table entries -0.061302 0.088725 0.110460 0.129231 0.146101 0.161618 0.176096 0.189763 0.202765 0.215213 0.227190 0.238754 0.249961 0.260854 0.271463 0.281817 0.291944 0.301857 0.311577 0.321120 0.330501 0.339728 0.348811 0.357760 0.366583 0.375288 0.383879 0.392362 0.400744 ! PC_GS_angles - Gain-schedule table: pitch angles [rad]. --1.918261 -1.686902 -1.496241 -1.336407 -1.200485 -1.083480 -0.981701 -0.892358 -0.813301 -0.742853 -0.679678 -0.622707 -0.571067 -0.524044 -0.481046 -0.441577 -0.405219 -0.371619 -0.340474 -0.311524 -0.284547 -0.259345 -0.235751 -0.213614 -0.192804 -0.173205 -0.154715 -0.137241 -0.120702 ! PC_GS_KP - Gain-schedule table: pitch controller kp gains [s]. --0.295306 -0.266827 -0.243358 -0.223684 -0.206953 -0.192551 -0.180022 -0.169025 -0.159294 -0.150622 -0.142846 -0.135833 -0.129477 -0.123688 -0.118396 -0.113537 -0.109062 -0.104926 -0.101092 -0.097529 -0.094208 -0.091106 -0.088202 -0.085477 -0.082915 -0.080503 -0.078227 -0.076076 -0.074040 ! PC_GS_KI - Gain-schedule table: pitch controller ki gains [-]. +0.053498 0.080572 0.102097 0.120792 0.137663 0.153253 0.167904 0.181791 0.195038 0.207781 0.220073 0.231967 0.243542 0.254797 0.265780 0.276517 0.287028 0.297323 0.307421 0.317353 0.327124 0.336738 0.346201 0.355521 0.364707 0.373767 0.382706 0.391527 0.400242 ! PC_GS_angles - Gain-schedule table: pitch angles [rad]. +-0.014943 -0.013093 -0.011578 -0.010316 -0.009247 -0.008330 -0.007536 -0.006840 -0.006226 -0.005681 -0.005192 -0.004753 -0.004355 -0.003993 -0.003663 -0.003360 -0.003082 -0.002824 -0.002586 -0.002365 -0.002159 -0.001967 -0.001787 -0.001618 -0.001460 -0.001311 -0.001170 -0.001038 -0.000912 ! PC_GS_KP - Gain-schedule table: pitch controller kp gains [s]. +-0.005486 -0.004939 -0.004492 -0.004118 -0.003802 -0.003531 -0.003296 -0.003091 -0.002909 -0.002748 -0.002604 -0.002474 -0.002356 -0.002249 -0.002151 -0.002062 -0.001979 -0.001903 -0.001833 -0.001768 -0.001707 -0.001650 -0.001597 -0.001547 -0.001500 -0.001456 -0.001414 -0.001375 -0.001338 ! PC_GS_KI - Gain-schedule table: pitch controller ki gains [-]. 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ! PC_GS_KD - Gain-schedule table: pitch controller kd gains 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ! PC_GS_TF - Gain-schedule table: pitch controller tf gains (derivative filter) 1.570800000000 ! PC_MaxPit - Maximum physical pitch limit, [rad]. -0.000000000000 ! PC_MinPit - Minimum physical pitch limit, [rad]. -0.034900000000 ! PC_MaxRat - Maximum pitch rate (in absolute value) in pitch controller, [rad/s]. --0.03490000000 ! PC_MinRat - Minimum pitch rate (in absolute value) in pitch controller, [rad/s]. -0.791680000000 ! PC_RefSpd - Desired (reference) HSS speed for pitch controller, [rad/s]. -0.000000000000 ! PC_FinePit - Record 5: Below-rated pitch angle set-point, [rad] +-0.00873000000 ! PC_MinPit - Minimum physical pitch limit, [rad]. +0.174500000000 ! PC_MaxRat - Maximum pitch rate (in absolute value) in pitch controller, [rad/s]. +-0.17450000000 ! PC_MinRat - Minimum pitch rate (in absolute value) in pitch controller, [rad/s]. +122.9096700000 ! PC_RefSpd - Desired (reference) HSS speed for pitch controller, [rad/s]. +-0.00873000000 ! PC_FinePit - Record 5: Below-rated pitch angle set-point, [rad] 0.017450000000 ! PC_Switch - Angle above lowest minimum pitch angle for switch, [rad] !------- INDIVIDUAL PITCH CONTROL ----------------------------------------- @@ -49,38 +49,38 @@ 0.0 ! IPC_CornerFreqAct - Corner frequency of the first-order actuators model, to induce a phase lag in the IPC signal {0: Disable}, [rad/s] !------- VS TORQUE CONTROL ------------------------------------------------ -96.55000000000 ! VS_GenEff - Generator efficiency mechanical power -> electrical power, [should match the efficiency defined in the generator properties!], [%] -19624046.66639 ! VS_ArSatTq - Above rated generator torque PI control saturation, [Nm] -4500000.000000 ! VS_MaxRat - Maximum torque rate (in absolute value) in torque controller, [Nm/s]. -21586451.33303 ! VS_MaxTq - Maximum generator torque in Region 3 (HSS side), [Nm]. +94.40000000000 ! VS_GenEff - Generator efficiency mechanical power -> electrical power, [should match the efficiency defined in the generator properties!], [%] +43093.51876000 ! VS_ArSatTq - Above rated generator torque PI control saturation, [Nm] +1500000.000000 ! VS_MaxRat - Maximum torque rate (in absolute value) in torque controller, [Nm/s]. +47402.87063000 ! VS_MaxTq - Maximum generator torque in Region 3 (HSS side), [Nm]. 0.000000000000 ! VS_MinTq - Minimum generator (HSS side), [Nm]. -0.523600000000 ! VS_MinOMSpd - Optimal mode minimum speed, cut-in speed towards optimal mode gain path, [rad/s] -34937749.21735 ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side), [Nm/(rad/s)^2] -15000000.00000 ! VS_RtPwr - Wind turbine rated power [W] -19624046.66639 ! VS_RtTq - Rated torque, [Nm]. -0.791680000000 ! VS_RefSpd - Rated generator speed [rad/s] +34.68909000000 ! VS_MinOMSpd - Optimal mode minimum speed, cut-in speed towards optimal mode gain path, [rad/s] +2.526550000000 ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side), [Nm/(rad/s)^2] +5000000.000000 ! VS_RtPwr - Wind turbine rated power [W] +43093.51876000 ! VS_RtTq - Rated torque, [Nm]. +122.9096700000 ! VS_RefSpd - Rated generator speed [rad/s] 1 ! VS_n - Number of generator PI torque controller gains --38005940.32297 ! VS_KP - Proportional gain for generator PI torque controller [-]. (Only used in the transitional 2.5 region if VS_ControlMode =/ 2) --4588245.18720 ! VS_KI - Integral gain for generator PI torque controller [s]. (Only used in the transitional 2.5 region if VS_ControlMode =/ 2) -9.00 ! VS_TSRopt - Power-maximizing region 2 tip-speed-ratio [rad]. +-988.020670000 ! VS_KP - Proportional gain for generator PI torque controller [-]. (Only used in the transitional 2.5 region if VS_ControlMode =/ 2) +-185.790360000 ! VS_KI - Integral gain for generator PI torque controller [s]. (Only used in the transitional 2.5 region if VS_ControlMode =/ 2) +7.51 ! VS_TSRopt - Power-maximizing region 2 tip-speed-ratio [rad]. !------- SETPOINT SMOOTHER --------------------------------------------- 1.00000 ! SS_VSGain - Variable speed torque controller setpoint smoother gain, [-]. 0.00100 ! SS_PCGain - Collective pitch controller setpoint smoother gain, [-]. !------- WIND SPEED ESTIMATOR --------------------------------------------- -120.000 ! WE_BladeRadius - Blade length (distance from hub center to blade tip), [m] +63.000 ! WE_BladeRadius - Blade length (distance from hub center to blade tip), [m] 1 ! WE_CP_n - Amount of parameters in the Cp array 0.0 0.0 0.0 0.0 ! WE_CP - Parameters that define the parameterized CP(lambda) function 0.0 ! WE_Gamma - Adaption gain of the wind speed estimator algorithm [m/rad] -1.0 ! WE_GearboxRatio - Gearbox ratio [>=1], [-] -318628138.00000 ! WE_Jtot - Total drivetrain inertia, including blades, hub and casted generator inertia to LSS, [kg m^2] +97.0 ! WE_GearboxRatio - Gearbox ratio [>=1], [-] +43702538.05700 ! WE_Jtot - Total drivetrain inertia, including blades, hub and casted generator inertia to LSS, [kg m^2] 1.225 ! WE_RhoAir - Air density, [kg m^-3] -"Cp_Ct_Cq.IEA15MW.txt" ! PerfFileName - File containing rotor performance tables (Cp,Ct,Cq) -104 72 ! PerfTableSize - Size of rotor performance tables, first number refers to number of blade pitch angles, second number referse to number of tip-speed ratios +"Cp_Ct_Cq.NREL5MW.txt" ! PerfFileName - File containing rotor performance tables (Cp,Ct,Cq) +52 24 ! PerfTableSize - Size of rotor performance tables, first number refers to number of blade pitch angles, second number referse to number of tip-speed ratios 60 ! WE_FOPoles_N - Number of first-order system poles used in EKF -3.00 3.27 3.53 3.80 4.07 4.33 4.60 4.87 5.14 5.40 5.67 5.94 6.20 6.47 6.74 7.00 7.27 7.54 7.80 8.07 8.34 8.60 8.87 9.14 9.41 9.67 9.94 10.21 10.47 10.74 10.74 11.23 11.72 12.22 12.71 13.20 13.69 14.18 14.67 15.17 15.66 16.15 16.64 17.13 17.62 18.12 18.61 19.10 19.59 20.08 20.57 21.07 21.56 22.05 22.54 23.03 23.52 24.02 24.51 25.00 ! WE_FOPoles_v - Wind speeds corresponding to first-order system poles [m/s] --0.02366483 -0.02577018 -0.02787553 -0.02998089 -0.03208624 -0.03419159 -0.03629695 -0.03840230 -0.04050765 -0.04261301 -0.04471836 -0.04682371 -0.04892907 -0.05103442 -0.05313977 -0.05524513 -0.05735048 -0.05945583 -0.06156119 -0.06366654 -0.06577189 -0.06787725 -0.06998260 -0.07208795 -0.07419331 -0.07629866 -0.07840401 -0.08050937 -0.08261472 -0.08472008 -0.07921295 -0.05358619 -0.05636426 -0.06307564 -0.07173987 -0.08172495 -0.09271927 -0.10454428 -0.11705643 -0.13017613 -0.14379976 -0.15793978 -0.17258746 -0.18766434 -0.20315149 -0.21909644 -0.23538854 -0.25208919 -0.26915631 -0.28659300 -0.30437969 -0.32249538 -0.34096095 -0.35974552 -0.37881117 -0.39822177 -0.41789494 -0.43785131 -0.45808118 -0.47857910 ! WE_FOPoles - First order system poles [1/s] +3.00 3.29 3.58 3.87 4.16 4.45 4.74 5.03 5.32 5.61 5.90 6.19 6.48 6.77 7.06 7.34 7.63 7.92 8.21 8.50 8.79 9.08 9.37 9.66 9.95 10.24 10.53 10.82 11.11 11.40 11.40 11.87 12.34 12.81 13.28 13.74 14.21 14.68 15.15 15.62 16.09 16.56 17.03 17.50 17.97 18.43 18.90 19.37 19.84 20.31 20.78 21.25 21.72 22.19 22.66 23.12 23.59 24.06 24.53 25.00 ! WE_FOPoles_v - Wind speeds corresponding to first-order system poles [m/s] +-0.01770597 -0.01941551 -0.02112505 -0.02283460 -0.02454414 -0.02625368 -0.02796322 -0.02967276 -0.03138231 -0.03309185 -0.03480139 -0.03651093 -0.03822047 -0.03993002 -0.04163956 -0.04334910 -0.04505864 -0.04676818 -0.04847773 -0.05018727 -0.05189681 -0.05360635 -0.05531589 -0.05702544 -0.05873498 -0.06044452 -0.06215406 -0.06386360 -0.06557315 -0.06728269 -0.05552595 -0.05495499 -0.06481768 -0.07579803 -0.08863535 -0.10099825 -0.11480101 -0.12893048 -0.14298214 -0.15838136 -0.17406396 -0.18905348 -0.20537865 -0.22279331 -0.23952741 -0.25585147 -0.27334216 -0.29183862 -0.31117855 -0.32846400 -0.34577001 -0.36400615 -0.38314903 -0.40320641 -0.42423868 -0.45327936 -0.48686846 -0.52162481 -0.55751173 -0.59451859 ! WE_FOPoles - First order system poles [1/s] !------- YAW CONTROL ------------------------------------------------------ 0.0 ! Y_ErrThresh - Yaw error threshold. Turbine begins to yaw when it passes this. [rad^2 s] @@ -102,15 +102,15 @@ !------- MINIMUM PITCH SATURATION ------------------------------------------- 60 ! PS_BldPitchMin_N - Number of values in minimum blade pitch lookup table (should equal number of values in PS_WindSpeeds and PS_BldPitchMin) -3.0000 3.2669 3.5338 3.8007 4.0676 4.3345 4.6014 4.8683 5.1352 5.4021 5.6690 5.9359 6.2028 6.4697 6.7366 7.0034 7.2703 7.5372 7.8041 8.0710 8.3379 8.6048 8.8717 9.1386 9.4055 9.6724 9.9393 10.2062 10.4731 10.7400 10.7400 11.2317 11.7234 12.2152 12.7069 13.1986 13.6903 14.1821 14.6738 15.1655 15.6572 16.1490 16.6407 17.1324 17.6241 18.1159 18.6076 19.0993 19.5910 20.0828 20.5745 21.0662 21.5579 22.0497 22.5414 23.0331 23.5248 24.0166 24.5083 25.0000 ! PS_WindSpeeds - Wind speeds corresponding to minimum blade pitch angles [m/s] -0.06981317 0.06981317 0.06981317 0.06544985 0.06108652 0.06108652 0.05672320 0.05235988 0.04363323 0.03926991 0.03054326 0.02617994 0.01745329 0.01308997 0.00436332 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 ! PS_BldPitchMin - Minimum blade pitch angles [rad] +3.0000 3.2897 3.5793 3.8690 4.1586 4.4483 4.7379 5.0276 5.3172 5.6069 5.8966 6.1862 6.4759 6.7655 7.0552 7.3448 7.6345 7.9241 8.2138 8.5034 8.7931 9.0828 9.3724 9.6621 9.9517 10.2414 10.5310 10.8207 11.1103 11.4000 11.4000 11.8690 12.3379 12.8069 13.2759 13.7448 14.2138 14.6828 15.1517 15.6207 16.0897 16.5586 17.0276 17.4966 17.9655 18.4345 18.9034 19.3724 19.8414 20.3103 20.7793 21.2483 21.7172 22.1862 22.6552 23.1241 23.5931 24.0621 24.5310 25.0000 ! PS_WindSpeeds - Wind speeds corresponding to minimum blade pitch angles [m/s] +-0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 -0.00872665 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0.400740000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] +0.436300000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] 0.418880000000 ! SD_CornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle, [rad/s] !------- Floating ----------------------------------------------------------- --9.32577000000 ! Fl_Kp - Nacelle velocity proportional feedback gain [s] +0.000000000000 ! Fl_Kp - Nacelle velocity proportional feedback gain [s] !------- FLAP ACTUATION ----------------------------------------------------- 0.000000000000 ! Flp_Angle - Initial or steady state flap angle [rad] From bb5a8e2d02be7360306d2b88c36bd12030db499e Mon Sep 17 00:00:00 2001 From: Nikhar Abbas Date: Fri, 5 Mar 2021 10:10:38 -0700 Subject: [PATCH 30/34] ROSCO install path bug fix --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 04d81de00..6f2694a91 100644 --- a/setup.py +++ b/setup.py @@ -96,9 +96,9 @@ def build_extension(self, ext): cmake_args = ['-DBUILD_SHARED_LIBS=OFF'] cmake_args += ['-DCMAKE_Fortran_FLAGS=-ffree-line-length-0'] + cmake_args += ['-DCMAKE_INSTALL_PREFIX={}'.format(localdir)] if platform.system() == 'Windows': - cmake_args += ['-DCMAKE_INSTALL_PREFIX={}'.format(localdir)] if self.compiler.compiler_type == 'msvc': cmake_args += ['-DCMAKE_GENERATOR_PLATFORM=x64'] else: From 96ec34db5ca68ef1f7bf8d5065b326bc45e8af19 Mon Sep 17 00:00:00 2001 From: dzalkind Date: Fri, 5 Mar 2021 14:19:25 -0700 Subject: [PATCH 31/34] Update IEA-15MW Tune and Test Cases --- .../ServoData/DISCON-UMaineSemi.IN | 52 +++++++++---------- Tune_Cases/IEA15MW.yaml | 4 +- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Test_Cases/IEA-15-240-RWT-UMaineSemi/ServoData/DISCON-UMaineSemi.IN b/Test_Cases/IEA-15-240-RWT-UMaineSemi/ServoData/DISCON-UMaineSemi.IN index 0307be805..3a4cb4cf2 100644 --- a/Test_Cases/IEA-15-240-RWT-UMaineSemi/ServoData/DISCON-UMaineSemi.IN +++ b/Test_Cases/IEA-15-240-RWT-UMaineSemi/ServoData/DISCON-UMaineSemi.IN @@ -1,5 +1,5 @@ -! Controller parameter input file for the IEA-15-240-RWT_semi wind turbine -! - File written using ROSCO Controller tuning logic on 04/21/20 +! Controller parameter input file for the IEA-15-240-RWT-UMaineSemi wind turbine +! - File written using ROSCO version 2.2.0 controller tuning logic on 03/05/21 !------- DEBUG ------------------------------------------------------------ 1 ! LoggingLevel - {0: write no debug files, 1: write standard output .dbg-file, 2: write standard output .dbg-file and complete avrSWAP-array .dbg2-file} @@ -20,20 +20,20 @@ !------- FILTERS ---------------------------------------------------------- 1.00810 ! F_LPFCornerFreq - Corner frequency (-3dB point) in the low-pass filters, [rad/s] -0.70000 ! F_LPFDamping - Damping coefficient [used only when F_FilterType = 2] -3.12000 ! F_NotchCornerFreq - Natural frequency of the notch filter, [rad/s] +0.70000 ! F_LPFDamping - Damping coefficient {used only when F_FilterType = 2} [-] +3.35500 ! F_NotchCornerFreq - Natural frequency of the notch filter, [rad/s] 0.00000 0.25000 ! F_NotchBetaNumDen - Two notch damping values (numerator and denominator, resp) - determines the width and depth of the notch, [-] 0.628320000000 ! F_SSCornerFreq - Corner frequency (-3dB point) in the first order low pass filter for the setpoint smoother, [rad/s]. -0.22600 1.00000 ! F_FlCornerFreq - Natural frequency and damping in the second order low pass filter of the tower-top fore-aft motion for floating feedback control [rad/s, -]. +0.21300 1.00000 ! F_FlCornerFreq - Natural frequency and damping in the second order low pass filter of the tower-top fore-aft motion for floating feedback control [rad/s, -]. 1.16240 1.00000 ! F_FlpCornerFreq - Corner frequency and damping in the second order low pass filter of the blade root bending moment for flap control [rad/s, -]. !------- BLADE PITCH CONTROL ---------------------------------------------- -28 ! PC_GS_n - Amount of gain-scheduling table entries -0.064065 0.091441 0.113134 0.131901 0.148787 0.164298 0.178797 0.192476 0.205467 0.217906 0.229898 0.241557 0.252756 0.263645 0.274434 0.284672 0.294952 0.304789 0.314694 0.324122 0.333781 0.342816 0.352034 0.361052 0.369784 0.378753 0.387278 0.395688 ! PC_GS_angles - Gain-schedule table: pitch angles --1.273191 -1.100149 -0.958278 -0.839852 -0.739503 -0.653385 -0.578671 -0.513238 -0.455456 -0.404058 -0.358041 -0.316603 -0.279092 -0.244975 -0.213811 -0.185234 -0.158933 -0.134648 -0.112155 -0.091262 -0.071805 -0.053641 -0.036645 -0.020708 -0.005734 0.008362 0.021655 0.034212 ! PC_GS_KP - Gain-schedule table: pitch controller kp gains --0.132832 -0.119684 -0.108904 -0.099906 -0.092281 -0.085737 -0.080060 -0.075088 -0.070698 -0.066792 -0.063296 -0.060147 -0.057297 -0.054705 -0.052337 -0.050165 -0.048167 -0.046322 -0.044612 -0.043025 -0.041547 -0.040166 -0.038875 -0.037664 -0.036526 -0.035455 -0.034445 -0.033491 ! PC_GS_KI - Gain-schedule table: pitch controller ki gains -0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ! PC_GS_KD - Gain-schedule table: pitch controller kd gains -0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ! PC_GS_TF - Gain-schedule table: pitch controller tf gains (derivative filter) +29 ! PC_GS_n - Amount of gain-scheduling table entries +0.061302 0.088725 0.110460 0.129231 0.146101 0.161618 0.176096 0.189763 0.202765 0.215213 0.227190 0.238754 0.249961 0.260854 0.271463 0.281817 0.291944 0.301857 0.311577 0.321120 0.330501 0.339728 0.348811 0.357760 0.366583 0.375288 0.383879 0.392362 0.400744 ! PC_GS_angles - Gain-schedule table: pitch angles [rad]. +-1.590144 -1.390427 -1.225842 -1.087870 -0.970537 -0.869535 -0.781676 -0.704552 -0.636308 -0.575495 -0.520961 -0.471781 -0.427204 -0.386613 -0.349495 -0.315424 -0.284039 -0.255034 -0.228149 -0.203159 -0.179871 -0.158116 -0.137749 -0.118640 -0.100676 -0.083758 -0.067796 -0.052712 -0.038435 ! PC_GS_KP - Gain-schedule table: pitch controller kp gains [s]. +-0.205073 -0.185297 -0.168999 -0.155336 -0.143717 -0.133716 -0.125016 -0.117378 -0.110621 -0.104599 -0.099198 -0.094328 -0.089914 -0.085895 -0.082219 -0.078845 -0.075737 -0.072865 -0.070203 -0.067728 -0.065422 -0.063268 -0.061251 -0.059359 -0.057580 -0.055905 -0.054324 -0.052831 -0.051417 ! PC_GS_KI - Gain-schedule table: pitch controller ki gains [-]. +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ! PC_GS_KD - Gain-schedule table: pitch controller kd gains +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ! PC_GS_TF - Gain-schedule table: pitch controller tf gains (derivative filter) 1.570800000000 ! PC_MaxPit - Maximum physical pitch limit, [rad]. 0.000000000000 ! PC_MinPit - Minimum physical pitch limit, [rad]. 0.034900000000 ! PC_MaxRat - Maximum pitch rate (in absolute value) in pitch controller, [rad/s]. @@ -43,9 +43,9 @@ 0.017450000000 ! PC_Switch - Angle above lowest minimum pitch angle for switch, [rad] !------- INDIVIDUAL PITCH CONTROL ----------------------------------------- -0.0 ! IPC_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from IPC), [rad] -0.0 0.0 ! IPC_KI - Integral gain for the individual pitch controller: first parameter for 1P reductions, second for 2P reductions, [-] -0.0 0.0 ! IPC_aziOffset - Phase offset added to the azimuth angle for the individual pitch controller, [rad]. +0.1 ! IPC_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from IPC), [rad] +0.0e+00 0.0 ! IPC_KI - Integral gain for the individual pitch controller: first parameter for 1P reductions, second for 2P reductions, [-] +0.0e+00 0.0 ! IPC_aziOffset - Phase offset added to the azimuth angle for the individual pitch controller, [rad]. 0.0 ! IPC_CornerFreqAct - Corner frequency of the first-order actuators model, to induce a phase lag in the IPC signal {0: Disable}, [rad/s] !------- VS TORQUE CONTROL ------------------------------------------------ @@ -55,13 +55,13 @@ 21586451.33303 ! VS_MaxTq - Maximum generator torque in Region 3 (HSS side), [Nm]. 0.000000000000 ! VS_MinTq - Minimum generator (HSS side), [Nm]. 0.523600000000 ! VS_MinOMSpd - Optimal mode minimum speed, cut-in speed towards optimal mode gain path, [rad/s] -33732396.86935 ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side), [N-m/(rad/s)^2] +34937749.21735 ! VS_Rgn2K - Generator torque constant in Region 2 (HSS side), [Nm/(rad/s)^2] 15000000.00000 ! VS_RtPwr - Wind turbine rated power [W] 19624046.66639 ! VS_RtTq - Rated torque, [Nm]. 0.791680000000 ! VS_RefSpd - Rated generator speed [rad/s] 1 ! VS_n - Number of generator PI torque controller gains --38609162.66552 ! VS_KP - Proportional gain for generator PI torque controller [1/(rad/s) Nm]. (Only used in the transitional 2.5 region if VS_ControlMode =/ 2) --4588245.18720 ! VS_KI - Integral gain for generator PI torque controller [1/rad Nm]. (Only used in the transitional 2.5 region if VS_ControlMode =/ 2) +-38005940.32297 ! VS_KP - Proportional gain for generator PI torque controller [-]. (Only used in the transitional 2.5 region if VS_ControlMode =/ 2) +-4588245.18720 ! VS_KI - Integral gain for generator PI torque controller [s]. (Only used in the transitional 2.5 region if VS_ControlMode =/ 2) 9.00 ! VS_TSRopt - Power-maximizing region 2 tip-speed-ratio [rad]. !------- SETPOINT SMOOTHER --------------------------------------------- @@ -74,7 +74,7 @@ 0.0 0.0 0.0 0.0 ! WE_CP - Parameters that define the parameterized CP(lambda) function 0.0 ! WE_Gamma - Adaption gain of the wind speed estimator algorithm [m/rad] 1.0 ! WE_GearboxRatio - Gearbox ratio [>=1], [-] -318628138.00000 ! WE_Jtot - Total drivetrain inertia, including blades, hub and casted generator inertia to LSS, [kg m^2] +318628138.00000 ! WE_Jtot - Total drivetrain inertia, including blades, hub and casted generator inertia to LSS, [kg m^2] 1.225 ! WE_RhoAir - Air density, [kg m^-3] "Cp_Ct_Cq.IEA15MW.txt" ! PerfFileName - File containing rotor performance tables (Cp,Ct,Cq) 104 72 ! PerfTableSize - Size of rotor performance tables, first number refers to number of blade pitch angles, second number referse to number of tip-speed ratios @@ -91,8 +91,8 @@ 0.0 ! Y_IPC_omegaLP - Low-pass filter corner frequency for the Yaw-by-IPC controller to filtering the yaw alignment error, [rad/s]. 0.0 ! Y_IPC_zetaLP - Low-pass filter damping factor for the Yaw-by-IPC controller to filtering the yaw alignment error, [-]. 0.0 ! Y_MErrSet - Yaw alignment error, set point [rad] -0.0 ! Y_omegaLPFast - Corner frequency fast low pass filter, 1.0 [Hz] -0.0 ! Y_omegaLPSlow - Corner frequency slow low pass filter, 1/60 [Hz] +0.0 ! Y_omegaLPFast - Corner frequency fast low pass filter, 1.0 [rad/s] +0.0 ! Y_omegaLPSlow - Corner frequency slow low pass filter, 1/60 [rad/s] 0.0 ! Y_Rate - Yaw rate [rad/s] !------- TOWER FORE-AFT DAMPING ------------------------------------------- @@ -101,19 +101,19 @@ 0.0 ! FA_IntSat - Integrator saturation (maximum signal amplitude contribution to pitch from FA damper), [rad] !------- MINIMUM PITCH SATURATION ------------------------------------------- -44 ! PS_BldPitchMin_N - Number of values in minimum blade pitch lookup table (should equal number of values in PS_WindSpeeds and PS_BldPitchMin) -3.00 3.50 4.00 4.50 5.00 5.50 6.00 6.50 7.00 7.50 8.00 8.50 9.00 9.50 10.00 10.50 11.09 11.59 12.09 12.59 13.09 13.59 14.09 14.59 15.09 15.59 16.09 16.59 17.09 17.59 18.09 18.59 19.09 19.59 20.09 20.59 21.09 21.59 22.09 22.59 23.09 23.59 24.09 24.59 ! PS_WindSpeeds - Wind speeds corresponding to minimum blade pitch angles [m/s] -0.06981317 0.06981317 0.06544985 0.05672320 0.04799655 0.03490659 0.02617994 0.00872665 -0.01745329 -0.01745329 -0.01745329 -0.01745329 -0.01096058 0.02043054 0.04426907 0.06340170 0.07720696 0.08784519 0.09811110 0.10810992 0.11787911 0.12742889 0.13680695 0.14602761 0.15508707 0.16402141 0.17286494 0.18166247 0.19028138 0.19882038 0.20741910 0.21571175 0.22414599 0.23233213 0.24065712 0.24869393 0.25697817 0.26483569 0.27290279 0.28085978 0.28864680 0.29667058 0.30437206 0.31202925 ! PS_BldPitchMin - Minimum blade pitch angles [rad] +60 ! PS_BldPitchMin_N - Number of values in minimum blade pitch lookup table (should equal number of values in PS_WindSpeeds and PS_BldPitchMin) +3.0000 3.2669 3.5338 3.8007 4.0676 4.3345 4.6014 4.8683 5.1352 5.4021 5.6690 5.9359 6.2028 6.4697 6.7366 7.0034 7.2703 7.5372 7.8041 8.0710 8.3379 8.6048 8.8717 9.1386 9.4055 9.6724 9.9393 10.2062 10.4731 10.7400 10.7400 11.2317 11.7234 12.2152 12.7069 13.1986 13.6903 14.1821 14.6738 15.1655 15.6572 16.1490 16.6407 17.1324 17.6241 18.1159 18.6076 19.0993 19.5910 20.0828 20.5745 21.0662 21.5579 22.0497 22.5414 23.0331 23.5248 24.0166 24.5083 25.0000 ! PS_WindSpeeds - Wind speeds corresponding to minimum blade pitch angles [m/s] +0.06981317 0.06981317 0.06981317 0.06544985 0.06108652 0.06108652 0.05672320 0.05235988 0.04363323 0.03926991 0.03054326 0.02617994 0.01745329 0.01308997 0.00436332 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 ! PS_BldPitchMin - Minimum blade pitch angles [rad] !------- SHUTDOWN ----------------------------------------------------------- -0.395690000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] +0.400740000000 ! SD_MaxPit - Maximum blade pitch angle to initiate shutdown, [rad] 0.418880000000 ! SD_CornerFreq - Cutoff Frequency for first order low-pass filter for blade pitch angle, [rad/s] !------- Floating ----------------------------------------------------------- --9.36350000000 ! Fl_Kp - Nacelle velocity proportional feedback gain [s] +-9.32577000000 ! Fl_Kp - Nacelle velocity proportional feedback gain [s] !------- FLAP ACTUATION ----------------------------------------------------- 0.000000000000 ! Flp_Angle - Initial or steady state flap angle [rad] 0.00000000e+00 ! Flp_Kp - Blade root bending moment proportional gain for flap control [s] -0.00000000e+00 ! Flp_Ki - Flap displacement integral gain for flap control [s] +0.00000000e+00 ! Flp_Ki - Flap displacement integral gain for flap control [-] 0.000000000000 ! Flp_MaxPit - Maximum (and minimum) flap pitch angle [rad] \ No newline at end of file diff --git a/Tune_Cases/IEA15MW.yaml b/Tune_Cases/IEA15MW.yaml index 87929771a..d926751de 100644 --- a/Tune_Cases/IEA15MW.yaml +++ b/Tune_Cases/IEA15MW.yaml @@ -41,7 +41,7 @@ controller_params: Flp_Mode: 0 # Flap control mode {0: no flap control, 1: steady state flap angle, 2: Proportional flap control} # Controller parameters zeta_pc: 1.0 # Pitch controller desired damping ratio [-] - omega_pc: 0.3 # Pitch controller desired natural frequency [rad/s] + omega_pc: 0.25 # Pitch controller desired natural frequency [rad/s] zeta_vs: 0.85 # Torque controller desired damping ratio [-] omega_vs: 0.12 # Torque controller desired natural frequency [rad/s] # Optional - these can be defined, but do not need to be @@ -51,7 +51,7 @@ controller_params: ss_cornerfreq: # None # First order low-pass filter cornering frequency for setpoint smoother [rad/s] ss_vsgain: # None # Torque controller setpoint smoother gain bias percentage [%, <= 1 ], {default = 100%} ss_pcgain: # None # Pitch controller setpoint smoother gain bias percentage [%, <= 1 ], {default = 0.1%} - ps_percent: # None # Percent peak shaving [%, <= 1 ], {default = 80%} + ps_percent: 0.8 # None # Percent peak shaving [%, <= 1 ], {default = 80%} sd_maxpit: # None # Maximum blade pitch angle to initiate shutdown [rad], {default = bld pitch at v_max} sd_cornerfreq: # None # Cutoff Frequency for first order low-pass filter for blade pitch angle [rad/s], {default = 0.41888 ~ time constant of 15s} flp_maxpit: # None # Maximum (and minimum) flap pitch angle [rad] From 8cd838860ae93c92b4fae8077451a9abcf9d9d6d Mon Sep 17 00:00:00 2001 From: dzalkind Date: Fri, 5 Mar 2021 14:22:38 -0700 Subject: [PATCH 32/34] Fix paths, print outputs to pdf, add submit script --- ROSCO_testing/ROSCO_testing.py | 49 ++++++++++++++++++++++++++++++++++ ROSCO_testing/run_Testing.py | 17 ++++++------ ROSCO_testing/submit.sh | 26 ++++++++++++++++++ 3 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 ROSCO_testing/submit.sh diff --git a/ROSCO_testing/ROSCO_testing.py b/ROSCO_testing/ROSCO_testing.py index fa30bff37..dca415682 100644 --- a/ROSCO_testing/ROSCO_testing.py +++ b/ROSCO_testing/ROSCO_testing.py @@ -21,6 +21,9 @@ from ROSCO_toolbox.ofTools.fast_io.FAST_reader import InputReader_OpenFAST from ROSCO_toolbox.ofTools.case_gen.CaseGen_IEC import CaseGen_IEC from ROSCO_toolbox.ofTools.case_gen.runFAST_pywrapper import runFAST_pywrapper_batch +from matplotlib.backends.backend_pdf import FigureCanvasPdf, PdfPages +from ROSCO_toolbox.ofTools.fast_io import output_processing +import matplotlib.pyplot as plt @@ -238,6 +241,8 @@ def ROSCO_Test_lite(self, more_case_inputs={}, U=[]): else: fastBatch.run_serial() + self.print_results(outFileNames) + def ROSCO_Test_heavy(self, more_case_inputs={}, U=[]): ''' @@ -401,6 +406,8 @@ def ROSCO_Test_heavy(self, more_case_inputs={}, U=[]): else: fastBatch.run_serial() + self.print_results(outFileNames) + def ROSCO_Controller_Comp(self, controller_paths, testtype='light', more_case_inputs={}, U=[]): ''' Heavy or light testing for n controllers, n = len(controller_paths) @@ -468,6 +475,48 @@ def ROSCO_DISCON_Comp(self, DISCON_filenames, testtype='light', more_case_inputs self.runDir = run_dir_init self.windDir = wind_dir_init + def print_results(self,outfiles): + print(outfiles) + + op = output_processing.output_processing() + FAST_Output = op.load_fast_out(outfiles, tmin=0) + + figs_fname = 'test_outputs.pdf' + with PdfPages(os.path.join(self.runDir,figs_fname)) as pdf: + for fast_out in FAST_Output: + if self.FAST_InputFile == 'NREL-5MW.fst': + plots2make = {'Baseline': ['Wind1VelX', 'GenPwr', 'RotSpeed', 'BldPitch1', 'GenTq']} + else: + plots2make = {'Baseline': ['Wind1VelX', 'GenPwr', 'RotSpeed', 'BldPitch1', 'GenTq','PtfmPitch']} + + numplots = len(plots2make) + maxchannels = np.max([len(plots2make[key]) for key in plots2make.keys()]) + fig = plt.figure(figsize=(8,6), constrained_layout=True) + gs_all = fig.add_gridspec(1, numplots) + for pnum, (gs, pname) in enumerate(zip(gs_all, plots2make.keys())): + gs0 = gs.subgridspec(len(plots2make[pname]),1) + for cid, channel in enumerate(plots2make[pname]): + subplt = fig.add_subplot(gs0[cid]) + try: + subplt.plot(fast_out['Time'], fast_out[channel]) + unit_idx = fast_out['meta']['channels'].index(channel) + subplt.set_ylabel('{:^} \n ({:^})'.format( + channel, + fast_out['meta']['attribute_units'][unit_idx])) + subplt.grid(True) + subplt.set_xlabel('Time (s)') + except: + print('Cannot plot {}'.format(channel)) + if cid == 0: + subplt.set_title(pname) + if cid != len(plots2make[pname])-1: + subplt.axes.get_xaxis().set_visible(False) + + plt.suptitle(fast_out['meta']['name']) + pdf.savefig(fig) + plt.close() + + if __name__=='__main__': rt = ROSCO_testing() diff --git a/ROSCO_testing/run_Testing.py b/ROSCO_testing/run_Testing.py index 51518530e..d6ff98e03 100644 --- a/ROSCO_testing/run_Testing.py +++ b/ROSCO_testing/run_Testing.py @@ -50,12 +50,12 @@ def run_testing(turbine2test, testtype, rosco_binaries=[], discon_files=[], **kw if turbine2test == 'NREL-5MW': rt.Turbine_Class = 'I' rt.Turbulence_Class = 'A' - rt.FAST_directory = os.path.join(os.path.dirname(__file__), '../Test_Cases/NREL-5MW') + rt.FAST_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../Test_Cases/NREL-5MW') rt.FAST_InputFile = 'NREL-5MW.fst' elif turbine2test == 'IEA-15MW': rt.Turbine_Class = 'I' rt.Turbulence_Class = 'B' - rt.FAST_directory = os.path.join(os.path.dirname(__file__), '../Test_Cases/IEA-15-240-RWT-UMaineSemi') + rt.FAST_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../Test_Cases/IEA-15-240-RWT-UMaineSemi') rt.FAST_InputFile = 'IEA-15-240-RWT-UMaineSemi.fst' else: raise ValueError('{} is not an available turbine to test!'.format(turbine2test)) @@ -79,12 +79,12 @@ def run_testing(turbine2test, testtype, rosco_binaries=[], discon_files=[], **kw if __name__ == "__main__": # WEIS directory, for running openfast, etc. - this_dir = os.path.dirname(__file__) + this_dir = os.path.dirname(os.path.realpath(__file__)) # Setup ROSCO testing parameters rt_kwargs = {} - rt_kwargs['runDir'] = os.path.join(this_dir,'results/') # directory for FAST simulations - rt_kwargs['namebase'] = 'lite_test' # Base name for FAST files + rt_kwargs['runDir'] = os.path.join(this_dir,'results/IEA-15MW') # directory for FAST simulations + rt_kwargs['namebase'] = 'heavy_test' # Base name for FAST files rt_kwargs['FAST_exe'] = 'openfast' # OpenFAST executable path rt_kwargs['Turbsim_exe']= 'turbsim' # Turbsim executable path rt_kwargs['FAST_ver'] = 'OpenFAST' # FAST version @@ -97,13 +97,14 @@ def run_testing(turbine2test, testtype, rosco_binaries=[], discon_files=[], **kw rt_kwargs['outfile_fmt'] = 2 # 1 = .txt, 2 = binary, 3 = both # ---- Define test type ---- - turbine2test = 'NREL-5MW' # IEA-15MW or NREL-5MW - testtype = 'lite' # lite, heavy, binary-comp, discon-comp + turbine2test = 'IEA-15MW' # IEA-15MW or NREL-5MW + testtype = 'heavy' # lite, heavy, binary-comp, discon-comp # Only fill one of these if comparing controllers rosco_binaries = [glob.glob(os.path.join(this_dir,'../ROSCO/build/libdiscon.*'))[0]] # Differently named libdiscons to compare discon_files = [] # Differently named DISCON.IN files to compare - + print(rosco_binaries) + print(this_dir) # Run testing run_testing(turbine2test, testtype, rosco_binaries=rosco_binaries, discon_files=discon_files, **rt_kwargs) diff --git a/ROSCO_testing/submit.sh b/ROSCO_testing/submit.sh new file mode 100644 index 000000000..182cf9a0e --- /dev/null +++ b/ROSCO_testing/submit.sh @@ -0,0 +1,26 @@ +#!/bin/bash +#SBATCH --account=ssc +#SBATCH --time=1:00:00 +#SBATCH --job-name=rosco_test +#SBATCH --nodes=1 # This should be nC/36 (36 cores on eagle) +#SBATCH --ntasks-per-node=36 +#SBATCH --mail-user dzalkind@nrel.gov +#SBATCH --mail-type BEGIN,END,FAIL +#SBATCH --output=output.%j.out +#SBATCH --partition=debug + +nDV=1 # Number of design variables (x2 for central difference) +nOF=60 # Number of openfast runs per finite-difference evaluation +nC=$((nDV + nDV * nOF)) # Number of cores needed. Make sure to request an appropriate number of nodes = N / 36 +## nC=72 + +source activate /home/dzalkind/.conda-envs/weis-env4 +which python + +# module purge +# module load conda +# module load comp-intel intel-mpi mkl + + +python run_Testing.py +# python weis_driver.py From 1a5e9ae727ed0bd5cd46d59a846f1b6674f303a0 Mon Sep 17 00:00:00 2001 From: dzalkind Date: Wed, 10 Mar 2021 10:27:46 -0700 Subject: [PATCH 33/34] Point submodule to main branch of ROSCO --- ROSCO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ROSCO b/ROSCO index b64ba171d..e53ff37a5 160000 --- a/ROSCO +++ b/ROSCO @@ -1 +1 @@ -Subproject commit b64ba171d244e2d286534f7816464ef903b92e93 +Subproject commit e53ff37a50ced633873a324386f279404953fe52 From b813a22734f4f478f2922ce98f0a3001b8845260 Mon Sep 17 00:00:00 2001 From: dzalkind Date: Wed, 10 Mar 2021 10:37:42 -0700 Subject: [PATCH 34/34] Clean up testing scripts --- ROSCO_testing/ROSCO_testing.py | 1 - ROSCO_testing/run_Testing.py | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/ROSCO_testing/ROSCO_testing.py b/ROSCO_testing/ROSCO_testing.py index dca415682..4aa7675e0 100644 --- a/ROSCO_testing/ROSCO_testing.py +++ b/ROSCO_testing/ROSCO_testing.py @@ -476,7 +476,6 @@ def ROSCO_DISCON_Comp(self, DISCON_filenames, testtype='light', more_case_inputs self.windDir = wind_dir_init def print_results(self,outfiles): - print(outfiles) op = output_processing.output_processing() FAST_Output = op.load_fast_out(outfiles, tmin=0) diff --git a/ROSCO_testing/run_Testing.py b/ROSCO_testing/run_Testing.py index d6ff98e03..9434c933c 100644 --- a/ROSCO_testing/run_Testing.py +++ b/ROSCO_testing/run_Testing.py @@ -84,7 +84,7 @@ def run_testing(turbine2test, testtype, rosco_binaries=[], discon_files=[], **kw # Setup ROSCO testing parameters rt_kwargs = {} rt_kwargs['runDir'] = os.path.join(this_dir,'results/IEA-15MW') # directory for FAST simulations - rt_kwargs['namebase'] = 'heavy_test' # Base name for FAST files + rt_kwargs['namebase'] = 'lite_test' # Base name for FAST files rt_kwargs['FAST_exe'] = 'openfast' # OpenFAST executable path rt_kwargs['Turbsim_exe']= 'turbsim' # Turbsim executable path rt_kwargs['FAST_ver'] = 'OpenFAST' # FAST version @@ -98,13 +98,11 @@ def run_testing(turbine2test, testtype, rosco_binaries=[], discon_files=[], **kw # ---- Define test type ---- turbine2test = 'IEA-15MW' # IEA-15MW or NREL-5MW - testtype = 'heavy' # lite, heavy, binary-comp, discon-comp + testtype = 'lite' # lite, heavy, binary-comp, discon-comp # Only fill one of these if comparing controllers rosco_binaries = [glob.glob(os.path.join(this_dir,'../ROSCO/build/libdiscon.*'))[0]] # Differently named libdiscons to compare discon_files = [] # Differently named DISCON.IN files to compare - print(rosco_binaries) - print(this_dir) # Run testing run_testing(turbine2test, testtype, rosco_binaries=rosco_binaries, discon_files=discon_files, **rt_kwargs)