diff --git a/julia/main.jl b/julia/main.jl index 6bcec68..65b3dd4 100644 --- a/julia/main.jl +++ b/julia/main.jl @@ -1,6 +1,8 @@ -using LinearAlgebra +using LinearAlgebra, JuMP, Ipopt include("constants.jl") include("conversions.jl") +include("spacecraft.jl") include("sft.jl") include("laguerre-conway.jl") +include("propagator.jl") diff --git a/julia/propagator.jl b/julia/propagator.jl new file mode 100644 index 0000000..fbcdaca --- /dev/null +++ b/julia/propagator.jl @@ -0,0 +1,36 @@ +""" +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_unit::Vector{Float64}, + state::Vector{Float64}, + duty_cycle::Float64, + num_thrusters::Int, + max_thrust::Float64, + mass::Float64, + mass_flow_rate::Float64, + μ::Float64, + time::Float64) + + if norm(ΔV_unit) > 1. + throw(ErrorException("ΔV input is too high")) + end + halfway = laguerre_conway(state, μ, time/2) + halfway[4:6] += ΔV_unit * max_ΔV(duty_cycle, num_thrusters, max_thrust, time, 0., mass) + return laguerre_conway(halfway, μ, time/2), mass - mass_flow_rate*norm(ΔV_unit)*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{Float64}, + state::Vector{Float64}, + craft::sc, + μ::Float64, + time::Float64) + 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 + diff --git a/julia/spacecraft.jl b/julia/spacecraft.jl new file mode 100644 index 0000000..5a8e79e --- /dev/null +++ b/julia/spacecraft.jl @@ -0,0 +1,17 @@ +struct sc + mass::Float64 + mass_flow_rate::Float64 + max_thrust::Float64 + num_thrusters::Int + duty_cycle::Float64 +end + +function sc(name::String) + if name == "test" + return sc(1000., 0.01, 0.1, 2, 1.) + elseif name == "no_thrust" + return sc(1000., 0.01, 0., 0, 0.) + else + throw(ErrorException("Bad sc name")) + end +end diff --git a/julia/test/laguerre-conway.jl b/julia/test/laguerre-conway.jl index ab641bc..6edb1a6 100644 --- a/julia/test/laguerre-conway.jl +++ b/julia/test/laguerre-conway.jl @@ -1,6 +1,8 @@ @testset "Laguerre-Conway" begin + + # Test that the propagator produces good periodic orbits (forwards and backwards) for T in rand(3600*1.5:3600*4, (5)) - start = oe_to_xyz([ (μs["Earth"]*(T/(2π))^2)^(1/3), 0.1, 0.1, 0., 0., 1. ], μs["Earth"]) + start = oe_to_xyz([ (μs["Earth"]*(T/(2π))^2)^(1/3), rand(0.01:0.01:0.5), rand(0.01:0.01:0.45π), 0., 0., 1. ], μs["Earth"]) orbit = start for _ in 1:5 i = 0. @@ -11,5 +13,15 @@ @test i ≈ T @test orbit ≈ start end + for _ in 1:5 + i = 0. + while i > -T + orbit = laguerre_conway(orbit, μs["Earth"], -1.) + i -= 1 + end + @test i ≈ -T + @test orbit ≈ start + end end + end diff --git a/julia/test/propagator.jl b/julia/test/propagator.jl new file mode 100644 index 0000000..c38d9ed --- /dev/null +++ b/julia/test/propagator.jl @@ -0,0 +1,33 @@ +@testset "Propagator" begin + + # Set up + start = oe_to_xyz([ (μs["Earth"]*(rand(3600*1.5:0.01:3600*4)/(2π))^2)^(1/3), + rand(0.01:0.01:0.5), + rand(0.01:0.01:0.45π), + 0., + 0., + 1. ], μs["Earth"]) + stepsize = rand(100.0:0.01:500.0) + + # Test that Laguerre-Conway is the default propagator + propped = prop_one([0., 0., 0.], start, 0., 0, 0., 1000., 0.1, μs["Earth"], stepsize) + @test laguerre_conway(start, μs["Earth"], stepsize) ≈ propped[1] + + # Test that Laguerre-Conway is the default propagator for spacecrafts + craft = sc("no_thrust") + state, craft = prop_one([0., 0., 0.], start, craft, μs["Earth"], stepsize) + @test laguerre_conway(start, μs["Earth"], stepsize) ≈ state + @test craft.mass == 1000. + + # Test that mass is reduced properly + craft = sc("test") + start_mass = craft.mass + state, craft = prop_one([1., 1., 1.]/√(3), start, craft, μs["Earth"], stepsize) + @test craft.mass == start_mass - craft.mass_flow_rate*stepsize + + # Test that a bad ΔV throws an error + craft = sc("test") + start_mass = craft.mass + @test_throws ErrorException prop_one([1., 1., -1.], start, craft, μs["Earth"], stepsize) + +end diff --git a/julia/test/spacecraft.jl b/julia/test/spacecraft.jl new file mode 100644 index 0000000..b8387df --- /dev/null +++ b/julia/test/spacecraft.jl @@ -0,0 +1,19 @@ +@testset "Spacecraft Construction" begin + + # Test that the standard spacecrafts can be created + craft = sc("test") + @test craft.mass == 1000. + @test craft.mass_flow_rate == 0.01 + @test craft.max_thrust == 0.1 + @test craft.num_thrusters == 2 + @test craft.duty_cycle == 1. + + craft = sc("no_thrust") + @test craft.mass == 1000. + @test craft.mass_flow_rate == 0.01 + @test craft.max_thrust == 0. + @test craft.num_thrusters == 0 + @test craft.duty_cycle == 0. + + +end diff --git a/julia/test/test.jl b/julia/test/test.jl index 99a9856..622eda9 100644 --- a/julia/test/test.jl +++ b/julia/test/test.jl @@ -5,12 +5,16 @@ using LinearAlgebra # Includes include("../constants.jl") include("../conversions.jl") +include("../spacecraft.jl") include("../sft.jl") include("../laguerre-conway.jl") +include("../propagator.jl") # Tests -@testset verbose=true "All Tests" begin +@testset "All Tests" begin + include("spacecraft.jl") include("laguerre-conway.jl") + include("propagator.jl") end print()