[General] Can't add more than 3 arcs in the direct optimisation

Đang mở
#581 6 bình luận 0 reaction 1 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@ocots đang làm issue này rồi.

Từ ngày 9/7/2025.

Đánh giá

Issue này chưa được đánh giá.

Mô tả

Voici le code.

Le debut est pour intégrer les toolbox nécessaire + définir les paramètres. Ensuite je formule 3 pbs: 1 arc fonctionne, 3 arcs aussi, 4 non...

Tout à la fin il y a une fonction de plot que je définis, pas nécessaire.

using SPICE
using OptimalControl
using NLPModelsIpopt
# using Interpolations
using JLD2
# using OrdinaryDiffEq
using DataInterpolations
using CSV
using JLD2
using Plots


using Downloads: download


# SPICE files that you have to download but only once
const LSK = "https://naif.jpl.nasa.gov/pub/naif/generic_kernels/lsk/naif0012.tls"
const SPK = "https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/de440.bsp"
const PCK = "https://naif.jpl.nasa.gov/pub/naif/generic_kernels/pck/pck00010.tpc"

# Download kernels
download(LSK, "naif0012.tls")
download(SPK, "de440.bsp")
download(PCK, "pck00010.tpc")

furnsh("naif0012.tls") # Leap seconds kernel
furnsh("de430.bsp") # Ephemeris kernel
furnsh("pck00010.tpc")  # PCK kernel for planetary constants


# Astrodynamical parameters
G = 6.6743e-11 / 1000^3 # km^3 kg^-1 s^-2
M_moon = 7.346e22 # kg
M_earth = 5.972168e24 # kg
M_sun = 1.989e30 # kg
AU = 1.495978707e11 / 1e3 # km
LU = 384399 # km
TU = sqrt(LU^3 / G / (M_moon + M_earth))
MUnit =  M_moon + M_earth
mu_Earth = 3.9860044188e14 / 1000^3 / LU^3 * TU^2
mu_Moon = 4.90486959e12 / 1000^3 / LU^3 * TU^2
mu_Sun = 1.327124400189e20  / 1000^3 / LU^3 * TU^2
mass_moon = M_moon / MUnit
mass_earth = M_earth / MUnit
mass_sun = M_sun / MUnit

# Spacecraft parameters
g0 = 9.80665 / 1000 / LU * TU^2
Isp = 1660 / TU 
wet_mass = 344 / MUnit 
fuel_mass = 90 / MUnit 
dry_mass = (wet_mass - fuel_mass) 
wet_by_dry = (dry_mass + fuel_mass) / dry_mass
Tmax =  0.090 / 1000 / MUnit / LU * TU^2 #thrust force in N
Q = Tmax / Isp / g0

mass_scaling_factor = wet_mass

# Mission data that I just copy paste here for simplicity
t0_J200 = 1.107747244e9
tf_J200 = 1.112803048e9
N = 15000 
t_values = LinRange(t0_J200, tf_J200, N-3)
t_values = vcat(-5e9, 0.0, collect(t_values), tf_J200 * 5)
states_moon = zeros(6, N)
states_earth = zeros(6, N)
states_sun = zeros(6, N)
t0 = t0_J200 / TU
tf = tf_J200 / TU

# Interpolations of the bodies positions/velocities
for i = 1:N
    states_moon[:,i], _ = spkezr("MOON", t_values[i], "ECLIPJ2000", "NONE", "EARTH MOON BARYCENTER")
    states_earth[:,i], _ = spkezr("EARTH", t_values[i], "ECLIPJ2000", "NONE", "EARTH MOON BARYCENTER")
    states_sun[:,i], _ = spkezr("SUN", t_values[i], "ECLIPJ2000", "NONE", "EARTH MOON BARYCENTER")
end

# Interpolation of the position and velocity of the celestial bodies (Sun, Moon, Earth)
x_moon = DataInterpolations.LinearInterpolation(states_moon[1,:] / LU, t_values / TU) 
y_moon = DataInterpolations.LinearInterpolation(states_moon[2,:] / LU, t_values / TU) 
z_moon = DataInterpolations.LinearInterpolation(states_moon[3,:] / LU, t_values / TU) 

x_earth = DataInterpolations.LinearInterpolation(states_earth[1,:] / LU, t_values / TU) 
y_earth = DataInterpolations.LinearInterpolation(states_earth[2,:] / LU, t_values / TU) 
z_earth = DataInterpolations.LinearInterpolation(states_earth[3,:] / LU, t_values / TU) 

x_sun = DataInterpolations.LinearInterpolation(states_sun[1,:] / LU, t_values / TU) 
y_sun = DataInterpolations.LinearInterpolation(states_sun[2,:] / LU, t_values / TU) 
z_sun = DataInterpolations.LinearInterpolation(states_sun[3,:] / LU, t_values / TU) 

