""" Maximum ΔV that a spacecraft can impulse for a given single time step """ function max_ΔV(duty_cycle::T, num_thrusters::Int, max_thrust::T, tf::T, t0::T, mass::S) where {T <: Real, S <: Real} return duty_cycle*num_thrusters*max_thrust*(tf-t0)/mass end """ This function propagates the spacecraft forward in time 1 Sim-Flanagan step (of variable length of time), applying a thrust in the center. """ function prop_one(ΔV::Vector{T}, state::Vector{S}, duty_cycle::Float64, num_thrusters::Int, max_thrust::Float64, mass::S, mass_flow_rate::Float64, μ::Float64, time::Float64) where {T <: Real, S <: Real} mag, α, β = ΔV # if mag > 1 || mag < 0 # throw(ErrorException("ΔV input is too high: $mag")) # elseif α > π || α < -π # throw(ErrorException("α angle is incorrect: $α")) # elseif β > π/2 || β < -π/2 # throw(ErrorException("β angle is incorrect: $β")) # end thrust_rθh = mag * [cos(β)*sin(α), cos(β)*cos(α), sin(β)] a,e,i,Ω,ω,ν = xyz_to_oe(state, μ) θ = ω+ν cΩ,sΩ,ci,si,cθ,sθ = cos(Ω),sin(Ω),cos(i),sin(i),cos(θ),sin(θ) DCM = [cΩ*cθ-sΩ*ci*sθ -cΩ*sθ-sΩ*ci*cθ sΩ*si; sΩ*cθ+cΩ*ci*sθ -sΩ*sθ+cΩ*ci*cθ -cΩ*si; si*sθ si*cθ ci] ΔV = DCM*thrust_rθh thrust = max_ΔV(duty_cycle, num_thrusters, max_thrust, time, 0., mass) * ΔV halfway = laguerre_conway(state, μ, time/2) + [0., 0., 0., thrust[1], thrust[2], thrust[3]] return laguerre_conway(halfway, μ, time/2), mass - mass_flow_rate*norm(ΔV)*time end """ A convenience function for using spacecraft. Note that this function outputs a sc instead of a mass """ function prop_one(ΔV_unit::Vector{T}, state::Vector{S}, craft::Sc, μ::Float64, time::Float64) where {T <: Real,S <: Real} state, mass = prop_one(ΔV_unit, state, craft.duty_cycle, craft.num_thrusters, craft.max_thrust, craft.mass, craft.mass_flow_rate, μ, time) return state, Sc(mass, craft.mass_flow_rate, craft.max_thrust, craft.num_thrusters, craft.duty_cycle) end """ This propagates over a given time period, with a certain number of intermediate steps """ function prop(ΔVs::Matrix{T}, state::Vector{Float64}, duty_cycle::Float64, num_thrusters::Int, max_thrust::Float64, mass::Float64, mass_flow_rate::Float64, μ::Float64, time::Float64) where T <: Real if size(ΔVs)[2] != 3 throw(ErrorException("ΔV input is wrong size")) end n = size(ΔVs)[i] for i in 1:n state, mass = prop_one(ΔVs[i,:], state, duty_cycle, num_thrusters, max_thrust, mass, mass_flow_rate, μ, time/n) end return state, mass end """ The same function, using Scs """ function prop(ΔVs::AbstractArray{T}, state::Vector{Float64}, craft::Sc, μ::Float64, time::Float64) where T <: Real if size(ΔVs)[2] != 3 throw(ErrorException("ΔV input is wrong size")) end n = size(ΔVs)[1] states = state' masses = craft.mass for i in 1:n state, craft = prop_one(ΔVs[i,:], state, craft, μ, time/n) states = [states; state'] masses = [masses, craft.mass] end return states, masses end