LinearModel#
- class LinearModel(model_type=None, symvar_type='SX')[source]#
Bases:
Model
The do-mpc LinearModel class. This class is inherited from do-mpc model class. This class holds the full model description and is at the core of
do_mpc.simulator.Simulator
,do_mpc.controller.MPC
,do_mpc.controller.LQR
anddo_mpc.estimator.Estimator
. This class can be used to define the linear time invariant models in both continuous and discrete time. TheLinearModel
class is created with setting themodel_type
(continuous or discrete).A
continous
linear model consists of an underlying ordinary differential equation (ODE)\[\begin{split}\dot{x}(t) &= Ax(t)+Bu(t),\\ y &= Cx(t)+Du(t)\end{split}\]whereas a
discrete
linear model consists of a difference equation.\[\begin{split} x_{k+1} &= Ax_k+Bu_k,\\ y_k &= Cx_k+Du_k\end{split}\]The do-mpc linear model can be initiated with
SX
variable type.Note
The option
symvar_type
will be inherited to all derived classes (e.g.do_mpc.simulator.Simulator
,do_mpc.controller.MPC
anddo_mpc.estimator.Estimator
). All symbolic variables in these classes will be chosen respectively.Configuration and setup: Configuring and setting up the
LinearModel
involves the following steps:Model can be setup in two different ways. The first method is as follows:
Use
set_variable()
to introduce new variables to the linear model.Optionally introduce “auxiliary” expressions as functions of the previously defined variables with
set_expression()
. The expressions can be used for monitoring or be reused as constraints, the cost function etc.Optionally introduce measurement equations with
set_meas()
. The syntax is identical toset_expression()
. By default state-feedback is assumed.Define the right-hand-side of the discrete or continuous model as a function of the previously defined variables with
set_rhs()
. This method must be called once for each introduced state.Call
setup()
to finalize theLinearModel
. No further changes are possible afterwards.
The second method is as follows:
Use
set_variable()
to introduce new variables to the linear model.Optionally introduce “auxiliary” expressions as functions of the previously defined variables with
set_expression()
. The expressions can be used for monitoring or be reused as constraints, the cost function etc.Call
setup()
and pass the system dynamics matrices as arguments instead of setting up the right hand side equations and measurement equations to finalize theLinearModel
. No further changes are possible afterwards.
Note
All introduced model variables are accessible as Attributes of the
Model
. Use these attributes to query to variables, e.g. to form the cost function in a seperate file for the MPC configuration.- Parameters
model_type (
Optional
[str
]) – Set if the model isdiscrete
orcontinuous
.symvar_type (
str
) – Set if the model is configured with CasADiSX
variables (default).
- Raises
assertion – model_type must be string
assertion – model_type must be either discrete or continuous
- __getitem__(ind)#
The
Model
class supports the__getitem__
method, which can be used to retrieve the model variables (see attribute list).# Query the states like this: x = model.x # or like this: x = model['x']
This also allows to retrieve multiple variables simultaneously:
x, u, z = model['x','u','z']
Methods#
discretize#
- discretize(self, t_step=0, conv_method='zoh')#
Converts continuous time to discrete time system.
This method utilizes the exisiting function in scipy library called
cont2discrete
to convert continuous time to discrete time system.This method allows the user to specify the type of discretization. For more details about the function click here .where \(A_{\text{discrete}}\) and \(B_{\text{discrete}}\) are the discrete state matrix and input matrix repectively and \(t_{\text{sample}}\) is the sampling time.
Warning
sampling time is zero when not specified or not required
- Parameters
t_step (
Union
[float
,int
]) – Sampling time (default -0
)conv_method (
str
) – Method of discretization - Five different methods can be applied. (default -‘zoh’)
- Returns
LinearModel
– Discretized linear model
get_linear_system_matrices#
- get_linear_system_matrices(self, xss=None, uss=None, z=None, tvp=None, p=None)#
Returns the matrix quadrupel \((A,B,C,D)\) of the linearized system around the operating point (
xss,uss,z,tvp,p,w,v
). All arguments are optional in which case the matrices might still be symbolic. If the matrices are not symbolic, they are returned as numpy arrays.- Parameters
xss (
Optional
[ndarray
]) – Steady state stateuss (
Optional
[ndarray
]) – Steady state inputz (
Optional
[ndarray
]) – Steady state algebraic statestvp (
Optional
[ndarray
]) – time varying parameters set pointp (
Optional
[ndarray
]) – parameters set point
- Returns
Union
[Tuple
[SX
,SX
,SX
,SX
],Tuple
[ndarray
,ndarray
,ndarray
,ndarray
]] – State matrix, Input matrix, Output matrix, Feedforward matrix
get_steady_state#
- get_steady_state(self, xss=None, uss=None)#
Calculates steady states for the given input or states.
This method calculates steady states of a discrete system for the given steady state input and vice versa. The mathematical formulation can be described as:
\[x_{ss} = (I-A)^{-1}Bu_{ss}\]or
\[u_{ss} = B^{-1}(I-A)x_{ss}\]- Parameters
xss (
Optional
[ndarray
]) – Steady state State valuesuss (
Optional
[ndarray
]) – Steady state Input values
- Returns
ndarray
– Steady state state or Steady state input
set_alg#
- set_alg(self, expr_name, expr, *args, **kwargs)#
Warning
This method is not supported for linear models.
set_expression#
- set_expression(self, expr_name, expr)#
Introduce new expression to the model class. Expressions are not required but can be used to extract further information from the model. Expressions must be formulated with respect to
_x
,_u
,_z
,_tvp
,_p
.Example:
Maybe you are interested in monitoring the product of two states?
Introduce two scalar states: x_1 = model.set_variable('_x', 'x_1') x_2 = model.set_variable('_x', 'x_2') # Introduce expression: model.set_expression('x1x2', x_1*x_2)
This new expression
x1x2
is then available in all do-mpc modules utilizing this model instance. It can be set, e.g. as the cost function indo_mpc.controller.MPC
or simply used in a graphical representation of the simulated / controlled system.- Parameters
expr_name (
str
) – Arbitrary name for the given expression. Names are used for key word indexing.expr (
Union
[SX
,MX
]) – CasADi SX or MX function depending on_x
,_u
,_z
,_tvp
,_p
.
- Raises
assertion – expr_name must be str
assertion – expr must be a casadi SX or MX type
assertion – Cannot call after
setup()
.
- Returns
Union
[SX
,MX
] – Returns the newly created expression. Expression can be used e.g. for the RHS.
set_meas#
- set_meas(self, name, meas)#
Checks if the measurement function is linear and calls
Model.set_meas()
.- Parameters
name (
str
) – Arbitrary name for the given expression. Names are used for key word indexing.meas (
SX
) – CasADi SX function depending on_x
,_u
,_tvp
,_p
.
- Return type
None
set_rhs#
- set_rhs(self, name, rhs)#
Checks if the right-hand-side function is linear and calls
Model.set_rhs()
.- Parameters
name (
str
) – Reference to previously introduced state names (withLinearModel.set_variable()
)rhs (
SX
) – CasADi SX function depending on_x
,_u
,_tvp
,_p
.
- Return type
None
set_variable#
- set_variable(self, var_type, var_name, shape=(1, 1))#
Introduce new variables to the model class. Define variable type, name and shape (optional).
Example:
# States struct (optimization variables): C_a = model.set_variable(var_type='_x', var_name='C_a', shape=(1,1)) T_K = model.set_variable(var_type='_x', var_name='T_K', shape=(1,1)) # Input struct (optimization variables): Q_dot = model.set_variable(var_type='_u', var_name='Q_dot') # Fixed parameters: alpha = model.set_variable(var_type='_p', var_name='alpha')
Note
var_type
allows a shorthand notation e.g._x
which is equivalent tostates
.- Parameters
var_type (
str
) – Declare the type of the variable.var_name (
str
) – Set a user-defined name for the parameter. The names are reused throughout do_mpc.shape (
Union
[int
,Tuple
]) – Shape of the current variable (optional), defaults to1
.
The following types of var_type are valid (long or short name is possible):
Long name
short name
Remark
states
_x
Required
inputs
_u
optional
algebraic
_z
Optional
parameter
_p
Optional
timevarying_parameter
_tvp
Optional
- Raises
assertion – var_type must be string
assertion – var_name must be string
assertion – shape must be tuple or int
assertion – Cannot call after
setup()
.
- Returns
Union
[SX
,MX
] – Returns the newly created symbolic variable.
setup#
- setup(self, A=None, B=None, C=None, D=None)#
Setup method must be called to finalize the modelling process. All required model variables must be declared. The right hand side expression for
_x
can be set withset_rhs()
or can be set by passing the state matrix and input matrix insetup()
.Sets default measurement function (state feedback) if
set_meas()
was not called or output matrix, feedforward matrix are not passed insetup()
.Warning
After calling
setup()
, the model is locked and no further variables, expressions etc. can be set.- Raises
assertion – Definition of right hand side (rhs) is incomplete
- Parameters
A (
Optional
[ndarray
]) – State matrix (optional)B (
Optional
[ndarray
]) – Input matrix (optional)C (
Optional
[ndarray
]) – Output matrix (optional)D (
Optional
[ndarray
]) – Feedforward matrix (optional)
- Return type
None
Attributes#
aux#
- LinearModel.aux#
Auxiliary expressions. CasADi symbolic structure, can be indexed with user-defined variable names.
Note
Expressions are introduced with
Model.set_expression()
Use this property only to query variables.Example:
model = do_mpc.model.Model('continuous') model.set_variable('_x','temperature', 4) # 4 states dt = model.x['temperature',0]- model.x['temperature', 1] model.set_expression('dtemp', dt) # Query: model.aux['dtemp', 0] # 0th element of variable model.aux['dtemp'] # all elements of variable
Useful CasADi symbolic structure methods:
.shape
.keys()
.labels()
- Raises
assertion – Cannot set aux directly Use set_expression instead.
p#
- LinearModel.p#
Static parameters. CasADi symbolic structure, can be indexed with user-defined variable names.
Note
Variables are introduced with
Model.set_variable()
Use this property only to query variables.Example:
model = do_mpc.model.Model('continuous') model.set_variable('_p','temperature', shape=(4,1)) # Query: model.p['temperature', 0] # 0th element of variable model.p['temperature'] # all elements of variable model.p['temperature', 0:2] # 0th and 1st element
Useful CasADi symbolic structure methods:
.shape
.keys()
.labels()
- Raises
assertion – Cannot set model variables directly Use set_variable instead.
sys_A#
- LinearModel.sys_A#
State matrix. This property provides the state matrix in the numerical array format. Accessible only after model is setup.
sys_B#
- LinearModel.sys_B#
Input matrix. This property provides the input matrix in the numerical array format. Accessible only after model is setup.
sys_C#
- LinearModel.sys_C#
Output matrix. This property provides the output matrix in the numerical array format. Accessible only after model is setup.
sys_D#
- LinearModel.sys_D#
Feedforward matrix. This property provides the feedforward matrix in the numerical array format. Accessible only after model is setup.
tvp#
- LinearModel.tvp#
Time-varying parameters. CasADi symbolic structure, can be indexed with user-defined variable names.
Note
Variables are introduced with
Model.set_variable()
Use this property only to query variables.Example:
model = do_mpc.model.Model('continuous') model.set_variable('_tvp','temperature', shape=(4,1)) # Query: model.tvp['temperature', 0] # 0th element of variable model.tvp['temperature'] # all elements of variable model.tvp['temperature', 0:2] # 0th and 1st element
Useful CasADi symbolic structure methods:
.shape
.keys()
.labels()
- Raises
assertion – Cannot set model variables directly Use set_variable instead.
u#
- LinearModel.u#
Inputs. CasADi symbolic structure, can be indexed with user-defined variable names.
Note
Variables are introduced with
Model.set_variable()
Use this property only to query variables.Example:
model = do_mpc.model.Model('continuous') model.set_variable('_u','heating', shape=(4,1)) # Query: model.u['heating', 0] # 0th element of variable model.u['heating'] # all elements of variable model.u['heating', 0:2] # 0th and 1st element
Useful CasADi symbolic structure methods:
.shape
.keys()
.labels()
- Raises
assertion – Cannot set model variables directly Use set_variable instead.
v#
- LinearModel.v#
Measurement noise. CasADi symbolic structure, can be indexed with user-defined variable names.
The measurement noise structure is created automatically, whenever the
Model.set_meas()
method is called with the argumentmeas_noise = True
.Note
The measurement noise is used for the
do_mpc.estimator.MHE
and can be used to simulate a disturbed system in thedo_mpc.simulator.Simulator
.Useful CasADi symbolic structure methods:
.shape
.keys()
.labels()
- Raises
assertion – Cannot set v directly
w#
- LinearModel.w#
Process noise. CasADi symbolic structure, can be indexed with user-defined variable names.
The process noise structure is created automatically, whenever the
Model.set_rhs()
method is called with the argumentprocess_noise = True
.Note
The process noise is used for the
do_mpc.estimator.MHE
and can be used to simulate a disturbed system in thedo_mpc.simulator.Simulator
.Useful CasADi symbolic structure methods:
.shape
.keys()
.labels()
- Raises
assertion – Cannot set w directly
x#
- LinearModel.x#
Dynamic states. CasADi symbolic structure, can be indexed with user-defined variable names.
Note
Variables are introduced with
Model.set_variable()
Use this property only to query variables.Example:
model = do_mpc.model.Model('continuous') model.set_variable('_x','temperature', shape=(4,1)) # Query: model.x['temperature', 0] # 0th element of variable model.x['temperature'] # all elements of variable model.x['temperature', 0:2] # 0th and 1st element
Useful CasADi symbolic structure methods:
.shape
.keys()
.labels()
- Raises
assertion – Cannot set model variables directly Use set_variable instead.
y#
- LinearModel.y#
Measurements. CasADi symbolic structure, can be indexed with user-defined variable names.
Note
Measured variables are introduced with
Model.set_meas()
Use this property only to query variables.Example:
model = do_mpc.model.Model('continuous') model.set_variable('_x','temperature', 4) # 4 states model.set_meas('temperature', model.x['temperature',:2]) # first 2 measured # Query: model.y['temperature', 0] # 0th element of variable model.y['temperature'] # all elements of variable
Useful CasADi symbolic structure methods:
.shape
.keys()
.labels()
- Raises
assertion – Cannot set model variables directly Use set_meas instead.
z#
- LinearModel.z#
Algebraic states. CasADi symbolic structure, can be indexed with user-defined variable names.
Note
Variables are introduced with
Model.set_variable()
Use this property only to query variables.Example:
model = do_mpc.model.Model('continuous') model.set_variable('_z','temperature', shape=(4,1)) # Query: model.z['temperature', 0] # 0th element of variable model.z['temperature'] # all elements of variable model.z['temperature', 0:2] # 0th and 1st element
Useful CasADi symbolic structure methods:
.shape
.keys()
.labels()
- Raises
assertion – Cannot set model variables directly Use set_variable instead.