From ec9703fc6d1c08897519150859732bd0d7b79ba9 Mon Sep 17 00:00:00 2001 From: Brecht Baeten Date: Sat, 28 Oct 2017 14:26:10 +0200 Subject: [PATCH] changed the progressbar implementation and updated unittests to run the examples --- doc/examples/quickstart.hires.png | Bin 0 -> 53862 bytes doc/examples/quickstart.pdf | Bin 0 -> 9651 bytes doc/examples/quickstart.png | Bin 0 -> 16659 bytes doc/examples/quickstart.py | 189 +++++++++++++++++++++++++++ doc/source/mpc.rst | 2 +- examples/quickstart.py | 17 ++- examples/simple_space_heating_mpc.py | 7 +- mpcpy/mpc.py | 40 +++--- tests/examples.py | 26 +--- 9 files changed, 224 insertions(+), 57 deletions(-) create mode 100644 doc/examples/quickstart.hires.png create mode 100644 doc/examples/quickstart.pdf create mode 100644 doc/examples/quickstart.png create mode 100644 doc/examples/quickstart.py diff --git a/doc/examples/quickstart.hires.png b/doc/examples/quickstart.hires.png new file mode 100644 index 0000000000000000000000000000000000000000..6d35fa4439ab6f8b605a4d0738f11510610b0faf GIT binary patch literal 53862 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�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 _?uNjlCNG^Ir`fJrBIa>hJ&k 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 literal 0 HcmV?d00001 diff --git a/doc/examples/quickstart.pdf b/doc/examples/quickstart.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b25b1af570cfbf0869fe7e796b3322718485f6c1 GIT binary patch literal 9651 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 literal 0 HcmV?d00001 diff --git a/doc/examples/quickstart.png b/doc/examples/quickstart.png new file mode 100644 index 0000000000000000000000000000000000000000..d0dc89b9dffdb727287f47e4b2cc6023ff9871a2 GIT binary patch literal 16659 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. +################################################################################ + +import numpy as np +import matplotlib.pyplot as plt + +import mpcpy +import pyomo.environ as pyomo + + +# Define an emulator class +class Emulator(mpcpy.Emulator): + """ + A custom system emulator + """ + def simulate(self, starttime, stoptime, input): + dt = 1 + time = np.arange(starttime, stoptime+dt, dt, dtype=np.float) + + # initialize + x = np.ones_like(time)*self.res['x'][-1] + + # interpolate inputs + u = np.interp(time, input['time'], input['u']) + d = np.interp(time, input['time'], input['d']) + + # perform simulation + for i, t in enumerate(time[:-1]): + # dx/dt = A*x + d + u + x[i+1] = x[i] + (self.parameters['A']*x[i] + d[i] + u[i])*dt + + # create and return a results dict + res = { + 'time': time, + 'x': x, + 'd': d, + 'u': u, + } + + return res + + +# Define a control class +class SetpointControl(mpcpy.Control): + """ + A control to keep the state as close to a set point as possible + """ + def formulation(self): + # create a pyomo model + model = pyomo.AbstractModel() + + model.i = pyomo.Set() + model.ip = pyomo.Set() + + model.time = pyomo.Param(model.ip) + model.d = pyomo.Param(model.ip, initialize=0.) + model.x = pyomo.Var(model.ip, domain=pyomo.Reals, initialize=0.) + model.u = pyomo.Var(model.ip, domain=pyomo.NonNegativeReals, bounds=(0., 1.), initialize=0.) + + model.x0 = pyomo.Param(initialize=0.) + + model.initialcondition = pyomo.Constraint( + rule=lambda model: model.x[0] == model.x0 + ) + + model.constraint = pyomo.Constraint( + model.i, + rule=lambda model, i: (model.x[i+1]-model.x[i])/(model.time[i+1]-model.time[i]) == + self.parameters['A']*model.x[i] + model.d[i] + model.u[i] + ) + + model.objective = pyomo.Objective( + rule=lambda model: sum((model.x[i]-self.parameters['set'])**2 for i in model.i) + ) + + # store the model inside the object + self.model = model + + def solution(self, sta, pre): + # create data and instantiate the pyomo model + ip = np.arange(len(pre['time'])) + data = { + None: { + 'i': {None: ip[:-1]}, + 'ip': {None: ip}, + 'time': {(i,): v for i, v in enumerate(pre['time'])}, + 'x0': {None: sta['x']}, + 'd': {(i,): pre['d'][i] for i in ip}, + } + } + + instance = self.model.create_instance(data) + + # solve and return the control inputs + optimizer = pyomo.SolverFactory('ipopt') + results = optimizer.solve(instance) + + sol = { + 'time': np.array([pyomo.value(instance.time[i]) for i in instance.ip]), + 'x': np.array([pyomo.value(instance.x[i]) for i in instance.ip]), + 'u': np.array([pyomo.value(instance.u[i]) for i in instance.ip]), + 'd': np.array([pyomo.value(instance.d[i]) for i in instance.ip]), + } + + return sol + + +# Define a state estimation class +class StateestimationPerfect(mpcpy.Stateestimation): + """ + Perfect state estimation + """ + def stateestimation(self, time): + return {'x': np.interp(time, self.emulator.res['time'], self.emulator.res['x'])} + + +# instantiate the emulator +emulator = Emulator(['u', 'd'], parameters={'A': -0.2}, initial_conditions={'x': 0}) + +# test the emulator with some random data +time = np.arange(0., 1001., 10.) +np.random.seed(0) +d = np.random.random(len(time)) - 0.5 +u = 1.0*np.ones(len(time)) + +emulator.initialize() +res = emulator(time, {'time': time, 'd': d, 'u': u}) +print(res) + + +# create a disturbances object +time = np.arange(0., 1001., 10.) +d = 0.5*np.sin(2*np.pi*time/1000) +disturbances = mpcpy.Disturbances({'time': time, 'd': d}) + +bcs = disturbances(np.array([0, 20, 40, 60, 100])) +print(bcs) + + +# create a stateestimation object +stateestimation = StateestimationPerfect(emulator) +sta = stateestimation(0) +print(sta) + + +# create a prediction object +prediction = mpcpy.Prediction(disturbances) +pre = prediction(np.array([0, 20, 40, 60, 100])) +print(pre) + + +# create a control object and mpc object +control = SetpointControl(stateestimation, prediction, parameters={'A': -0.2, 'set': 3.0}, + horizon=100., timestep=10., receding=10.) +mpc = mpcpy.MPC(emulator, control, disturbances, emulationtime=1000, resulttimestep=10) + +# run the mpc +res = mpc(verbose=1) +print(res) + + +# plot results +fig, ax = plt.subplots(2, 1) +ax[0].plot(res['time'], res['u']) +ax[0].set_ylabel('u') + +ax[1].plot(res['time'], res['x']) +ax[1].set_xlabel('time') +ax[1].set_ylabel('x') + + +if __name__ == '__main__': + plt.show() \ No newline at end of file diff --git a/doc/source/mpc.rst b/doc/source/mpc.rst index e266652..6da7f11 100644 --- a/doc/source/mpc.rst +++ b/doc/source/mpc.rst @@ -3,4 +3,4 @@ MPC .. autoclass:: mpcpy.MPC :members: - \ No newline at end of file + :special-members: __call__ \ No newline at end of file diff --git a/examples/quickstart.py b/examples/quickstart.py index b387a75..15983bb 100644 --- a/examples/quickstart.py +++ b/examples/quickstart.py @@ -171,20 +171,19 @@ def stateestimation(self, time): mpc = mpcpy.MPC(emulator, control, disturbances, emulationtime=1000, resulttimestep=10) # run the mpc -res = mpc() +res = mpc(verbose=1) print(res) -def plot_result(): - fig, ax = plt.subplots(2, 1) - ax[0].plot(res['time'], res['u']) - ax[0].set_ylabel('u') +# plot results +fig, ax = plt.subplots(2, 1) +ax[0].plot(res['time'], res['u']) +ax[0].set_ylabel('u') - ax[1].plot(res['time'], res['x']) - ax[1].set_xlabel('time') - ax[1].set_ylabel('x') +ax[1].plot(res['time'], res['x']) +ax[1].set_xlabel('time') +ax[1].set_ylabel('x') if __name__ == '__main__': - plot_result() plt.show() \ No newline at end of file diff --git a/examples/simple_space_heating_mpc.py b/examples/simple_space_heating_mpc.py index 9f19ad8..63211fc 100644 --- a/examples/simple_space_heating_mpc.py +++ b/examples/simple_space_heating_mpc.py @@ -262,7 +262,7 @@ def solution(self, sta, pre): # MPC mpc = mpcpy.MPC(emulator, control, disturbances, emulationtime=1*24*3600., resulttimestep=60) -res = mpc() +res = mpc(verbose=1) # Plot results @@ -289,7 +289,7 @@ def solution(self, sta, pre): def_control = LinearProgram(def_stateestimation, prediction, parameters=control_parameters, horizon=24*3600., timestep=3600.) def_mpc = mpcpy.MPC(def_emulator, def_control, disturbances, emulationtime=1*24*3600., resulttimestep=60) -def_res = def_mpc() +def_res = def_mpc(verbose=1) fix, ax = plt.subplots(2, 1) ax[0].plot(def_res['time']/3600, def_res['Q_flow_hp'], 'k', label='hp') @@ -308,4 +308,5 @@ def solution(self, sta, pre): ax[1].legend(loc='lower right') -plt.show() +if __name__ == '__main__': + plt.show() diff --git a/mpcpy/mpc.py b/mpcpy/mpc.py index 0baff59..fe80a6a 100644 --- a/mpcpy/mpc.py +++ b/mpcpy/mpc.py @@ -74,10 +74,15 @@ def nextstepcalculator(controlsolution): self.res = {} self.appendres = {} - def __call__(self): + def __call__(self, verbose=0): """ Runs the mpc simulation - + + Parameters + ---------- + verbose: optional, int + Controls the amount of print output + Returns ------- dict @@ -88,19 +93,17 @@ def __call__(self): # initialize the emulator self.emulator.initialize() starttime = 0 - - + if self.plotfunction: (fig,ax,pl) = self.plotfunction() # prepare a progress bar - barwidth = 80 + barwidth = 80-2 barvalue = 0 - print('Run MPC %s |' %(' '*(barwidth-10))) - # sys.stdout.write('[%s]\n' % (' ' * barwidth)) - # sys.stdout.flush() - # sys.stdout.write('\b' * (barwidth+1)) - + if verbose > 0: + print('Running MPC') + print('[' + (' '*barwidth) + ']', end='') + while starttime < self.emulationtime: # calculate control signals for the control horizon @@ -147,21 +150,18 @@ def __call__(self): starttime = self.emulator.res['time'][-1] # update the progress bar - if starttime/self.emulationtime*barwidth >= barvalue: - addbars = int(round(starttime/self.emulationtime*barwidth-barvalue)) - sys.stdout.write(addbars*'-') - sys.stdout.flush() - barvalue += addbars - + if verbose > 0: + if starttime/self.emulationtime*barwidth >= barvalue: + barvalue += int(round(starttime/self.emulationtime*barwidth-barvalue)) + print('\r[' + ('='*barvalue) + (' '*(barwidth-barvalue)) + ']', end='') + # copy the results to a local res dictionary self.res.update(self.emulator.res) # interpolate the boundary conditions and add them to self.res self.res.update(self.disturbances(self.res['time'])) - - sys.stdout.write(' done') - sys.stdout.write("\n") - sys.stdout.flush() + if verbose > 0: + print(' done') return self.res diff --git a/tests/examples.py b/tests/examples.py index 8cf97cb..b4a4853 100644 --- a/tests/examples.py +++ b/tests/examples.py @@ -17,40 +17,18 @@ # along with mpcpy. If not, see . ################################################################################ -import unittest -import mpcpy -import numpy as np -import sys -import os -import subprocess -# module path -modulepath = os.path.abspath(os.path.dirname(sys.modules['mpcpy'].__file__)) -examplespath = os.path.abspath(os.path.join(modulepath,'..','examples')) +import unittest -# define null file -fnull = open(os.devnull, 'w') class TestExamples(unittest.TestCase): def test_simple_space_heating_mpc(self): - - currentdir = os.getcwd() - os.chdir(examplespath) - filename = 'simple_space_heating_mpc' - p = subprocess.Popen(['jupyter', 'nbconvert', '--execute', '--to', 'notebook', '{}.ipynb'.format(filename)], stdout=fnull, stderr=subprocess.PIPE) - output, error = p.communicate() - os.remove('{}.nbconvert.ipynb'.format(filename)) - os.chdir(currentdir) - - self.assertEqual(p.returncode, 0, error) + from examples import simple_space_heating_mpc def test_quickstart(self): - from examples import quickstart - - if __name__ == '__main__': unittest.main() \ No newline at end of file