DPC#

class do_dpc.dpc.dpc.DPC(dpc_params, training_data, **kwargs)[source]#

Bases: ABC

Abstract base class for Data-Driven Predictive Control (DPC).

This serves as the base class for all DPC-based controllers, enforcing a common API and providing essential functionality such as updating measurements and reference trajectory, solving the optimization problem, returning the next optimal control action.

dpc_params#

Controller configuration parameters for the DPC.

Type:

DPCParameters

dims#

Calculated dimensions based on controller parameters.

Type:

Dimensions

hankel_matrices#

Constructed Hankel matrices from trajectory data.

Type:

HankelMatrices

pred_matrices#

Prediction matrices for predicting y_f.

Type:

DPCPredictorMatrices

reg_matrices#

Regularization matrices to calculate cost.

Type:

DPCRegularizationMatrices

constr#

List of constraints for the CVXPY optimization problem.

Type:

list[Constraint]

cost#

Total cost function for the optimization problem.

Type:

cvxpy.Expression

problem#

CVXPY problem instance for solving the optimization.

Type:

cvxpy.Problem

valid_optimization_problem#

Flag indicating if the optimization problem is valid.

Type:

bool

u_f_cp#

Control input decision variable for the optimization.

Type:

cp.Variable

y_f_cp#

Output variable decision for the optimization.

Type:

cp.Variable

y_r_cp#

Reference output parameter for the optimization problem.

Type:

cp.Parameter

u_r_cp#

Reference control input parameter for the optimization problem.

Type:

cp.Parameter

z_p_cp#

Parameter related to perturbations or uncertainties in the system.

Type:

cp.Parameter

u_f#

Offline computed control input (closed-form solution).

Type:

np.ndarray

is_unconstrained#

Flag indicating if the optimization is unconstrained.

Type:

bool

cf_matrices#

Closed-form gains computed for the controller.

Type:

np.ndarray

control_step#

Counter for the number of control steps taken.

Type:

int

use_mpc_cf#

Flag indicating if MPC closed-form is used.

Type:

bool

Parameters:
  • dpc_params (DPCParameters) – Controller configuration parameters.

  • training_data (InputOutputTrajectory) – Collected trajectory data.

  • **kwargs – Additional keyword arguments.

Methods#

add_custom_constraints#

do_dpc.dpc.dpc.DPC.add_custom_constraints(self, constraints)#

Adds custom constraints to the optimization problem.

Note

  • Users should access cvxpy parameters and decision variables directly from the DPC class.

  • All such attributes are denoted by the _cp suffix.

  • Ensure that added constraints do not conflict with existing ones.

  • For simple linear inequality constraints, prefer using set_input_constraint or set_output_constraint.

Parameters:

constraints (list[Constraint]) – A list of cvxpy constraints.

add_input_constraints#

do_dpc.dpc.dpc.DPC.add_input_constraints(self, u_bounds)#

Sets input constraints based on provided bounds.

Parameters:

u_bounds (Bounds) – An instance of Bounds containing upper (max_values) and lower (min_values) constraints for the control inputs.

Raises:
  • ValueError – If u_bounds.max_values and u_bounds.min_values have incorrect shapes.

  • ValueError – If u_bounds.max_values is smaller than u_bounds.min_values.

Special Cases:
  • To impose no bounds on specific inputs, set np.inf as the upper bound and -np.inf as the lower bound.

add_linear_constraints#

do_dpc.dpc.dpc.DPC.add_linear_constraints(self, A, b)#

Adds linear inequality constraints to the optimization problem.

The constraints are applied in the form:

A @ [ y_f u_f ]^T <= b

where:
  • A is a matrix of shape (n_constraints, n_y_f + n_u_f)

  • y_f (future outputs) is of shape (n_y_f, )

  • u_f (future inputs) is of shape (n_u_f, )

  • b is a vector of shape (n_constraints, )

Parameters:
  • A (np.ndarray) – Constraint matrix of shape (n_constraints, n_y_f + n_u_f).

  • b (np.ndarray) – Constraint vector of shape (n_constraints, ).

Raises:
  • ValueError – If A and b have incompatible shapes.

  • TypeError – If A or b are not numpy arrays.

  • Warning – If the first p columns of A are nonzero, indicating constraints on the first outputs.

add_terminal_output_constraints#

do_dpc.dpc.dpc.DPC.add_terminal_output_constraints(self, y_bounds)#

Adds terminal output constraints for the final step of the prediction horizon.

Notes

  • Only the final predicted output in the finite future horizon is constrained.

  • Due to system lag, immediate output constraints may not always be enforceable.

  • This design choice enhances solver feasibility for a wide range of systems.

  • If stricter constraints are needed, use add_custom_constraints.

Parameters:

y_bounds (Bounds) – A Bounds instance defining upper (max_values) and lower (min_values) constraints for system outputs.

Raises:
  • ValueError – If y_bounds.max_values and y_bounds.min_values have incorrect shapes.

  • ValueError – If any element in y_bounds.max_values is smaller than its corresponding y_bounds.min_values.

Special Cases:
  • To impose no bounds on specific outputs, set np.inf as the upper bound and -np.inf as the lower bound.

build_optimization_problem#

do_dpc.dpc.dpc.DPC.build_optimization_problem(self)#

