Skip to content

Commit

Permalink
Modify example-17a to work with new zeromq wind farm control interfac…
Browse files Browse the repository at this point in the history
…e and some minor changes
  • Loading branch information
abhineet-gupta committed Nov 20, 2023
1 parent 63cc574 commit 8247bc1
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 29 deletions.
47 changes: 23 additions & 24 deletions Examples/17a_zeromq_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,32 @@
from ROSCO_toolbox.inputs.validation import load_rosco_yaml
from ROSCO_toolbox.utilities import write_DISCON
from ROSCO_toolbox import control_interface as ROSCO_ci
from ROSCO_toolbox.control_interface import turbine_zmq_server
from ROSCO_toolbox.control_interface import wfc_zmq_server
from ROSCO_toolbox import sim as ROSCO_sim
from ROSCO_toolbox import turbine as ROSCO_turbine
from ROSCO_toolbox import controller as ROSCO_controller
from ROSCO_toolbox.ofTools.fast_io import output_processing
import numpy as np
import multiprocessing as mp

this_dir = os.path.dirname(os.path.abspath(__file__))
example_out_dir = os.path.join(this_dir, "examples_out")
TIME_CHECK = 30
DESIRED_YAW_OFFSET = 20
DESIRED_PITCH_OFFSET = np.deg2rad(2) * np.sin(0.1 * TIME_CHECK) + np.deg2rad(2)

def run_zmq():
connect_zmq = True
s = turbine_zmq_server(network_address="tcp://*:5555", timeout=10.0)
while connect_zmq:
# Get latest measurements from ROSCO
measurements = s.get_measurements()
def run_zmq(logfile=None):
# Start the server at the following address
network_address = "tcp://*:5555"
server = wfc_zmq_server(network_address, timeout=60.0, verbose=False, logfile=logfile)

# Decide new control input based on measurements
# Provide the wind farm control algorithm as the wfc_controller method of the server
server.wfc_controller = wfc_controller

# Yaw set point
current_time = measurements['Time']
# Run the server to receive measurements and send setpoints
server.runserver()

def wfc_controller(id,current_time,measurements):
if current_time <= 10.0:
yaw_setpoint = 0.0
else:
Expand All @@ -49,18 +52,13 @@ def run_zmq():
col_pitch_command = 0.0

# Send new setpoints back to ROSCO
s.setpoints['ZMQ_TorqueOffset'] = 0.0
s.setpoints['ZMQ_YawOffset'] = yaw_setpoint
s.setpoints['ZMQ_PitOffset(1)'] = col_pitch_command
s.setpoints['ZMQ_PitOffset(2)'] = col_pitch_command
s.setpoints['ZMQ_PitOffset(3)'] = col_pitch_command

s.send_setpoints()

if measurements['iStatus'] == -1:
connect_zmq = False
s._disconnect()

setpoints = {}
setpoints['ZMQ_TorqueOffset'] = 0.0
setpoints['ZMQ_YawOffset'] = yaw_setpoint
setpoints['ZMQ_PitOffset(1)'] = col_pitch_command
setpoints['ZMQ_PitOffset(2)'] = col_pitch_command
setpoints['ZMQ_PitOffset(3)'] = col_pitch_command
return setpoints

def sim_rosco():
# Load yaml file
Expand Down Expand Up @@ -168,9 +166,10 @@ def sim_rosco():
np.testing.assert_almost_equal(local_vars[0]['ZMQ_PitOffset'][ind_30], DESIRED_PITCH_OFFSET, decimal=3)

if __name__ == "__main__":
p1 = mp.Process(target=run_zmq)
logfile = os.path.join(example_out_dir,os.path.splitext(os.path.basename(__file__))[0]+'.log')
p1 = mp.Process(target=run_zmq,args=(logfile,))
p1.start()
p2 = mp.Process(target=sim_rosco)
p2.start()
p1.join()
p2.join()
p2.join()
15 changes: 11 additions & 4 deletions Examples/17b_zeromq_multi_openfast.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
this_dir = os.path.dirname(os.path.abspath(__file__))
example_out_dir = os.path.join(this_dir, "examples_out")
os.makedirs(example_out_dir, exist_ok=True)
TIME_CHECK = 30
TIME_CHECK = 20
DESIRED_YAW_OFFSET = [-10, 10]


Expand All @@ -20,7 +20,7 @@ def run_zmq(logfile=None):

# Start the server at the following address
network_address = "tcp://*:5555"
server = wfc_zmq_server(network_address, timeout=60.0, verbose=True, logfile = logfile)
server = wfc_zmq_server(network_address, timeout=60.0, verbose=False, logfile = logfile)

# Provide the wind farm control algorithm as the wfc_controller method of the server
server.wfc_controller = wfc_controller
Expand All @@ -42,13 +42,20 @@ def wfc_controller(id, current_time, measurements):
"""
if current_time <= 10.0:
YawOffset = 0.0
col_pitch_command = 0.0
else:
col_pitch_command = np.deg2rad(2) * np.sin(0.1 * current_time) + np.deg2rad(2) # Implement dynamic induction control
if id == 1:
YawOffset = DESIRED_YAW_OFFSET[0]
else:
YawOffset = DESIRED_YAW_OFFSET[1]


setpoints = {}
setpoints["ZMQ_YawOffset"] = YawOffset
setpoints['ZMQ_PitOffset(1)'] = col_pitch_command
setpoints['ZMQ_PitOffset(2)'] = col_pitch_command
setpoints['ZMQ_PitOffset(3)'] = col_pitch_command
return setpoints


Expand All @@ -59,7 +66,7 @@ def sim_openfast_1():
r.wind_case_fcn = cl.power_curve
r.wind_case_opts = {
"U": [8],
"TMax": 100,
"TMax": 25,
}
run_dir = os.path.join(example_out_dir, "17b_zeromq_OF1")
r.controller_params = {}
Expand All @@ -78,7 +85,7 @@ def sim_openfast_2():
r.wind_case_fcn = cl.power_curve
r.wind_case_opts = {
"U": [8],
"TMax": 100,
"TMax": 25,
}
run_dir = os.path.join(example_out_dir, "17b_zeromq_OF2")
r.save_dir = run_dir
Expand Down
1 change: 0 additions & 1 deletion ROSCO/src/ZeroMQInterface.f90
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ end subroutine zmq_client

write (zmq_address, '(A,A)') TRIM(CntrPar%ZMQ_CommAddress), C_NULL_CHAR
#ifdef ZMQ_CLIENT
write(*,*) 'Spawning a zeromq client and waiting for server...'
call zmq_client(zmq_address, turbine_measurements, setpoints)
#else
! Add RoutineName to error message
Expand Down

0 comments on commit 8247bc1

Please sign in to comment.