# Times
t0 = 2952.5065962806448
t1 = 2953.955962786101
t2 = 2954.4423792964794
t3 = 2955.398985817685
t4 = 2957.4519685112937
t5 = 2959.0986010622196
t6 = 2960.6895789585565

# States at the previous times
ap0      =  [-0.992463207586249; 0.7937735622182638; 0.07902677416947182; 0.4497665242298916;  0.5768992856452368; -0.08990077540870026]
occult1  =  [0.024011456548615025; 1.0839463211562548; -0.06721110889958525; 0.8370532723530986; -0.2849379073937811; -0.09055054145691602]
lunar2   =  [0.42191676845234877; 0.8365166413216278; -0.10058044976319964; 1.0641134073373073;  -0.7420861511380829; 0.2221102307286784]
ap3      =  [0.8866648294530993; 0.07703956973358668; 0.28758014926093095; 0.010909379448810359; -1.0104415437867642; 0.3065975859809964]
lunar4   =  [-0.5240519542473246; -0.8727170323241018; 0.06983526263136841; -1.0656424593386877; 0.4013541226489389; -0.24177176981236737]
ap5      =  [-1.2845625006191574; 0.07452729181167739; -0.02061966816776342; 0.03379116945381267; 0.7236740339189934; -0.05964259399261467]
occult6  =  [-0.5063291057829847; 0.9375405520827109; -0.0856392904912281; 0.906825723975573; 0.17758145410610057; -0.009952663265456345]


# Changement de variable pour le temps
function phi(s, t0, t1)
    return t0 + (t1 - t0) * s
end

# Dynamique
function Fu(t, x, u)
    # Earth & Moon & Sun gravity
    
    r = x[1:3]
    v = x[4:6]
    m = x[7] * mass_scaling_factor

    x_e = [x_earth(t), y_earth(t), z_earth(t)]
    x_m = [x_moon(t), y_moon(t), z_moon(t)]
    x_s = [x_sun(t), y_sun(t), z_sun(t)]

    normrE = sqrt(sum((x_e - r).^2))
    normrM = sqrt(sum((x_m - r).^2))
    normrS = sqrt(sum((x_s - r).^2))

    normrSE = sqrt(sum((x_e - x_s).^2))
    normrMS = sqrt(sum((x_m - x_s).^2))

    dv = mu_Earth / normrE^3 * (x_e - r) + mu_Moon / normrM^3 * (x_m - r) + mu_Sun / normrS^3 * (x_s - r) - (1 / (mass_earth + mass_moon)) * ( x_s * (mu_Sun * mass_earth / normrSE^3 + mu_Moon * mass_sun / normrMS^3) - x_m * (mu_Moon * mass_sun / normrMS^3) - x_e * (mu_Sun * mass_earth / normrSE^3)) 
    dvu = Tmax * u / m
    dm = - Q * sqrt(sum(u.^2)) / mass_scaling_factor

    dx = [v; dv + dvu; dm]
    return dx
end


# Pb avec 1 arc
@def ocp1arc begin
    s ∈ [ 0, 1 ], time
    y ∈ R^7, state
    w ∈ R^3, control

    x1  = y[1:7]

    u1  = w[1:3]

    mf  = y[end]

    -5 ≤ x1[1](s) ≤ 5
    -5 ≤ x1[2](s) ≤ 5
    -5 ≤ x1[3](s) ≤ 5
    -5 ≤ x1[4](s) ≤ 5
    -5 ≤ x1[5](s) ≤ 5
    -5 ≤ x1[6](s) ≤ 5
    0.5 ≤ x1[7](s) ≤ 1 # careful here ! dry mass > 0

    0 ≤ sum(u1(s).^2) ≤ 1

    x1[1:6](0)    == occult1
    x1[7](0)      == 1 
    x1[1:6](1)    == lunar2


    ẏ(s) == (t2 - t1) * Fu(phi(s, t1, t2), x1(s), u1(s))
    mf(1) → max

end


sol = solve(ocp1arc)
plot(sol)
# sol = solve(ocp1arc, grid_size = 100, max_iter = 3000, tol = 1e-6, acceptable_tol = 1e-5)

