我正在尝试添加一个约束,它指定在优化过程中,求解器必须在设置的持续时间内选择u的值,并且只能在该设置的时间量之后切换。例如,假设我有一个机械设备,它每10秒只能切换一次输入值。然后,我希望优化器考虑到这一点。我只需将代码附加在这里:
for it_i in range(0, N-1, equivalence_samples):
print("N: {}".format(N))
for it_j in range(0, equivalence_samples - 1):
if (it_i + it_j + 1) > N-1:
print("Breaking")
break
else:
constraint_u0 = prog.AddConstraint(u[0, it_i + it_j] == u[0, it_i + it_j + 1]) # add equivalence constraints
constraint_u1 = prog.AddConstraint(u[1, it_i + it_j] == u[1, it_i + it_j + 1]) # add equivalence constraints
print('Constraint_u_PE: {}'.format(constraint_u0))
print('Constraint_u_NI: {}'.format(constraint_u1))我已经实现了这一点,我希望这是一个有效的解决方案。有时它看起来像是在工作,而在另一些时候,它不是。
我将展示一些由此产生的输出约束的照片,然后是一个不起作用的示例。


然后,这里是清晰地显示切换时间之间存在一些界限的曲线图,但这些值并不相等。我附上了生成这个图的代码。

u_sol = result.GetSolution(u)
u_time = np.linspace(0, N-1, num = N)
# u_sol_trajectory = PiecewisePolynomial.ZeroOrderHold(u_time, u_sol)
plt.figure()
plt.plot(u_time, u_sol[0, :], 'o')
plt.plot(u_time, u_sol[1, :], 'o')
plt.xlabel('time steps')
plt.ylabel('u [mcg/min]')
plt.legend(['u_PE', 'u_NI'])发布于 2020-08-01 02:27:26
本例中使用的特定求解器是OSQP求解器。尽管在理想的求解器世界中,我在上面的代码中指定了正确的约束(输入1 == input 2,输入2 == input 3等),但我没有考虑到求解器具有尝试保持约束的准确性这一事实。
我可以通过更新求解器的精度(根据https://osqp.discourse.group/t/constraints-violated/143的建议)或输入更多显式约束来解决此问题。我用第二种选择解决了这个问题。现在,我指定的不仅仅是像以下模式这样的约束:
input 1 == input 2、input 2 == input 3等。
但我也包含了类似以下模式的约束:
输入1 ==输入3,输入1 ==输入4,输入1 ==输入5
input 2 == input 4,input 2 == input 5等。
更明确地说,我的求解器现在正在做我要求的事情,与约束的偏差很小。然而,对于我的应用程序来说,小的偏差是可以接受的!它有点慢,但对于我目前使用它的目的来说,这不是问题。下面是我更新的代码:
for it_i in range(0, N-1, equivalence_samples):
for it_j in range(0, equivalence_samples - 1):
for it_f in range(1, equivalence_samples - it_j):
if (it_i + it_j + it_f) > N-1:
print("Breaking")
break
else:
con_0 = eq(u[:, it_i + it_j], u[:, it_i + it_j + it_f])
constraint_u = prog.AddConstraint(con_0) # add equivalence constraints
print('Constraint_u: {}'.format(constraint_u))这不是世界上最漂亮的代码,但它可以工作。
https://stackoverflow.com/questions/63181611
复制相似问题