Skip to content

Commit

Permalink
Merge pull request #82 from dzalkind/rosco_update
Browse files Browse the repository at this point in the history
ROSCO & Toolbox Update
  • Loading branch information
johnjasa committed Mar 12, 2021
2 parents b01f7ad + f36f309 commit 6a8861f
Show file tree
Hide file tree
Showing 105 changed files with 3,518 additions and 1,572 deletions.
4 changes: 3 additions & 1 deletion ROSCO/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Source/x64/
Source/Release/
*build*
Makefile

*install*

# Archive
Scripts/CompileDISCONHereCopyRun\.cmd
Expand All @@ -20,6 +20,8 @@ Scripts/CompileDISCONHereCopyRun\.cmd
*~
.DS_Store
*.u2d
*.i90
*.swp

# vs code
.vscode
24 changes: 20 additions & 4 deletions ROSCO/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.6)
project(ROSCO VERSION 2.1.1 LANGUAGES Fortran)
project(ROSCO VERSION 2.2.0 LANGUAGES Fortran)

set(CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/ftnmods")

Expand All @@ -12,15 +12,16 @@ message(STATUS "CMAKE_Fortran_COMPILER_ID = ${CMAKE_Fortran_COMPILER_ID}")
if(APPLE OR UNIX)
# Enable .dll export
if (CMAKE_Fortran_COMPILER_ID STREQUAL "Intel")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -DIMPLICIT_DLLEXPORT -r8 -double_size 64")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -DIMPLICIT_DLLEXPORT -r8 -double_size 64 -cpp")
else()
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -DIMPLICIT_DLLEXPORT -ffree-line-length-0 -fdefault-real-8 -fdefault-double-8")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -DIMPLICIT_DLLEXPORT -ffree-line-length-0 -fdefault-real-8 -fdefault-double-8 -cpp")
endif()
elseif(WIN32 AND MINGW)
# Ensure static linking to avoid requiring Fortran runtime dependencies
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -ffree-line-length-0 -static-libgcc -static-libgfortran -static -fdefault-real-8 -fdefault-double-8")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -ffree-line-length-0 -static-libgcc -static-libgfortran -static -fdefault-real-8 -fdefault-double-8 -cpp")
endif()


