Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/RWTH-EBC/pyDMPC
Browse files Browse the repository at this point in the history
# Conflicts:
#	pyDMPC/ControlFramework/Init.py
#	pyDMPC/ControlFramework/Subsystem.py
  • Loading branch information
MBaranskiEBC committed Jul 29, 2019
2 parents 615796f + d8d53c0 commit 708fee7
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 302 deletions.
2 changes: 1 addition & 1 deletion pyDMPC/ControlFramework/Experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def main():
start_time = time.time()
sys.execute()
#time.sleep(max(0, min_samp_inter - time.time() + start_time))

System.Bexmoc.close_mod()
System.Bexmoc.close_cont_sys()
print("Success")
Expand Down
26 changes: 13 additions & 13 deletions pyDMPC/ControlFramework/Init.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
contr_sys_typ = "Modelica"
ads_id = '5.59.199.202.1.1'
ads_port = 851
name_fmu = r'ModelicaModels_ControlledSystems_ControlledSystemBoundaries.fmu'
name_fmu = 'ModelicaModels_ControlledSystems_ControlledSystemBoundaries.fmu'
orig_fmu_path = glob_res_path + '\\' + name_fmu
dest_fmu_path = glob_res_path + '\\' + name_wkdir + '\\' + name_fmu
time_incr = 120
Expand Down Expand Up @@ -71,26 +71,26 @@
par_neigh.append(None)
input_names.append(["coolerTemperature.T"])
input_variables.append([r"variation.table[1,2]"])
inputs.append(range(280,325,5))
inputs.append([i for i in range(280,325,1)])
output_names.append(["supplyAirTemperature.T"])
set_points.append([303])
state_var_names.append(["heaterInitials[1].y"])
model_state_var_names.append(["mas1.k"])
start.append(0.)
stop.append(3600)
incr.append(10.)
opt_time.append(0)
samp_time.append(10)
opt_time.append(600)
samp_time.append(60)
lib_paths.append(glob_lib_paths)
res_path.append(glob_res_path + "\\" + name_wkdir)
dym_path.append(glob_dym_path)
mod_path.append(r'D:\dymola\heater')
mod_path.append(f'{glob_res_path}\\heater')
command_names.append(["valveHeater"])
command_variables.append(["decisionVariables.table[1,2]"])
commands.append(range(0,105,5))
commands.append([[0,0], [10,10], [30,30], [60,60], [80,80], [100,100]])
traj_points.append([])
traj_var.append([])
cost_fac.append([0.5, 0.0, 1.0])
cost_fac.append([0.1, 0.0, 1.0])

sys_id.append(1)
name.append("Cooler")
Expand All @@ -100,23 +100,23 @@
par_neigh.append(None)
input_names.append(["preHeaterTemperature.T"])
input_variables.append([r"variation.table[1,2]"])
inputs.append(range(280,325,5))
inputs.append([i for i in range(280,325,1)])
output_names.append(["supplyAirTemperature.T"])
set_points.append([303])
state_var_names.append(["coolerInitials[1].y"])
model_state_var_names.append(["hex.ele[1].mas.T"])
start.append(0.)
stop.append(3600.)
incr.append(10.)
opt_time.append(0)
samp_time.append(10)
opt_time.append(600)
samp_time.append(60)
lib_paths.append(glob_lib_paths)
res_path.append(glob_res_path + "\\" + name_wkdir)
dym_path.append(glob_dym_path)
mod_path.append(r'D:\dymola\cooler')
mod_path.append(f'{glob_res_path}\\cooler')
command_names.append(["valveCooler"])
command_variables.append(["decisionVariables.table[1,2]"])
commands.append(range(0,105,5))
commands.append([[0,0], [2,2], [4,4], [6,6], [8,8], [10,10], [12,12], [14,14], [16,16], [18,18], [20,20], [22,22]])
traj_points.append([])
traj_var.append([])
cost_fac.append([0.5, 1.0, 0])
cost_fac.append([0.0, 1.0, 0])
29 changes: 20 additions & 9 deletions pyDMPC/ControlFramework/Modeling.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,19 +195,28 @@ def translate(self):

def simulate(self):
ModelicaMod.dymola.cd(self.paths.res_path)

command_variables = [f"decisionVariables.table[{i+1},2]"
for i in range(1)]

