Seems like a lot changed...

This commit is contained in:
Connor
2022-02-19 12:30:54 -07:00
parent 5d5c79c909
commit 329a2990c5
16 changed files with 532 additions and 273 deletions

View File

@@ -99,6 +99,12 @@ git-tree-sha1 = "bdc0937269321858ab2a4f288486cb258b9a0af7"
uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
version = "1.3.0"
[[CodeTracking]]
deps = ["InteractiveUtils", "UUIDs"]
git-tree-sha1 = "9aa8a5ebb6b5bf469a7e0e2b5202cf6f8c291104"
uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
version = "1.0.6"
[[CodecBzip2]]
deps = ["Bzip2_jll", "Libdl", "TranscodingStreams"]
git-tree-sha1 = "2e62a725210ce3c3c2e1a3080190e7ca491f18d7"
@@ -329,6 +335,12 @@ git-tree-sha1 = "2f49f7f86762a0fbbeef84912265a1ae61c4ef80"
uuid = "7d188eb4-7ad8-530c-ae41-71a32a6d4692"
version = "0.3.4"
[[JuliaInterpreter]]
deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"]
git-tree-sha1 = "b55aae9a2bf436fc797d9c253a900913e0e90178"
uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a"
version = "0.9.3"
[[Kaleido_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "2ef87eeaa28713cb010f9fb0be288b6c1a4ecd53"
@@ -390,6 +402,12 @@ version = "0.3.0"
[[Logging]]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
[[LoweredCodeUtils]]
deps = ["JuliaInterpreter"]
git-tree-sha1 = "6b0440822974cab904c8b14d79743565140567f6"
uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b"
version = "2.2.1"
[[METIS_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "2dc1a9fc87e57e32b1fc186db78811157b30c118"
@@ -559,6 +577,12 @@ git-tree-sha1 = "63ee24ea0689157a1113dbdab10c6cb011d519c4"
uuid = "37e2e3b7-166d-5795-8a7a-e32c996b4267"
version = "1.9.0"
[[Revise]]
deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "Requires", "UUIDs", "Unicode"]
git-tree-sha1 = "2f9d4d6679b5f0394c52731db3794166f49d5131"
uuid = "295af30f-e4ad-537b-8983-00126c2a3abe"
version = "3.3.1"
[[SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"

View File

@@ -12,6 +12,7 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5"
PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
SNOW = "105f6ee8-0889-46b1-9d4b-65e03cbc8f13"
SPICE = "5bab7191-041a-5c2e-a744-024b9c3a5062"
SymbolServer = "cf896787-08d5-524d-9de7-132aaa0cb996"

View File

@@ -7,7 +7,7 @@ module Thesis
using PlotlyJS
using Distributed
using SPICE
using Dates: DateTime, Millisecond, Dates, Second, format, datetime2unix, unix2datetime
using Dates: DateTime, Millisecond, Dates, Second, format, datetime2julian, julian2datetime
try
furnsh("../../spice_files/naif0012.tls")

View File

@@ -2,30 +2,27 @@ using SNOW
export solve_mission
const pos_scale = ones(3)
# const vel_scale = 100. * ones(3)
const vel_scale = ones(3)
# const v∞_scale = norm(vel_scale)
const v∞_scale = 1.
const state_scale = [pos_scale; vel_scale ]
function constraint_bounds(guess::Mission_Guess)
low_constraint = Vector{Float64}()
high_constraint = Vector{Float64}()
for phase in guess.phases
state_constraint = [100., 100., 100., 0.005, 0.005, 0.005] .* state_scale
# Constraints on the final state
state_constraint = [10_000., 10_000., 10_000., 0.05, 0.05, 0.05]
push!(low_constraint, (-1 * state_constraint)... )
push!(high_constraint, state_constraint... )
if phase != guess.phases[end]
push!(low_constraint, -0.005*v∞_scale, 100.)
push!(high_constraint, 0.005*v∞_scale, 1e7)
# Constraints on the v∞ and turning angle
push!(low_constraint, -0.05, 100.)
push!(high_constraint, 0.05, 1e7)
else
# Constraints on mass
push!(low_constraint, 0.)
push!(high_constraint, guess.start_mass - guess.sc.dry_mass)
end
end
# Constraints on C3 and V∞
push!(low_constraint, 0., 0.)
push!(high_constraint, 1e3, 1e3)
@@ -57,8 +54,8 @@ function solve_mission( guess::Mission_Guess,
# Establish initial conditions
v∞_out = x[2:4]
current_planet = Earth
launch_date = unix2datetime(x[1])
time = utc2et(format(launch_date,"yyyy-mm-ddTHH:MM:SS"))
launch_date = julian2datetime(x[1])
time = Dates.datetime2julian(launch_date)
start = state(current_planet, time, v∞_out, guess.start_mass)
final = zeros(7)
@@ -80,16 +77,16 @@ function solve_mission( guess::Mission_Guess,
thrusts = reshape(phase_params[8:end], (n,3))
# Propagate
final = prop(thrusts, start, guess.sc, tof)[2]
final = prop(thrusts, start, guess.sc, tof)[end,:]
current_planet = flyby
time += tof
time += tof/86400
goal = state(current_planet, time, v∞_in)[1:6]
start = state(current_planet, time, v∞_out, final[7])
# Do Checks
g[1+8i:6+8i] .= (final[1:6] .- goal[1:6]) .* state_scale
g[1+8i:6+8i] .= (final[1:6] .- goal[1:6])
if flyby != flybys[end]
g[7+8i] = (norm(v∞_out) - norm(v∞_in)) * v∞_scale
g[7+8i] = (norm(v∞_out) - norm(v∞_in))
δ = acos( ( v∞_in v∞_out ) / ( norm(v∞_in) * norm(v∞_out) ) )
g[8+8i] = (current_planet.μ/(v∞_in v∞_in)) * ( 1/sin(δ/2) - 1 ) - current_planet.r
else
@@ -100,7 +97,7 @@ function solve_mission( guess::Mission_Guess,
i += 1
end
return 1.0
return -final[end]
catch e
@@ -114,7 +111,7 @@ function solve_mission( guess::Mission_Guess,
end
end
max_time = datetime2unix(latest_arrival) - datetime2unix(launch_window[1])
max_time = (datetime2julian(latest_arrival) - datetime2julian(launch_window[1]))*86400
lower_x = lowest_mission_vector(launch_window, length(guess.phases), n)
upper_x = highest_mission_vector(launch_window, max_time, length(guess.phases), n)
num_constraints = 8*(length(guess.phases)-1) + 9
@@ -123,7 +120,7 @@ function solve_mission( guess::Mission_Guess,
"acceptable_constr_viol_tol" => 100tol,
"bound_relax_factor" => 0.,
"max_iter" => 100_000,
"max_cpu_time" => 5. * length(guess.phases),
"max_cpu_time" => 10. * length(guess.phases),
"print_level" => print_level)
options = Options(solver=IPOPT(ipopt_options), derivatives=ForwardFD())

View File

@@ -1,22 +1,106 @@
export state, period
struct Body
μ::Float64
r::Float64 # radius
μ::Real
r::Real # radius
color::String
id::Int # SPICE id
a::Float64 # semi-major axis
a::Real # semi-major axis
line_color::AbstractString
name::AbstractString
end
period(b::Body) = 2π * (b.a^3 / Sun.μ)
function state(p::Body, t::DateTime, add_v∞::Vector{T}=[0., 0., 0.], add_mass::Float64=1e10) where T <: Real
time = utc2et(format(t,"yyyy-mm-ddTHH:MM:SS"))
[ spkssb(p.id, time, "ECLIPJ2000"); 0.0 ] + [ zeros(3); add_v∞; add_mass ]
function state(p::Body, t::DateTime, add_v∞::AbstractVector=[0., 0., 0.], add_mass::Float64=1e10)
time = Dates.datetime2julian(t)
[ basic_ephemeris(p,time); 0.0 ] + [ zeros(3); add_v∞; add_mass ]
end
function state(p::Body, t::S, add_v∞::Vector{T}=[0., 0., 0.], add_mass::Float64=1e10) where {T,S <: Real}
[ spkssb(p.id, t, "ECLIPJ2000"); 0.0 ] + [ zeros(3); add_v∞; add_mass ]
function state(p::Body, t::Real, add_v∞::AbstractVector=[0., 0., 0.], add_mass::Real=1e10)
[ basic_ephemeris(p,t); 0.0 ] + [ zeros(3); add_v∞; add_mass ]
end
"""
Provides a really basic, but fast, ephemeris for most planets.
"""
function basic_ephemeris(planet::Body,date::Real)
century = (date-2451545)/36525
if planet.name == "Mercury"
table = [ 252.250906 149472.6746358 0.00000535 0.000000002 ;
0.387098310 0 0 0 ;
0.20563175 0.000020406 0.0000000284 0.00000000017 ;
7.004986 -0.0059516 0.00000081 0.000000041 ;
48.330893 -0.1254229 -0.00008833 -0.000000196 ;
77.456119 0.1588643 -0.00001343 0.000000039]
elseif planet.name == "Venus"
table = [ 181.979801 58517.8156760 0.00000165 -0.000000002 ;
0.72332982 0 0 0 ;
0.00677188 -0.000047766 0.0000000975 0.00000000044 ;
3.394662 -0.0008568 -0.00003244 0.000000010 ;
76.679920 -0.2780080 -0.00014256 -0.000000198 ;
131.563707 0.0048646 -0.00138232 -0.000005332]
elseif planet.name == "Earth"
table = [ 100.466449 35999.3728519 -0.00000568 0 ;
1.000001018 0 0 0 ;
0.01670862 -0.000042037 -0.0000001236 0.00000000004 ;
0 0.0130546 -0.00000931 -0.000000034 ;
174.873174 -0.2410908 0.00004067 -0.000001327 ;
102.937348 0.3225557 0.00015026 0.000000478]
elseif planet.name == "Mars"
table = [ 355.433275 19140.2993313 0.00000261 -0.000000003 ;
1.523679342 0 0 0 ;
0.09340062 0.000090483 -0.0000000806 -0.00000000035 ;
1.849726 -0.0081479 -0.00002255 -0.000000027 ;
49.558093 -0.2949846 -0.00063993 -0.000002143 ;
336.060234 0.4438898 -0.00017321 0.000000300]
elseif planet.name == "Jupiter"
table = [ 34.351484 3034.9056746 -0.00008501 0.000000004 ;
5.202603191 0.0000001913 0 0 ;
0.04849485 0.000163244 -0.0000004719 -0.00000000197 ;
1.303270 -0.0019872 0.00003318 0.000000092 ;
100.464441 0.1766828 0.00090387 -0.000007032 ;
14.331309 0.2155525 0.00072252 -0.000004590]
elseif planet.name == "Saturn"
table = [ 50.077471 1222.1137943 0.00021004 -0.000000019 ;
9.554909596 -0.0000021389 0 0 ;
0.05550862 -0.000346818 -0.0000006456 0.00000000338 ;
2.488878 0.0025515 -0.00004903 0.000000018 ;
113.665524 -0.2566649 -0.00018345 0.000000357 ;
93.056787 0.5665496 0.00052809 0.000004882]
elseif planet.name == "Uranus"
table = [ 314.055005 429.8640561 0.00030434 0.000000026 ;
19.218446062 -0.0000000372 0.00000000098 0 ;
0.04629590 -0.000027337 0.0000000790 0.00000000025 ;
0.773196 0.0007744 0.00003749 -0.000000092 ;
74.005947 0.5211258 0.00133982 0.000018516 ;
173.005159 1.4863784 0.0021450 0.000000433]
elseif planet.name == "Neptune"
table = [ 304.348665 219.8833092 0.00030926 0.000000018 ;
30.110386869 -0.0000001663 0.00000000069 0 ;
0.00898809 0.000006408 -0.0000000008 -0.00000000005 ;
1.769952 -0.0093082 -0.00000708 0.000000028 ;
131.784057 1.1022057 0.00026006 -0.000000636 ;
48.123691 1.4262677 0.00037918 -0.000000003]
elseif planet.name == "Pluto"
table = [ 238.92903833 145.20780515 0 0 ;
39.48211675 -0.00031596 0 0 ;
0.24882730 0.00005170 0 0 ;
17.14001206 0.00004818 0 0 ;
110.30393684 -0.01183482 0 0 ;
224.06891629 -0.04062942 0 0]
else
return "No such planet"
end
poly = [1,century,century^2,century^3]
L,a,e,i,Ω,P = table * poly
L,i,Ω,P = [L,i,Ω,P] * (π/180)
ω = P-Ω
M = L-P
θ = M + (2e - 0.25e^3 + (5/96)*e^5)*sin(M) +
(1.25e^2 - (11/24)*e^4)*sin(2M) + ((13/12)*e^3 - (43/64)*e^5)*sin(3M) +
(103/96)*e^4*sin(4M) + (1097/960)*e^5*sin(5M)
oe = [a*AU,e,i,Ω,ω,θ]
return oe_to_xyz(oe, Sun.μ)
end

View File

@@ -49,7 +49,7 @@ This is the opposite of the function below. It takes a vector and any other nece
"""
function Mission_Guess(x::Vector{Float64}, sc::Sc, mass::Float64, flybys::Vector{Body})
# Variable mission params
launch_date = unix2datetime(x[1])
launch_date = julian2datetime(x[1])
launch_v∞ = x[2:4]
# Try to intelligently determine n
@@ -78,7 +78,7 @@ information from the guess though.
"""
function Base.Vector(g::Mission_Guess)
result = Vector{Float64}()
push!(result, datetime2unix(g.launch_date))
push!(result, datetime2julian(g.launch_date))
push!(result, g.launch_v∞...)
for phase in g.phases
push!(result,phase.v∞_in...)
@@ -91,7 +91,7 @@ end
function lowest_mission_vector(launch_window::Tuple{DateTime,DateTime}, num_phases::Int, n::Int)
result = Vector{Float64}()
push!(result, datetime2unix(launch_window[1]))
push!(result, datetime2julian(launch_window[1]))
push!(result, -10*ones(3)...)
for i in 1:num_phases
push!(result, -10*ones(3)...)
@@ -104,7 +104,7 @@ end
function highest_mission_vector(launch_window::Tuple{DateTime,DateTime}, mission_length::Float64, num_phases::Int, n::Int)
result = Vector{Float64}()
push!(result, datetime2unix(launch_window[2]))
push!(result, datetime2julian(launch_window[2]))
push!(result, 10*ones(3)...)
for i in 1:num_phases
push!(result, 10*ones(3)...)
@@ -133,14 +133,14 @@ function Mission(sc::Sc, mass::Float64, date::DateTime, v∞::Vector{Float64}, p
force=false)
# First do some checks to make sure that it's valid
if !force
time = utc2et(format(date,"yyyy-mm-ddTHH:MM:SS"))
time = datetime2julian(date)
current_planet = Earth
start = state(current_planet, time, v∞, mass)
for phase in phases
#Propagate
final = prop(phase.thrust_profile, start, sc, phase.tof)[2]
final = prop(phase.thrust_profile, start, sc, phase.tof)[end,:]
current_planet = phase.planet
time += phase.tof
time += phase.tof/86400
goal = state(current_planet, time, phase.v∞_in)
start = state(current_planet, time, phase.v∞_out, final[7])
@@ -178,7 +178,7 @@ end
function Mission(x::Vector{Float64}, sc::Sc, mass::Float64, flybys::Vector{Body})
# Variable mission params
launch_date = unix2datetime(x[1])
launch_date = julian2datetime(x[1])
launch_v∞ = x[2:4]
# Try to intelligently determine n

View File

@@ -1,4 +1,4 @@
function laguerre_conway(state::Vector{<:Real}, time::Float64, primary::Body=Sun)
function laguerre_conway(state::AbstractArray, time::Real, primary::Body=Sun)
μ = primary.μ
n = 5 # Choose LaGuerre-Conway "n"

View File

@@ -59,27 +59,27 @@ end
"""
A fundamental function to generate a plot for a single orbit path
"""
function gen_plot(path::Vector{Vector{Float64}};
function gen_plot(path::AbstractArray;
label::Union{AbstractString, Nothing} = nothing,
color::AbstractString = random_color(),
markers=true)
# Plot the orbit
if label === nothing
path_trace = scatter3d(;x=(path[1]),y=(path[2]),z=(path[3]),
path_trace = scatter3d(;x=(path[:,1]),y=(path[:,2]),z=(path[:,3]),
mode="lines", showlegend=false, line_color=color, line_width=3)
else
path_trace = scatter3d(;x=(path[1]),y=(path[2]),z=(path[3]),
path_trace = scatter3d(;x=(path[:,1]),y=(path[:,2]),z=(path[:,3]),
mode="lines", name=label, line_color=color, line_width=3)
end
traces = [ path_trace ]
# Plot the markers
if markers
push!(traces, scatter3d(;x=([path[1][1]]),y=([path[2][1]]),z=([path[3][1]]),
push!(traces, scatter3d(;x=([path[1,1]]),y=([path[1,2]]),z=([path[1,3]]),
mode="markers", showlegend=false,
marker=attr(color=color, size=3, symbol="circle")))
push!(traces, scatter3d(;x=([path[1][end]]),y=([path[2][end]]),z=([path[3][end]]),
push!(traces, scatter3d(;x=([path[end,1]]),y=([path[end,2]]),z=([path[end,3]]),
mode="markers", showlegend=false,
marker=attr(color=color, size=3, symbol="diamond")))
end
@@ -222,7 +222,7 @@ end
"""
Generic plotting function for a bunch of paths. Useful for debugging.
"""
function plot(paths::Vector{Vector{Vector{Float64}}};
function plot(paths::Vector{Matrix{Real}};
labels::Union{Vector{String},Nothing}=nothing,
colors::Union{Vector{String},Nothing}=nothing,
markers::Bool=true,
@@ -243,7 +243,8 @@ function plot(paths::Vector{Vector{Vector{Float64}}};
push!(traces, gen_plot(Sun)[1]...)
# Determine layout details
layout = standard_layout(limit, title)
# layout = standard_layout(limit, title)
layout = standard_layout(1e9, title)
# Plot
PlotlyJS.plot( PlotlyJS.Plot( traces, layout ) )
@@ -253,19 +254,20 @@ end
function plot(m::Union{Mission, Mission_Guess}; title::String="Mision Plot")
# First plot the earth
# Then plot phase plus planet phase
time = m.launch_date
time = datetime2julian(m.launch_date)
mass = m.start_mass
current_planet = Earth
earth_trace, limit = gen_plot(current_planet, time, year)
earth_trace, limit = gen_plot(current_planet, julian2datetime(time), year)
start = state(current_planet, time, m.launch_v∞, mass)
traces = [ earth_trace... ]
i = 1
for phase in m.phases
# First do the path
path, final = prop(phase.thrust_profile, start, m.sc, phase.tof, interpolate=true)
path = prop(phase.thrust_profile, start, m.sc, phase.tof)
final = path[end,:]
mass = final[7]
time += Second(floor(phase.tof))
time += phase.tof/86400
current_planet = phase.planet
start = state(current_planet, time, phase.v∞_out, mass)
path_trace, new_limit = gen_plot(path, label="Phase "*string(i))
@@ -273,7 +275,7 @@ function plot(m::Union{Mission, Mission_Guess}; title::String="Mision Plot")
limit = max(limit, new_limit)
# Then the planet
planet_trace, new_limit = gen_plot(current_planet, time, -phase.tof)
planet_trace, new_limit = gen_plot(current_planet, julian2datetime(time), -phase.tof)
push!(traces, planet_trace...)
limit = max(limit, new_limit)

View File

@@ -3,83 +3,52 @@ export prop
"""
Maximum ΔV that a spacecraft can impulse for a given single time step
"""
function max_ΔV(duty_cycle::Float64,
function max_ΔV(duty_cycle::Real,
num_thrusters::Int,
max_thrust::Float64,
tf::Float64,
t0::Float64,
mass::T) where T <: Real
return duty_cycle*num_thrusters*max_thrust*(tf-t0)/mass
end
"""
A convenience function for using spacecraft. Note that this function outputs a sc instead of a mass
"""
function prop_one(ΔV_unit::Vector{<:Real},
state::Vector{<:Real},
craft::Sc,
time::Float64,
primary::Body=Sun)
ΔV = max_ΔV(craft.duty_cycle, craft.num_thrusters, craft.max_thrust, time, 0., state[7]) * ΔV_unit
halfway = laguerre_conway(state, time/2, primary) + [zeros(3); ΔV]
final = laguerre_conway(halfway, time/2, primary)
return [final; state[7] - mfr(craft)*norm(ΔV_unit)*time]
max_thrust::Real,
tf::Real,
t0::Real)
return duty_cycle*num_thrusters*max_thrust*(tf-t0)
end
"""
The propagator function
"""
function prop(ΔVs::Matrix{T},
state::Vector{Float64},
function prop(ΔVs::AbstractArray,
state::AbstractArray,
craft::Sc,
time::Float64,
primary::Body=Sun;
interpolate::Bool=false) where T <: Real
time::Real;
primary::Body=Sun)
size(ΔVs)[2] == 3 || throw(ΔVsize_Error())
size(ΔVs)[2] == 3 || throw(ΔVsize_Error(size(ΔVs)))
n = size(ΔVs)[1]
states = [ Vector{T}(),Vector{T}(),Vector{T}(),Vector{T}(),Vector{T}(),Vector{T}(),Vector{T}() ]
for i in 1:7 push!(states[i], state[i]) end
output = Array{Real,2}(undef,n,7)
current = copy(state)
full_thrust = max_ΔV(craft.duty_cycle, craft.num_thrusters, craft.max_thrust, time/n, 0.)
for i in 1:n
if interpolate
interpolated_state = copy(state)
for j in 1:49
interpolated_state = [laguerre_conway(interpolated_state, time/50n, primary); 0.0]
for k in 1:7 push!(states[k], interpolated_state[k]) end
end
halfway = laguerre_conway(current[1:6], time/(2n), primary)
if time > 0
halfway += [zeros(3); full_thrust * ΔVs[i,:]] / current[7]
current[7] -= mfr(craft) * norm(ΔVs[i,:]) * time/n
else
current[7] -= mfr(craft) * norm(ΔVs[i,:]) * time/n
halfway += [zeros(3); full_thrust * ΔVs[i,:]] / current[7]
end
try
state = prop_one(ΔVs[i,:], state, craft, time/n, primary)
catch e
if isa(e,PropOne_Error)
for val in e.ΔV_unit
# If this isn't true, then we just let it slide
if abs(val) > 1.0001
rethrow()
end
end
else
rethrow()
end
end
for j in 1:7 push!(states[j], state[j]) end
current[1:6] = laguerre_conway(halfway, time/(2n), primary)
output[i,:] = current
end
state[7] > craft.dry_mass || throw(Mass_Error(state[7]))
current[7] > craft.dry_mass || throw(Mass_Error(current[7]))
return states, state
return output
end
"""
Convenience function for propagating a state with no thrust
"""
prop(x::Vector{Float64}, t::Float64, p::Body=Sun) = prop(zeros(1000,3), [x;1.], no_thrust, t, p)[1]
prop(x::AbstractArray, t::Real, p::Body=Sun) = prop(zeros(1000,3), x, no_thrust, t, p)
"""
This is solely for the purposes of getting the final state of a mission or guess
@@ -91,7 +60,7 @@ function prop(m::Union{Mission, Mission_Guess})
final = zeros(7)
for phase in m.phases
final = prop(phase.thrust_profile, start, m.sc, phase.tof)[2]
final = prop(phase.thrust_profile, start, m.sc, phase.tof)[end,:]
mass = final[7]
current_planet = phase.planet
time += Second(floor(phase.tof))

View File

@@ -7,23 +7,23 @@ Spacecraft: bepi
num_thrusters: 2
duty_cycle: 0.9
Launch Mass: 3600.0 kg
Launch Date: 2021-10-31T23:59:59.769
Launch V∞: [1.0462564431708832, -2.520754077506101, -2.301043507881933] km/s
Launch Date: 2021-10-31T22:00:16.400
Launch V∞: [1.0097399011270518, -2.6447886914618515, -2.5394649406128433] km/s
Phase 1:
Planet: Venus
V∞_in: [0.4205842845952983, -3.5241183574614556, 4.879873784266574] km/s
V∞_out: [2.657685712690303, -4.920354075306563, 2.266369032728228] km/s
time of flight: 1.2614399691127092e7 seconds
arrival date: 2022-03-26T23:59:58.769
thrust profile: [0.08791530712557315 -0.009101317973001748 0.010254083007822207; 0.07287521745776969 -0.011381949725375708 0.051332448819202944; 0.04543116258472458 -0.01531732267940295 0.08273458014460809; 0.011034188560216448 -0.020310595889307323 0.10100599446320643; -0.009607377273254756 -0.02382633371411493 0.1081982710061048; -0.028510355701058584 -0.030611944159923403 0.11101434996597628; -0.039048295910837236 -0.03820244320795566 0.11279184708362161; -0.048252651406879885 -0.04651039104792323 0.11301481830933677; -0.05288674350674192 -0.0561882917884983 0.11293454239992265; -0.05458628096513579 -0.06643801004024381 0.11223764822140121; -0.053564283975236535 -0.07751051107973227 0.11061646758637526; -0.049500823222769094 -0.0891415249668692 0.10769319474620971; -0.04185476746663511 -0.10066361474827486 0.10355236756997019; -0.03087924291992901 -0.1112479139000727 0.09781871133696314; -0.015564164113106642 -0.11996802006040436 0.09064682025194883; 0.001781758545597473 -0.12613079909578606 0.0809801955196938; 0.021345925406049154 -0.12876486287710442 0.06930029766487243; 0.041502826765638504 -0.12763804654948588 0.054677487677216745; 0.06024411885991524 -0.12236183464053872 0.038231302757203295; 0.07560839256024353 -0.114157581119008 0.018886579096999003] %
V∞_in: [0.6971321781569763, -3.000415336232889, 5.257930893162622] km/s
V∞_out: [3.155471614002537, -4.846243818499916, 1.9261368837603878] km/s
time of flight: 1.261440000905646e7 seconds
arrival date: 2022-03-26T22:00:16.400
thrust profile: [0.034282174989117516 0.030630284530489906 0.0516767016545959; 0.04055472535721235 0.027376197088858283 0.04809039664320572; 0.043660143604191994 0.03047637966598728 0.04358760046457853; 0.04125099543115894 0.03016179866323979 0.04499932191472562; 0.04495441021193453 0.03348083036100891 0.03861183062100992; 0.04710965203705168 0.02635602095857307 0.04054560175736578; 0.05033947480940243 0.03062684297509654 0.032922298467773295; 0.04663650635412875 0.030369216537824293 0.03703971691255565; 0.048565701285880614 0.029118981813448557 0.034508738912923845; 0.05056448644255328 0.028722504694661054 0.031034420379757226; 0.04932798248085456 0.03007397062288681 0.030824783232637425; 0.047996060872376366 0.028952951818463326 0.032857369566278626; 0.04951821298908887 0.028758116977346378 0.027958339954661; 0.0489313400699588 0.03046347487498191 0.027859841906091212; 0.04520420340375004 0.031670198439770064 0.030514442243397236; 0.04566034232248259 0.034381957552538395 0.024900845759794794; 0.04082535412813151 0.03357236769501879 0.03170011587741194; 0.04621217362755022 0.03182636410505487 0.02410773528455805; 0.045645717216652795 0.032921517920520164 0.02079135127615303; 0.042597542211632096 0.03558968396172082 0.021282994074205266; 0.03731044485129105 0.03994289623933655 0.02130495307758324; 0.04247833588674327 0.03457796735712127 0.01899569141913135; 0.04312850336659755 0.03399248745544899 0.013149159955936978; 0.03754604612989521 0.03763011819702751 0.018318693954420588; 0.03535094668642273 0.036858320028499134 0.02199684830247042; 0.028891076662331875 0.04324155785176078 0.014413619206886816; 0.03267849036426984 0.0401634806637448 0.011840587979407397; 0.024706839495172658 0.043042163807245896 0.01826522977160073; 0.028601237657836467 0.041588848578667854 0.014411946517623132; 0.028228090581187873 0.04015749743865513 0.01508529741887872; 0.024783781293558266 0.04189396738290361 0.014616887877185162; 0.024764235231400287 0.0412235929856152 0.014206631004299218; 0.022700981741250053 0.04285522888573239 0.008652897464076466; 0.023149708367887163 0.04204784290805528 0.011482287191821549; 0.030060665695868752 0.03682561335933804 0.01406740384301527; 0.020327198179371554 0.03967929127546447 0.01907556971774192; 0.01948576963473395 0.04150171458022886 0.01440277138047399; 0.014609183554173198 0.04193091541988154 0.0190142349738259; 0.017338241200120032 0.0405327064144073 0.019397828837718817; 0.013519064235294736 0.043194207588669445 0.012618271521276186; 0.01416527483071525 0.042360112796518024 0.018565046588499192; 0.016192504354863486 0.04321790744316709 0.014857969976184007; 0.005926517746692747 0.04385012579593121 0.01848227965737381; 0.007881472501745706 0.045008039792868576 0.01571801630208125; 0.006544092936553959 0.04561895672702495 0.016342515520064185; 0.0018483989093118227 0.046533973409849064 0.014988164886431584; -0.000568247332158013 0.047073416094890685 0.01286929122897256; -0.008004594524198529 0.046599777614930456 0.013010850227684606; -0.00696671229499173 0.048339673337854945 0.010999881717700421; -0.0070218437672999665 0.04911375570173229 0.010996777473604348] %
Phase 2:
Planet: Mars
V∞_in: [3.866657617879469, -3.8561104436565112, -1.1528388074396114] km/s
V∞_out: [-0.04156826938628659, 0.04537147320396694, 0.010962101613372877] km/s
time of flight: 1.3305600070108933e7 seconds
arrival date: 2022-08-27T23:59:58.769
thrust profile: [0.12294683695617006 -0.14210501591303906 -0.015953927996763824; 0.1346036754636979 -0.11703322342276389 -0.02118233265872474; 0.14035562458965456 -0.09253436643679969 -0.026037109750586127; 0.14159974389839877 -0.07034252588185486 -0.02965559917950358; 0.13983758574258884 -0.0508280123903436 -0.03226072974284784; 0.13628355001371623 -0.03381714643542805 -0.033706183284138075; 0.13174907912062978 -0.01944710462973476 -0.03378159713957984; 0.12690191547644916 -0.006666552590772735 -0.032314321099804075; 0.12190989012800546 0.005350412631176013 -0.02896415432946389; 0.11640547480173373 0.01766009561198736 -0.024295908236754368; 0.11004779022898785 0.029624240108957346 -0.018629744776725948; 0.10255142565747595 0.041391197147168296 -0.011260773047897207; 0.09257939116538691 0.054055648527399226 -0.0018819573006649628; 0.07862129598678515 0.06762185940978795 0.006827208192964654; 0.06184044671572194 0.07873199678299247 0.015671300335402687; 0.04256729407158805 0.08711502955932304 0.023547740065060118; 0.022644089962366266 0.0922573542104121 0.029300773045221138; 0.0012772594401787602 0.09453861142625342 0.0335188440659034; -0.017213511457067864 0.09403439603239908 0.036105272081528195; -0.03466637624188391 0.0910940423628138 0.03867124120601387] %
V∞_in: [3.934071361708631, -4.0556866988998195, -0.9569218994864468] km/s
V∞_out: [2.835079207012675, -3.038506396757051, -0.8239067509398897] km/s
time of flight: 1.3305600002135515e7 seconds
arrival date: 2022-08-27T22:00:16.400
thrust profile: [0.07875872819429838 -0.07602928888291517 -0.002461076427925589; 0.08368497242841927 -0.06670986115534407 0.001665869512245407; 0.08577981435177857 -0.05793119355590426 0.011165188393882227; 0.08758545440549516 -0.0339816665457332 0.026794441364176573; 0.08293133779344392 -0.02340157704539268 0.034551607127364624; 0.07757395448326561 -0.006354368804274271 0.03802615353405709; 0.0644275187408338 0.00817115132820835 0.04477293215146323; 0.052643603336670175 0.021208603088669686 0.04641877730052604; 0.0422696791291819 0.03249686419539815 0.04293455453504036; 0.0299947244754212 0.0342146829206795 0.04610828643246764; 0.028375921792895057 0.031929570942726804 0.04880758017415033; 0.021457075341902082 0.03512409953676916 0.047848639128187716; 0.014050820576587325 0.03598753239044044 0.048208234639668036; 0.01239374458074181 0.03519088938079009 0.04991578465780201; 0.005554038390401058 0.03590306275800209 0.04943448284625346; 0.004594710645977571 0.03473960951290201 0.05085953544892566; 0.004962419167461687 0.03677569856463667 0.05029354676804025; 0.0007318114245317572 0.03710676170960615 0.050422609329575686; -0.0008906817624837742 0.03770220933797602 0.05041455076147805; -0.006778334873847526 0.03779829345387088 0.04962125740173904; -0.007046493202932243 0.03568043355312452 0.051960594399799505; -0.008049628911291552 0.03913802154188755 0.05028104660474625; -0.010537903266724359 0.03672325453597655 0.051884804336631986; -0.00818351261490794 0.038741730202093635 0.05210658416215128; -0.010666656787731375 0.03849972475725258 0.05243476797310733; -0.012555727410020852 0.0382137309957785 0.05268364578100002; -0.009820005328087349 0.03916769798664862 0.05359353372069135; -0.012387176669361927 0.03970296584000698 0.05331339060382668; -0.01244834483921497 0.041886262658702045 0.05253893772334037; -0.013444072160084112 0.04262744032016184 0.05253898626998434; -0.012523862311046558 0.04142301768047668 0.05454027471095643; -0.012895225834978194 0.042511978835118515 0.0544877324498131; -0.012679086383971097 0.04485961538708221 0.05361843203762159; -0.01233563279407355 0.04412582031595734 0.05489553351056654; -0.011291838361870397 0.04737557615034447 0.05363956736166156; -0.011230502857283789 0.04704594850205801 0.05467457973688944; -0.008797763456055051 0.04928744387907065 0.05415511568853677; -0.008048802844087589 0.05075747730843418 0.0538825677403911; -0.0056970113123549744 0.05224183281724393 0.05369505177198884; -0.006070834938122434 0.052936925948144475 0.05379731537648658; -0.0024653651357053295 0.05567255160163994 0.05213940324181525; -0.000733453786943943 0.057067189219935754 0.05145199179114529; 0.0012456777227569263 0.059943358064031824 0.04907287600209174; 0.004373513720293685 0.06169575905345249 0.047206183474067936; 0.009873790970193171 0.06486640320654036 0.04255101782330187; 0.013319573203495716 0.06692522008245975 0.03887179390451873; 0.018201455983236366 0.06835502892414509 0.034298233864195185; 0.023662275014910684 0.06904022589813187 0.029150000528514425; 0.02774195908046571 0.07005784655018363 0.02165291283778826; 0.031997497603024734 0.06946489515884077 0.015502921841459603] %
Mass Used: 121.86921799846004 kg
Launch C3: 12.743654889305812 km²/s²
||V∞_in||: 5.58118860132149 km/s
Mass Used: 61.61570260672124 kg
Launch C3: 14.463364075014354 km²/s²
||V∞_in||: 5.730725224643533 km/s

View File

@@ -4,72 +4,37 @@
println("Testing NLP solver")
# Test the optimizer for a one-phase mission
# The lambert's solver said this should be pretty valid
launch_window = DateTime(1992,11,1), DateTime(1992,12,1)
latest_arrival = DateTime(1993,6,1)
leave, arrive = DateTime(1992,11,19), DateTime(1993,4,1)
test_leave = DateTime(1992,11,12)
earth_state = state(Earth, leave)
venus_state = state(Venus, arrive)
v∞_out, v∞_in, tof = Thesis.lamberts(Earth, Venus, leave, arrive)
# We can get the thrust profile and tof pretty wrong and still be ok
phase = Phase(Venus, 1.1v∞_in, v∞_in, 0.9*tof, 0.1*ones(20,3))
guess = Mission_Guess(bepi, 3_600., test_leave, 0.9*v∞_out, [phase])
m = solve_mission(guess, launch_window, latest_arrival, 200., 20., verbose=true)
@test typeof(m) == Mission
# Now we can plot the results to check visually
p = plot(m, title="NLP Test Solution")
savefig(p,"../plots/nlp_test_1_phase.html")
store(m, "missions/nlp_1_phase")
# Now we can look at a slightly more complicated trajectory
flybys = [Earth, Venus, Mars]
# This will be the only test to verify rather than testing different complexities
n = 50
flybys = [Earth, Venus, Mars]#, Jupiter]
launch_window = DateTime(2021,10,1), DateTime(2021,12,1)
latest_arrival = DateTime(2023,1,1)
dates = [DateTime(2021,11,1), DateTime(2022,3,27), DateTime(2022,8,28)]
latest_arrival = DateTime(2028,1,1)
dates = [DateTime(2021,11,1),
DateTime(2022,3,27),
DateTime(2022,8,28)]
# DateTime(2028,3,1)]
phases = Vector{Phase}()
launch_v∞, _, tof1 = Thesis.lamberts(flybys[1], flybys[2], dates[1], dates[2])
for i in 1:length(dates)-2
v∞_out1, v∞_in1, tof1 = Thesis.lamberts(flybys[i], flybys[i+1], dates[i], dates[i+1])
v∞_out2, v∞_in2, tof2 = Thesis.lamberts(flybys[i+1], flybys[i+2], dates[i+1], dates[i+2])
push!(phases, Phase(flybys[i+1], v∞_in1, v∞_out2, tof1, 0.01*ones(20,3)))
v∞_in1, tof1 = Thesis.lamberts(flybys[i], flybys[i+1], dates[i], dates[i+1])[2:3]
v∞_out2 = Thesis.lamberts(flybys[i+1], flybys[i+2], dates[i+1], dates[i+2])[1]
push!(phases, Phase(flybys[i+1], v∞_in1, v∞_out2, tof1, 0.01*ones(50,3)))
end
v∞_out, v∞_in, tof = Thesis.lamberts(flybys[end-1], flybys[end], dates[end-1], dates[end])
push!(phases, Phase(flybys[end], v∞_in, v∞_in, tof, 0.01*ones(20,3)))
v∞_in, tof = Thesis.lamberts(flybys[end-1], flybys[end], dates[end-1], dates[end])[2:3]
push!(phases, Phase(flybys[end], v∞_in, v∞_in, tof, 0.01*ones(50,3)))
guess = Mission_Guess(bepi, 3_600., dates[1], launch_v∞, phases)
m = solve_mission(guess, launch_window, latest_arrival, 200., 20., verbose=true)
m = solve_mission(guess,
launch_window,
latest_arrival,
200.,
20.,
verbose=true,
print_level=4)
@test typeof(m) == Mission
p = plot(m, title="NLP Test Solution (2 Phases)")
savefig(p,"../plots/nlp_test_2_phase.html")
store(m, "missions/nlp_2_phase")
# Here is the final, most complicated, trajectory to test
# Ignoring for now as the initial guess makes the test take too long to converge with mbh settings
# flybys = [Earth, Venus, Earth, Mars, Earth, Jupiter]
# launch_window = DateTime(2023,1,1), DateTime(2024,1,1)
# latest_arrival = DateTime(2031,1,1)
# dates = [DateTime(2023,5,23),
# DateTime(2023,10,21),
# DateTime(2024,8,24),
# DateTime(2025,2,13),
# DateTime(2026,11,22),
# DateTime(2032,1,1)]
# phases = Vector{Phase}()
# launch_v∞, _, tof1 = Thesis.lamberts(flybys[1], flybys[2], dates[1], dates[2])
# for i in 1:length(dates)-2
# v∞_out1, v∞_in1, tof1 = Thesis.lamberts(flybys[i], flybys[i+1], dates[i], dates[i+1])
# v∞_out2, v∞_in2, tof2 = Thesis.lamberts(flybys[i+1], flybys[i+2], dates[i+1], dates[i+2])
# push!(phases, Phase(flybys[i+1], 1.02v∞_in1, 0.98v∞_out2, 1.02tof1, 0.02*ones(20,3)))
# end
# v∞_out, v∞_in, tof = Thesis.lamberts(flybys[end-1], flybys[end], dates[end-1], dates[end])
# push!(phases, Phase(flybys[end], v∞_in, v∞_in, tof, 0.01*ones(20,3)))
# guess = Mission_Guess(bepi, 3_600., dates[1], launch_v∞, phases)
# m = solve_mission(guess, launch_window, latest_arrival, 200., 20., verbose=true)
# @test typeof(m) == Mission
# p = plot(m, title="NLP Test Solution (5 Phases)")
# savefig(p,"../plots/nlp_test_5_phase.html")
# store(m, "missions/nlp_5_phase")
if typeof(m) == Mission
p = plot(m, title="NLP Test Solution (2 Phases)")
savefig(p,"../plots/nlp_test_2_phase.html")
store(m, "missions/nlp_2_phase")
end
end

View File

@@ -1,21 +1,27 @@
@testset "Propagator" begin
println("Testing propagator")
using PlotlyJS: savefig
using Thesis: prop_one
println("Testing Propagator")
# Set up
start_mass = 10_000.
start = gen_orbit(rand(.5year : hour : 2year), start_mass)
stepsize = rand(hour : second : 6hour)
time = rand(0.2year : second : 0.5year)
n = 1_000
# Test that Laguerre-Conway is the default propagator for spacecrafts
state = prop_one([0., 0., 0.], start, no_thrust, stepsize)
@test laguerre_conway(start, stepsize) state[1:6]
@test state[7] == start_mass
# Test that Propagation works
states = prop(zeros(n,3), start, no_thrust, time)
@test states[1,:] != states[end,:]
# Test that mass is reduced properly
state = prop_one([1., 0., 0.], start, bepi, stepsize)
@test state[7] == start_mass - mfr(bepi)*stepsize
states = prop(ones(n,3)/3, start, bepi, time)
@test states[end,7] start_mass - mfr(bepi)*time
# Test that the propagator works backwards
backwards = prop(ones(n,3)/3, states[end,:], bepi, -time)
p = plot([states, backwards])
savefig(p,"../plots/prop_back.html")
@test backwards[end,:] start
end

View File

@@ -3,7 +3,7 @@ using Random
using LinearAlgebra
using SPICE
using Thesis
using Dates: DateTime, Millisecond, Dates, Second, format, datetime2unix, unix2datetime
using Dates: DateTime, Millisecond, Dates, Second, format, datetime2julian, julian2datetime
try
furnsh("../../spice_files/naif0012.tls")
@@ -14,10 +14,10 @@ catch
end
@testset "All Tests" begin
include("plotting.jl")
include("laguerre-conway.jl")
# include("plotting.jl")
# include("laguerre-conway.jl")
include("propagator.jl")
include("nlp_solver.jl")
include("mbh.jl")
include("genetic_algorithm.jl")
# include("nlp_solver.jl")
# include("mbh.jl")
# include("genetic_algorithm.jl")
end