Source code for do_mpc.model._iteratedvariables

#
#   This file is part of do-mpc
#
#   do-mpc: An environment for the easy, modular and efficient implementation of
#        robust nonlinear model predictive control
#
#   Copyright (c) 2014-2019 Sergio Lucia, Alexandru Tatulea-Codrean
#                        TU Dortmund. All rights reserved
#
#   do-mpc is free software: you can redistribute it and/or modify
#   it under the terms of the GNU Lesser General Public License as
#   published by the Free Software Foundation, either version 3
#   of the License, or (at your option) any later version.
#
#   do-mpc is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with do-mpc.  If not, see <http://www.gnu.org/licenses/>.

import numpy as np
import casadi.tools as castools
import pdb


[docs] class IteratedVariables: """ Class to initiate properties and attributes for iterated variables. This class is inherited to all iterating **do-mpc** classes and based on the :py:class:`Model`. Warnings: This base class can not be used independently. """ def __init__(self): assert 'model' in self.__dict__.keys(), 'Cannot initialize variables before assigning the model to the current class instance.' # Initialize structure for intial conditions: self._x0 = self.model._x(0.0) self._u0 = self.model._u(0.0) self._z0 = self.model._z(0.0) self._t0 = np.array([0.0]) def _convert2struct(self, val, struct): """ Convert array to structure. Pass ``val`` which can be an int, float, array, structure and return a numerical structure based on the second argument ``structure``. If a structure is passed, return the structure unchanged. Performs some sanity checks. """ # convert to array if isinstance(val, (float, int)): val = np.array([val]) # Check dimensions err_msg = 'Variable cannot be set because the supplied vector has the wrong size. You have {} and the model is setup for {}' n_val = np.prod(val.shape) n_var = struct.size assert n_val == n_var, err_msg.format(n_val, n_var) # Convert to structure (or return structure) if isinstance(val, (np.ndarray, castools.DM)): val = struct(val) elif isinstance(val, castools.structure3.DMStruct): pass else: types = (np.ndarray, castools.DM, castools.structure3.DMStruct) raise Exception('x0 must be of tpye {}. You have: {}'.format(types, type(val))) return val @property def x0(self): """ Initial state and current iterate. This is the numerical structure holding the information about the current states in the class. The property can be indexed according to the model definition. **Example:** :: model = do_mpc.model.Model('continuous') model.set_variable('_x','temperature', shape=(4,1)) ... mhe = do_mpc.estimator.MHE(model) # or mpc = do_mpc.estimator.MPC(model) # Get or set current value of variable: mpc.x0['temperature', 0] # 0th element of variable mpc.x0['temperature'] # all elements of variable mpc.x0['temperature', 0:2] # 0th and 1st element Useful CasADi symbolic structure methods: * ``.shape`` * ``.keys()`` * ``.labels()`` """ return self._x0 @x0.setter def x0(self, val): self._x0 = self._convert2struct(val, self.model._x) @property def u0(self): """ Initial input and current iterate. This is the numerical structure holding the information about the current input in the class. The property can be indexed according to the model definition. **Example:** :: model = do_mpc.model.Model('continuous') model.set_variable('_u','heating', shape=(4,1)) ... mhe = do_mpc.estimator.MHE(model) # or mpc = do_mpc.estimator.MPC(model) # Get or set current value of variable: mpc.u0['heating', 0] # 0th element of variable mpc.u0['heating'] # all elements of variable mpc.u0['heating', 0:2] # 0th and 1st element Useful CasADi symbolic structure methods: * ``.shape`` * ``.keys()`` * ``.labels()`` """ return self._u0 @u0.setter def u0(self, val): self._u0 = self._convert2struct(val, self.model._u) @property def z0(self): """ Initial algebraic state and current iterate. This is the numerical structure holding the information about the current algebraic states in the class. The property can be indexed according to the model definition. **Example:** :: model = do_mpc.model.Model('continuous') model.set_variable('_z','temperature', shape=(4,1)) ... mhe = do_mpc.estimator.MHE(model) # or mpc = do_mpc.estimator.MPC(model) # Get or set current value of variable: mpc.z0['temperature', 0] # 0th element of variable mpc.z0['temperature'] # all elements of variable mpc.z0['temperature', 0:2] # 0th and 1st element Useful CasADi symbolic structure methods: * ``.shape`` * ``.keys()`` * ``.labels()`` """ return self._z0 @z0.setter def z0(self, val): self._z0 = self._convert2struct(val, self.model._z) @property def t0(self): """ Current time marker of the class. Use this property to set of query the time. Set with ``int``, ``float``, ``numpy.ndarray`` or ``casadi.DM`` type. """ return self._t0 @t0.setter def t0(self,val): if isinstance(val, (int,float)): self._t0 = np.array([val]) elif isinstance(val, np.ndarray): assert val.size == 1, 'Cant set time with shape {}. Must contain exactly one element.'.format(val.size) self._t0 = val.flatten() elif isinstance(val, castools.DM): assert val.size == 1, 'Cant set time with shape {}. Must contain exactly one element.'.format(val.size) self._t0 = val.full().flatten() else: types = (np.ndarray, float, int, castools.DM) raise Exception('Passing object of type {} to set the current time. Must be of type {}'.format(type(val), types))