time_variables = [f"decisionVariables.table[{i+1},1]"
for i in range(1)]

times = [i*600 for i in range(1)]

if self.states.input_variables[0] == "external":
initialNames = (self.states.command_variables +
self.states.model_state_var_names)
initialValues = (self.states.commands + self.states.state_vars)
self.states.model_state_var_names + time_variables)
initialValues = (self.states.commands + self.states.state_vars + times)
else:
initialValues = (self.states.commands + self.states.inputs +
self.states.state_vars)
self.states.state_vars + times)

initialNames = (self.states.command_variables +
initialNames = (command_variables +
self.states.input_variables +
self.states.model_state_var_names)
self.states.model_state_var_names + time_variables)
print(initialNames)
print(initialValues)


for k in range(3):
Expand Down Expand Up @@ -267,17 +276,19 @@ def load_mod(self):
def write_inputs(self):
import numpy as np

commands = [com*np.ones(60) for com in self.states.commands]
inputs = [inp*np.ones(60) for inp in self.states.inputs]
commands_1 = self.states.commands[0]*np.ones(10)
commands_2 = self.states.commands[1]*np.ones(50)
commands = commands_1.tolist() + commands_2.tolist()
inputs = self.states.inputs[0]*np.ones(60)
inputs = inputs.tolist()

inputs = np.stack((commands + inputs), axis=1)
inputs = np.stack(([commands] + [inputs]), axis=1)

self.scal_inputs = self.scaler.transform(inputs)

def predict(self):
self.write_inputs()
self.states.outputs = [self.model.predict(self.scal_inputs)]
#print(f"MLP outputs: {self.states.outputs}")

class LinMod(Model):

Expand Down
53 changes: 24 additions & 29 deletions pyDMPC/ControlFramework/Subsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ def predict(self, inputs, commands):

if self.model.states.state_var_names != []:
for i,nam in enumerate(self.model.states.state_var_names):
#print("State variable names: " + str(nam))
state_vars.append(System.Bexmoc.read_cont_sys(nam))

if inputs != "external":
Expand Down Expand Up @@ -150,16 +149,13 @@ def interp_minimize(self, interp):
from scipy import interpolate as it
import time

#print('minimizing')

opt_costs = []
opt_outputs = []
opt_command = []

states = self.get_state_vars()
if states != []:
self.model.states.state_vars = states[0]
#print(f"States: {self.model.states.state_vars}")

if self.model.states.input_variables[0] != "external":
if self.inputs == []:
Expand All @@ -180,14 +176,12 @@ def interp_minimize(self, interp):
costs = []

for com in self.commands:
results = self.predict(inp, [com])
results = self.predict(inp, com)
outputs.append(results)
costs.append(self.calc_cost(com, results[-1][-1]))

min_ind = costs.index(min(costs))

#print("index: " + str(min_ind))

opt_costs.append(costs[min_ind])
temp = outputs[min_ind]
opt_outputs.append(temp[0][-1])
Expand All @@ -200,6 +194,7 @@ def interp_minimize(self, interp):
for pts in self.traj_points:
traj_costs.append((pts - set_point)**2)


self.traj_points.insert(self.traj_points[0] - 1.)
traj_costs.insert(traj_costs[0] * 5)
self.traj_points.append(self.traj_points[-1] + 1)
Expand All @@ -221,7 +216,6 @@ def interp_minimize(self, interp):

if len(inputs) >= 2:
if interp:

self.coup_vars_send = opt_outputs
self.command_send = it.interp1d(inputs, opt_command,
fill_value = (100,100), bounds_error = False)
Expand All @@ -233,75 +227,74 @@ def interp_minimize(self, interp):
self.coup_vars_send = opt_outputs[0]
self.command_send = opt_command[0]

print(f"self.cost_send: {self.cost_send}")
time.sleep(2)
print(f"Command: {self.command_send}")

def calc_cost(self, command, outputs):
import scipy.interpolate
import numpy as np

cost = self.cost_fac[0] * command
cost = self.cost_fac[0] * sum(command)

if self.cost_rec != [] and self.cost_rec != [[]]:
for c in self.cost_rec:
if type(c) is scipy.interpolate.interpolate.interp1d:
cost += self.cost_fac[1] * c(outputs)
#print(f"Interp. cost: {c(outputs)}")
elif type(c) is list:
cost += self.cost_fac[1] * c[0]
idx = self.find_nearest(np.asarray(self.inputs), outputs)
cost += self.cost_fac[1] * c[idx]
else:
cost += self.cost_fac[1] * c