# 3 Arcs
@def ocp3arc begin
    s ∈ [ 0, 1 ], time
    y ∈ R^21, state
    w ∈ R^9, control

    x1  = y[1:7]
    x2  = y[8:14]
    x3  = y[15:21]

    u1  = w[1:3]
    u2  = w[4:6]
    u3  = w[7:9]

    mf  = y[end]

    -5 ≤ x1[1](s) ≤ 5
    -5 ≤ x1[2](s) ≤ 5
    -5 ≤ x1[3](s) ≤ 5
    -5 ≤ x1[4](s) ≤ 5
    -5 ≤ x1[5](s) ≤ 5
    -5 ≤ x1[6](s) ≤ 5
    0.5 ≤ x1[7](s) ≤ 1 # careful here ! dry mass > 0

    -5 ≤ x2[1](s) ≤ 5
    -5 ≤ x2[2](s) ≤ 5
    -5 ≤ x2[3](s) ≤ 5
    -5 ≤ x2[4](s) ≤ 5
    -5 ≤ x2[5](s) ≤ 5
    -5 ≤ x2[6](s) ≤ 5
    0.5 ≤ x2[7](s) ≤ 1 # careful here ! dry mass > 0

    -5 ≤ x3[1](s) ≤ 5
    -5 ≤ x3[2](s) ≤ 5
    -5 ≤ x3[3](s) ≤ 5
    -5 ≤ x3[4](s) ≤ 5
    -5 ≤ x3[5](s) ≤ 5
    -5 ≤ x3[6](s) ≤ 5
    0.5 ≤ x3[7](s) ≤ 1 # careful here ! dry mass > 0


    0 ≤ sum(u1(s).^2) ≤ 1
    0 ≤ sum(u2(s).^2) ≤ 1
    0 ≤ sum(u3(s).^2) ≤ 1


    x1[1:6](0)    == ap0
    x1[7](0)      == 1 
    x1[1:6](1)    == occult1
    x2(0) - x1(1) == [0, 0, 0, 0, 0, 0, 0]
    x2[1:6](1)    == lunar2
    x3(0) - x2(1) == [0, 0, 0, 0, 0, 0, 0]
    x3[1:6](1)    == ap3


    ẏ(s) == [(t1 - t0) * Fu(phi(s, t0, t1), x1(s), u1(s)); (t2 - t1) * Fu(phi(s, t1, t2), x2(s), u2(s)); (t3 - t2) * Fu(phi(s, t2, t3), x3(s), u3(s))]
    mf(1) → max

end

sol = solve(ocp3arc, grid_size = 100, tol = 1e-6, disc_method=:gauss_legendre_2)
plot(sol)
# plot_trajNV_multiarc(sol, 3, [t0,t1,t2,t3])

# 4 arcs
@def ocp4arc begin
    s ∈ [ 0, 1 ], time
    y ∈ R^28, state
    w ∈ R^12, control

    x1  = y[1:7]
    x2  = y[8:14]
    x3  = y[15:21]
    x4  = y[22:28]

    u1  = w[1:3]
    u2  = w[4:6]
    u3  = w[7:9]
    u4  = w[10:12]

    mf  = y[end]

    -5 ≤ x1[1](s) ≤ 5
    -5 ≤ x1[2](s) ≤ 5
    -5 ≤ x1[3](s) ≤ 5
    -5 ≤ x1[4](s) ≤ 5
    -5 ≤ x1[5](s) ≤ 5
    -5 ≤ x1[6](s) ≤ 5
    0.5 ≤ x1[7](s) ≤ 1 # careful here ! dry mass > 0

    -5 ≤ x2[1](s) ≤ 5
    -5 ≤ x2[2](s) ≤ 5
    -5 ≤ x2[3](s) ≤ 5
    -5 ≤ x2[4](s) ≤ 5
    -5 ≤ x2[5](s) ≤ 5
    -5 ≤ x2[6](s) ≤ 5
    0.5 ≤ x2[7](s) ≤ 1 # careful here ! dry mass > 0

    -5 ≤ x3[1](s) ≤ 5
    -5 ≤ x3[2](s) ≤ 5
    -5 ≤ x3[3](s) ≤ 5
    -5 ≤ x3[4](s) ≤ 5
    -5 ≤ x3[5](s) ≤ 5
    -5 ≤ x3[6](s) ≤ 5
    0.5 ≤ x3[7](s) ≤ 1 # careful here ! dry mass > 0

    -5 ≤ x4[1](s) ≤ 5
    -5 ≤ x4[2](s) ≤ 5
    -5 ≤ x4[3](s) ≤ 5
    -5 ≤ x4[4](s) ≤ 5
    -5 ≤ x4[5](s) ≤ 5
    -5 ≤ x4[6](s) ≤ 5
    0.5 ≤ x4[7](s) ≤ 1 # careful here ! dry mass > 0


    0 ≤ sum(u1(s).^2) ≤ 1
    0 ≤ sum(u2(s).^2) ≤ 1
    0 ≤ sum(u3(s).^2) ≤ 1
    0 ≤ sum(u4(s).^2) ≤ 1

    x1[1:6](0)    == ap0
    x1[7](0)      == 1 
    x1[1:6](1)    == occult1
    x2(0) - x1(1) == [0, 0, 0, 0, 0, 0, 0]
    x2[1:6](1)    == lunar2
    x3(0) - x2(1) == [0, 0, 0, 0, 0, 0, 0]
    x3[1:6](1)    == ap3
    x4(0) - x3(1) == [0, 0, 0, 0, 0, 0, 0]
    x4[1:6](1)    == lunar4

    ẏ(s) == [(t1 - t0) * Fu(phi(s, t0, t1), x1(s), u1(s)); (t2 - t1) * Fu(phi(s, t1, t2), x2(s), u2(s)); (t3 - t2) * Fu(phi(s, t2, t3), x3(s), u3(s)); (t4 - t3) * Fu(phi(s, t3, t4), x4(s), u4(s))]
    mf(1) → max

