Update for ky
This commit is contained in:
63
julia/find_neptune.jl
Normal file
63
julia/find_neptune.jl
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
using Thesis
|
||||||
|
using Dates
|
||||||
|
using SPICE
|
||||||
|
using LinearAlgebra
|
||||||
|
using PlotlyJS: savefig
|
||||||
|
|
||||||
|
try
|
||||||
|
furnsh("../../spice_files/naif0012.tls")
|
||||||
|
furnsh("../../spice_files/de430.bsp")
|
||||||
|
catch
|
||||||
|
furnsh("spice_files/naif0012.tls")
|
||||||
|
furnsh("spice_files/de430.bsp")
|
||||||
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
The cost function for the mission
|
||||||
|
"""
|
||||||
|
function easy_cost(m::Union{Mission, Mission_Guess}, C3::Float64, v∞::Float64)
|
||||||
|
norm_mass = (m.start_mass - prop(m)[7]) / m.start_mass
|
||||||
|
norm_C3 = ( m.launch_v∞ ⋅ m.launch_v∞ ) / C3
|
||||||
|
norm_v∞ = norm(m.phases[end].v∞_in) / v∞
|
||||||
|
return norm_mass + norm_C3# + norm_v∞
|
||||||
|
end
|
||||||
|
|
||||||
|
# Using some fairly realistic parameters now
|
||||||
|
sc = Sc("mySat", 200., 3200., 0.00025, 1, 1.0)
|
||||||
|
fuel = 3300.
|
||||||
|
max_c3 = 200.
|
||||||
|
max_v∞ = 500.
|
||||||
|
voyager_launch = DateTime(1977,9,5)
|
||||||
|
launch_window = voyager_launch - Year(2), voyager_launch + Year(2)
|
||||||
|
latest_arrival = voyager_launch + Year(25)
|
||||||
|
println("Max thrust at full bore: $(fuel/(mfr(sc)*Thesis.year)) years")
|
||||||
|
println("Max mission length: $((latest_arrival - launch_window[1]).value/(1000Thesis.year)) years")
|
||||||
|
|
||||||
|
# Convenience function for these tests
|
||||||
|
Thesis.mbh(fbs) = mbh(fbs,
|
||||||
|
sc,
|
||||||
|
sc.dry_mass + fuel,
|
||||||
|
launch_window,
|
||||||
|
max_c3,
|
||||||
|
max_v∞,
|
||||||
|
latest_arrival,
|
||||||
|
easy_cost,
|
||||||
|
search_patience=20_000,
|
||||||
|
drill_patience=200,
|
||||||
|
verbose=true)
|
||||||
|
|
||||||
|
function log(m::Mission, archive::Vector{Mission}, planets::Vector{Body})
|
||||||
|
abbrev = join([ planet.name[1] for planet in planets ])
|
||||||
|
p = plot(m, title="Best $(abbrev) Trajectory")
|
||||||
|
savefig(p,"archive/$(abbrev).html")
|
||||||
|
store(m, "archive/$(abbrev)")
|
||||||
|
store(archive, "archive/$(abbrev)_archive")
|
||||||
|
end
|
||||||
|
|
||||||
|
log(_::Nothing, _::Vector{Mission}, _::Vector{Body}) = println("No Mission Found...")
|
||||||
|
|
||||||
|
planets = [Earth, Jupiter, Saturn, Uranus, Neptune]
|
||||||
|
best, archive = mbh(planets)
|
||||||
|
log(best, archive, planets)
|
||||||
|
|
||||||
|
println("Complete!")
|
||||||
@@ -5,7 +5,7 @@ module Thesis
|
|||||||
using PlotlyJS
|
using PlotlyJS
|
||||||
using Distributed
|
using Distributed
|
||||||
using SPICE
|
using SPICE
|
||||||
using Dates: DateTime, Millisecond, Dates
|
using Dates: DateTime, Millisecond, Dates, Second, format, datetime2unix, unix2datetime
|
||||||
|
|
||||||
try
|
try
|
||||||
furnsh("../../spice_files/naif0012.tls")
|
furnsh("../../spice_files/naif0012.tls")
|
||||||
@@ -15,18 +15,18 @@ module Thesis
|
|||||||
furnsh("spice_files/de430.bsp")
|
furnsh("spice_files/de430.bsp")
|
||||||
end
|
end
|
||||||
|
|
||||||
include("./errors.jl")
|
include("./types/errors.jl")
|
||||||
include("./bodies.jl")
|
include("./types/bodies.jl")
|
||||||
include("./constants.jl")
|
include("./utilities/constants.jl")
|
||||||
include("./spacecraft.jl")
|
include("./types/spacecraft.jl")
|
||||||
include("./inner_loop/laguerre-conway.jl")
|
include("./utilities/laguerre-conway.jl")
|
||||||
include("./mission.jl")
|
include("./types/mission.jl")
|
||||||
include("./inner_loop/propagator.jl")
|
include("./utilities/propagator.jl")
|
||||||
include("./conversions.jl")
|
include("./utilities/conversions.jl")
|
||||||
include("./plotting.jl")
|
include("./utilities/plotting.jl")
|
||||||
include("./inner_loop/nlp_solver.jl")
|
include("./nlp_solver.jl")
|
||||||
include("./inner_loop/monotonic_basin_hopping.jl")
|
include("./mbh.jl")
|
||||||
# include("./outer_loop.jl")
|
include("./genetic_algorithm.jl")
|
||||||
include("./lamberts.jl")
|
include("./utilities/lamberts.jl")
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
36
julia/src/genetic_algorithm.jl
Normal file
36
julia/src/genetic_algorithm.jl
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
export outer_loop
|
||||||
|
|
||||||
|
function outer_loop()
|
||||||
|
|
||||||
|
# Ok, so here's the pseudocode
|
||||||
|
# generate a population randomly -> rand(sequence)
|
||||||
|
# run mbh and find cost for each member of population -> mbh.(population)
|
||||||
|
# loop
|
||||||
|
# loop (number of children)
|
||||||
|
# randomly choose some parents from pool -> shuffle(pool)[1:n]
|
||||||
|
# choose best member = mom -> sort(pool)[1]
|
||||||
|
# randomly choose some parents from pool again -> shuffle(pool)[1:n]
|
||||||
|
# choose best member = dad -> sort(pool)[1]
|
||||||
|
# take the first and last random number of entries from mom and middle from dad -> mate()
|
||||||
|
# insert new child into population -> push!()
|
||||||
|
# loop (number of mutated)
|
||||||
|
# randomly choose some parents from the pool -> shuffle(pool)[1:n]
|
||||||
|
# best member = retained -> sort(pool)[1]
|
||||||
|
# copy retained -> mutated and possibly mutate each chromosome -> mutate()
|
||||||
|
# insert mutated into population -> push!()
|
||||||
|
# loop (number of elite)
|
||||||
|
# insert the top individuals into the pool -> push!(new_pool, sort(pool)[1:n])
|
||||||
|
# run mbh and evaluate all members of new pool
|
||||||
|
# return the best
|
||||||
|
#
|
||||||
|
# Functions Needed:
|
||||||
|
# rand(flyby_sequence)
|
||||||
|
# mate(flyby_sequence, flyby_sequence)
|
||||||
|
# mutate(flyby_sequence)
|
||||||
|
# snapshot(generation)
|
||||||
|
#
|
||||||
|
|
||||||
|
println("And so the end begins")
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
using Dates
|
|
||||||
|
|
||||||
export inner_loop
|
|
||||||
|
|
||||||
"""
|
|
||||||
This is it. The outer function call for the inner loop. After this is done,
|
|
||||||
there's only the outer loop left to do. And that's pretty easy.
|
|
||||||
"""
|
|
||||||
function inner_loop(launch_date::DateTime,
|
|
||||||
craft::Sc,
|
|
||||||
start_mass::Float64,
|
|
||||||
phases::Vector{Phase};
|
|
||||||
min_flyby::Float64=1000.,
|
|
||||||
mbh_specs=nothing,
|
|
||||||
verbose=false)
|
|
||||||
|
|
||||||
# First we need to do some quick checks that the mission is well formed
|
|
||||||
for i in 1:length(phases)
|
|
||||||
if i == 1
|
|
||||||
@assert phases[i].from_planet == "Earth"
|
|
||||||
else
|
|
||||||
# Check that the planet is valid
|
|
||||||
if phases[i].from_planet ∉ keys(μs)
|
|
||||||
error("Planet is not valid: ", phases[i].from_planet)
|
|
||||||
# Check that there is only one flyby planet
|
|
||||||
elseif phases[i].from_planet != phases[i-1].to_planet
|
|
||||||
fromP, toP = phases[i].from_planet, phases[i-1].to_planet
|
|
||||||
error("Planets don't match up: (phase $(i)) $(fromP) / (phase $(i-1)) $(toP)")
|
|
||||||
# Check that v∞_in == v∞_out
|
|
||||||
elseif !isapprox(norm(phases[i].v∞_outgoing), norm(phases[i-1].v∞_incoming))
|
|
||||||
norm_incoming = norm(phases[i-1].v∞_incoming)
|
|
||||||
norm_outgoing = norm(phases[i].v∞_outgoing)
|
|
||||||
error("""Norms of vectors aren't equal:
|
|
||||||
Phase $(i-1): $(phases[i-1].v∞_incoming) / norm: $(norm_incoming)
|
|
||||||
Phase $(i): $(phases[i].v∞_outgoing) / norm: $(norm_outgoing)""")
|
|
||||||
end
|
|
||||||
# Check that the approach is not too low
|
|
||||||
v∞ = norm(phases[i].v∞_outgoing)
|
|
||||||
δ = acos((phases[i].v∞_outgoing ⋅ phases[i-1].v∞_incoming)/v∞^2)
|
|
||||||
flyby = μs[phases[i].from_planet]/v∞^2 * (1/sin(δ/2) - 1)
|
|
||||||
true_min = rs[phases[i].from_planet] + min_flyby
|
|
||||||
flyby <= true_min || error("Flyby too low from phase $(i-1) to $(i): $(flyby) / $(true_min)")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
time = utc2et(Dates.format(launch_date,"yyyy-mm-ddTHH:MM:SS"))
|
|
||||||
thrust_profiles = Vector{Matrix{Float64}}()
|
|
||||||
|
|
||||||
for phase in phases
|
|
||||||
planet1_state = [spkssb(ids[phase.from_planet], time, "ECLIPJ2000"); 0.0]
|
|
||||||
time += phase.time_of_flight
|
|
||||||
planet2_state = [spkssb(ids[phase.to_planet], time, "ECLIPJ2000"); 0.0]
|
|
||||||
start = planet1_state + [0., 0., 0., phase.v∞_outgoing..., start_mass]
|
|
||||||
final = planet2_state + [0., 0., 0., phase.v∞_incoming..., start_mass]
|
|
||||||
println(start)
|
|
||||||
println(final)
|
|
||||||
# TODO: Come up with improved method of calculating "n"
|
|
||||||
if mbh_specs === nothing
|
|
||||||
best = mbh(start, final, craft, μs["Sun"], 0.0, phase.time_of_flight, 20,
|
|
||||||
verbose=verbose)[1]
|
|
||||||
else
|
|
||||||
sil, dil = mbh_specs
|
|
||||||
best = mbh(start, final, craft, μs["Sun"], 0.0, phase.time_of_flight, 20,
|
|
||||||
verbose=verbose, search_patience_lim=sil, drill_patience_lim=dil)[1]
|
|
||||||
end
|
|
||||||
push!(thrust_profiles, best.zero)
|
|
||||||
end
|
|
||||||
return thrust_profiles
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -28,7 +28,7 @@ Perturbs a valid mission with pareto-distributed variables, generating a mission
|
|||||||
function perturb(mission::Mission)
|
function perturb(mission::Mission)
|
||||||
mission_guess = Bad_Mission("Starting point")
|
mission_guess = Bad_Mission("Starting point")
|
||||||
while typeof(mission_guess) == Bad_Mission
|
while typeof(mission_guess) == Bad_Mission
|
||||||
new_launch_date = mission.launch_date + Dates.Second(floor(7day * (pareto()-1)))
|
new_launch_date = mission.launch_date + Second(floor(7day * (pareto()-1)))
|
||||||
new_launch_v∞ = mission.launch_v∞ .* pareto(3)
|
new_launch_v∞ = mission.launch_v∞ .* pareto(3)
|
||||||
new_phases = Vector{Phase}()
|
new_phases = Vector{Phase}()
|
||||||
for phase in mission.phases
|
for phase in mission.phases
|
||||||
@@ -57,7 +57,7 @@ function mission_guess( flybys::Vector{Body},
|
|||||||
mission_guess = Bad_Mission("Keep trying to generate a guess")
|
mission_guess = Bad_Mission("Keep trying to generate a guess")
|
||||||
while mission_guess == Bad_Mission("Keep trying to generate a guess")
|
while mission_guess == Bad_Mission("Keep trying to generate a guess")
|
||||||
# TODO: Eventually I can calculate n more intelligently
|
# TODO: Eventually I can calculate n more intelligently
|
||||||
n = 20
|
n = 40
|
||||||
|
|
||||||
# Determine the launch conditions
|
# Determine the launch conditions
|
||||||
launch_date = rand(launch_window...)
|
launch_date = rand(launch_window...)
|
||||||
@@ -114,6 +114,16 @@ function mission_guess( flybys::Vector{Body},
|
|||||||
return mission_guess
|
return mission_guess
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function record(m::Mission, planets::Vector{Body})
|
||||||
|
t = Dates.now()
|
||||||
|
abbrev = join([ planet.name[1] for planet in planets ])
|
||||||
|
mkdir("archive/$(abbrev)_$(t)")
|
||||||
|
store(m, "archive/$(abbrev)_$(t)/mission")
|
||||||
|
p = plot(m, title="$(abbrev) Trajectory")
|
||||||
|
savefig(p,"archive/$(abbrev)_$(t)/plot.html")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This is the main monotonic basin hopping function. There's a lot going on here, but the general idea
|
This is the main monotonic basin hopping function. There's a lot going on here, but the general idea
|
||||||
is that hopefully you can provide mission parameters and a list of flybys and get the optimal
|
is that hopefully you can provide mission parameters and a list of flybys and get the optimal
|
||||||
@@ -134,11 +144,12 @@ function mbh( flybys::Vector{Body},
|
|||||||
|
|
||||||
# Convenience Functions
|
# Convenience Functions
|
||||||
random_guess() = mission_guess(flybys,sc,start_mass,launch_window,max_C3,max_v∞,latest_arrival)
|
random_guess() = mission_guess(flybys,sc,start_mass,launch_window,max_C3,max_v∞,latest_arrival)
|
||||||
solve(g::Mission_Guess) = solve_mission(g, launch_window, latest_arrival)
|
cost(m::Union{Mission,Mission_Guess}) = cost_fn(m, max_C3, max_v∞)
|
||||||
cost(m::Mission) = cost_fn(m, max_C3, max_v∞)
|
|
||||||
cost(_::Nothing) = Inf
|
cost(_::Nothing) = Inf
|
||||||
|
solve(g::Mission_Guess) = solve_mission(g, launch_window, latest_arrival, max_C3, max_v∞)
|
||||||
|
|
||||||
# Initialize stuff
|
# Initialize stuff
|
||||||
|
x_current = nothing
|
||||||
search_count = 0
|
search_count = 0
|
||||||
drill_count = 0
|
drill_count = 0
|
||||||
archive = Vector{Mission}()
|
archive = Vector{Mission}()
|
||||||
@@ -152,7 +163,6 @@ function mbh( flybys::Vector{Body},
|
|||||||
end
|
end
|
||||||
|
|
||||||
# The main loop
|
# The main loop
|
||||||
x_current = nothing
|
|
||||||
while search_count < search_patience
|
while search_count < search_patience
|
||||||
|
|
||||||
# Intialize an x_star, if it doesn't converge, hop on to the next basin
|
# Intialize an x_star, if it doesn't converge, hop on to the next basin
|
||||||
@@ -189,7 +199,10 @@ function mbh( flybys::Vector{Body},
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
x_current in archive || push!(archive, x_current)
|
if x_current ∉ archive
|
||||||
|
push!(archive, x_current)
|
||||||
|
record(x_current, flybys)
|
||||||
|
end
|
||||||
|
|
||||||
# If in test mode, we don't need to actually optimize. Just grab the first valid basin-best
|
# If in test mode, we don't need to actually optimize. Just grab the first valid basin-best
|
||||||
if test
|
if test
|
||||||
@@ -25,6 +25,10 @@ function constraint_bounds(guess::Mission_Guess)
|
|||||||
push!(high_constraint, guess.start_mass - guess.sc.dry_mass)
|
push!(high_constraint, guess.start_mass - guess.sc.dry_mass)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
push!(low_constraint, 0., 0.)
|
||||||
|
push!(high_constraint, 1e3, 1e3)
|
||||||
|
|
||||||
return low_constraint, high_constraint
|
return low_constraint, high_constraint
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -36,10 +40,12 @@ guess otherwise
|
|||||||
"""
|
"""
|
||||||
function solve_mission( guess::Mission_Guess,
|
function solve_mission( guess::Mission_Guess,
|
||||||
launch_window::Tuple{DateTime,DateTime},
|
launch_window::Tuple{DateTime,DateTime},
|
||||||
latest_arrival::DateTime;
|
latest_arrival::DateTime,
|
||||||
|
max_C3::Float64,
|
||||||
|
max_v∞::Float64;
|
||||||
tol=1e-12,
|
tol=1e-12,
|
||||||
verbose::Bool=false,
|
verbose::Bool=false,
|
||||||
print_level=0 )
|
print_level=0)
|
||||||
|
|
||||||
# First we define our starting point
|
# First we define our starting point
|
||||||
x0 = Vector(guess)
|
x0 = Vector(guess)
|
||||||
@@ -51,9 +57,10 @@ function solve_mission( guess::Mission_Guess,
|
|||||||
# Establish initial conditions
|
# Establish initial conditions
|
||||||
v∞_out = x[2:4]
|
v∞_out = x[2:4]
|
||||||
current_planet = Earth
|
current_planet = Earth
|
||||||
launch_date = Dates.unix2datetime(x[1])
|
launch_date = unix2datetime(x[1])
|
||||||
time = utc2et(Dates.format(launch_date,"yyyy-mm-ddTHH:MM:SS"))
|
time = utc2et(format(launch_date,"yyyy-mm-ddTHH:MM:SS"))
|
||||||
start = state(current_planet, time, v∞_out, guess.start_mass)
|
start = state(current_planet, time, v∞_out, guess.start_mass)
|
||||||
|
final = zeros(7)
|
||||||
|
|
||||||
# Now, for each phase we must require:
|
# Now, for each phase we must require:
|
||||||
# - That the ending state matches (all legs)
|
# - That the ending state matches (all legs)
|
||||||
@@ -88,13 +95,16 @@ function solve_mission( guess::Mission_Guess,
|
|||||||
else
|
else
|
||||||
g[8*(length(flybys)-1)+7] = final[7] - guess.sc.dry_mass
|
g[8*(length(flybys)-1)+7] = final[7] - guess.sc.dry_mass
|
||||||
end
|
end
|
||||||
|
g[8*(length(flybys)-1)+8] = max_C3 - norm(x[2:4])^2
|
||||||
|
g[8*(length(flybys)-1)+9] = max_v∞ - norm(v∞_in)
|
||||||
i += 1
|
i += 1
|
||||||
end
|
end
|
||||||
|
|
||||||
return 1.0
|
return 1.0
|
||||||
|
|
||||||
catch e
|
catch e
|
||||||
|
|
||||||
if isa(e,LaGuerreConway_Error)
|
if isa(e,LaGuerreConway_Error) || isa(e, Mass_Error)
|
||||||
g[1:8*(length(flybys)-1)+7] .= 1e10
|
g[1:8*(length(flybys)-1)+7] .= 1e10
|
||||||
return 1e10
|
return 1e10
|
||||||
else
|
else
|
||||||
@@ -104,16 +114,16 @@ function solve_mission( guess::Mission_Guess,
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
max_time = Dates.datetime2unix(latest_arrival) - Dates.datetime2unix(launch_window[1])
|
max_time = datetime2unix(latest_arrival) - datetime2unix(launch_window[1])
|
||||||
lower_x = lowest_mission_vector(launch_window, length(guess.phases), n)
|
lower_x = lowest_mission_vector(launch_window, length(guess.phases), n)
|
||||||
upper_x = highest_mission_vector(launch_window, max_time, length(guess.phases), n)
|
upper_x = highest_mission_vector(launch_window, max_time, length(guess.phases), n)
|
||||||
num_constraints = 8*(length(guess.phases)-1) + 7
|
num_constraints = 8*(length(guess.phases)-1) + 9
|
||||||
g_low, g_high = constraint_bounds(guess)
|
g_low, g_high = constraint_bounds(guess)
|
||||||
ipopt_options = Dict("constr_viol_tol" => tol,
|
ipopt_options = Dict("constr_viol_tol" => tol,
|
||||||
"acceptable_constr_viol_tol" => 100tol,
|
"acceptable_constr_viol_tol" => 100tol,
|
||||||
"bound_relax_factor" => 0.,
|
"bound_relax_factor" => 0.,
|
||||||
"max_iter" => 100_000,
|
"max_iter" => 100_000,
|
||||||
"max_cpu_time" => 5. * length(guess.phases),
|
"max_cpu_time" => 3. * length(guess.phases),
|
||||||
"print_level" => print_level)
|
"print_level" => print_level)
|
||||||
options = Options(solver=IPOPT(ipopt_options), derivatives=ForwardFD())
|
options = Options(solver=IPOPT(ipopt_options), derivatives=ForwardFD())
|
||||||
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
using Random, Dates
|
|
||||||
|
|
||||||
export gen_decision_vector
|
|
||||||
|
|
||||||
"""
|
|
||||||
Returns a random date between two dates
|
|
||||||
"""
|
|
||||||
function gen_date(date_range::Vector{DateTime})
|
|
||||||
l0, lf = date_range
|
|
||||||
l0 + Dates.Millisecond(floor(rand()*(lf-l0).value))
|
|
||||||
end
|
|
||||||
|
|
||||||
"""
|
|
||||||
Returns a random amount of time in a range
|
|
||||||
"""
|
|
||||||
function gen_period(date_range::Vector{DateTime})
|
|
||||||
l0, lf = date_range
|
|
||||||
Dates.Millisecond(floor(rand()*(lf-l0).value))
|
|
||||||
end
|
|
||||||
|
|
||||||
"""
|
|
||||||
So ideally, this should generate a nice random decision vector, given the constraints.
|
|
||||||
Everything that you need to produce a vector of phases
|
|
||||||
|
|
||||||
Start with an empty vector of the right size
|
|
||||||
You need:
|
|
||||||
- launch_date
|
|
||||||
- 3 components v∞_out for Earth
|
|
||||||
- and then up to four flybys which contain:
|
|
||||||
- a planet
|
|
||||||
- three components v∞_in
|
|
||||||
- turning angle (in ecliptic)
|
|
||||||
- tof to planet
|
|
||||||
and finally, the ending planet is held fixed
|
|
||||||
"""
|
|
||||||
function gen_decision_vector(launch_range::Vector{DateTime},
|
|
||||||
target::String,
|
|
||||||
arrival_deadline::DateTime)
|
|
||||||
phases = Vector{Phase}()
|
|
||||||
launch_date = gen_date(launch_range)
|
|
||||||
v∞_out = 20rand(Float64,3) .- 10.
|
|
||||||
|
|
||||||
# Generate the planets (or null flybys)
|
|
||||||
planets = [ ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"];
|
|
||||||
repeat(["None"],8) ] # Just as likely to get a planet as no flyby
|
|
||||||
long_flybys = [ "Earth"; filter(x -> x != "None", rand(planets, 4)); target ]
|
|
||||||
# This will cut the flybys off if the target shows up early
|
|
||||||
flybys = long_flybys[1:findfirst(x->x==target, long_flybys)]
|
|
||||||
|
|
||||||
time = launch_date
|
|
||||||
for i in 1:length(flybys)-1
|
|
||||||
v∞_in = 20rand(Float64,3) .- 10. # Generate the v∞_in components
|
|
||||||
tof = gen_period([time,arrival_deadline])
|
|
||||||
time += tof
|
|
||||||
push!(phases,Phase(flybys[i],flybys[i+1], tof.value/1000, v∞_out, v∞_in))
|
|
||||||
v∞_out_base = rand(Float64,3) .- 0.5
|
|
||||||
v∞_out = norm(v∞_in) * v∞_out_base/norm(v∞_out_base)
|
|
||||||
end
|
|
||||||
|
|
||||||
return phases
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
"""
|
|
||||||
This is the binary crossover function, implemented as detailed in Englander.
|
|
||||||
It chooses the first n and last m phases from
|
|
||||||
"""
|
|
||||||
function crossover()
|
|
||||||
end
|
|
||||||
@@ -13,7 +13,7 @@ end
|
|||||||
period(b::Body) = 2π * √(b.a^3 / Sun.μ)
|
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
|
function state(p::Body, t::DateTime, add_v∞::Vector{T}=[0., 0., 0.], add_mass::Float64=1e10) where T <: Real
|
||||||
time = utc2et(Dates.format(t,"yyyy-mm-ddTHH:MM:SS"))
|
time = utc2et(format(t,"yyyy-mm-ddTHH:MM:SS"))
|
||||||
[ spkssb(p.id, time, "ECLIPJ2000"); 0.0 ] + [ zeros(3); add_v∞; add_mass ]
|
[ spkssb(p.id, time, "ECLIPJ2000"); 0.0 ] + [ zeros(3); add_v∞; add_mass ]
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -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})
|
function Mission_Guess(x::Vector{Float64}, sc::Sc, mass::Float64, flybys::Vector{Body})
|
||||||
# Variable mission params
|
# Variable mission params
|
||||||
launch_date = Dates.unix2datetime(x[1])
|
launch_date = unix2datetime(x[1])
|
||||||
launch_v∞ = x[2:4]
|
launch_v∞ = x[2:4]
|
||||||
|
|
||||||
# Try to intelligently determine n
|
# Try to intelligently determine n
|
||||||
@@ -78,7 +78,7 @@ information from the guess though.
|
|||||||
"""
|
"""
|
||||||
function Base.Vector(g::Mission_Guess)
|
function Base.Vector(g::Mission_Guess)
|
||||||
result = Vector{Float64}()
|
result = Vector{Float64}()
|
||||||
push!(result, Dates.datetime2unix(g.launch_date))
|
push!(result, datetime2unix(g.launch_date))
|
||||||
push!(result, g.launch_v∞...)
|
push!(result, g.launch_v∞...)
|
||||||
for phase in g.phases
|
for phase in g.phases
|
||||||
push!(result,phase.v∞_in...)
|
push!(result,phase.v∞_in...)
|
||||||
@@ -91,7 +91,7 @@ end
|
|||||||
|
|
||||||
function lowest_mission_vector(launch_window::Tuple{DateTime,DateTime}, num_phases::Int, n::Int)
|
function lowest_mission_vector(launch_window::Tuple{DateTime,DateTime}, num_phases::Int, n::Int)
|
||||||
result = Vector{Float64}()
|
result = Vector{Float64}()
|
||||||
push!(result, Dates.datetime2unix(launch_window[1]))
|
push!(result, datetime2unix(launch_window[1]))
|
||||||
push!(result, -10*ones(3)...)
|
push!(result, -10*ones(3)...)
|
||||||
for i in 1:num_phases
|
for i in 1:num_phases
|
||||||
push!(result, -10*ones(3)...)
|
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)
|
function highest_mission_vector(launch_window::Tuple{DateTime,DateTime}, mission_length::Float64, num_phases::Int, n::Int)
|
||||||
result = Vector{Float64}()
|
result = Vector{Float64}()
|
||||||
push!(result, Dates.datetime2unix(launch_window[2]))
|
push!(result, datetime2unix(launch_window[2]))
|
||||||
push!(result, 10*ones(3)...)
|
push!(result, 10*ones(3)...)
|
||||||
for i in 1:num_phases
|
for i in 1:num_phases
|
||||||
push!(result, 10*ones(3)...)
|
push!(result, 10*ones(3)...)
|
||||||
@@ -133,7 +133,7 @@ function Mission(sc::Sc, mass::Float64, date::DateTime, v∞::Vector{Float64}, p
|
|||||||
force=false)
|
force=false)
|
||||||
# First do some checks to make sure that it's valid
|
# First do some checks to make sure that it's valid
|
||||||
if !force
|
if !force
|
||||||
time = utc2et(Dates.format(date,"yyyy-mm-ddTHH:MM:SS"))
|
time = utc2et(format(date,"yyyy-mm-ddTHH:MM:SS"))
|
||||||
current_planet = Earth
|
current_planet = Earth
|
||||||
start = state(current_planet, time, v∞, mass)
|
start = state(current_planet, time, v∞, mass)
|
||||||
for phase in phases
|
for phase in phases
|
||||||
@@ -178,7 +178,7 @@ end
|
|||||||
|
|
||||||
function Mission(x::Vector{Float64}, sc::Sc, mass::Float64, flybys::Vector{Body})
|
function Mission(x::Vector{Float64}, sc::Sc, mass::Float64, flybys::Vector{Body})
|
||||||
# Variable mission params
|
# Variable mission params
|
||||||
launch_date = Dates.unix2datetime(x[1])
|
launch_date = unix2datetime(x[1])
|
||||||
launch_v∞ = x[2:4]
|
launch_v∞ = x[2:4]
|
||||||
|
|
||||||
# Try to intelligently determine n
|
# Try to intelligently determine n
|
||||||
@@ -224,7 +224,7 @@ function Base.write(io::IO, m::Mission)
|
|||||||
time = m.launch_date
|
time = m.launch_date
|
||||||
i = 1
|
i = 1
|
||||||
for phase in m.phases
|
for phase in m.phases
|
||||||
time += Dates.Second(floor(phase.tof))
|
time += Second(floor(phase.tof))
|
||||||
write(io, "Phase $(i):\n")
|
write(io, "Phase $(i):\n")
|
||||||
write(io, "\tPlanet: $(phase.planet.name)\n")
|
write(io, "\tPlanet: $(phase.planet.name)\n")
|
||||||
write(io, "\tV∞_in: $(phase.v∞_in) km/s\n")
|
write(io, "\tV∞_in: $(phase.v∞_in) km/s\n")
|
||||||
@@ -6,8 +6,8 @@ Convenience function for solving lambert's problem
|
|||||||
"""
|
"""
|
||||||
function lamberts(planet1::Body,planet2::Body,leave::DateTime,arrive::DateTime)
|
function lamberts(planet1::Body,planet2::Body,leave::DateTime,arrive::DateTime)
|
||||||
|
|
||||||
time_leave = utc2et(Dates.format(leave,"yyyy-mm-ddTHH:MM:SS"))
|
time_leave = utc2et(format(leave,"yyyy-mm-ddTHH:MM:SS"))
|
||||||
time_arrive = utc2et(Dates.format(arrive,"yyyy-mm-ddTHH:MM:SS"))
|
time_arrive = utc2et(format(arrive,"yyyy-mm-ddTHH:MM:SS"))
|
||||||
tof_req = time_arrive - time_leave
|
tof_req = time_arrive - time_leave
|
||||||
|
|
||||||
state1 = [spkssb(planet1.id, time_leave, "ECLIPJ2000"); 0.0]
|
state1 = [spkssb(planet1.id, time_leave, "ECLIPJ2000"); 0.0]
|
||||||
@@ -265,7 +265,7 @@ function plot(m::Union{Mission, Mission_Guess}; title::String="Mision Plot")
|
|||||||
# First do the path
|
# First do the path
|
||||||
path, final = prop(phase.thrust_profile, start, m.sc, phase.tof, interpolate=true)
|
path, final = prop(phase.thrust_profile, start, m.sc, phase.tof, interpolate=true)
|
||||||
mass = final[7]
|
mass = final[7]
|
||||||
time += Dates.Second(floor(phase.tof))
|
time += Second(floor(phase.tof))
|
||||||
current_planet = phase.planet
|
current_planet = phase.planet
|
||||||
start = state(current_planet, time, phase.v∞_out, mass)
|
start = state(current_planet, time, phase.v∞_out, mass)
|
||||||
path_trace, new_limit = gen_plot(path, label="Phase "*string(i))
|
path_trace, new_limit = gen_plot(path, label="Phase "*string(i))
|
||||||
@@ -70,6 +70,8 @@ function prop(ΔVs::Matrix{T},
|
|||||||
for j in 1:7 push!(states[j], state[j]) end
|
for j in 1:7 push!(states[j], state[j]) end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
state[7] > craft.dry_mass || throw(Mass_Error(state[7]))
|
||||||
|
|
||||||
return states, state
|
return states, state
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -82,7 +84,7 @@ prop(x::Vector{Float64}, t::Float64, p::Body=Sun) = prop(zeros(1000,3), [x;1.],
|
|||||||
"""
|
"""
|
||||||
This is solely for the purposes of getting the final state of a mission or guess
|
This is solely for the purposes of getting the final state of a mission or guess
|
||||||
"""
|
"""
|
||||||
function prop(m::Mission)
|
function prop(m::Union{Mission, Mission_Guess})
|
||||||
time = m.launch_date
|
time = m.launch_date
|
||||||
current_planet = Earth
|
current_planet = Earth
|
||||||
start = state(current_planet, time, m.launch_v∞, m.start_mass)
|
start = state(current_planet, time, m.launch_v∞, m.start_mass)
|
||||||
@@ -92,7 +94,7 @@ function prop(m::Mission)
|
|||||||
final = prop(phase.thrust_profile, start, m.sc, phase.tof)[2]
|
final = prop(phase.thrust_profile, start, m.sc, phase.tof)[2]
|
||||||
mass = final[7]
|
mass = final[7]
|
||||||
current_planet = phase.planet
|
current_planet = phase.planet
|
||||||
time += Dates.Second(floor(phase.tof))
|
time += Second(floor(phase.tof))
|
||||||
start = state(current_planet, time, phase.v∞_out, mass)
|
start = state(current_planet, time, phase.v∞_out, mass)
|
||||||
end
|
end
|
||||||
|
|
||||||
7
julia/test/genetic_algorithm.jl
Normal file
7
julia/test/genetic_algorithm.jl
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
@testset "Genetic Algorithm" begin
|
||||||
|
|
||||||
|
println("Testing Genetic Algorithm")
|
||||||
|
|
||||||
|
@test true
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
@testset "Inner Loop" begin
|
|
||||||
|
|
||||||
println("Testing Inner Loop")
|
|
||||||
|
|
||||||
using Dates, SPICE, PlotlyJS
|
|
||||||
|
|
||||||
sc = Sc("test")
|
|
||||||
|
|
||||||
launch_date = DateTime(2016,3,28)
|
|
||||||
launch_j2000 = utc2et(Dates.format(launch_date,"yyyy-mm-ddTHH:MM:SS"))
|
|
||||||
leg1_tof = 3600*24*30*10.75
|
|
||||||
leg2_tof = 3600*24*365*5.5
|
|
||||||
v∞s = [ [0.34251772594197877, -2.7344726708862477, -1.1854707164631975],
|
|
||||||
[-1.1, -3., -2.6],
|
|
||||||
[3.5, 3.5, √(5^2 - 2*3.5^2)],
|
|
||||||
[0.3, 1., 0.] ]
|
|
||||||
p1 = "Mars"
|
|
||||||
p2 = "Saturn"
|
|
||||||
start_mass = 10_000.
|
|
||||||
|
|
||||||
phase1 = Phase("Earth", p1, leg1_tof, v∞s[1], v∞s[2])
|
|
||||||
phase2 = Phase(p1, p2, leg2_tof, v∞s[3], v∞s[4])
|
|
||||||
|
|
||||||
# For finding the best trajectories
|
|
||||||
earth_state = [spkssb(Thesis.ids["Earth"], launch_j2000, "ECLIPJ2000"); start_mass]
|
|
||||||
p1_state = [spkssb(Thesis.ids[p1], launch_j2000+leg1_tof, "ECLIPJ2000"); start_mass]
|
|
||||||
p2_state = [spkssb(Thesis.ids[p2], launch_j2000+leg1_tof+leg2_tof, "ECLIPJ2000"); start_mass]
|
|
||||||
earth = prop(zeros(100,3), earth_state, sc, μs["Sun"], 3600*24*365.)[1]
|
|
||||||
p1_path = prop(zeros(100,3), p1_state, sc, μs["Sun"], 3600*24*365*2.)[1]
|
|
||||||
p2_path = prop(zeros(100,3), p2_state, sc, μs["Sun"], 3600*24*365*8.)[1]
|
|
||||||
leg1, leg1_final = prop(zeros(400,3),
|
|
||||||
earth_state+[zeros(3);v∞s[1];start_mass],
|
|
||||||
copy(sc),
|
|
||||||
μs["Sun"],
|
|
||||||
leg1_tof)
|
|
||||||
leg2, leg2_final = prop(zeros(400,3),
|
|
||||||
p1_state+[zeros(3);v∞s[3];start_mass],
|
|
||||||
copy(sc),
|
|
||||||
μs["Sun"],
|
|
||||||
leg2_tof)
|
|
||||||
savefig(plot_orbits( [earth, p1_path, p2_path, leg1, leg2],
|
|
||||||
primary="Sun",
|
|
||||||
labels=["Earth", p1, p2, "Leg 1", "Leg 2"],
|
|
||||||
title="Inner Loop without thrusting",
|
|
||||||
colors=["#0000FF", "#FF0000", "#FFFF00", "#FF00FF", "#00FFFF"] ),
|
|
||||||
"../plots/inner_loop_before.html")
|
|
||||||
|
|
||||||
# The first leg should be valid
|
|
||||||
fresh_sc = copy(sc)
|
|
||||||
thrusts = inner_loop( launch_date,
|
|
||||||
sc,
|
|
||||||
start_mass,
|
|
||||||
[phase1],
|
|
||||||
verbose=true,
|
|
||||||
mbh_specs=(25,50) )
|
|
||||||
path, final = prop(thrusts[1], earth_state+[zeros(3);v∞s[1];0.0], Sc("test"), μs["Sun"], leg1_tof)
|
|
||||||
@test final[1:6] ≈ p1_state[1:6] + [zeros(3); v∞s[2]]
|
|
||||||
savefig(plot_orbits( [earth, p1_path, path],
|
|
||||||
primary="Sun",
|
|
||||||
labels=["Earth", p1, "Leg 1"],
|
|
||||||
title="Inner Loop with thrusting",
|
|
||||||
colors=["#0000FF", "#FF0000", "#FF00FF"] ),
|
|
||||||
"../plots/inner_loop_after.html")
|
|
||||||
|
|
||||||
# The second one was too hard to figure out on my own, so I'm letting it fail
|
|
||||||
@test_throws ErrorException inner_loop( launch_date,
|
|
||||||
sc,
|
|
||||||
start_mass,
|
|
||||||
[phase1, phase2],
|
|
||||||
verbose=true,
|
|
||||||
mbh_specs=(10,10) )
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -7,19 +7,19 @@ Spacecraft: bepi
|
|||||||
num_thrusters: 2
|
num_thrusters: 2
|
||||||
duty_cycle: 0.9
|
duty_cycle: 0.9
|
||||||
Launch Mass: 4000.0 kg
|
Launch Mass: 4000.0 kg
|
||||||
Launch Date: 2022-03-06T01:59:18.919
|
Launch Date: 2024-08-10T04:39:14.851
|
||||||
Launch V∞: [-1.1356413222408823, -4.788069365262547, 2.7000635369246] km/s
|
Launch V∞: [5.086503138635964, 5.7458326772994415, -0.07148502064229807] km/s
|
||||||
Phase 1:
|
Phase 1:
|
||||||
Planet: Jupiter
|
Planet: Jupiter
|
||||||
V∞_in: [0.606990343209641, 4.407893426470118, 0.9244860672598548] km/s
|
V∞_in: [0.036227390916599315, 0.15967408190094506, 0.14767480118449552] km/s
|
||||||
V∞_out: [1.2183577357736917, -3.9826645468861925, 2.3687041043301797] km/s
|
V∞_out: [0.02010676850789124, 0.050598467400280935, -0.04060341677187609] km/s
|
||||||
time of flight: 1.194581479969281e8 seconds
|
time of flight: 2.2119244577042913e8 seconds
|
||||||
arrival date: 2025-12-17T16:48:25.919
|
arrival date: 2031-08-14T06:59:59.851
|
||||||
thrust profile: [0.2047491180715187 -0.37019469041025893 -0.10453549807669095; 0.4301220091095493 -0.12441963747750297 -0.006770873233015344; 0.43924678986775806 0.1285374874465679 -0.07977271709638968; 0.42297198253230855 0.31380495510861767 -0.07919431310255642; 0.3614168205981836 0.39602843825488454 -0.05704653521018108; 0.2902414389460733 0.4053822027059241 -0.02821739799974643; 0.22430933743909634 0.43938508487263367 -0.00930631106824115; 0.13232647607691467 0.4188738913138919 0.007567873851875307; 0.054141732819826004 0.39551671259361465 0.010428460581952593; -0.012077434841877642 0.3792721276901153 0.0231446451624962; -0.042939891420425445 0.367704668401295 0.04590678245879779; -0.06832185713480624 0.39461571349444186 0.06647905984921844; -0.06871098668169624 0.3943544952193675 0.07996958584990013; -0.043122107121887 0.3236627227698529 0.06434542295394348; 0.0002258095938542581 0.3100245138960139 0.08315646808686966; 0.024384212213495196 0.1820219401839858 0.049878939508001104; 0.014803074731020839 0.09226807883171781 0.03031339291970727; 0.04882521682144194 0.07182823075104046 0.030435679401299; 0.07679479397181303 0.04220157719360384 0.024296177838332548; 0.07770574743624227 0.006328096858830944 0.01324607153162614] %
|
thrust profile: [-0.03786142679064034 0.27339859122748333 0.0005726056795561895; -0.1960519532066938 0.1387630677841132 0.004600353091805394; -0.2161656001051881 0.03829454149587224 0.005463035319820266; -0.20722821473665434 -0.02785165286999182 0.00642011251062416; -0.19350969113180666 -0.07336980382318779 0.005798735353253219; -0.17166276097528518 -0.10180245936266212 0.0060229587041231505; -0.14580486341259447 -0.12481013938147219 0.0051907101257523776; -0.10323445301057829 -0.1259218870425957 0.003716732277081773; -0.09355176597918236 -0.130871233294346 0.003306535594834942; -0.07124572651241741 -0.12553468471214665 0.0020108136415145092; -0.0557767268511364 -0.1685959768674539 0.0019437293843202214; -0.021549123169529897 -0.10803755957761324 0.002034600881493311; -0.016013238333261934 -0.09622842770217328 -0.0002741920932820072; -0.004335206653515529 -0.0793719785110731 -0.0008939603722934327; 0.004740346893240406 -0.0607329376874639 -0.001716631473891448; 0.009818095755854734 -0.04491273068933977 -0.0022094281086108515; 0.01312805451032741 -0.027616502567377823 -0.0019177513080552329; 0.011878743159361204 -0.022925058186254264 -0.0022168412947191586; 0.0023818939899512676 -0.018414092946291174 -1.3347743447259673e-5; -0.0031036018027195927 -0.01627946171253065 -0.007426356212648579] %
|
||||||
|
|
||||||
Mass Used: 1527.1786215537763 kg
|
Mass Used: 1077.835193306381 kg
|
||||||
Launch C3: 31.505632562776483 km²/s²
|
Launch C3: 58.892217443051806 km²/s²
|
||||||
||V∞_in||: 4.544517160758207 km/s
|
||V∞_in||: 0.22049055124520436 km/s
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,16 +7,16 @@ Spacecraft: bepi
|
|||||||
num_thrusters: 2
|
num_thrusters: 2
|
||||||
duty_cycle: 0.9
|
duty_cycle: 0.9
|
||||||
Launch Mass: 4000.0 kg
|
Launch Mass: 4000.0 kg
|
||||||
Launch Date: 2022-03-06T01:59:18.919
|
Launch Date: 2024-08-10T04:39:14.851
|
||||||
Launch V∞: [-1.1356413222408823, -4.788069365262547, 2.7000635369246] km/s
|
Launch V∞: [5.086503138635964, 5.7458326772994415, -0.07148502064229807] km/s
|
||||||
Phase 1:
|
Phase 1:
|
||||||
Planet: Jupiter
|
Planet: Jupiter
|
||||||
V∞_in: [0.606990343209641, 4.407893426470118, 0.9244860672598548] km/s
|
V∞_in: [0.036227390916599315, 0.15967408190094506, 0.14767480118449552] km/s
|
||||||
V∞_out: [1.2183577357736917, -3.9826645468861925, 2.3687041043301797] km/s
|
V∞_out: [0.02010676850789124, 0.050598467400280935, -0.04060341677187609] km/s
|
||||||
time of flight: 1.194581479969281e8 seconds
|
time of flight: 2.2119244577042913e8 seconds
|
||||||
arrival date: 2025-12-17T16:48:25.919
|
arrival date: 2031-08-14T06:59:59.851
|
||||||
thrust profile: [0.2047491180715187 -0.37019469041025893 -0.10453549807669095; 0.4301220091095493 -0.12441963747750297 -0.006770873233015344; 0.43924678986775806 0.1285374874465679 -0.07977271709638968; 0.42297198253230855 0.31380495510861767 -0.07919431310255642; 0.3614168205981836 0.39602843825488454 -0.05704653521018108; 0.2902414389460733 0.4053822027059241 -0.02821739799974643; 0.22430933743909634 0.43938508487263367 -0.00930631106824115; 0.13232647607691467 0.4188738913138919 0.007567873851875307; 0.054141732819826004 0.39551671259361465 0.010428460581952593; -0.012077434841877642 0.3792721276901153 0.0231446451624962; -0.042939891420425445 0.367704668401295 0.04590678245879779; -0.06832185713480624 0.39461571349444186 0.06647905984921844; -0.06871098668169624 0.3943544952193675 0.07996958584990013; -0.043122107121887 0.3236627227698529 0.06434542295394348; 0.0002258095938542581 0.3100245138960139 0.08315646808686966; 0.024384212213495196 0.1820219401839858 0.049878939508001104; 0.014803074731020839 0.09226807883171781 0.03031339291970727; 0.04882521682144194 0.07182823075104046 0.030435679401299; 0.07679479397181303 0.04220157719360384 0.024296177838332548; 0.07770574743624227 0.006328096858830944 0.01324607153162614] %
|
thrust profile: [-0.03786142679064034 0.27339859122748333 0.0005726056795561895; -0.1960519532066938 0.1387630677841132 0.004600353091805394; -0.2161656001051881 0.03829454149587224 0.005463035319820266; -0.20722821473665434 -0.02785165286999182 0.00642011251062416; -0.19350969113180666 -0.07336980382318779 0.005798735353253219; -0.17166276097528518 -0.10180245936266212 0.0060229587041231505; -0.14580486341259447 -0.12481013938147219 0.0051907101257523776; -0.10323445301057829 -0.1259218870425957 0.003716732277081773; -0.09355176597918236 -0.130871233294346 0.003306535594834942; -0.07124572651241741 -0.12553468471214665 0.0020108136415145092; -0.0557767268511364 -0.1685959768674539 0.0019437293843202214; -0.021549123169529897 -0.10803755957761324 0.002034600881493311; -0.016013238333261934 -0.09622842770217328 -0.0002741920932820072; -0.004335206653515529 -0.0793719785110731 -0.0008939603722934327; 0.004740346893240406 -0.0607329376874639 -0.001716631473891448; 0.009818095755854734 -0.04491273068933977 -0.0022094281086108515; 0.01312805451032741 -0.027616502567377823 -0.0019177513080552329; 0.011878743159361204 -0.022925058186254264 -0.0022168412947191586; 0.0023818939899512676 -0.018414092946291174 -1.3347743447259673e-5; -0.0031036018027195927 -0.01627946171253065 -0.007426356212648579] %
|
||||||
|
|
||||||
Mass Used: 1527.1786215537763 kg
|
Mass Used: 1077.835193306381 kg
|
||||||
Launch C3: 31.505632562776483 km²/s²
|
Launch C3: 58.892217443051806 km²/s²
|
||||||
||V∞_in||: 4.544517160758207 km/s
|
||V∞_in||: 0.22049055124520436 km/s
|
||||||
|
|||||||
@@ -7,26 +7,26 @@ Spacecraft: bepi
|
|||||||
num_thrusters: 2
|
num_thrusters: 2
|
||||||
duty_cycle: 0.9
|
duty_cycle: 0.9
|
||||||
Launch Mass: 4000.0 kg
|
Launch Mass: 4000.0 kg
|
||||||
Launch Date: 2024-10-23T01:57:04.645
|
Launch Date: 2024-03-01T19:28:21.132
|
||||||
Launch V∞: [-2.756658080311089, 5.4981544960382, 1.2354164981485998] km/s
|
Launch V∞: [-1.4933474839937355, -1.896757005945588, 0.1342176084154792] km/s
|
||||||
Phase 1:
|
Phase 1:
|
||||||
Planet: Mars
|
Planet: Mars
|
||||||
V∞_in: [-6.97287754424969, 6.962353258098406, 0.0607051347526173] km/s
|
V∞_in: [-3.139849731672998, -2.3945611648587124, -1.1632748362007634] km/s
|
||||||
V∞_out: [-6.685432199487985, 6.971638091675174, 1.9494641006878624] km/s
|
V∞_out: [-4.106939244074457, 0.1211665771442673, -0.25340515321231993] km/s
|
||||||
time of flight: 1.16503060035366e7 seconds
|
time of flight: 1.3574607375499237e8 seconds
|
||||||
arrival date: 2025-03-06T22:08:50.645
|
arrival date: 2028-06-19T22:42:54.132
|
||||||
thrust profile: [0.0007372127333915423 -0.0014732374607987512 -0.0001436849126190515; 0.0015863792714624523 -0.0020954380857885 -3.9222886974518435e-5; 0.0028749200111876953 -0.0029070168117665577 -6.834239668653902e-5; 0.00400664873911032 -0.0036102638724926027 -0.0011534186183358992; 0.003002315886422529 -0.004155862034974375 -0.0019852589032208707; 0.003937369046006624 -0.003292245456470277 -0.00033744520390480056; 0.004022116761090881 -0.0014747882735426667 0.0009925828352185433; 0.0028363477848649932 -0.0006118542455278574 0.0011994525100711487; 0.0010235706279971136 -0.0007807187007764947 0.0007198591227898102; 1.9987192194599394e-5 -0.0011241077612402291 0.00021045682481486607; 0.0007623347096515055 -0.001326552903003275 0.00047334230828265155; -0.0019176703329012404 -0.003664068924494901 -0.0007926699243678642; -0.0034278750339086722 -0.005605775872095162 -0.001640142456026017; -0.003879314794056328 -0.007180423427345347 -0.0021627562917433257; -0.00457576381748711 -0.009085671380846889 -0.0027950147837868416; -0.00496447070432947 -0.011003150581070032 -0.0033564467543545713; -0.005782291476516903 -0.013187396198780097 -0.0040189185350814815; -0.005773642750057005 -0.015126117254672524 -0.00448918463406626; -0.006039589107819558 -0.017206354330223952 -0.00500209304716878; -0.0059712529665976325 -0.019287648124267687 -0.005416379053301935] %
|
thrust profile: [-0.0019400973522372704 -0.0007861976680016341 0.0047112570560932255; 0.011634267167378483 0.025735587840716192 0.015153714739090269; 0.04023878204178935 0.0875934946637386 0.007499740159682127; -0.009467277325537368 0.13876616197672662 -0.012524106010789855; -0.10004425231685016 0.12061531322012457 -0.028391166185409118; -0.13327392532361876 0.014962677832168262 -0.03063014336273122; -0.049361915376229575 -0.06085040873226821 -0.01270432841636952; 0.03642870741492757 -0.027538682887140276 0.010604705365215029; 0.07311582311878274 0.038779781029538184 0.025999504078259884; 0.06015230279261901 0.1158643457634677 0.020078516937108694; -0.013284907011255715 0.16994053570631942 0.00015397612701227304; -0.11629264735479383 0.1487421375314807 -0.021401583793150897; -0.1698188059938155 0.045135754639904074 -0.03845221948411285; -0.10895165489995216 -0.06905174529770598 -0.03101882979146279; 0.011677929356157265 -0.0782197824462757 8.240504302237164e-6; 0.08774076836901655 -0.026355447222636122 0.017807315158523546; 0.12797619031639904 0.06837594720414757 0.02080641615928975; 0.09935124388498132 0.1833040558826352 0.0018019410798225937; -0.014862072610943274 0.2643385793887136 -0.021909120364733334; -0.1795798671224834 0.22847319945157946 -0.034527888025767346] %
|
||||||
Phase 2:
|
Phase 2:
|
||||||
Planet: Jupiter
|
Planet: Jupiter
|
||||||
V∞_in: [-2.501340292332268, 1.6226626635888894, -0.637397317769162] km/s
|
V∞_in: [-1.9097984490864515, -1.884467804288567, 0.1478655003952606] km/s
|
||||||
V∞_out: [-0.39137693018363046, -0.6158439855618857, -0.6179155724361174] km/s
|
V∞_out: [0.5920296309381583, 0.5185305548716211, -0.34102424514328644] km/s
|
||||||
time of flight: 1.634809557285843e8 seconds
|
time of flight: 1.1362938739949062e8 seconds
|
||||||
arrival date: 2030-05-12T01:31:25.645
|
arrival date: 2032-01-26T02:26:01.132
|
||||||
thrust profile: [-0.26518247245545706 -0.09071259046697609 -0.06169797323040991; -0.08236380894068383 -0.03242059745452859 -0.0437757891207446; -0.0040559771435419905 -0.006989709543848695 -0.015529763525228361; 0.007774341207249076 -0.008985090840076109 -0.01850530400329914; 0.0012813370577481318 0.0011348539591867289 -0.0155496567606658; -0.007785092497807246 0.05338536306193304 0.019317990985589086; -0.0009728321119441025 0.08815185628620617 0.03949499622566367; 0.04305174658529387 0.2568399121830553 0.055654966170718544; -0.2720351356694226 0.46384420969664153 0.03864258122986833; -0.4887396982520584 0.11774562801231306 0.0008189965640148597; -0.3013298404095551 -0.13014726189273046 -0.05096356023658363; -0.13491430696546597 -0.11875243254479609 -0.04906685950011366; -0.07101074561201698 -0.09571411749724586 -0.04115396467769674; -0.03429442666375736 -0.08608492077264626 -0.032404742164699976; -0.005411454576501817 -0.08226389770332371 -0.021813716609185803; 0.01648826033313751 -0.08220086232228146 0.011531267107186598; -0.0514818142417244 -0.08481514714903496 -0.00037084018174361565; 0.04041503097410506 -0.045097405358868914 -0.044059162529628035; 0.22484925497674185 -0.023660465666373143 -0.05114459775451727; 0.4409715896106006 -0.006503526378072674 -0.04283633117576671] %
|
thrust profile: [-0.31559923909748794 0.09689755853754745 -0.006919717656144527; -0.30761255565472767 -0.06071900887661422 0.008886404181900506; -0.23940374340653783 -0.15237412731650837 0.01667661369899387; -0.16751972908560994 -0.18821805967249375 0.01986348857730926; -0.10623664248862286 -0.19402685372102804 0.0208771393007191; -0.060042826303610866 -0.18882809282483437 0.021283405055828517; -0.027539940112158413 -0.17483716811234296 0.02049137689324002; -0.0021956619139218967 -0.1584555561559198 0.018984903410624785; 0.016974641677018447 -0.14078038683935779 0.0167485607342253; 0.03155709680599301 -0.122954819538575 0.013916179224635464; 0.042971402866106234 -0.10500259722323473 0.010513311074341624; 0.051634652307553965 -0.08728578079858391 0.006688169997632232; 0.0574625357891749 -0.0697078228574546 0.0023646019984288227; 0.06072929134486919 -0.053286809801298365 -0.0018027124516590476; 0.06007688200669981 -0.037667520940349315 -0.005792135480144473; 0.057800904682763964 -0.027552712555901016 -0.006802209283455497; 0.06140519856479137 -0.020185703984587373 -0.0058901658649188025; 0.06143756674033954 -0.01604342102490885 -0.0053401725681727595; 0.07062559388589974 -8.785146671736722e-5 -0.00863782359632625; 0.07614643902899883 0.016291745427162347 -0.010062236831540575] %
|
||||||
|
|
||||||
Mass Used: 1093.7042742756403 kg
|
Mass Used: 1283.6554577493703 kg
|
||||||
Launch C3: 39.355120557947245 km²/s²
|
Launch C3: 5.845788213962862 km²/s²
|
||||||
||V∞_in||: 3.0489363257617543 km/s
|
||V∞_in||: 2.687082661129041 km/s
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,23 +7,23 @@ Spacecraft: bepi
|
|||||||
num_thrusters: 2
|
num_thrusters: 2
|
||||||
duty_cycle: 0.9
|
duty_cycle: 0.9
|
||||||
Launch Mass: 4000.0 kg
|
Launch Mass: 4000.0 kg
|
||||||
Launch Date: 2024-10-23T01:57:04.645
|
Launch Date: 2024-03-01T19:28:21.132
|
||||||
Launch V∞: [-2.756658080311089, 5.4981544960382, 1.2354164981485998] km/s
|
Launch V∞: [-1.4933474839937355, -1.896757005945588, 0.1342176084154792] km/s
|
||||||
Phase 1:
|
Phase 1:
|
||||||
Planet: Mars
|
Planet: Mars
|
||||||
V∞_in: [-6.97287754424969, 6.962353258098406, 0.0607051347526173] km/s
|
V∞_in: [-3.139849731672998, -2.3945611648587124, -1.1632748362007634] km/s
|
||||||
V∞_out: [-6.685432199487985, 6.971638091675174, 1.9494641006878624] km/s
|
V∞_out: [-4.106939244074457, 0.1211665771442673, -0.25340515321231993] km/s
|
||||||
time of flight: 1.16503060035366e7 seconds
|
time of flight: 1.3574607375499237e8 seconds
|
||||||
arrival date: 2025-03-06T22:08:50.645
|
arrival date: 2028-06-19T22:42:54.132
|
||||||
thrust profile: [0.0007372127333915423 -0.0014732374607987512 -0.0001436849126190515; 0.0015863792714624523 -0.0020954380857885 -3.9222886974518435e-5; 0.0028749200111876953 -0.0029070168117665577 -6.834239668653902e-5; 0.00400664873911032 -0.0036102638724926027 -0.0011534186183358992; 0.003002315886422529 -0.004155862034974375 -0.0019852589032208707; 0.003937369046006624 -0.003292245456470277 -0.00033744520390480056; 0.004022116761090881 -0.0014747882735426667 0.0009925828352185433; 0.0028363477848649932 -0.0006118542455278574 0.0011994525100711487; 0.0010235706279971136 -0.0007807187007764947 0.0007198591227898102; 1.9987192194599394e-5 -0.0011241077612402291 0.00021045682481486607; 0.0007623347096515055 -0.001326552903003275 0.00047334230828265155; -0.0019176703329012404 -0.003664068924494901 -0.0007926699243678642; -0.0034278750339086722 -0.005605775872095162 -0.001640142456026017; -0.003879314794056328 -0.007180423427345347 -0.0021627562917433257; -0.00457576381748711 -0.009085671380846889 -0.0027950147837868416; -0.00496447070432947 -0.011003150581070032 -0.0033564467543545713; -0.005782291476516903 -0.013187396198780097 -0.0040189185350814815; -0.005773642750057005 -0.015126117254672524 -0.00448918463406626; -0.006039589107819558 -0.017206354330223952 -0.00500209304716878; -0.0059712529665976325 -0.019287648124267687 -0.005416379053301935] %
|
thrust profile: [-0.0019400973522372704 -0.0007861976680016341 0.0047112570560932255; 0.011634267167378483 0.025735587840716192 0.015153714739090269; 0.04023878204178935 0.0875934946637386 0.007499740159682127; -0.009467277325537368 0.13876616197672662 -0.012524106010789855; -0.10004425231685016 0.12061531322012457 -0.028391166185409118; -0.13327392532361876 0.014962677832168262 -0.03063014336273122; -0.049361915376229575 -0.06085040873226821 -0.01270432841636952; 0.03642870741492757 -0.027538682887140276 0.010604705365215029; 0.07311582311878274 0.038779781029538184 0.025999504078259884; 0.06015230279261901 0.1158643457634677 0.020078516937108694; -0.013284907011255715 0.16994053570631942 0.00015397612701227304; -0.11629264735479383 0.1487421375314807 -0.021401583793150897; -0.1698188059938155 0.045135754639904074 -0.03845221948411285; -0.10895165489995216 -0.06905174529770598 -0.03101882979146279; 0.011677929356157265 -0.0782197824462757 8.240504302237164e-6; 0.08774076836901655 -0.026355447222636122 0.017807315158523546; 0.12797619031639904 0.06837594720414757 0.02080641615928975; 0.09935124388498132 0.1833040558826352 0.0018019410798225937; -0.014862072610943274 0.2643385793887136 -0.021909120364733334; -0.1795798671224834 0.22847319945157946 -0.034527888025767346] %
|
||||||
Phase 2:
|
Phase 2:
|
||||||
Planet: Jupiter
|
Planet: Jupiter
|
||||||
V∞_in: [-2.501340292332268, 1.6226626635888894, -0.637397317769162] km/s
|
V∞_in: [-1.9097984490864515, -1.884467804288567, 0.1478655003952606] km/s
|
||||||
V∞_out: [-0.39137693018363046, -0.6158439855618857, -0.6179155724361174] km/s
|
V∞_out: [0.5920296309381583, 0.5185305548716211, -0.34102424514328644] km/s
|
||||||
time of flight: 1.634809557285843e8 seconds
|
time of flight: 1.1362938739949062e8 seconds
|
||||||
arrival date: 2030-05-12T01:31:25.645
|
arrival date: 2032-01-26T02:26:01.132
|
||||||
thrust profile: [-0.26518247245545706 -0.09071259046697609 -0.06169797323040991; -0.08236380894068383 -0.03242059745452859 -0.0437757891207446; -0.0040559771435419905 -0.006989709543848695 -0.015529763525228361; 0.007774341207249076 -0.008985090840076109 -0.01850530400329914; 0.0012813370577481318 0.0011348539591867289 -0.0155496567606658; -0.007785092497807246 0.05338536306193304 0.019317990985589086; -0.0009728321119441025 0.08815185628620617 0.03949499622566367; 0.04305174658529387 0.2568399121830553 0.055654966170718544; -0.2720351356694226 0.46384420969664153 0.03864258122986833; -0.4887396982520584 0.11774562801231306 0.0008189965640148597; -0.3013298404095551 -0.13014726189273046 -0.05096356023658363; -0.13491430696546597 -0.11875243254479609 -0.04906685950011366; -0.07101074561201698 -0.09571411749724586 -0.04115396467769674; -0.03429442666375736 -0.08608492077264626 -0.032404742164699976; -0.005411454576501817 -0.08226389770332371 -0.021813716609185803; 0.01648826033313751 -0.08220086232228146 0.011531267107186598; -0.0514818142417244 -0.08481514714903496 -0.00037084018174361565; 0.04041503097410506 -0.045097405358868914 -0.044059162529628035; 0.22484925497674185 -0.023660465666373143 -0.05114459775451727; 0.4409715896106006 -0.006503526378072674 -0.04283633117576671] %
|
thrust profile: [-0.31559923909748794 0.09689755853754745 -0.006919717656144527; -0.30761255565472767 -0.06071900887661422 0.008886404181900506; -0.23940374340653783 -0.15237412731650837 0.01667661369899387; -0.16751972908560994 -0.18821805967249375 0.01986348857730926; -0.10623664248862286 -0.19402685372102804 0.0208771393007191; -0.060042826303610866 -0.18882809282483437 0.021283405055828517; -0.027539940112158413 -0.17483716811234296 0.02049137689324002; -0.0021956619139218967 -0.1584555561559198 0.018984903410624785; 0.016974641677018447 -0.14078038683935779 0.0167485607342253; 0.03155709680599301 -0.122954819538575 0.013916179224635464; 0.042971402866106234 -0.10500259722323473 0.010513311074341624; 0.051634652307553965 -0.08728578079858391 0.006688169997632232; 0.0574625357891749 -0.0697078228574546 0.0023646019984288227; 0.06072929134486919 -0.053286809801298365 -0.0018027124516590476; 0.06007688200669981 -0.037667520940349315 -0.005792135480144473; 0.057800904682763964 -0.027552712555901016 -0.006802209283455497; 0.06140519856479137 -0.020185703984587373 -0.0058901658649188025; 0.06143756674033954 -0.01604342102490885 -0.0053401725681727595; 0.07062559388589974 -8.785146671736722e-5 -0.00863782359632625; 0.07614643902899883 0.016291745427162347 -0.010062236831540575] %
|
||||||
|
|
||||||
Mass Used: 1093.7042742756403 kg
|
Mass Used: 1283.6554577493703 kg
|
||||||
Launch C3: 39.355120557947245 km²/s²
|
Launch C3: 5.845788213962862 km²/s²
|
||||||
||V∞_in||: 3.0489363257617543 km/s
|
||V∞_in||: 2.687082661129041 km/s
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
@testset "Outer Loop" begin
|
|
||||||
|
|
||||||
using Dates
|
|
||||||
|
|
||||||
println("Testing Genetic Algorithm")
|
|
||||||
|
|
||||||
launch_range = [ DateTime(2016,3,28), DateTime(2019,3,28) ]
|
|
||||||
target = "Saturn"
|
|
||||||
deadline = DateTime(2028,12,31)
|
|
||||||
|
|
||||||
# First let's just test that we can generate a member of the population
|
|
||||||
member = gen_decision_vector(launch_range, target, deadline)
|
|
||||||
println(member)
|
|
||||||
|
|
||||||
@test typeof(member) == Vector{Phase}
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -3,7 +3,7 @@ using Random
|
|||||||
using LinearAlgebra
|
using LinearAlgebra
|
||||||
using SPICE
|
using SPICE
|
||||||
using Thesis
|
using Thesis
|
||||||
using Dates: DateTime, Dates
|
using Dates: DateTime, Millisecond, Dates, Second, format, datetime2unix, unix2datetime
|
||||||
|
|
||||||
try
|
try
|
||||||
furnsh("../../spice_files/naif0012.tls")
|
furnsh("../../spice_files/naif0012.tls")
|
||||||
@@ -15,8 +15,9 @@ end
|
|||||||
|
|
||||||
@testset "All Tests" begin
|
@testset "All Tests" begin
|
||||||
include("plotting.jl")
|
include("plotting.jl")
|
||||||
include("inner_loop/laguerre-conway.jl")
|
include("laguerre-conway.jl")
|
||||||
include("inner_loop/propagator.jl")
|
include("propagator.jl")
|
||||||
include("inner_loop/nlp_solver.jl")
|
include("nlp_solver.jl")
|
||||||
include("inner_loop/monotonic_basin_hopping.jl")
|
include("mbh.jl")
|
||||||
|
include("genetic_algorithm.jl")
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user