Major changes
Data
- New `__getitem__` method to conveniently retrieve values from `Data` object (details [here](https://github.com/do-mpc/do-mpc/blob/41402152aeb4a2a9b7220434d47c6fa23ca92841/do_mpc/data.py#L75))
- New `MPCData` class (which inherits form `Data`). This adds the `prediction` method, which can be used to query the optimal trajectories. Details [here](https://github.com/do-mpc/do-mpc/blob/41402152aeb4a2a9b7220434d47c6fa23ca92841/do_mpc/data.py#L236).
Both methods were previously (in a slightly different form) in the `Graphics` module. They are still used in this class but can also be convenient under different circumstances.
Graphics
The Graphics module is now initialized with a specific `Data` instance (e.g. `mpc.data`). Each `Data` class has their own `Graphics` class (if it is supposed to be displayed).
Compared to the previous implementation, we now initialize all lines that are supposed to be plotted (and store them in `pred_lines` and `result_lines`). During runtime, the data on these lines is getting updated.
- Added new `structure` class in `do_mpc.tools`. Used for tracking the new `Graphics` properties: `pred_lines` and `result_lines`.
- The properties `pred_lines` and `result_lines` can be used to retrieve line instances with power indices. Line instances can be easily configured (linestyle, alpha, color etc.)
Process noise
Process noise can be added to rhs of `Model` class: [link](https://github.com/do-mpc/do-mpc/blob/3f11da50cb8ab15798411be1c6400753c83d53e4/do_mpc/model.py#L596)
This is solving issue 53 .
This change was necessary to allow for the more natural MHE formulation where the process noise is penalised in the cost function. The user can define for each state (vector) individually if this is intended or not.
As a consequence of this change I had to introduce the new variable `w` throughout **do-mpc**. For the MPC and simulator module this is without effect.
The main difference is [here](https://github.com/do-mpc/do-mpc/blob/3f11da50cb8ab15798411be1c6400753c83d53e4/do_mpc/estimator.py#L573)
**Remark**: The change also allows to estimate parameters that change over time (e.g. environmental influences). Our regular estimated parameters are constant over the entire MHE horizon, which is not always valid. To estimate varying parameters, they should be defined as states with unknown dynamics. Concretely, their RHS is zero (for ODEs) and they have a high process noise.
Symbolic variables for MHE weighting matrices
As originally intended, it is now possible to have symbolic matrices as MHE tuning factors. The result of this change can be seen in the `rotating_oscillating_masses` example.
The symbolic variables are defined in the **do-mpc** `Model` where typically, you want to have `P_x` and `P_p` as parameters and `P_y` and `P_w` as time-varying parameters. Example of their [definition](https://github.com/do-mpc/do-mpc/blob/3f11da50cb8ab15798411be1c6400753c83d53e4/examples/rotating_oscillating_masses_mhe_mpc/template_model.py#L65).
and [here](https://github.com/do-mpc/do-mpc/blob/3f11da50cb8ab15798411be1c6400753c83d53e4/examples/rotating_oscillating_masses_mhe_mpc/template_mhe.py#L51) they are used.
The purpose of using symbolic weighting is of course to update them at each iteration. Since they are parameters and time-varying parameters respectively, this is done with the `set_p_fun` and `set_tvp_fun` method of the `MHE`: [link](https://github.com/do-mpc/do-mpc/blob/3f11da50cb8ab15798411be1c6400753c83d53e4/examples/rotating_oscillating_masses_mhe_mpc/template_mhe.py#L79)
Note that in the example above, we don't actually need varying weighting matrices and the returned values are in fact constant. This can be seen as a proof of concept.
This change had some other implications. Most notably, having additional parameters interferes with the multi-stage robust `MPC` module. Where we previously had to pass
a number of scenarios for each defined parameter.
Since parameters for the MHE are irrelevant for MPC the API for the call `set_uncertainty_values` has changed: [link](https://github.com/do-mpc/do-mpc/blob/3f11da50cb8ab15798411be1c6400753c83d53e4/do_mpc/controller.py#L477)
**The new API is fully backwards compatible.**
However, it is much more intuitive now. The function is called with keyword arguments, where each keyword refers to one uncertain parameter (note that we can ignore the parameters that are irrelevant).
In practice this looks something like [this](https://github.com/do-mpc/do-mpc/blob/3f11da50cb8ab15798411be1c6400753c83d53e4/examples/rotating_oscillating_masses_mhe_mpc/template_mpc.py#L89)