Question:
I’m trying to implement a model predictive control (MPC) for a rendezvous problem using CVXPY. The code calculates the control u
to drive the state x
towards a reference state x_ref
over a specified horizon N
. However, I’m encountering a DCPError
, which states that the problem does not follow DCP (Disciplined Convex Programming) rules due to a division by a norm inside a constraint. Here’s a truncated version of the error:
DCPError: Problem does not follow DCP rules. Specifically:
The following constraints are not DCP:
500.0 <= (var4917985[0:6, 0] / Promote(Pnorm(var4917985[0:6, 0], 2), (6,))) @ var4917985[0:6, 0], because the following subexpressions are not:
|-- var4917985[0:6, 0] / Promote(Pnorm(var4917985[0:6, 0], 2), (6,))
...
The problematic part of my code seems to be this line:
q = (x[:, k]) / cp.norm((x[:, k]), 2)
constraints += [q.T @ x[:, k] >= r1]
The code snippet for the mpc_rendezvous
function is below:
import cvxpy as cp
import numpy as np
def mpc_rendezvous(x0, N, A, B, u_max, Q, R, Qf, lambda_rendezvous, r1):
n = A.shape[0]
m = B.shape[1]
x = cp.Variable((n, N+1))
u = cp.Variable((m, N))
x_ref = [r1, 0, 0, 0, 0, 0]
H = generate_H_matrix(cone_angle_rendezvous, 4)
cost = 0
constraints = [x[:, 0] == x0] # initial condition constraint
for k in range(N):
cost += cp.quad_form(x[:, k] - x_ref, Q) + cp.quad_form(u[:, k], R)
constraints += [x[:, k+1] == A @ x[:, k] + B @ u[:, k]]
constraints += [cp.norm_inf(u[:, k]) <= u_max]
q = (x[:,k]) / cp.norm((x[:,k]), 2)
constraints += [q.T @ x[:, k] >= r1]
cost += cp.quad_form(x[:, N] - x_ref, Qf)
cost += terminal_penalty(x[:, N], H, lambda_rendezvous)
prob = cp.Problem(cp.Minimize(cost), constraints)
prob.solve(solver=cp.SCS, warm_start=False)
print("Rendezvous phase problem status:", prob.status)
return u[:, 0].value
# Calling the function
u = mpc_rendezvous(x_current, N_rendezvous, A_rendezvous, B_rendezvous, u_max_rendezvous, Q_rendezvous, R_rendezvous, Qf_rendezvous, lambda_rendezvous, r1)
Additional Information:
A
andB
are discretized matrices.r1
is an integer.- The objective includes a terminal penalty
terminal_penalty(x[:, N], H, lambda_rendezvous)
.
Parameters
N_rendezvous = 30
Q_rendezvous = np.diag([1, 1, 100, 1, 1, 10])
R_rendezvous = 1e3 * np.eye(3)
Qf_rendezvous = Q_rendezvous.copy()
lambda_rendezvous = 10
cone_angle_rendezvous = 20 # degrees
u_max_rendezvous = 0.1786 # m/s
How can I rewrite or relax the constraints to conform to DCP rules and avoid this error? I tried following this thread: How to handle nonlinear equality constraints? - #4 by mcg
Thank you!