Constructs the DPC optimization problem.

\[\begin{split}\min_{u_f, \cdot} &\quad \|y_f - y_r\|_Q^2 + \|u_f - u_r\|_R^2 + r(\cdot) \\ \text{s.t.} &\quad y_f = f(\cdot) \\ &\quad u_f \in \mathcal{U}, \quad y_f \in \mathcal{Y}\end{split}\]

where \(r(\cdot)\), \(f(\cdot)\) are linear functions which utilize matrices calculated in the Offline Calculations. Additional slack decision variables can be introduced. \(r(\cdot)\), \(f(\cdot)\) differ between different DPC algorithm.

The constraints for \(u_f\), \(y_f\) are handled by other methods.

calculate_closed_form_solution_matrices#

do_dpc.dpc.dpc.DPC.calculate_closed_form_solution_matrices(self)#

Abstract method to be implemented by subclasses to calculate closed-form gains.

If the implementation does not support closed-form solutions, this method returns None. Otherwise, it validates the computed gains and sets self.implemented_cf to True.

Returns:

The computed gain matrices if available, otherwise None.

Return type:

Optional[DPCClosedFormSolutionMatrices]

calculate_predictor_matrices#

do_dpc.dpc.dpc.DPC.calculate_predictor_matrices(self)#

Calculates predictor matrices for the DPC controller.

Return type:

DPCPredictorMatrices

calculate_regularization_matrices#

do_dpc.dpc.dpc.DPC.calculate_regularization_matrices(self)#

Calculates regularization matrices for optimal control.

Return type:

DPCRegularizationMatrices

get_next_control_action#

do_dpc.dpc.dpc.DPC.get_next_control_action(self)#

Retrieves the next computed control input.

Returns:

The next control input of shape (m,).

Return type:

np.ndarray

Raises:
  • IndexError – If the control horizon is exceeded.

  • RuntimeError – If the optimization problem has not been solved or the solution is invalid.

get_predictor_constraint_expression#

do_dpc.dpc.dpc.DPC.get_predictor_constraint_expression(self)#

Calculates and returns the CVXPY expression for the predictor constraint f.

Returns:

The CVXPY constraint for the predictor constraint.

Return type:

cp.Constraint

get_regularization_cost_expression#

do_dpc.dpc.dpc.DPC.get_regularization_cost_expression(self)#

Calculated and returns the regularization cost expression r(.) :rtype: Expression

Returns:

cp.Expression: The CVXPY expression for the regularization cost.

instantiate#

do_dpc.dpc.dpc.DPC.instantiate(dpc_type, *args, **kwargs)#

Factory method to create an instance of a registered DPC subclass.

Parameters:
  • dpc_type (str) – The type of DPC controller to instantiate.

  • *args – Positional arguments for the subclass constructor.

  • **kwargs – Keyword arguments for the subclass constructor.

Returns:

An instance of the corresponding DPC subclass.

Return type:

DPC

Raises:

ValueError – If the specified dpc_type is not registered.

register#

do_dpc.dpc.dpc.DPC.register(dpc_type)#

Decorator to register subclasses for dynamic instantiation.

Usage:

@DPC.register(“my_dpc”) class MyDPC(DPC):

Parameters:

dpc_type (str) – Name of the DPC subclass type.

Returns:

The decorator function.

Return type:

Callable[[Type[“DPC”]], Type[“DPC”]]

reset_constraints#

do_dpc.dpc.dpc.DPC.reset_constraints(self)#

Removes all existing constraints from the optimization problem.

Return type:

None

set_state_x#

do_dpc.dpc.dpc.DPC.set_state_x(self, x_new)#

Sets the state (x) for the estimated model.

This method is intended to be overridden by subclasses that have a model, such as MPC variants.

solve#

do_dpc.dpc.dpc.DPC.solve(self, verbose=False, solver='SCS', **kwargs)#

Solves the optimization problem to calculate the optimal control input.

Recommended to use SCS as it does not require a license. MOSEK should be used for better performance if a license is available.

Parameters:
  • verbose (bool) – If True, solver output is displayed.

  • solver (str) – Solver to use (default: SCS).

  • **kwargs – Additional solver parameters.

Raises:
  • ValueError – If the optimization problem is not properly built.

  • ValueError – If the cf_matrices are None while using the closed-form solution.

  • RuntimeError – If the solver encounters an issue or produces an infeasible result.

  • Warning – If another solver than Mosek is used.

update_past_measurements#

do_dpc.dpc.dpc.DPC.update_past_measurements(self, z_p_new)#

Updates the stored past measurements with new incoming data.

Parameters:

z_p_new (np.ndarray) – New past measurement data (shape (mp,)).

Raises:

ValueError – If z_p_new does not match the expected shape.

update_tracking_reference#

do_dpc.dpc.dpc.DPC.update_tracking_reference(self, y_r_new, u_r_new)#

Updates the tracking reference trajectory.

Parameters:
  • y_r_new (np.ndarray) – New reference trajectory for outputs (shape (p,)).

  • u_r_new (np.ndarray) – New reference trajectory for inputs (shape (m,)).

Raises:
  • ValueError – If y_r_new does not match expected dimensions (p,).

  • ValueError – If u_r_new does not match expected dimensions (m,).