end

sol = solve(ocp4arc)



function plot_trajNV_multiarc(sol, nb_arcs, tvec)

    sol_time = sol.time_grid.value 


    Nsol = length(sol_time)
    sol_state = zeros(7 * nb_arcs, Nsol)
    sol_control = zeros(4 * nb_arcs, Nsol)
    for i in range(1, length(sol.time_grid.value))
        sol_state[:, i] = sol.state.value(sol.time_grid.value[I])
    end


    x_vals_opti = zeros(nb_arcs, Nsol)
    y_vals_opti = zeros(nb_arcs, Nsol)
    z_vals_opti = zeros(nb_arcs, Nsol)
    vx_vals_opti = zeros(nb_arcs, Nsol)
    vy_vals_opti = zeros(nb_arcs, Nsol)
    vz_vals_opti = zeros(nb_arcs, Nsol)
    m_vals_opti = zeros(nb_arcs, Nsol)

    for i in range(1, nb_arcs)
        x_vals_opti[i, :] = sol_state[1 + 7 * (i - 1), :]
        y_vals_opti[i, :] = sol_state[2 + 7 * (i - 1), :]
        z_vals_opti[i, :] = sol_state[3 + 7 * (i - 1), :]
        vx_vals_opti[i, :] = sol_state[4 + 7 * (i - 1), :]
        vy_vals_opti[i, :] = sol_state[5 + 7 * (i - 1), :]
        vz_vals_opti[i, :] = sol_state[6 + 7 * (i - 1), :]
        m_vals_opti[i, :] = sol_state[7 + 7 * (i - 1), :]
    end
 
    sol_time_plot = LinRange(tvec[1], tvec[end], N)
    x_moon_pos = [x_moon(t) for t in sol_time_plot]
    y_moon_pos = [y_moon(t) for t in sol_time_plot]
    z_moon_pos = [z_moon(t) for t in sol_time_plot]
    x_earth_pos = [x_earth(t) for t in sol_time_plot]
    y_earth_pos = [y_earth(t) for t in sol_time_plot]
    z_earth_pos = [z_earth(t) for t in sol_time_plot]

    p = plot(x_moon_pos, y_moon_pos, z_moon_pos, label = "moon orbit")
    plot!(x_earth_pos, y_earth_pos, z_earth_pos, label = "earth orbit")

    scatter!([x_vals_opti[1, 1]], [y_vals_opti[1, 1]], [z_vals_opti[1, 1]], label = "previous occultation")

    for i in range(1, nb_arcs)
        rand_color = RGB(rand(), rand(), rand()) 
        plot!(x_vals_opti[i, :], y_vals_opti[i, :], z_vals_opti[i, :], size=(600, 600), camera = (30,30), xlabel="x", ylabel="y", zlabel="z", label="solar sail trajectory", linewidth = 2, color = "black", legend =:topleft)
        scatter!([x_vals_opti[i, end]], [y_vals_opti[i, end]], [z_vals_opti[i, end]], label = "next occultation")
    end


    xlims!(-2, 2)
    ylims!(-2, 2)
    zlims!(-1.5, 1.5)
    
    display(p)
    # arrow_factor = 1e-1
    # quiver!(x_vals_opti[u_norm .> 0.1][1:2:end], y_vals_opti[u_norm .> 0.1][1:2:end], z_vals_opti[u_norm .> 0.1][1:2:end], quiver=(ux[u_norm .> 0.1][1:2:end] * arrow_factor, uy[u_norm .> 0.1][1:2:end] * arrow_factor, uz[u_norm .> 0.1][1:2:end] * arrow_factor), label="thrust directions", arrow=true, color = "red")

end
Ngôn ngữ chính
Julia
Star
135
Fork
11
Merge trung bình
7 giờ 51 phút
Pull request đã merge (30 ngày)
22

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của control-toolbox/OptimalControl.jl

Tất cả issue của control-toolbox/OptimalControl.jl

Issue tương tự

Thêm issue về Julia

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.