Currently working on refactor, much work to do
This commit is contained in:
@@ -1,45 +0,0 @@
|
||||
using NLsolve
|
||||
|
||||
export nlp_solve, mass_est
|
||||
|
||||
function mass_est(T)
|
||||
ans = 0
|
||||
n = Int(length(T)/3)
|
||||
for i in 1:n ans += norm(T[i,:]) end
|
||||
return ans/n
|
||||
end
|
||||
|
||||
struct Result
|
||||
converged::Bool
|
||||
zero::Matrix{Float64}
|
||||
end
|
||||
|
||||
function nlp_solve(start::Vector{Float64},
|
||||
final::Vector{Float64},
|
||||
craft::Sc,
|
||||
μ::Float64,
|
||||
t0::Float64,
|
||||
tf::Float64,
|
||||
x0::Matrix{Float64};
|
||||
tol=1e-6,
|
||||
num_iters=1_000)
|
||||
|
||||
function f!(F,x)
|
||||
try
|
||||
F .= 0.0
|
||||
F[1:6, 1] .= prop(tanh.(x), start, copy(craft), μ, tf-t0)[2][1:6] .- final[1:6]
|
||||
catch e
|
||||
F .= 10000000.0
|
||||
end
|
||||
end
|
||||
|
||||
result = Result(false, zeros(size(x0)))
|
||||
try
|
||||
nl_results = nlsolve(f!, atanh.(x0), ftol=tol, autodiff=:forward, iterations=num_iters)
|
||||
result = Result(converged(nl_results), tanh.(nl_results.zero))
|
||||
catch e
|
||||
end
|
||||
|
||||
return result
|
||||
|
||||
end
|
||||
@@ -1,5 +1,6 @@
|
||||
function laguerre_conway(state::Vector{<:Real}, μ::Float64, time::Float64)
|
||||
function laguerre_conway(state::Vector{<:Real}, time::Float64, primary::Body=Sun)
|
||||
|
||||
μ = primary.μ
|
||||
n = 5 # Choose LaGuerre-Conway "n"
|
||||
i = 0
|
||||
|
||||
@@ -22,7 +23,7 @@ function laguerre_conway(state::Vector{<:Real}, μ::Float64, time::Float64)
|
||||
sign = dF >= 0 ? 1 : -1
|
||||
ΔE_new = ΔE - n*F / ( dF + sign * √(abs((n-1)^2*dF^2 - n*(n-1)*F*d2F )))
|
||||
i += 1
|
||||
if i > 100 throw(ErrorException("LaGuerre-Conway did not converge!")) end
|
||||
if i > 100 throw(LaGuerreConway_Error("LaGuerre-Conway did not converge!")) end
|
||||
end
|
||||
F = 1 - a/r0_mag * (1-cos(ΔE))
|
||||
G = a * σ0/ √(μ) * (1-cos(ΔE)) + r0_mag * √(a) / √(μ) * sin(ΔE)
|
||||
@@ -41,7 +42,7 @@ function laguerre_conway(state::Vector{<:Real}, μ::Float64, time::Float64)
|
||||
sign = dF >= 0 ? 1 : -1
|
||||
ΔH_new = ΔH - n*F / ( dF + sign * √(abs((n-1)^2*dF^2 - n*(n-1)*F*d2F )))
|
||||
i += 1
|
||||
if i > 100 throw(ErrorException("LaGuerre-Conway did not converge!")) end
|
||||
if i > 100 throw(LaGuerreConway_Error("LaGuerre-Conway did not converge!")) end
|
||||
end
|
||||
F = 1 - a/r0_mag * (1-cos(ΔH))
|
||||
G = a * σ0/ √(μ) * (1-cos(ΔH)) + r0_mag * √(-a) / √(μ) * sin(ΔH)
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
export mbh
|
||||
|
||||
"""
|
||||
Generates n pareto-distributed random numbers
|
||||
"""
|
||||
function pareto(α::Float64, n::Int)
|
||||
s = rand((-1,1), (n,3))
|
||||
r = rand(Float64, (n,3))
|
||||
@@ -7,6 +10,10 @@ function pareto(α::Float64, n::Int)
|
||||
return (s./ϵ) * (α - 1.0) ./ (ϵ ./ (ϵ .+ r)).^(-α)
|
||||
end
|
||||
|
||||
"""
|
||||
Perturbs the monotonic basin hopping decision vector
|
||||
TODO: This needs to be updated
|
||||
"""
|
||||
function perturb(x::AbstractMatrix, n::Int)
|
||||
ans = x + pareto(1.01, n)
|
||||
map!(elem -> elem > 1.0 ? 1.0 : elem, ans, ans)
|
||||
@@ -14,11 +21,13 @@ function perturb(x::AbstractMatrix, n::Int)
|
||||
return ans
|
||||
end
|
||||
|
||||
|
||||
function new_x(n::Int)
|
||||
2.0 * rand(Float64, (n,3)) .- 1.
|
||||
end
|
||||
|
||||
function mbh(flybys::Vector{Planet})
|
||||
end
|
||||
|
||||
function mbh(start::AbstractVector,
|
||||
final::AbstractVector,
|
||||
craft::Sc,
|
||||
|
||||
@@ -1,9 +1,38 @@
|
||||
export Phase
|
||||
using NLsolve
|
||||
|
||||
export solve_phase
|
||||
|
||||
"""
|
||||
This function will take a single phase (so an initial state, and a final state) and an initial guess
|
||||
to the thrust profile and use an NLP solver to find the nearest thrust profile to that initial guess
|
||||
that satisfies the final state condition
|
||||
"""
|
||||
function solve_phase( start::Vector{Float64},
|
||||
final::Vector{Float64},
|
||||
craft::Sc,
|
||||
tof::Float64,
|
||||
x0::Matrix{Float64},
|
||||
primary::Body=Sun;
|
||||
tol=1e-6,
|
||||
num_iters=1_000 )
|
||||
|
||||
function f!(F,x)
|
||||
try
|
||||
F .= 0.0
|
||||
F[1:6, 1] .= prop(tanh.(x), start, craft, tof, primary)[2][1:6] .- final[1:6]
|
||||
catch e
|
||||
# If the error is due to something natural, just imply a penalty
|
||||
if isa(Mass_Error, e) || isa(PropOne_Error, e)
|
||||
F .= 10000000.0
|
||||
else
|
||||
rethrow()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
result = nlsolve(f!, atanh.(x0), ftol=tol, autodiff=:forward, iterations=num_iters)
|
||||
result.zero = tanh.(result.zero)
|
||||
|
||||
return result
|
||||
|
||||
struct Phase
|
||||
from_planet::String
|
||||
to_planet::String
|
||||
time_of_flight::Float64 # seconds
|
||||
v∞_outgoing::Vector{Float64} # Km/s
|
||||
v∞_incoming::Vector{Float64} # Km/s
|
||||
end
|
||||
|
||||
@@ -18,18 +18,15 @@ A convenience function for using spacecraft. Note that this function outputs a s
|
||||
function prop_one(ΔV_unit::Vector{<:Real},
|
||||
state::Vector{<:Real},
|
||||
craft::Sc,
|
||||
μ::Float64,
|
||||
time::Float64)
|
||||
time::Float64,
|
||||
primary::Body=Sun)
|
||||
|
||||
for direction in ΔV_unit
|
||||
if abs(direction) > 1.0
|
||||
println(direction)
|
||||
error("ΔV is impossibly high")
|
||||
end
|
||||
abs(direction) <= 1.0 || throw(PropOne_Error(ΔV_unit))
|
||||
end
|
||||
ΔV = max_ΔV(craft.duty_cycle, craft.num_thrusters, craft.max_thrust, time, 0., state[7]) * ΔV_unit
|
||||
halfway = laguerre_conway(state, μ, time/2) + [zeros(3); ΔV]
|
||||
final = laguerre_conway(halfway, μ, time/2)
|
||||
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
|
||||
@@ -40,10 +37,10 @@ The propagator function
|
||||
function prop(ΔVs::Matrix{T},
|
||||
state::Vector{Float64},
|
||||
craft::Sc,
|
||||
μ::Float64,
|
||||
time::Float64) where T <: Real
|
||||
time::Float64,
|
||||
primary::Body=Sun) where T <: Real
|
||||
|
||||
if size(ΔVs)[2] != 3 throw(ErrorException("ΔV input is wrong size")) end
|
||||
size(ΔVs)[2] == 3 || throw(ΔVsize_Error())
|
||||
n = size(ΔVs)[1]
|
||||
|
||||
x_states = Vector{T}()
|
||||
@@ -63,7 +60,7 @@ function prop(ΔVs::Matrix{T},
|
||||
push!(masses, state[7])
|
||||
|
||||
for i in 1:n
|
||||
state = prop_one(ΔVs[i,:], state, craft, μ, time/n)
|
||||
state = prop_one(ΔVs[i,:], state, craft, time/n, primary)
|
||||
push!(x_states, state[1])
|
||||
push!(y_states, state[2])
|
||||
push!(z_states, state[3])
|
||||
@@ -71,12 +68,14 @@ function prop(ΔVs::Matrix{T},
|
||||
push!(dy_states, state[5])
|
||||
push!(dz_states, state[6])
|
||||
push!(masses, state[7])
|
||||
if state[7] < craft.dry_mass
|
||||
println(state[7])
|
||||
error("Mass is too low")
|
||||
end
|
||||
state[7] >= craft.dry_mass || throw(Mass_Error(state[7]))
|
||||
end
|
||||
|
||||
return [x_states, y_states, z_states, dx_states, dy_states, dz_states, masses], 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, no_thrust, t, p)[1]
|
||||
|
||||
Reference in New Issue
Block a user