set(SOURCES
src/Constants.f90
src/ControllerBlocks.f90
Expand All @@ -32,6 +33,18 @@ set(SOURCES
src/ReadSetParameters.f90
)

# Git version
if( DEFINED GIT_DESCRIBE )
message( WARNING
"Version information has been set as a CMake flag. This should only used when the git-version cannot be set automatically."
)
else()
include(${CMAKE_SOURCE_DIR}/cmake/GetGitRevisionDescription.cmake)
git_describe(GIT_DESCRIBE)
endif()
add_definitions(-DGIT_VERSION_INFO="${GIT_DESCRIBE}")

# Library
add_library(discon SHARED ${SOURCES})

install(TARGETS discon
Expand All @@ -40,3 +53,6 @@ install(TARGETS discon
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/install")
endif()
43 changes: 13 additions & 30 deletions ROSCO/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,18 @@
NREL's Reference OpenSource Controller (ROSCO) for wind turbine applications uses the Bladed-style DISCON interface used by OpenFAST, Bladed (versions 4.5 or earlier), HAWC2, and more.

## Introduction
The NREL Reference OpenSource Controller (ROSCO) provides an open, modular and fully adaptable baseline wind turbine controller to the scientific community. Because of the open character and modular set-up, scientists are able to collaborate and contribute in making continuous improvements to the code. New control implementations can be added to the existing baseline controller, and in this way, convenient assessments of the proposed algorithms is possible. ROSCO is being developed in Fortran and uses the Bladed-style DISCON controller interface. The compiled controller is configured by a single control settings parameter file, and can work with any wind turbine model and simulation software using the DISCON interface. Baseline parameter files are supplied for the NREL 5-MW and DTU 10-MW reference wind turbines.
The NREL Reference OpenSource Controller (ROSCO) provides an open, modular and fully adaptable baseline wind turbine controller to the scientific community. Because of the open character and modular set-up, scientists are able to collaborate and contribute in making continuous improvements to the code. New control implementations can be added to the existing baseline controller, and in this way, convenient assessments of the proposed algorithms is possible. ROSCO is being developed in Fortran and uses the Bladed-style DISCON controller interface. The compiled controller is configured by a single control settings parameter file, and can work with any wind turbine model and simulation software using the DISCON interface. Baseline parameter files are supplied for the NREL 5-MW, DTU 10-MW, and IEA15MW reference wind turbines.

## Compiling ROSCO
Compiling ROSCO is made simple using [cmake](https://cmake.org/) on Unix based machines. Currently (November 2019), we recommend that you compile the code using a unix machine (or subsystem on Windows). Some compiled binaries are also provided via github.
## Documentation
Relevant documentation about the ROSCO controller and corresponding ROSCO toolbox can all be found at https://rosco-toolbox.readthedocs.io/.

### Required Software to build ROSCO
* Fortran compiler (GNU compiler version above 4.6.0 or Intel compiler version above 11)
* C/C++ compiler
* GNU Make (version 3.81 or later)
* CMake (version 2.8.12 or later) - for unix

### Steps to compile
First, clone the git repository:
```
git clone https://github.com/NREL/ROSCO.git
```
Second, you will need to compile the controller. From the ROSCO home directory:
```
mkdir build
cd build
cmake ..
make
```
A dynamic link library will be compiled into the directory with the title `libdiscon.*`, where the file extension is `.so`, `.dll`, or `.dylib`, depending on the user's operating system.
## Downloading/Compiling ROSCO
The easiest way to get the most recent version release of ROSCO is to download it from the [tagged releases](https://github.com/NREL/ROSCO/tags) page. If you wish to download ROSCO using [Anaconda](https://www.anaconda.com/) or compile ROSCO yourself, please follow the instruction [here](https://rosco-toolbox.readthedocs.io/en/latest/source/install.html#compiling-rosco). Compiling ROSCO will be necessary if you wish to use any version of ROSCO that is not a tagged release.

## Running ROSCO
A few files are needed to run ROSCO. Of course, the compiled binary, named `libdiscon.*` by default, is needed. This should be appropriately pointed to by your ServoDyn input file (for OpenFAST). In addition to the binary, a controller input file title DISCON.IN is necessary. Two example input files are provided for the NREL 5MW and DTU 10MW wind turbine controllers in the [parameter_files](parameter_files) folder. Note that DISCON.IN (or similar) is pointed to by the `DLL_InFile` parameter in ServoDyn. For generic controller tuning methods, and an automated writing of this DISCON.IN file, we point you to the complete [ROSCO_toolbox](https://github.com/nrel/rosco_toolbox).
A few files are needed to run ROSCO. Of course, the compiled binary, named `libdiscon.*` by default, is needed. This should be appropriately pointed to by your ServoDyn input file (for OpenFAST). In addition to the binary, a controller input file title DISCON.IN is necessary. Three example input files are provided for the NREL 5MW, DTU 10MW, and IEA 15MW wind turbine controllers in the [parameter_files](parameter_files) folder. Note that DISCON.IN (or similar) is pointed to by the `DLL_InFile` parameter in ServoDyn. For generic controller tuning methods, and an automated writing of this DISCON.IN file, we point you to the complete [ROSCO_toolbox](https://github.com/nrel/rosco_toolbox).

In addition to DISCON.IN, if you wish to use either of the wind speed estimators offered by ROSCO (`WE_mode > 0`), you will need a rotor performance input file. This is, again, provided for the NREL 5MW and DTU 10MW wind turbines, and can be easily made for other turbines using the [ROSCO_toolbox](https://github.com/nrel/rosco_toolbox). The input `PerfFileName` in DISCON.IN points to this file.
In addition to DISCON.IN, if you wish to use either of the wind speed estimators (`WE_Mode > 0`) or pitch saturation routines (`PS_Mode > 0`) offered by ROSCO , you will need a rotor performance input file. This is, again, provided for the sample wind turbines, and can be easily made for other turbines using the [ROSCO_toolbox](https://github.com/nrel/rosco_toolbox). The input `PerfFileName` in DISCON.IN points to this file.

## Using ROSCO for Bladed
If you want to use the controller with DNV GL Bladed v4.5 or earlier (which still has support for the DISCON external controller interface), do the following:
Expand All @@ -44,15 +27,15 @@ If you want to use the controller with DNV GL Bladed v4.5 or earlier (which stil
If ROSCO 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.
ROSCO. Version 2.2.0 (2021). Available at https://github.com/nrel/rosco.

For LaTeX users:

```
@misc{ROSCO_2020,
@misc{ROSCO_2021,
author = {NREL},
title = {{ROSCO. Version 1.0.0}},
year = {2020},
title = {{ROSCO. Version 2.2.0}},
year = {2021},
publisher = {GitHub},
journal = {GitHub repository},
url = {https://github.com/NREL/rosco}
Expand All @@ -66,7 +49,7 @@ The initial release of this controller was the Delft Research Controller. This w
* Mulders, S.P. and van Wingerden, J.W. "Delft Research Controller: an open-source and community-driven wind turbine baseline controller." Journal of Physics: Conference Series. Vol. 1037. No. 3. IOP Publishing, 2018. [Link to the paper](https://iopscience.iop.org/article/10.1088/1742-6596/1037/3/032009/meta)
The Delft Research Controller was the initial version of this work. It has since been grown significantly and become NREL's ROSCO.

Primary contributions to ROSCO have been provided by researchers the National Renewable Energy Laboratory (Nikhar J. Abbas, Alan Wright, and Paul Fleming), Delft University of Technology (Sebastiaan Mulders and Jan-Willem van Wingerden), and the University of Colorado Boulder (Lucy Pao). Much of the intellect behind these contributions has been inspired or derived from an extensive amount of work in the literature. The bulk of this has been cited through the primary publications about this work.
Primary contributions to ROSCO have been provided by researchers the National Renewable Energy Laboratory (Nikhar J. Abbas, Daniel Zalkind, Alan Wright, and Paul Fleming), Delft University of Technology (Sebastiaan Mulders and Jan-Willem van Wingerden), and the University of Colorado Boulder (Lucy Pao). Much of the intellect behind these contributions has been inspired or derived from an extensive amount of work in the literature. The bulk of this has been cited through the primary publications about this work.

There are also some specific acknowledgements we would like to communicate:
* The setpoint smoothing regime implemented through the ROSCO controller was contributed by sowento GmbH.
* The setpoint smoothing regime implemented through the ROSCO controller was contributed by sowento GmbH.
160 changes: 160 additions & 0 deletions ROSCO/cmake/GetGitRevisionDescription.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# - Returns a version string from Git
#
# These functions force a re-configure on each git commit so that you can
# trust the values of the variables in your build system.
#
# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
#
# Returns the refspec and sha hash of the current head revision
#
# git_describe(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the source tree, and adjusting
# the output so that it tests false if an error occurs.
#
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe --exact-match on the source tree,
# and adjusting the output so that it tests false if there was no exact
# matching tag.
#
# git_local_changes(<var>)
#
# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes.
# Uses the return code of "git diff-index --quiet HEAD --".
# Does not regard untracked files.
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Obtained from https://github.com/rpavlik/cmake-modules/blob/master/GetGitRevisionDescription.cmake
# on August 29 2017
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)

if(__get_git_revision_description)
return()
endif()
set(__get_git_revision_description YES)

# We must run the following at "include" time, not at function call time,
# to find the path to this module rather than the path to a calling list file
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)

function(get_git_head_revision _refspecvar _hashvar)
set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories
set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
# We have reached the root directory, we are not in git
set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
return()
endif()
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
endwhile()
# check if this is a submodule
if(NOT IS_DIRECTORY ${GIT_DIR})
file(READ ${GIT_DIR} submodule)
string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule})
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
endif()
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
if(NOT EXISTS "${GIT_DATA}")
file(MAKE_DIRECTORY "${GIT_DATA}")
endif()

if(NOT EXISTS "${GIT_DIR}/HEAD")
return()
endif()
set(HEAD_FILE "${GIT_DATA}/HEAD")
configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)

configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
"${GIT_DATA}/grabRef.cmake"
@ONLY)
include("${GIT_DATA}/grabRef.cmake")

set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
endfunction()

function(git_describe _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
return()
endif()

execute_process(COMMAND
"${GIT_EXECUTABLE}"
describe --abbrev=8 --tags --dirty
# ${hash}
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()

set(${_var} "${out}" PARENT_SCOPE)
endfunction()

function(git_get_exact_tag _var)
git_describe(out --exact-match ${ARGN})
set(${_var} "${out}" PARENT_SCOPE)
endfunction()

function(git_local_changes _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
return()
endif()

execute_process(COMMAND
"${GIT_EXECUTABLE}"
diff-index --quiet HEAD --
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(res EQUAL 0)
set(${_var} "CLEAN" PARENT_SCOPE)
else()
set(${_var} "DIRTY" PARENT_SCOPE)
endif()
endfunction()
44 changes: 44 additions & 0 deletions ROSCO/cmake/GetGitRevisionDescription.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#
# Internal file for GetGitRevisionDescription.cmake
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Obtained from https://github.com/rpavlik/cmake-modules/blob/master/GetGitRevisionDescription.cmake.in
# on August 29 2017
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)

set(HEAD_HASH)

file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)

string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
if(HEAD_CONTENTS MATCHES "ref")
# named branch
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
else()
configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
set(HEAD_HASH "${CMAKE_MATCH_1}")
endif()
endif()
else()
# detached HEAD
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
endif()

if(NOT HEAD_HASH)
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 8)
string(STRIP "${HEAD_HASH}" HEAD_HASH)
endif()
2 changes: 1 addition & 1 deletion ROSCO/src/ControllerBlocks.f90
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ SUBROUTINE SetpointSmoother(LocalVar, CntrPar, objInst)
! ------ Setpoint Smoothing ------
IF ( CntrPar%SS_Mode == 1) THEN
! Find setpoint shift amount
DelOmega = ((LocalVar%PC_PitComT - CntrPar%PC_MinPit)/0.524) * CntrPar%SS_VSGain - ((CntrPar%VS_RtTq - LocalVar%VS_LastGenTrq))/CntrPar%VS_RtTq * CntrPar%SS_PCGain ! Normalize to 30 degrees for now
DelOmega = ((LocalVar%PC_PitComT - CntrPar%PC_MinPit)/0.524) * CntrPar%SS_VSGain - ((LocalVar%VS_GenPwr - LocalVar%VS_LastGenTrq))/CntrPar%VS_RtPwr * CntrPar%SS_PCGain ! Normalize to 30 degrees for now
DelOmega = DelOmega * CntrPar%PC_RefSpd
! Filter
LocalVar%SS_DelOmegaF = LPFilter(DelOmega, LocalVar%DT, CntrPar%F_SSCornerFreq, LocalVar%iStatus, .FALSE., objInst%instLPF)
Expand Down

0 comments on commit 6a8861f

Please sign in to comment.