如何将车辆避碰约束转为凸约束以解决CVXPY的DCP规则错误?
SCP轨迹优化中CVXPY的DCP规则错误解决建议
我用序列凸规划(Sequential Convex Programming, SCP)求解轨迹优化问题,每次迭代需解决QP问题,将车辆间避碰约束线性化为如下形式:
运行CVXPY时抛出DCP规则错误,相关代码片段:
s_cvx = cvx.Variable((11, 12)) u_cvx = cvx.Variable((10, 6)) for k in range(N): if k>0: dist_linear = cvx.norm(agent_i_q-agent_j_q,2) + \ (agent_i_q-agent_j_q/cvx.norm(agent_i_q-agent_j_q,2)) @ (s_try[1,0:3]-s_try[1,6:9]) constraints += [dist_linear >= 0.5] ......
其中(s_cvx[k,0:3]-s_cvx[k,6:9])表示两车当前位置差,agent_i_q,agent_j_q为上一次迭代的车辆位置。具体错误信息:
DCPError: Problem does not follow DCP rules. Specifically: The following constraints are not DCP: 0.5 <= Pnorm(var1216896[0, 0:3] + -var1216896[0, 6:9], 2) + (var1216896[0, 0:3] + -var1216896[0, 6:9] / Promote(Pnorm(var1216896[0, 0:3] + -var1216896[0, 6:9], 2), (3,))) @ (var1216795[1, 0:3] + -var1216795[1, 6:9]) , because the following subexpressions are not: |-- var1216896[0, 6:9] / Promote(Pnorm(var1216896[0, 0:3] + -var1216896[0, 6:9], 2), (3,)) 0.5 <= Pnorm(var1216896[1, 0:3] + -var1216896[1, 6:9], 2) + (var1216896[1, 0:3] + -var1216896[1, 6:9] / Promote(Pnorm(var1216896[1, 0:3] + -var1216896[1, 6:9], 2), (3,))) @ (var1216795[1, 0:3] + -var1216795[1, 6:9]) , because the following subexpressions are not: |-- var1216896[1, 6:9] / Promote(Pnorm(var1216896[1, 0:3] + -var1216896[1, 6:9], 2), (3,)) ......
解决建议
核心问题:代码错误地将当前迭代的CVXPY变量用于构建单位向量,违反了DCP规则。变量的2范数作为分母、向量除以自身范数的操作都是非线性的,不符合DCP对凸/凹性的要求。
修正线性化逻辑:SCP的线性化必须基于上一次迭代的固定值,而非当前变量。正确实现如下:
import numpy as np import cvxpy as cvx s_cvx = cvx.Variable((11, 12)) u_cvx = cvx.Variable((10, 6)) # 用上一次迭代的位置计算固定的位置差、范数和单位向量 delta_q_prev = agent_i_q - agent_j_q norm_delta_q_prev = np.linalg.norm(delta_q_prev, 2) # 处理范数接近0的边界情况,避免除以0 if norm_delta_q_prev < 1e-6: unit_vec = np.array([1.0, 0.0, 0.0]) # 自定义默认单位向量 else: unit_vec = delta_q_prev / norm_delta_q_prev for k in range(N): if k > 0: # 当前迭代的位置差变量 delta_q_curr = s_cvx[k, 0:3] - s_cvx[k, 6:9] # 线性化距离约束:上一次距离 + 单位向量点乘当前位置差增量 >= 安全距离 dist_linear = norm_delta_q_prev + unit_vec @ delta_q_curr constraints += [dist_linear >= 0.5]关键注意点:
agent_i_q和agent_j_q必须是上一次迭代得到的数值型数组(如numpy数组),不能是CVXPY变量。- 必须处理
norm_delta_q_prev接近0的情况,防止除以0错误,此时可直接添加强约束强制两车分离,或设置默认单位向量。 - 修正后的约束是仿射函数 >= 常数,完全符合DCP规则,CVXPY可以正常处理。
内容的提问来源于stack exchange,提问作者Randy Chen
相关产品推荐
相关产品推荐

