Files
thesis/julia/src/inner_loop/inner_loop.jl
2021-09-16 09:41:16 -06:00

74 lines
3.0 KiB
Julia

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,
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
if flyby <= true_min
error("Flyby was too low between phase $(i-1) and $(i): $(flyby) / $(true_min)")
end
end
end
time = utc2et(Dates.format(launch_date,"yyyy-mm-ddTHH:MM:SS"))
thrust_profiles = []
try
for phase in phases
planet1_state = spkssb(ids[phase.from_planet], time, "J2000")
time += phase.time_of_flight
planet2_state = spkssb(ids[phase.to_planet], time, "J2000")
# TODO: Come up with improved method of calculating "n"
start = planet1_state + [0., 0., 0., phase.v∞_outgoing...]
final = planet2_state + [0., 0., 0., phase.v∞_incoming...]
if mbh_specs === nothing
best = mbh(start, final, craft, μs["Sun"], 0.0, phase.time_of_flight, 10,
verbose=verbose)[1]
else
num_iters, sil, dil = mbh_specs
best = mbh(start, final, craft, μs["Sun"], 0.0, phase.time_of_flight, 10,
verbose=verbose, num_iters=num_iters, search_patience_lim=sil,
drill_patience_lim=dil)
end
push!(thrust_profiles, best)
craft.mass = prop(tanh.(best.zero), planet1_state, sc, μs["Sun"], prop_time)[2][end]
end
return craft.mass, thrust_profiles
catch
return "One path did not converge"
end
end