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