Currently working on refactor, much work to do

This commit is contained in:
Connor
2021-09-25 16:10:02 -06:00
parent 7d0037f38d
commit af545ba1a7
23 changed files with 286 additions and 353 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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,

View File

@@ -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

View File

@@ -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]