Run a model predictive control algorithm on a microgrid. In model predictive control, a model of the microgrid is used to predict the microgrid's response to taking certain actions. Armed with this prediction model, we can predict the microgrid's response to simulating forward a ce
| 53 | |
| 54 | |
| 55 | class ModelPredictiveControl: |
| 56 | """ |
| 57 | Run a model predictive control algorithm on a microgrid. |
| 58 | |
| 59 | In model predictive control, a model of the microgrid is used to predict the microgrid's response to taking |
| 60 | certain actions. Armed with this prediction model, we can predict the microgrid's response to simulating forward |
| 61 | a certain number of steps (the forecast "horizon"). This results in an objective function -- with the objective |
| 62 | being the cost of running the microgrid over the entire horizon. |
| 63 | |
| 64 | Given the solution of this optimization problem, we apply the control we found at the current step (ignoring the |
| 65 | rest) and then repeat. |
| 66 | |
| 67 | The specifics of the model implementation can be seen in the accompanying paper. |
| 68 | |
| 69 | .. warning:: |
| 70 | This implementation of model predictive control does not support arbitrary microgrid components. One each |
| 71 | of load, renewable, battery, grid, and genset are allowed. Microgrids are not required to have both grid and |
| 72 | genset but they must have one; they also must have one each of load, renewable, and battery. |
| 73 | |
| 74 | Parameters |
| 75 | ---------- |
| 76 | |
| 77 | microgrid : :class:`pymgrid.Microgrid` |
| 78 | Microgrid on which to run model predictive control. |
| 79 | |
| 80 | """ |
| 81 | def __init__(self, microgrid, solver=None): |
| 82 | self.microgrid, self.is_modular, self.microgrid_module_names = self._verify_microgrid(microgrid) |
| 83 | self.horizon = self._get_horizon() |
| 84 | |
| 85 | if self.has_genset: |
| 86 | self.p_vars = cp.Variable((8*self.horizon,), pos=True) |
| 87 | self.u_genset = cp.Variable((self.horizon,), boolean=True) |
| 88 | self.costs = cp.Parameter(8 * self.horizon) |
| 89 | self.inequality_rhs = cp.Parameter(9 * self.horizon) |
| 90 | |
| 91 | else: |
| 92 | self.p_vars = cp.Variable((7*self.horizon,), pos=True) |
| 93 | self.u_genset = None |
| 94 | self.costs = cp.Parameter(7 * self.horizon, nonneg=True) |
| 95 | self.inequality_rhs = cp.Parameter(8 * self.horizon) |
| 96 | |
| 97 | self.equality_rhs = cp.Parameter(2 * self.horizon) # rhs |
| 98 | |
| 99 | parameters = self._parse_microgrid() |
| 100 | |
| 101 | self.problem = self._create_problem(*parameters) |
| 102 | self._passed_solver = solver |
| 103 | self._solver = self._get_solver() |
| 104 | |
| 105 | @property |
| 106 | def has_genset(self): |
| 107 | """ |
| 108 | :meta private: |
| 109 | """ |
| 110 | if self.is_modular: |
| 111 | return "genset" in self.microgrid_module_names.keys() |
| 112 | else: |
no outgoing calls