Я отправил вопрос о том, как решить эту проблему в общем, здесь:
Оптимизация траектории для "Ракеты" с использованием scipy.optimize.minimize
В идеале я хотел бы просто минимизировать конечное время, но я не мог заставить оптимизатор добавлять время к переменной, которую можно корректно настроить, поэтому я решил, что вместо этого пока просто попытаюсь минимизировать u ^ 2. .
Вот код:
# 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)
Код выполняется, но оптимизатор не работает. Вот ошибка с выхода.
c1 0.0
c2 0.0
c3 -100.0
c4 -100.0
c1 0.0
c2 0.0
c3 -100.0
c4 -100.0
c1 0.0
c1 0.0
c1 0.0
c1 0.0
c1 0.0
c1 0.0
c1 0.0
c1 0.0
c1 0.0
c1 0.0
c1 0.0
c2 0.0
c2 0.0
c2 0.0
c2 0.0
c2 0.0
c2 0.0
c2 0.0
c2 0.0
c2 0.0
c2 0.0
c2 0.0
c3 -100.0
c3 -73.76543209876543
c3 -50.617283950617285
c3 -56.79012345679013
c3 -62.96296296296296
c3 -69.1358024691358
c3 -75.30864197530863
c3 -81.4814814814815
c3 -87.65432098765432
c3 -93.82716049382715
c3 -98.45679012345678
c4 -100.0
c4 -72.22222222222223
c4 -44.44444444444445
c4 -44.44444444444445
c4 -44.44444444444445
c4 -44.444444444444436
c4 -44.44444444444445
c4 -44.44444444444448
c4 -44.44444444444445
c4 -44.44444444444442
c4 -72.22222222222221
Singular matrix C in LSQ subproblem (Exit mode 6)
Current function value: 4225000.0
Iterations: 1
Function evaluations: 12
Gradient evaluations: 1
fun: 4225000.0
jac: array([1800., 1800., 1800., 1800., 1800., 1800., 1800., 1800., 1800.,
1800.])
message: 'Singular matrix C in LSQ subproblem'
nfev: 12
nit: 1
njev: 1
status: 6
success: False
x: array([650., 650., 650., 650., 650., 650., 650., 650., 650., 650.])
Кажется, ограничения не соблюдаются в некотором количестве итераций. Должен ли я переключить свою целевую функцию, чтобы она содержала конечную скорость и конечную позицию? Я пробовал разные размеры шагов и что не с тем же кодом выхода.
Есть ли лучший способ использовать эту функцию для того, что я пытаюсь получить? Я пытаюсь получить управляющий вектор u (t) во всем интервале от t0 до t_f, чтобы я мог отправить эти команды ракете для оптимального управления. Сейчас я упростил оптимизацию до одной оси, просто чтобы узнать, как использовать функцию. Но, как вы видите, мне это не удалось.
Подобные примеры были бы чрезвычайно полезны, и я открыт для других методов оптимизации, если они являются числовыми и относительно быстрыми, поскольку я планирую в конечном итоге реализовать их в качестве прогнозирующего контроллера модели в реальном времени.