if self.model.states.set_points != []:
cost += (self.cost_fac[2] * (outputs -
self.model.states.set_points[0])**2)

return cost

def find_nearest(self, a, a0):
import numpy as np
"Element in nd array `a` closest to the scalar value `a0`"
idx = np.abs(a - a0).argmin()

return idx

def interp(self, iter_real):
import scipy.interpolate
import time
import numpy as np

if iter_real == "iter" and self.coup_vars_rec != []:
inp = self.coup_vars_rec
else:
inp = self.model.states.inputs

#print(f"{self.name}: {inp}")
idx = self.find_nearest(np.asarray(self.inputs), inp[0])

if self.command_send != []:
if (type(self.command_send) is scipy.interpolate.interpolate.interp1d):
self.fin_command = self.command_send(inp[0])
else:
self.fin_command = self.command_send[0]
self.fin_command = self.command_send[idx]

if self.coup_vars_send != []:
if type(self.coup_vars_send) is scipy.interpolate.interpolate.interp1d:
self.fin_coup_vars = self.coup_vars_send(inp[0])
else:
self.fin_coup_vars = self.coup_vars_send

#print(f"{self.name}: {self.fin_command}")
#time.sleep(2)
self.fin_coup_vars = self.coup_vars_send[idx]

def get_inputs(self):

cur_time = Time.Time.get_time()
#print("Time: " + str(cur_time))
#print("Sample time: " + str(self.model.times.samp_time))

inputs = []
#print("Input variables: "+ str(self.model.states.input_variables))

if self.model.states.input_variables is not None:
for nam in self.model.states.input_names:
#print("check")
inputs.append(System.Bexmoc.read_cont_sys(nam))
#print("Inputs" + str(inputs))

self.model.states.inputs = inputs

def get_state_vars(self):

cur_time = Time.Time.get_time()

states = []

if self.model.states.state_var_names is not None:
Expand All @@ -316,7 +309,9 @@ def send_commands(self):

if (cur_time - self.last_write) > self.model.times.samp_time:
self.last_write = cur_time

print(self.fin_command[0])

if self.model.states.command_names is not None:
for nam in self.model.states.command_names:
System.Bexmoc.write_cont_sys(nam, self.fin_command)
System.Bexmoc.write_cont_sys(nam, self.fin_command[0])
14 changes: 8 additions & 6 deletions pyDMPC/ControlFramework/System.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,10 @@ def initialize(self):
def execute(self):

for i in range(len(self.subsystems)):
self.subsystems[i].optimize(interp=True)
self.subsystems[i].optimize(interp=False)
if self.subsystems[i].par_neigh is not None:
for j in self.subsystems[i].par_neigh:
self.subsystems[j].optimize(interp=True)
self.subsystems[j].optimize(interp=False)
self.broadcast([i] + self.subsystems[i].par_neigh)
else:
#print(f"Broadcasting: {i}")
Expand All @@ -253,8 +253,7 @@ def execute(self):
cur_time = Time.Time.get_time()

Bexmoc.proceed(cur_time, Time.Time.time_incr)
tim = Time.Time.set_time()
#print("Time: " + str(tim))
Time.Time.set_time()

def iterate(self):
import time
Expand Down Expand Up @@ -292,10 +291,13 @@ def iterate(self):
#print(f"Coupling: {sub.coup_vars_rec[0]}")
if (self.subsystems[1].inputs[0] <
self.subsystems[1].model.states.set_points[0]):
sub.inputs = [min(sub.coup_vars_rec[0], sub.model.states.set_points[0] - 0.5), sub.model.states.set_points[0]]
sub.inputs = [min(sub.coup_vars_rec[0],
sub.model.states.set_points[0] - 0.5),
sub.model.states.set_points[0]]
else:
sub.inputs = [max(sub.coup_vars_rec[1],
sub.model.states.set_points[0] + 0.5), sub.model.states.set_points[0]]
sub.model.states.set_points[0] + 0.5),
sub.model.states.set_points[0]]

sub.inputs.sort()
print(f"{sub.name}: {sub.inputs}")
Expand Down
Loading

0 comments on commit 708fee7

Please sign in to comment.