export prop """ Maximum ΔV that a spacecraft can impulse for a given single time step """ function max_ΔV(duty_cycle::Float64, 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] - craft.mass_flow_rate*norm(ΔV_unit)*time] end """ The propagator function """ function prop(ΔVs::Matrix{T}, state::Vector{Float64}, craft::Sc, time::Float64, primary::Body=Sun; interpolate::Bool=false) where T <: Real size(ΔVs)[2] == 3 || throw(ΔVsize_Error()) 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 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 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 end return states, state 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] """ This is solely for the purposes of getting the final state of a mission or guess """ function prop(m::Mission) time = m.launch_date current_planet = Earth start = state(current_planet, time, m.launch_v∞, m.start_mass) final = zeros(7) for phase in m.phases final = prop(phase.thrust_profile, start, m.sc, phase.tof)[2] mass = final[7] current_planet = phase.planet time += Dates.Second(floor(phase.tof)) start = state(current_planet, time, phase.v∞_out, mass) end return final end