Repository navigation
Fixed Blade Pitch Control Updates for MHKs - #508
Conversation
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Unresolved findings remain in cavitation handling, FBP validation and scheduling, case-sweep isolation, and generated DISCON consistency.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 3
Open (3)
What changed in this PR
This PR hardens fixed-blade-pitch MHK control with cavitation screening, validation, scheduling fixes, expanded examples, and updated documentation.
Changes:
- Adds FBP validation, torque de-rating, and cavitation checks.
- Updates controller configurations, case sweeps, and generated inputs.
- Expands MHK documentation and adjusts documentation workflows.
| File | Reviewed change |
|---|---|
rosco/toolbox/utilities.py |
Updates controller descriptions and PRC defaults. |
rosco/toolbox/turbine.py |
Loads MHK cavitation properties. |
rosco/toolbox/ofTools/case_gen/CaseLibrary.py |
Adds full controller sweep support. |
rosco/toolbox/inputs/toolbox_schema.yaml |
Corrects VS_ControlMode documentation. |
rosco/toolbox/controller.py |
Adds FBP validation, scheduling, and cavitation checks. |
rosco/controller/src/ReadSetParameters.f90 |
Allows PRC de-rating with FBP. |
rosco/controller/src/Controllers.f90 |
Applies torque de-rating to FBP limits. |
Examples/Tune_Cases/RM1_MHK.yaml |
Updates MHK operating-range and estimator settings. |
Examples/Tune_Cases/RM1_MHK_FBP.yaml |
Corrects FBP rated-speed configuration. |
Examples/Tune_Cases/NREL5MW.yaml |
Reviews controller configuration documentation. |
Examples/Tune_Cases/NREL5MW_PassThrough.yaml |
Reviews controller configuration documentation. |
Examples/Tune_Cases/IEA15MW.yaml |
Reviews controller configuration documentation. |
Examples/Tune_Cases/IEA15MW_robust.yaml |
Reviews controller configuration documentation. |
Examples/Tune_Cases/IEA15MW_PRC.yaml |
Reviews PRC configuration documentation. |
Examples/Tune_Cases/IEA15MW_OL.yaml |
Reviews open-loop configuration documentation. |
Examples/Tune_Cases/IEA15MW_MultiOmega.yaml |
Reviews controller configuration documentation. |
Examples/Tune_Cases/IEA15MW_FOCAL.yaml |
Reviews controller configuration documentation. |
Examples/Tune_Cases/IEA15MW_ExtInterface.yaml |
Reviews controller configuration documentation. |
Examples/Tune_Cases/IEA15MW_cable.yaml |
Reviews controller configuration documentation. |
Examples/Tune_Cases/IEA15MW_ballast.yaml |
Reviews controller configuration documentation. |
Examples/Tune_Cases/BAR.yaml |
Reviews controller configuration documentation. |
Examples/Test_Cases/NREL-5MW/DISCON.IN |
Updates generated controller inputs. |
Examples/Test_Cases/NREL_2p8_127/NREL-2p8-127_DISCON.IN |
Updates generated controller inputs. |
Examples/Test_Cases/MHK_RM1/MHK_RM1_DISCON.IN |
Updates generated MHK controller inputs. |
Examples/Test_Cases/IEA-15-240-RWT/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_ROSCO.yaml |
Updates generated ROSCO configuration. |
Examples/Test_Cases/IEA-15-240-RWT/IEA-15-240-RWT-UMaineSemi/IEA-15-240-RWT-UMaineSemi_DISCON.IN |
Updates generated controller inputs. |
Examples/Test_Cases/IEA-15-240-RWT/IEA-15-240-RWT-Monopile/IEA-15-240-RWT-Monopile_ROSCO.yaml |
Updates generated ROSCO configuration. |
Examples/Test_Cases/IEA-15-240-RWT/IEA-15-240-RWT-Monopile/IEA-15-240-RWT-Monopile_DISCON.IN |
Updates generated controller inputs. |
Examples/Test_Cases/BAR_10/BAR_10_DISCON.IN |
Updates generated controller inputs. |
Examples/31_fixed_pitch_mhk.py |
Adds six FBP configurations and simulations. |
Examples/26_marine_hydro.py |
Updates the example description. |
docs/source/marine_hydro.rst |
Expands MHK and FBP documentation. |
docs/index.rst |
Adds local documentation build instructions. |
.readthedocs.yaml |
Simplifies documentation dependency installation. |
.github/workflows/Publish_ROSCO.yml |
Adjusts workflow compiler setup. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
abhineet-gupta
left a comment
There was a problem hiding this comment.
Looks good to me.
|
|
||
| .. [Stockhouse2025] Stockhouse, D. *Fixed-Blade-Pitch Control in ROSCO for MHK | ||
| Turbines.* National Renewable Energy Laboratory presentation, 2025. | ||
| (Source material for this page.) |
There was a problem hiding this comment.
Does this line need to be replaced by the DOI of the document?
There was a problem hiding this comment.
This was an unpublished presentation, so we don't have a DOI.
* Increase number of available instances of filters, etc to 1024 * WindIO Support (#492) * Clean up examples to clarify inputs/outputs * Change default ss_pcgain * Add tuning input to change setpoint separation when tuning * Fix directories in ex 06 * Bug fix: Use LSS speed throughout TRA subroutine * Add setpoint separation to DISCON_dict * Test build on macos-latest and not 13, those runners being depreciated * Clarify DISCON description for SD_TimeActivate * Remove macos-13 from publish CI * Tidy example 02 * Increment version * Update discons * Add script for creating windio input yamls * Create rosco vt from windio and functionize * Add windio schema conversion to own file * Make example self-contained in ROSCO * Update inputs for openfast 4.2.0 (#491) * Update inputs for openfast 4.2.0 * Update openfast versions in environment * Pull windIO yamls from their repos for example * Revert to windIO versions because they have the updated control inputs * Account for gearbox ratio in windio conversion (#498) * Account for gearbox ratio in windio conversion * Pin openfast_io pip install * Add windio yaml for nrel-5mw * Fix typo while here * OpenFAST 5.0 Support (#503) * Update RM1 model and control * Update RM1 tuning yaml and SeaState input * Add discon parameter sweep to CaseLibrary * Make shorter MHK example * Update inputs for openfast 4.2.0 * Update openfast versions in environment * Disable cavitcheck, shutdown at 9999 * Tidy MHK example * Increase generator inertia * Set new tuning parameters for RM1 * Update DISCONs * Update input files to openfast v5 * Update environment yaml * Add discon_param sweep to CaseLibrary * Update output file reader so it can grab partial lines without failing * Read elastodyn file more robustly * Skip blade input reading, unused * Increase toml version * Re-generate discons * Add note about getting pre-compiled libraries from conda * Re-generate registry * Update NREL-5MW, RM1 models to OF 5.0 * Update NREL 2.8 MW * Update toml, discons * Update StC_DOF_MODE for OF5, add TEST_MODE * Update FAST.Farm for OF5.0 * Pip install with no-deps * Set default DISCON dict Co-authored-by: Copilot Autofix powered by AI <[email protected]> * Restore explicit GenDOF setting in base_op_case * Use generic DLL_Filename Co-authored-by: Copilot Autofix powered by AI <[email protected]> * Use generic DISCON_LIB_PATH for external users with generic flag * Update StC mode description * Update python versions to >=3.11 * Try manylinux_2_28 * Skip 32-bit linux, not supported with numpy 2.5 * Fix toml format --------- Co-authored-by: dzalkind <[email protected]> Co-authored-by: Copilot Autofix powered by AI <[email protected]> Co-authored-by: copilot-swe-agent[bot] <[email protected]> * Update documentation errors (#506) * Update yaw/rad errors * remove accidental mispelling --------- Co-authored-by: dzalkind <[email protected]> * Fixed Blade Pitch Control Updates for MHKs (#508) * Account for gearbox ratio in windio conversion * Add docs for building the docs * Add more generic param_sweeps * Clean up and sweep all cases in ex 31 * Add a few more checks to FBP modes * Review MHK control docs * Add cavitation check and docs * Align VS_ControlMode with docs * Try mamba install with fewer solves * Re-organize example and docs to follow three main examples * Add soft-start to FBP modes * Update comment, defaults for MHK settings, VS_ControlMode * Add variable-pitch section * Copy-edit the marine_hydro docs * Clarify 2- vs. 3-bladed remarks * Fix and document v_rated change for FBP * Fix Cp_op in below rated FBP * Relocate min rotor speed limits to before they are used in all cases * Fix comment, FULL_TEST * Fix output name * Try skipping the compiler on macoc-14 --------- Co-authored-by: dzalkind <[email protected]> * Deep-copy controller params for each sweep case Controller.__init__ writes per-case OL_* DISCON overrides into the nested open_loop dict, which was shared across sweep cases by the shallow merge, so later cases could inherit an earlier case's open-loop file or indices. Co-Authored-By: Claude Opus 5.5 <[email protected]> * Remove toolbox cavitation check The check needed the steady angle of attack at each blade section to be more than a heuristic, which the toolbox does not have without CCBlade. AeroDyn's CavitCheck does this properly, so drop the toolbox check and keep the cavitation speed limit in the docs as design guidance. Co-Authored-By: Claude Opus 5.5 <[email protected]> --------- Co-authored-by: dzalkind <[email protected]> Co-authored-by: Copilot Autofix powered by AI <[email protected]> Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: Skylar A Gering <[email protected]> Co-authored-by: Claude Opus 5.5 <[email protected]>

Description and Purpose
Review and harden the fixed-blade-pitch (FBP) MHK control path, and document it properly. Came out of a review of the MHK/FBP feature while setting up tidal DLCs in WEIS.
Cavitation check on the operating schedule
Controller.cavitation_speed_limit()estimates the rotor speed at which tip cavitation begins, from the cavitation number criterionsigma > -Cp_minwith the hydrostatic head at the blade tip's shallowest point.Turbinenow loadsPatm,Pvap,MSL2SWL, the tip depth, andsigma_v = -Cp_minfrom the outboard (>=70% span) AeroDyn polars.tune_controllerwarns when the tuned speed schedule crosses that limit. Overspeed schedules raise rotor speed while lowering torque, so the existing torque check cannot catch them. This is a tip, attached-flow screening estimate at a fixed hub depth — the docstring and docs say so, and point at AeroDyn'sCavitCheckfor confirmation.FBP configuration checks
ReadSetParameters.f90aborts on at runtime (PC_ControlMode != 0,VS_ConstPower != 0,PRC_Mode == 1withVS_FBP > 0), rather than writing a DISCON that cannot run.VS_ControlModeis not the Region 2 mode paired with the selectedVS_FBP(1→1, 2→2, 3→4), since both regions drive the same actuator and the references have to agree through the transition.VS_FBP = 1follows a fixed control law and ignores the power curve; the toolbox now says so and generates the schedule ROSCO will actually follow instead of a schedule it silently discards.VS_FBP = 3non-invertible torque schedule failure.Soft start for FBP
VS_MaxTqis now de-rated byPRC_R_Torquein the FBP branch ofControllers.f90, so an open-loopR_Torqueramp can phase in the torque limit while the rotor spins up.PRC_R_Torquedefaults to 1, so existing configurations are unaffected.PRC_Mode = 2(de-rating only) is now allowed alongsideVS_FBP; onlyPRC_Mode = 1, whose speed-setpoint lookup would override the FBP reference, is still rejected. Example 31 uses this for a 100 s sigma ramp on all six configurations.Bug fixes
TSR_operationalregardless of the requested power curve, soCp_opis now held on the Cp surface at that TSR. Previously the(Cp, TSR)pair was not an equilibrium and the resulting speed and torque setpoints were unreachable. Warns when the power curve asks for below-rated curtailment, which FBP cannot do.vs_minspd,pc_minspd) are now set before the operating schedule saturates against them, instead of after, so they apply in all cases rather than only the ones that happened to run later.PRC_WindSpeeds/PRC_GenSpeedsdefaults inutilities.pywere hard-coded to 3–25 m/s and a 7.56 rpm reference; they now derive fromturbine.v_min/v_maxandPC_RefSpd, which matters for MHK speed ranges.VS_ControlModeis documented as the below rated torque mode everywhere (schema, DISCON writer, regenerated DISCON files). It was labeled "above rated" in every one of those places.Examples and case generation
Examples/31_fixed_pitch_mhk.pyreorganized around three verified case studies (constant power overspeed, linear increasing power, generic user-defined curve), each stating itsVS_FBPand pairedVS_ControlModeexplicitly, followed by three experimental configurations that exercise the rest of the input space. Sweeps all cases rather than selecting one by hand.CaseLibrary.sweep_control_paramsaccepts aparam_sweepslist of fullcontroller_paramsoverrides, not just one parameter at a time. The existingcontrol_param/discon_parampath is unchanged, except that adiscon_paramsweep no longer mutates the caller's nestedDISCONdict.RM1_MHK_FBP.yaml:v_ratedcorrected to 1.72 m/s (the rated speed point where the rotor reaches 1.204 rad/s at TSR 7 and the FBP lookup engages, not a rated power point),VS_ControlMode= 4 to pair withVS_FBP= 3.RM1_MHK.yaml:v_max3.0 → 4.0,WE_Mode→ 2 (EKF), and theVS_ConstPowercomment corrected.Documentation
docs/source/marine_hydro.rstsubstantially expanded: a variable-pitch MHK section, over/underspeed reference setpoints and their dynamics, alternate Region 3 operating schedules, rotor speed limits and cavitation, toolbox and ROSCO implementation notes, simulation verification of the three case studies, recommendations, and future work.docs/index.rst: how to build the docs locally..readthedocs.yaml:mamba installwith fewer solves, to speed up the docs build.Type of change
TODO Items General:
TODO Items API Change:
VS_ControlModedescription corrected; no parameters added or removedGithub issues addressed, if one exists
None.
Examples/Testing, if applicable
Examples/31_fixed_pitch_mhk.pynow tunes and simulates all six fixed-pitch configurations in one run, and produces the schedule and simulation figures used in the verification section of the MHK docs. The three verified case studies are compared against ROSCO simulation results there.