Skip to content

Commit

Permalink
Merge commit '2d3c83c16cfd935bfd73f883e144e258fce4718c' into docs
Browse files Browse the repository at this point in the history
  • Loading branch information
nikhar-abbas committed May 13, 2021
2 parents 71567be + 2d3c83c commit fd7b0b1
Show file tree
Hide file tree
Showing 11 changed files with 194 additions and 29 deletions.
19 changes: 19 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
## Description and Purpose

## Type of change
What types of change is it?
_Select the appropriate type(s) that describe this PR_

- [ ] Bugfix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (non-backwards-compatible fix or feature)
- [ ] Code style update (formatting, renaming)
- [ ] Refactoring (no functional changes, no API changes)
- [ ] Documentation update
- [ ] Maintenance update
- [ ] Other (please describe)

## Github issues addressed, if one exists

## Examples/Testing, if applicable

106 changes: 106 additions & 0 deletions .github/workflows/CI_rosco-toolbox.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: CI_rosco-toolbox

# We run CI on push commits on all branches
on: [push, pull_request]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
build:
name: Build (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
os: ["ubuntu-latest", "macOS-latest", "windows-latest"]
python-version: ["3.8"]
defaults:
run:
shell: bash -l {0}

steps:
- name: Checkout repository and submodules
uses: actions/checkout@v2
with:
submodules: recursive

- name: Setup environment
uses: conda-incubator/setup-miniconda@v2
with:
miniconda-version: "latest"
channels: conda-forge, general
auto-update-conda: true
python-version: 3.8
environment-file: environment.yml


# Install dependencies of ROSCO toolbox
- name: Add dependencies ubuntu specific
if: false == contains( matrix.os, 'windows')
run: |
conda install -y compilers
conda install -y wisdem
- name: Add dependencies windows specific
if: true == contains( matrix.os, 'windows')
run: |
conda install -y m2w64-toolchain libpython
conda install -y wisdem
# Install ROSCO toolbox
- name: Install ROSCO toolbox
run: |
python setup.py develop --compile-rosco
run_examples:
name: Run Examples
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
os: ["ubuntu-latest"] #, "macOS-latest"]
python-version: ["3.8"]
defaults:
run:
shell: bash -l {0}

steps:
- name: Checkout repository and submodules
uses: actions/checkout@v2
with:
submodules: recursive

- name: Setup environment
uses: conda-incubator/setup-miniconda@v2
with:
miniconda-version: "latest"
channels: conda-forge, general
auto-update-conda: true
python-version: 3.8
environment-file: environment.yml


# Install dependencies of ROSCO toolbox
- name: Add dependencies ubuntu specific
if: false == contains( matrix.os, 'windows')
run: |
conda install -y compilers
conda install -y wisdem
# Install ROSCO toolbox
- name: Install ROSCO toolbox
run: |
python setup.py develop --compile-rosco
# Install OpenFAST
- name: Install OpenFAST
run: |
conda install openfast==2.5.0
# Run examples
- name: Run examples
run: |
cd Examples
python run_examples.py
4 changes: 3 additions & 1 deletion Examples/example_09.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,7 @@
wind_directory = os.path.join(this_dir,'../Test_Cases/Wind/')
turbsim_infile = '90m_12mps_twr.inp'

run_openfast(wind_directory, fastcall='turbsim', fastfile=turbsim_infile, chdir=False)
run_openfast(wind_directory, fastcall='turbsim',
fastfile=os.path.join(wind_directory, turbsim_infile), chdir=False)

print('test')
4 changes: 3 additions & 1 deletion Examples/run_examples.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import unittest
import sys
from time import time
import importlib

Expand Down Expand Up @@ -100,4 +101,5 @@ def suite():


if __name__ == "__main__":
unittest.TextTestRunner().run(suite())
result = unittest.TextTestRunner().run(suite())
sys.exit(not result.wasSuccessful())
46 changes: 39 additions & 7 deletions ROSCO_toolbox/control_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.

from ctypes import byref, cdll, c_int, POINTER, c_float, c_char_p, c_double, create_string_buffer, c_int32
from ctypes import byref, cdll, c_int, POINTER, c_float, c_char_p, c_double, create_string_buffer, c_int32, c_void_p
import numpy as np
from numpy.ctypeslib import ndpointer

Expand All @@ -35,19 +35,31 @@ class ControllerInterface():
"""

def __init__(self, lib_name, param_filename='DISCON.IN'):
def __init__(self, lib_name, param_filename='DISCON.IN', **kwargs):
"""
Setup the interface
"""
self.lib_name = lib_name
self.param_name = param_filename

# Temp fixed parameters
# Set default parameters
# PARAMETERS
self.DT = 0.1
self.num_blade = 3
self.char_buffer = 500
self.avr_size = 500
self.sim_name = 'simDEBUG'

# Set kwargs, like DT
for (k, w) in kwargs.items():
try:
setattr(self, k, w)
except:
pass

self.init_discon()

def init_discon(self):

# Initialize
self.pitch = 0
Expand All @@ -56,10 +68,12 @@ def __init__(self, lib_name, param_filename='DISCON.IN'):
self.discon = cdll.LoadLibrary(self.lib_name)
self.avrSWAP = np.zeros(self.avr_size)

# Define some avrSWAP parameters
# Define some avrSWAP parameters, NOTE: avrSWAP indices are offset by -1 from Fortran
self.avrSWAP[2] = self.DT
self.avrSWAP[60] = self.num_blade
self.avrSWAP[20] = 1 # HARD CODE initial rot speed = 1 rad/s
self.avrSWAP[19] = 1.0 # HARD CODE initial gen speed = 1 rad/s
self.avrSWAP[20] = 1.0 # HARD CODE initial rot speed = 1 rad/s
self.avrSWAP[82] = 0 # HARD CODE initial nacIMU = 0
self.avrSWAP[26] = 10 # HARD CODE initial wind speed = 10 m/s


Expand All @@ -76,7 +90,7 @@ def __init__(self, lib_name, param_filename='DISCON.IN'):
self.aviFAIL = c_int32() # 1
self.accINFILE = self.param_name.encode('utf-8')
# self.avcOUTNAME = create_string_buffer(1000) # 'DEMO'.encode('utf-8')
self.avcOUTNAME = 'simDEBUG.dbg'.encode('utf-8')
self.avcOUTNAME = (self.sim_name + '.RO.dbg').encode('utf-8')
self.avcMSG = create_string_buffer(1000)
self.discon.DISCON.argtypes = [POINTER(c_float), POINTER(c_int32), c_char_p, c_char_p, c_char_p] # (all defined by ctypes)

Expand All @@ -103,7 +117,7 @@ def call_discon(self):
self.avrSWAP = data


def call_controller(self,t,dt,pitch,torque,genspeed,geneff,rotspeed,ws):
def call_controller(self,t,dt,pitch,torque,genspeed,geneff,rotspeed,ws,NacIMU_FA_Acc=0):
'''
Runs the controller. Passes current turbine state to the controller, and returns control inputs back
Expand All @@ -123,6 +137,9 @@ def call_controller(self,t,dt,pitch,torque,genspeed,geneff,rotspeed,ws):
rotor speed, (rad/s)
ws: float
wind speed, (m/s)
NacIMU_FA_Acc : float
nacelle IMU accel. in the nodding dir. , (m/s**2)
default to 0 (fixed-bottom, simple 1-DOF sim does not include it, but OpenFAST linearizations do)
'''

# Add states to avr
Expand All @@ -136,6 +153,7 @@ def call_controller(self,t,dt,pitch,torque,genspeed,geneff,rotspeed,ws):
self.avrSWAP[19] = genspeed
self.avrSWAP[20] = rotspeed
self.avrSWAP[26] = ws
self.avrSWAP[82] = NacIMU_FA_Acc

# call controller
self.call_discon()
Expand All @@ -152,3 +170,17 @@ def show_control_values(self):
'''
print('Pitch',self.pitch)
print('Torque',self.torque)

def kill_discon(self):
'''
Unload the dylib from memory: https://stackoverflow.com/questions/359498/how-can-i-unload-a-dll-using-ctypes-in-python
This is unix-specific, but there seems to be a windows solution as well
'''

print('Shutting down {}'.format(self.lib_name))
handle = self.discon._handle
dlclose_func = self.discon.dlclose
dlclose_func.argtypes = [c_void_p]

del self.discon
dlclose_func(handle)
23 changes: 8 additions & 15 deletions ROSCO_toolbox/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
from matplotlib import transforms
from itertools import takewhile, product
import struct
import subprocess
import ROSCO_toolbox

from ROSCO_toolbox.ofTools.util import spectral
# Some useful constants
now = datetime.datetime.now()
pi = np.pi
Expand Down Expand Up @@ -455,7 +455,7 @@ def DISCON_dict(turbine, controller, txt_filename=None):
return DISCON_dict


def run_openfast(fast_dir,fastcall='openfast',fastfile=None,chdir=False):
def run_openfast(fast_dir, fastcall='openfast', fastfile=None, chdir=True):
'''
Runs a openfast openfast simulation.
Expand Down Expand Up @@ -483,18 +483,11 @@ def run_openfast(fast_dir,fastcall='openfast',fastfile=None,chdir=False):
print('Using {} to run OpenFAST simulation'.format(fastfile))

if chdir: # Change cwd before calling OpenFAST -- note: This is an artifact of needing to call OpenFAST from the same directory as DISCON.IN
# save starting file path
original_path = os.getcwd()
# change path, run OpenFAST
os.chdir(fast_dir)
print('Running OpenFAST simulation for {} through the ROSCO toolbox...'.format(fastfile))
os.system('{} {}'.format(fastcall, os.path.join(fastfile)))
print('OpenFAST simulation complete. ')
# return to original path
os.chdir(original_path)
cwd = fast_dir
else:
# Run OpenFAST
print('Running OpenFAST simulation for {} through the ROSCO toolbox...'.format(fastfile))
os.system('{} {}'.format(fastcall, os.path.join(fast_dir,fastfile)))
print('OpenFAST simulation complete. ')
cwd = None

print('Running OpenFAST simulation for {} through the ROSCO toolbox...'.format(fastfile))
# os.system('{} {}'.format(fastcall, os.path.join(fastfile)))
subprocess.run([fastcall, os.path.join(fastfile)], check=True, cwd=cwd)
print('OpenFAST simulation complete.')
2 changes: 1 addition & 1 deletion Test_Cases/BAR_10/BAR_10_ServoDyn.dat
Original file line number Diff line number Diff line change
Expand Up @@ -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/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]
"../../ROSCO/install/lib/libdiscon.so" 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]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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/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]
"../../ROSCO/install/lib/libdiscon.so" 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]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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/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]
"../../ROSCO/install/lib/libdiscon.so" 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]
Expand Down
4 changes: 2 additions & 2 deletions docs/source/rosco_toolbox.rst
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ A yaml_ formatted input file is used for the standard ROSCO toolbox tuning proce
- :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.)
- Wind speed estimator mode. 0: One-second low pass filtered hub height wind speed, 1: Immersion and Invariance Estimator (Ortega et al.), 2: Extended Kalman filter
* -
- :code:`PS_Mode`
- Yes
Expand Down Expand Up @@ -277,4 +277,4 @@ A yaml_ formatted input file is used for the standard ROSCO toolbox tuning proce

.. _OpenFAST: https://github.com/openfast/openfast
.. _yaml: https://yaml.org/
.. _yaml: https://yaml.org/
11 changes: 11 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
channels:
- conda-forge
- defaults

dependencies:
- matplotlib
- numpy
- pytest
- scipy
- pyYAML
- pandas

0 comments on commit fd7b0b1

Please sign in to comment.