114 lines
3.5 KiB
Julia
114 lines
3.5 KiB
Julia
"""
|
||
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
|