문제 설명
힘을 최소화하기 위한 최적의 궤적, 최종 조건 문제 (Optimal trajectory to minimize force, issues with final conditions)
한 점에서 다른 점으로 블록을 이동시키는 힘의 제곱 적분을 최소화하는 궤적을 찾으려고 합니다. 시스템 역학은 다음과 같습니다.
dx/dt = v (derivative of position is velocity)
dv/dt = u (derivative of velocity is acceleration, which is what I am trying to minimize)
min integral of u**2
초기 조건과 최종 조건은 다음과 같습니다.
x(0) = 0, v(0) = 0
x(1) = 1, v(1) = 1
Gekko 라이브러리를 사용하여 파이썬에서 이것을 구현했지만 최종 조건이 제대로 작동하지 않습니다. . m.fix()
를 사용하여 끝 위치를 수정하면 문제를 해결할 수 없습니다.
온라인에서 읽을 때 m.Minimize()
를 사용하여 소프트 제약 조건이 있지만 솔루션은 최종 조건에서 매우 멀리 떨어져 있었습니다. 끝에서 속도를 0보다 작게 만들기 위해 추가 방정식을 추가했고, 이는 솔루션이 올바른 솔루션처럼 보이도록 만들었습니다.
참조 솔루션
방법 1:
You can fix the problem by putting a higher weight on the final conditions:
m.Minimize(final*1e5*(x‑1)**2)
m.Minimize(final*1e5*(v‑0)**2)
There is still some tradeoff with the u
minimization but it is minimal.
The constraint m.Equation(x*final >= 1)
is infeasible when final=0
because this results in the inequality 0 >= 1
. If you'd like to use the final position constraint, you'll need to use m.Equation((x‑1)*final >= 0)
so that the constraint is enforced only at the end but is feasible (0 >= 0)
elsewhere. You don't necessarily need the hard constraints with the soft (objective function) constraints for the final condition. Here is a related problem with an inverted pendulum.
from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt
m = GEKKO() # initialize gekko
nt = 101; m.time = np.linspace(0,1,nt)
# Variables
x = m.Var(value=0)
v = m.Var(value=0)
u = m.Var(fixed_initial=False)
p = np.zeros(nt) # mark final time point
p[‑1] = 1.0
final = m.Param(value=p)
# Equations
m.Equation(x.dt()==v)
m.Equation(v.dt()==u)
m.Equation((x‑1)*final >= 0)
m.Equation(v*final <= 0)
m.Minimize(final*1e5*(x‑1)**2)
m.Minimize(final*1e5*(v‑0)**2)
m.Obj(m.integral(u**2)*final) # Objective function
m.options.IMODE = 6 # optimal control mode
m.solve() # solve
plt.figure(1) # plot results
plt.grid()
plt.plot(m.time,x.value,'k‑',label=r'$x$')
plt.plot(m.time,v.value,'b‑',label=r'$v$')
plt.plot(m.time,u.value,'r‑‑',label=r'$u$')
plt.legend(loc='best')
plt.xlabel('Time')
plt.ylabel('Value')
plt.show()
(by Loppy、John Hedengren)