I have a question about how the use of generator speed is calculated within OpenFAST/ROSCO and Simulink. I am interested in controlling blade pitch angle to track the rated generator speed in Region 3 control.
When determining control based on the ROSCO paper, the generator speed can be calculated as follows:
However, there seems to be a discrepancy between the above formulation and how Simulink, and moreover the S-Function block handles. I know it has something to do with the interpolation order, but I am unsure of what is exactly happening inside the S-Func block.
How does the S-Func block take in the commanded blade pitch angle and current generator speed and output the next timestep’s generator speed?
The OpenFAST S-Function block does not use this equation, although certainly it is using a balance between the aerodynamic torque and generator torque to compute the generator acceleration and time-integrating. The big differences are that OpenFAST does not use a simple Cp curve (but rather solves the aeroelastics of the rotor to compute the torque) and OpenFAST does not time-integrate with a simple first-order Euler scheme (but rather the time integrator is of higher order).
So the S-Function block solves the aeroelastics of the rotor in order to output the next time step. Is there a way to see this in the source code? The S-Function block doesn’t show what’s going inside of it.
Yes, that is correct. The S-Function is simply a wrapper to call the OpenFAST dynamic library, where the equations of motion of the wind turbine are solved. This is best documented in Figure 8 and the associated text in the FAST v8 ReadMe file (the documentation of which has not been fully ported to OpenFAST readthedocs): https://openfast.readthedocs.io/en/main/_downloads/5f2ddf006568adc9b88d8118dc3f1732/FAST8_README.pdf.
The document has been helpful in showing how the solver gets called. I still have some doubts, however. In my control formulation, I’m interested in finding the actual generator speed as calculated by OpenFAST instead of the equations in my first image. Inside MATLAB and Simulink, there is the S-Function block which can be called as:
Which gives a 40 long vector and can even be called in a script. I looked into the source code in FAST_SFunc.c and as far as I understand the parameters taken in are:
FAST_SFunc(FAST_InputFileName, TMax, 0, Flag)
I have two questions following this:
- In Simulink, we give the SFunc block a vector of inputs. How does these inputs get put into FAST_SFunc?
- Is it possible to call the SFunc in multiple places within Simulink and inside function blocks?
The FAST_SFunc.c file is the C-based source code that gets compiled into the Level-2 S-Function (MEX function) that is called by MATLAB/Simulink. It is in this source code that the S-Function block calls the OpenFAST Dynamic Library, and transfers the inputs from MATLAB/Simulink to OpenFAST and transfers the outputs from OpenFAST to MATLAB/Simulink. The actual calls and data transfers to/from the OpenFAST Dynamic Library take place in the calls to
I’m not sure I understand your second question, or what use case you are considering.
FYI: The actual generator speed calculated by OpenFAST can be output and returned to MATLAB/Simulink via ElastoDyn output
GenSpeed, which will be included in the
OutData array returned and accessible by MATLAB/Simulink when specified within the
OutList of ElastoDyn.