最小化力的最佳轨迹,最终条件问题
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 库在 python 中实现了这个,但是我无法使最终条件正常工作。使用m.fix()
固定结束位置,问题无解
网上看的,我用m.Minimize()
做了一个软约束,但是解离结束条件很远。我添加了一个额外的方程,使速度在最后小于零,这使得解看起来像正确的解,尽管结束位置是错误的(如果解按一个因子缩放,它将是正确的)。
我应该好好解决这个问题吗?
from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt
##model
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*final >= 1) #@error: Solution Not Found
m.Equation(v*final <= 0)
m.Minimize(final*(x-1)**2)
m.Minimize(final*(v-0)**2)
m.Obj(m.integral(u**2)*final) # Objective function
m.options.IMODE = 6 # optimal control mode
##solve
m.solve() # solve
##plot
plt.figure(1) # plot results
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')
##show plot
plt.show()
Plot of my results
您可以通过提高最终条件的权重来解决问题:
m.Minimize(final*1e5*(x-1)**2)
m.Minimize(final*1e5*(v-0)**2)
u
最小化仍有一些折衷,但它是最小的。
约束 m.Equation(x*final >= 1)
在 final=0
时不可行,因为这会导致不等式 0 >= 1
。如果您想使用最终位置约束,则需要使用 m.Equation((x-1)*final >= 0)
以便约束仅在最后强制执行,但在其他地方可行 (0 >= 0)
。对于最终条件,您不一定需要具有软(objective 函数)约束的硬约束。这里有一个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()
我试图找到一条轨迹,使将方块从一个点移动到另一个点的力的平方积分最小。以下是系统动态:
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 库在 python 中实现了这个,但是我无法使最终条件正常工作。使用m.fix()
固定结束位置,问题无解
网上看的,我用m.Minimize()
做了一个软约束,但是解离结束条件很远。我添加了一个额外的方程,使速度在最后小于零,这使得解看起来像正确的解,尽管结束位置是错误的(如果解按一个因子缩放,它将是正确的)。
我应该好好解决这个问题吗?
from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt
##model
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*final >= 1) #@error: Solution Not Found
m.Equation(v*final <= 0)
m.Minimize(final*(x-1)**2)
m.Minimize(final*(v-0)**2)
m.Obj(m.integral(u**2)*final) # Objective function
m.options.IMODE = 6 # optimal control mode
##solve
m.solve() # solve
##plot
plt.figure(1) # plot results
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')
##show plot
plt.show()
Plot of my results
您可以通过提高最终条件的权重来解决问题:
m.Minimize(final*1e5*(x-1)**2)
m.Minimize(final*1e5*(v-0)**2)
u
最小化仍有一些折衷,但它是最小的。
约束 m.Equation(x*final >= 1)
在 final=0
时不可行,因为这会导致不等式 0 >= 1
。如果您想使用最终位置约束,则需要使用 m.Equation((x-1)*final >= 0)
以便约束仅在最后强制执行,但在其他地方可行 (0 >= 0)
。对于最终条件,您不一定需要具有软(objective 函数)约束的硬约束。这里有一个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()