我在这里发布了一个问题,询问如何解决这个问题:
Trajectory Optimization for "Rocket" using scipy.optimize.minimize
理想情况下,我只想最小化最终时间,但是我无法让优化器将时间附加到可以适当调整的变量上,因此我决定暂时尝试最小化u ^ 2。
代码如下:
'\\'.join(l)
代码运行,但优化器失败。这是输出中的错误。
# Code
t_f = 1.0
t = np.linspace(0., t_f, num = 10) # Time array for 1 second into the future with 0.01 increment
u = np.zeros(t.size) + 650
print(u)
g = -650
initial_position = 0
initial_velocity = 0
final_position = 100
final_velocity = 100
def car_dynamics(x):
# Create time vector
# t = np.linspace(0., t_f, num = 100) # Time array for 1 second into the future with 0.01 increment
# Integrate over entire time to find v as a function of t
a = x + g
v = int.cumtrapz(a, t, initial = 0) + initial_velocity
# Integrate v(t) to get s(t)
s = int.cumtrapz(v, t, initial = 0) + initial_position
return s, v
def constraint1(x): # Final state constraints (Boundary conditions)
s, v = car_dynamics(x)
print('c1', s[0] - initial_position)
return s[0] - initial_position
def constraint2(x): # Initial state constraints (initial conditions)
s, v = car_dynamics(x)
print('c2', v[0] - initial_velocity)
return v[0] - initial_velocity
def constraint3(x):
s, v = car_dynamics(x)
print('c3', s[-1] - final_position)
return s[-1] - final_position
def constraint4(x):
s, v = car_dynamics(x)
print('c4', v[-1] - final_velocity)
return v[-1] - final_velocity
def constraint5(x):
return x - 1000
def objective(x):
u2 = np.square(x)
return np.sum(u2)
cons = [{'type':'eq', 'fun':constraint1},
{'type':'eq', 'fun':constraint2},
{'type':'eq', 'fun':constraint3},
{'type':'eq', 'fun':constraint4}]
# {'type':'ineq', 'fun':constraint5}]
result = minimize(objective, u, constraints = cons, method = 'SLSQP', options={'eps':500, 'maxiter':1000, 'ftol':0.001, 'disp':True})
print(result)
似乎在一些迭代中没有满足约束。我是否应该切换目标函数以包含最终速度和最终位置?我尝试了不同的步长,而没有使用相同的退出代码。
是否有更好的方法将此功能用于我要获得的功能?我试图获取从t0到t_f的整个时间间隔内的控制向量u(t),这样我就可以将这些命令发送到火箭以获得最佳控制。现在,我已经将优化简化为单轴,只是为了学习如何使用该函数。但是如您所见,我没有成功。
类似的示例将非常有帮助,并且我愿意接受其他优化方法,只要它们是数值方法即可,并且相对较快,因为我计划最终将其作为模型预测控制器实时实现。
答案 0 :(得分:2)
您的模型同时具有代数方程和微分方程。您需要DAE求解器来解决上述隐式ODE函数。我知道的一种这样的包装是gekko。 (https://github.com/BYU-PRISM/GEKKO) Gekko专门研究线性,混合整数和非线性优化问题的动态优化。
下面是一个示例火箭发射问题,该问题最大程度地减少了最终时间。在http://apmonitor.com/wiki/index.php/Apps/RocketLaunch
可用import numpy as np
import matplotlib.pyplot as plt
from gekko import GEKKO
# create GEKKO model
m = GEKKO()
# scale 0-1 time with tf
m.time = np.linspace(0,1,101)
# options
m.options.NODES = 6
m.options.SOLVER = 3
m.options.IMODE = 6
m.options.MAX_ITER = 500
m.options.MV_TYPE = 0
m.options.DIAGLEVEL = 0
# final time
tf = m.FV(value=1.0,lb=0.1,ub=100)
tf.STATUS = 1
# force
u = m.MV(value=0,lb=-1.1,ub=1.1)
u.STATUS = 1
u.DCOST = 1e-5
# variables
s = m.Var(value=0)
v = m.Var(value=0,lb=0,ub=1.7)
mass = m.Var(value=1,lb=0.2)
# differential equations scaled by tf
m.Equation(s.dt()==tf*v)
m.Equation(mass*v.dt()==tf*(u-0.2*v**2))
m.Equation(mass.dt()==tf*(-0.01*u**2))
# specify endpoint conditions
m.fix(s, pos=len(m.time)-1,val=10.0)
m.fix(v, pos=len(m.time)-1,val=0.0)
# minimize final time
m.Obj(tf)
# Optimize launch
m.solve()
print('Optimal Solution (final time): ' + str(tf.value[0]))
# scaled time
ts = m.time * tf.value[0]
# plot results
plt.figure(1)
plt.subplot(4,1,1)
plt.plot(ts,s.value,'r-',linewidth=2)
plt.ylabel('Position')
plt.legend(['s (Position)'])
plt.subplot(4,1,2)
plt.plot(ts,v.value,'b-',linewidth=2)
plt.ylabel('Velocity')
plt.legend(['v (Velocity)'])
plt.subplot(4,1,3)
plt.plot(ts,mass.value,'k-',linewidth=2)
plt.ylabel('Mass')
plt.legend(['m (Mass)'])
plt.subplot(4,1,4)
plt.plot(ts,u.value,'g-',linewidth=2)
plt.ylabel('Force')
plt.legend(['u (Force)'])
plt.xlabel('Time')
plt.show()