From af3c3ecdd3009aa68b993895ab62a55eaddbe815 Mon Sep 17 00:00:00 2001 From: Branan Riley Date: Wed, 29 Oct 2025 15:39:36 -0700 Subject: [PATCH] Initial import --- .idea/.gitignore | 5 + .idea/Script.iml | 10 ++ .idea/misc.xml | 6 + .idea/modules.xml | 8 ++ .idea/vcs.xml | 6 + boot/bumper.ks | 27 ++++ boot/cherenkov.ks | 14 ++ boot/gravimetric.ks | 30 ++++ boot/high-altitude-cosmic.ks | 26 ++++ boot/ir-radiometry.ks | 19 +++ boot/jupiter.ks | 37 +++++ boot/kh-1.ks | 60 ++++++++ boot/kh-4.ks | 53 +++++++ boot/magnetometry.ks | 32 +++++ boot/mercury-orbit.ks | 61 +++++++++ boot/mercury-return.ks | 39 ++++++ boot/moon-impactor.ks | 177 ++++++++++++++++++++++++ boot/moon-orbiter.ks | 170 +++++++++++++++++++++++ boot/navsat-1.ks | 28 ++++ boot/navsat-2.ks | 30 ++++ boot/orbit-return.ks | 73 ++++++++++ boot/orbiter.ks | 42 ++++++ boot/sun-synchronous.ks | 24 ++++ boot/tv.ks | 37 +++++ boot/v2_camera.ks | 15 ++ boot/wac.ks | 17 +++ lib/common.ks | 103 ++++++++++++++ lib/moonmath.ks | 110 +++++++++++++++ lib/stage/able.ks | 208 ++++++++++++++++++++++++++++ lib/stage/agena.ks | 85 ++++++++++++ lib/stage/atlas.ks | 102 ++++++++++++++ lib/stage/centaur.ks | 172 +++++++++++++++++++++++ lib/stage/probe.ks | 72 ++++++++++ lib/stage/thor.ks | 63 +++++++++ lib/stage/v2.ks | 37 +++++ lib/switch.ks | 259 +++++++++++++++++++++++++++++++++++ notes.md | 35 +++++ todo.md | 16 +++ 38 files changed, 2308 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/Script.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 boot/bumper.ks create mode 100644 boot/cherenkov.ks create mode 100644 boot/gravimetric.ks create mode 100644 boot/high-altitude-cosmic.ks create mode 100644 boot/ir-radiometry.ks create mode 100644 boot/jupiter.ks create mode 100644 boot/kh-1.ks create mode 100644 boot/kh-4.ks create mode 100644 boot/magnetometry.ks create mode 100644 boot/mercury-orbit.ks create mode 100644 boot/mercury-return.ks create mode 100644 boot/moon-impactor.ks create mode 100644 boot/moon-orbiter.ks create mode 100644 boot/navsat-1.ks create mode 100644 boot/navsat-2.ks create mode 100644 boot/orbit-return.ks create mode 100644 boot/orbiter.ks create mode 100644 boot/sun-synchronous.ks create mode 100644 boot/tv.ks create mode 100644 boot/v2_camera.ks create mode 100644 boot/wac.ks create mode 100644 lib/common.ks create mode 100644 lib/moonmath.ks create mode 100644 lib/stage/able.ks create mode 100644 lib/stage/agena.ks create mode 100644 lib/stage/atlas.ks create mode 100644 lib/stage/centaur.ks create mode 100644 lib/stage/probe.ks create mode 100644 lib/stage/thor.ks create mode 100644 lib/stage/v2.ks create mode 100644 lib/switch.ks create mode 100644 notes.md create mode 100644 todo.md diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..a0ccf77 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Environment-dependent path to Maven home directory +/mavenHomeManager.xml diff --git a/.idea/Script.iml b/.idea/Script.iml new file mode 100644 index 0000000..c696812 --- /dev/null +++ b/.idea/Script.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..89ee753 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..777ba16 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/boot/bumper.ks b/boot/bumper.ks new file mode 100644 index 0000000..3deab79 --- /dev/null +++ b/boot/bumper.ks @@ -0,0 +1,27 @@ +@lazyglobal off. +wait until ship:unpacked. + +runoncepath("0:/lib/stage/v2.ks"). +runoncepath("0:/lib/common.ks"). + + +local target_azimuth is 90. +local target_pitch is 10. +rcs off. +v2:launch(target_azimuth, target_pitch). + + +rcs on. +local hdg is lookdirup(ship:srfprograde:forevector, ship:up:forevector). +lock throttle to 1.0. +lock steering to hdg. +wait 1. +wait until steering_locked(). + +stage. +wait 3. +stage. +wait until stage:ready. +stage. + +wait until ship:thrust = 0. \ No newline at end of file diff --git a/boot/cherenkov.ks b/boot/cherenkov.ks new file mode 100644 index 0000000..2f46a46 --- /dev/null +++ b/boot/cherenkov.ks @@ -0,0 +1,14 @@ +@lazyglobal off. +wait until ship:unpacked. +rcs off. + +runoncepath("0:/lib/common.ks"). +runoncepath("0:/lib/stage/thor.ks"). +runoncepath("0:/lib/stage/able.ks"). + +local hdg is 90. + +thor:launch(hdg, 250_000, 7). +stage. +able:orbit(hdg, true). +stage. diff --git a/boot/gravimetric.ks b/boot/gravimetric.ks new file mode 100644 index 0000000..774d024 --- /dev/null +++ b/boot/gravimetric.ks @@ -0,0 +1,30 @@ +@lazyglobal off. +wait until ship:unpacked. +rcs off. + +runoncepath("0:/lib/common.ks"). +runoncepath("0:/lib/stage/thor.ks"). +runoncepath("0:/lib/stage/able.ks"). + +local target_inclination is 55. +local target_alt is 1_050_000. +local target_ecc is 0.0029. +local hdg is launch_azimuth(target_inclination, target_alt). + +thor:launch(hdg, target_alt, 5). +stage. +able:yeet(hdg, target_alt). +able:power_down(). +wait 1. +set warpmode to "rails". +set warp to 2. +wait until eta:apoapsis < 180. +set warp to 1. +wait until eta:apoapsis < 150. +set warp to 0. +wait 1. +wait until kuniverse:timewarp:issettled. +able:power_up(). +able:circularize(target_ecc). +wait 1. +stage. diff --git a/boot/high-altitude-cosmic.ks b/boot/high-altitude-cosmic.ks new file mode 100644 index 0000000..104b550 --- /dev/null +++ b/boot/high-altitude-cosmic.ks @@ -0,0 +1,26 @@ +@lazyglobal off. +wait until ship:unpacked. +rcs off. + +runoncepath("0:/lib/common.ks"). +runoncepath("0:/lib/stage/thor.ks"). +runoncepath("0:/lib/stage/able.ks"). + +local target_inclination is ship:latitude. +local target_alt is 300_000. + +local hdg is launch_azimuth(target_inclination, target_alt). + +thor:launch(hdg, target_alt). +stage. +able:burn(hdg). + +rcs on. +lock steering to heading(hdg, 0, -hdg). +wait until steering_locked(). +stage. +wait 1. +set warpmode to "physics". +set warp to 3. +wait until ship:thrust = 0. +set warp to 0. \ No newline at end of file diff --git a/boot/ir-radiometry.ks b/boot/ir-radiometry.ks new file mode 100644 index 0000000..e40fa53 --- /dev/null +++ b/boot/ir-radiometry.ks @@ -0,0 +1,19 @@ +@lazyglobal off. +wait until ship:unpacked. +rcs off. + +runoncepath("0:/lib/common.ks"). +runoncepath("0:/lib/stage/thor.ks"). +runoncepath("0:/lib/stage/able.ks"). + +local target_inclination is 80. +local target_alt is 600_000. + +local hdg is launch_azimuth(target_inclination, target_alt). + +thor:launch(hdg, target_alt, 6). +stage. +able:orbit(hdg). + +wait 1. // Ensure engine shuts down? +stage. \ No newline at end of file diff --git a/boot/jupiter.ks b/boot/jupiter.ks new file mode 100644 index 0000000..b85afdb --- /dev/null +++ b/boot/jupiter.ks @@ -0,0 +1,37 @@ +@lazyglobal off. +wait until ship:unpacked. + +runoncepath("0:/lib/stage/v2.ks"). +runoncepath("0:/lib/common.ks"). + + +local target_azimuth is 90. + +// 6Mm with A-6 +//local target_pitch is 10. +// 7.5Mm with A-6H +local target_pitch is 7. + +rcs off. +v2:launch(target_azimuth, target_pitch). + +// Release upper stage and align. +rcs on. +stage. +local hdg is lookdirup(ship:srfprograde:forevector, ship:up:forevector). +lock throttle to 1.0. +lock steering to hdg. +wait 1. + +// spin up solids +wait until steering_locked(0.001). +unlock steering. +set ship:control:roll to 1.0. +wait 20. + +// Sequence solid motors +stage. +wait 8. +stage. +wait 8. +stage. diff --git a/boot/kh-1.ks b/boot/kh-1.ks new file mode 100644 index 0000000..dc60f76 --- /dev/null +++ b/boot/kh-1.ks @@ -0,0 +1,60 @@ +@lazyglobal off. +wait until ship:unpacked. +rcs off. + +runoncepath("0:/lib/common.ks"). +runoncepath("0:/lib/stage/thor.ks"). +runoncepath("0:/lib/stage/agena.ks"). + +local target_inclination is 90. +local target_alt is 150_000. + +local hdg is launch_azimuth(target_inclination, target_alt). + +thor:launch(hdg, target_alt, 9.3). +stage. +agena:orbit(hdg). +agena:power_down(). +print "Waiting for film or batteries to run out". + +wait 1. +set warpmode to "rails". +set warp to 4. + +local cam is ship:partsdubbed("RO-BasicFilmCamera")[0]:getmodule("Experiment"). +until false { + if agena:low_power() { + break. + } + local done is false. + for evt in cam:allevents { + if evt:contains("depleted") { + set done to true. + } + } + if done { + break. + } + wait 1. +} + +set warp to 0. +wait until kuniverse:timewarp:issettled. +print "Transferring data to return capsule". +wait until ship:rootpart:getmodule("HardDrive"):hasevent("transfer data here"). +ship:rootpart:getmodule("HardDrive"):doevent("Transfer data here"). + +print "Aligning for return". +agena:power_up(). +rcs on. +lock steering to ship:retrograde. +wait 20. +wait until steering_locked(0.001). + +print "Deorbit!". +stage. + +// Stage parachute +wait until ship:altitude < 25000. +print "Parachute deploy". +stage. diff --git a/boot/kh-4.ks b/boot/kh-4.ks new file mode 100644 index 0000000..c69226a --- /dev/null +++ b/boot/kh-4.ks @@ -0,0 +1,53 @@ +@lazyglobal off. +wait until ship:unpacked. +rcs off. + +runoncepath("0:/lib/common.ks"). +runoncepath("0:/lib/stage/thor.ks"). +runoncepath("0:/lib/stage/agena.ks"). + +local target_inclination is 90. +local target_alt is 200_000. + +local hdg is launch_azimuth(target_inclination, target_alt). + +thor:launch(hdg, target_alt, 8). +stage. +agena:orbit(hdg). +agena:power_down(). +print "Waiting for film or batteries to run out". + +wait 1. +set warpmode to "rails". +set warp to 4. + +local cam is ship:partsdubbed("RO-ImprovedFilmCamera")[0]:getmodule("Experiment"). +until false { + if agena:low_power() { + break. + } + if cam:depleted { + break. + } + wait 1. +} + +set warp to 0. +wait until kuniverse:timewarp:issettled. +print "Transferring data to return capsule". +ship:rootpart:getmodule("HardDrive"):transferHere. + +print "Aligning for return". +agena:power_up(). +rcs on. +lock steering to ship:retrograde. +wait 20. +wait until steering_locked(0.1). + +print "Deorbit!". +stage. + +// Stage parachute +wait until ship:altitude < 25000. +print "Parachute deploy". +stage. diff --git a/boot/magnetometry.ks b/boot/magnetometry.ks new file mode 100644 index 0000000..86e0d8f --- /dev/null +++ b/boot/magnetometry.ks @@ -0,0 +1,32 @@ +@lazyglobal off. +wait until ship:unpacked. +rcs off. + +runoncepath("0:/lib/common.ks"). +runoncepath("0:/lib/stage/thor.ks"). +runoncepath("0:/lib/stage/able.ks"). + +local hdg is 90. + +thor:launch(hdg, 250_000, 8). +stage. +able:yeet(hdg, 3_050_000). + +rcs off. +able:power_down(). +wait 1. +set warpmode to "rails". +set warp to 2. +wait until eta:apoapsis < 120. +set warp to 1. +wait until eta:apoapsis < 45. +set warp to 0. +wait 1. +wait until kuniverse:timewarp:issettled. +able:power_up(). +lock steering to ship:prograde. +rcs on. +wait 1. +wait until steering_locked(0.05). +wait until eta:apoapsis < 20. +stage. diff --git a/boot/mercury-orbit.ks b/boot/mercury-orbit.ks new file mode 100644 index 0000000..149008a --- /dev/null +++ b/boot/mercury-orbit.ks @@ -0,0 +1,61 @@ +@lazyglobal off. +wait until ship:unpacked. +rcs off. +lock throttle to 0. + +runoncepath("0:/lib/common.ks"). +runoncepath("0:/lib/moonmath.ks"). +runoncepath("0:/lib/stage/atlas.ks"). + +on abort { + unlock steering. + sas on. + wait 5. + stage. + wait until stage:ready. + stage. + rcs on. + set sasmode to "retrograde". + ship:rootpart:getmodule("kOSProcessor"):deactivate. +} + +// Any automatic abort triggers go where +when false then { + abort on. +} + +local orbit_time is 26*60*60. +local target_alt is 225_000. +atlas:launch(90, target_alt, 7.5). + +stage. +panels on. +wait 1. +rcs on. +local dir is sun:direction. +lock steering to dir. +wait 1. +wait until steering_locked(). +set warpmode to "rails". +set warp to 1. + +// Human can time-warp faster here if they want + +wait orbit_time. +set warp to 0. +wait 1. +wait until kuniverse:timewarp:issettled. + +local retro is ship:retrograde. +lock steering to retro. +wait 1. +wait until steering_locked(). +stage. +wait 20. +stage. +set warpmode to "rails". +set warp to 2. +wait until ship:altitude < 140_000. +lock steering to ship:retrograde. +wait until ship:altitude < 35_000. +stage. \ No newline at end of file diff --git a/boot/mercury-return.ks b/boot/mercury-return.ks new file mode 100644 index 0000000..e70b400 --- /dev/null +++ b/boot/mercury-return.ks @@ -0,0 +1,39 @@ +@lazyglobal off. +wait until ship:unpacked. +rcs off. +lock throttle to 0. + +runoncepath("0:/lib/common.ks"). +runoncepath("0:/lib/moonmath.ks"). +runoncepath("0:/lib/stage/atlas.ks"). + +local orbit_time is 24*60*60. +stage. +rcs on. +local dir is ship:prograde. +lock steering to dir. +wait 1. +wait until steering_locked(). +set warpmode to "rails". +set warp to 1. + +// Human can time-warp faster here if they want + +wait orbit_time. +set warp to 0. +wait 1. +wait until kuniverse:timewarp:issettled. + +local retro is ship:retrograde. +lock steering to retro. +wait 1. +wait until steering_locked(). +stage. +wait 20. +stage. +set warpmode to "rails". +set warp to 2. +wait until ship:altitude < 140_000. +lock steering to ship:retrograde. +wait until ship:altitude < 35_000. +stage. \ No newline at end of file diff --git a/boot/moon-impactor.ks b/boot/moon-impactor.ks new file mode 100644 index 0000000..d5ad0dc --- /dev/null +++ b/boot/moon-impactor.ks @@ -0,0 +1,177 @@ +@lazyglobal off. +wait until ship:unpacked. +rcs off. +lock throttle to 0. + +runoncepath("0:/lib/common.ks"). +runoncepath("0:/lib/moonmath.ks"). +runoncepath("0:/lib/stage/atlas.ks"). +runoncepath("0:/lib/stage/agena.ks"). + +local state is lex(). + +local function ship_volume { + return ship:rootpart:getmodule("kosprocessor"):volume. +} + +local function phase { + switch to ship_volume(). + if not ship_volume():exists("state.json") { + set_phase("prelaunch"). + } + set state to readjson("state.json"). + return state["phase"]. +} + +local function set_phase { + parameter new_phase. + switch to ship_volume(). + set state["phase"] to new_phase. + writejson(state, "state.json"). + kuniverse:quicksaveto("moon-impactor-"+new_phase). +} + +if phase() = "prelaunch" { + local target_inclination is max(moon:obt:inclination,ship:latitude). + local target_alt is 500_000. + set state["azimuth"] to launch_azimuth(target_inclination, target_alt). + + local launch_params is moonmath:calculate_launch(target_inclination, state["azimuth"], target_alt). + local launch_time is launch_params:launch_time. + set state["moon_altitude"] to launch_params:moon_altitude. + set state["burn_longitude"] to launch_params:burn_longitude. + print "Burning for moon at " + state["burn_longitude"] + " right ascension". + + wait 2. + + until launch_time - time:seconds < 10 { + print "Not ready to launch yet, warping...". + warpto(launch_time-9). + wait 0. + wait until warp = 0. + wait until kuniverse:timewarp:issettled. + print "Maybe done warping?". + } + wait until time:seconds > launch_time. + + atlas:launch(state["azimuth"], target_alt, 4). + stage. + set_phase("circularize"). +} + +if phase() = "circularize" { + agena:orbit(state["azimuth"]). + agena:power_down(). + + wait 1. + set_phase("parkingorbit"). +} + +local function ship_longitude { + return mod(ship:longitude + ship:body:rotationangle + 360, 360). +} + +local function transfer_lead_angle { + parameter moon_alt. + local moon_range is moon:apoapsis - moon:periapsis. + local moon_frac is (moon_alt - moon:periapsis) / moon_range. + local lead_angle_frac is 1.0 - moon_frac. + return 1.1 + 0.65 * lead_angle_frac. +} + +if phase() = "parkingorbit" { + // Just in case our burn point is RIGHT HERE, we want to go around at least once. + set warpmode to "physics". + set warp to 3. + wait until abs(ship_longitude() - state["burn_longitude"]) > 10. + set warp to 0. + wait until kuniverse:timewarp:issettled. + wait 1. + + // Rails warp until we're nearish to the burn point + print "Warping to dLongitude < 15". + set warpmode to "rails". + set warp to 2. + wait until abs(ship_longitude() - state["burn_longitude"]) < 15. + set warp to 0. + wait until kuniverse:timewarp:issettled. + wait 1. + + // Physics warp until we're nearish-er + print "Warping to dLongitude < 7". + set warpmode to "physics". + set warp to 3. + wait until abs(ship_longitude() - state["burn_longitude"]) < 4. + set warp to 0. + wait until kuniverse:timewarp:issettled. + wait 1. + + agena:power_up(). + rcs on. + lock steering to ship:prograde. + local lead_angle is transfer_lead_angle(state["moon_altitude"]). + wait until abs(ship_longitude() - state["burn_longitude"]) < lead_angle. // Hand-picked rather than computing burn time & time to target longitude + local transfer_vel is circular_vel() + hohmann_transfer_dv(earth, ship:altitude, state["moon_altitude"]). + print "Moon altitude is: " + state["moon_altitude"]. + print "Transfer DV is: " + (transfer_vel - ship:velocity:orbit:mag). + print "Burn lead angle is: " + lead_angle. + agena:transfer_burn(transfer_vel). + wait 1. + stage. + + set_phase("adjust"). +} + +if phase() = "adjust" { + panels on. + rcs on. + + lock throttle to 0.0. + lock steering to lookdirup(ship:prograde:forevector, ship:up:forevector). + local adjustment is 8_000_000. // 1.5%..2.0%? + print "Alt Adjustment is " + adjustment. + + local target_alt is state["moon_altitude"] + adjustment. + local max_alt_delta is 1_000_000. + local threshold is 0.1. + until false { + local p is threshold / max_alt_delta. + local da is target_alt - ship:orbit:apoapsis. + local horz_factor is da * p. + if abs(horz_factor) < threshold { + set ship:control:fore to 0. + break. + } + set ship:control:fore to horz_factor. + wait 0. + } + set_phase("pretransfer"). +} + +if phase() = "pretransfer" { + rcs on. + lock steering to sun:direction. + wait 1. + wait until steering_locked(). + wait 1. + local avi_mod is ship:rootpart:getmodule("ModuleProceduralAvionics"). + avi_mod:doaction("shutdown avionics", true). + wait 1. + + set_phase("transfer"). +} + +if phase() = "transfer" { + set warpmode to "rails". + warpto(eta:transition + time:seconds). + wait until ship:obt:body = moon. + wait until kuniverse:timewarp:issettled. + + set_phase("done"). +} + +if phase() <> "done" { + print "Phase logic failed, expected to be in phase '" + phase() + "'". +} + +print "Done". \ No newline at end of file diff --git a/boot/moon-orbiter.ks b/boot/moon-orbiter.ks new file mode 100644 index 0000000..eee2e07 --- /dev/null +++ b/boot/moon-orbiter.ks @@ -0,0 +1,170 @@ +@lazyglobal off. +wait until ship:unpacked. +rcs off. +lock throttle to 0. + +runoncepath("0:/lib/common.ks"). +runoncepath("0:/lib/moonmath.ks"). +runoncepath("0:/lib/stage/atlas.ks"). +runoncepath("0:/lib/stage/centaur.ks"). +runoncepath("0:/lib/stage/probe.ks"). + +local state is lex(). + +local function ship_volume { + return ship:rootpart:getmodule("kosprocessor"):volume. +} + +local function phase { + switch to ship_volume(). + if not ship_volume():exists("state.json") { + set_phase("prelaunch"). + } + set state to readjson("state.json"). + return state["phase"]. +} + +local function set_phase { + parameter new_phase. + switch to ship_volume(). + set state["phase"] to new_phase. + writejson(state, "state.json"). + kuniverse:quicksaveto("moon-impactor-"+new_phase). +} + +if phase() = "prelaunch" { + local target_inclination is max(moon:obt:inclination,ship:latitude). + local target_alt is 500_000. + set state["azimuth"] to launch_azimuth(target_inclination, target_alt). + + local launch_params is moonmath:calculate_launch(target_inclination, state["azimuth"], target_alt). + local launch_time is launch_params:launch_time. + set state["moon_altitude"] to launch_params:moon_altitude. + set state["departure_ra"] to launch_params:burn_longitude. + print "Departing for moon at " + state["departure_ra"] + " right ascension". + + wait 2. + + until launch_time - time:seconds < 10 { + print "Not ready to launch yet, warping...". + warpto(launch_time-9). + wait 0. + wait until warp = 0. + wait until kuniverse:timewarp:issettled. + print "Maybe done warping?". + } + wait until time:seconds > launch_time. + + atlas:launch(state["azimuth"], target_alt, 4). + stage. + set_phase("circularize"). +} + +if phase() = "circularize" { + centaur:orbit(state["azimuth"]). + centaur:power_down(). + + wait 1. + set_phase("parkingorbit"). +} + +local function ship_ra { + return mod(ship:longitude + ship:body:rotationangle + 360, 360). +} + +if phase() = "parkingorbit" { + local transfer_dv is hohmann_transfer_dv(earth, ship:altitude, state["moon_altitude"]). + local burn_time is centaur:burn_time(transfer_dv / 2). + local burn_angle is (burn_time / ship:obt:period) * 360. + local burn_ra is mod(state["departure_ra"] - burn_angle + 360, 360). + + + // Just in case our departure point is RIGHT HERE, we want to go around at least once. + set warpmode to "physics". + set warp to 3. + wait until abs(ship_ra() - burn_ra) > 16. + set warp to 0. + wait until kuniverse:timewarp:issettled. + wait 1. + + // Rails warp until we're nearish to the burn point + print "Warping to dLongitude < 15". + set warpmode to "rails". + set warp to 2. + wait until abs(ship_ra() - burn_ra) < 15. + set warp to 0. + wait until kuniverse:timewarp:issettled. + wait 1. + + // Physics warp until we're nearish-er + print "Warping to dLongitude < 4". + set warpmode to "physics". + set warp to 3. + wait until abs(ship_ra() - burn_ra) < 4. + set warp to 0. + wait until kuniverse:timewarp:issettled. + wait 1. + + centaur:power_up(). + rcs on. + lock steering to ship:prograde. + wait until ship_ra() >= burn_ra. + print "Moon altitude is: " + state["moon_altitude"]. + print "Transfer DV is: " + transfer_dv. + centaur:transfer_burn(state["moon_altitude"]). + wait 1. + + set_phase("pretransfer"). +} + +if phase() = "pretransfer" { + rcs on. + panels on. + stage. + wait 1. + probe:power_up(). + lock steering to sun:direction. + wait 1. + wait until steering_locked(). + wait 1. + rcs off. + probe:power_down(). + wait 1. + + set_phase("transfer"). +} + +if phase() = "transfer" { + set warpmode to "rails". + warpto(eta:transition + time:seconds). + wait until ship:obt:body = moon. + wait until kuniverse:timewarp:issettled. + + set_phase("lunar_arrival"). +} + +if phase() = "lunar_arrival" { + stage. + probe:capture_burn(). + + set_phase("lunar_deploy"). +} + +if phase() = "lunar_deploy" { + probe:power_up(). + lock steering to sun:direction. + wait 1. + wait until steering_locked(). + wait 1. + rcs off. + probe:power_down(). + + set_phase("done"). +} + + +if phase() <> "done" { + print "Phase logic failed, expected to be in phase '" + phase() + "'". +} + +print "Done". \ No newline at end of file diff --git a/boot/navsat-1.ks b/boot/navsat-1.ks new file mode 100644 index 0000000..7d9d427 --- /dev/null +++ b/boot/navsat-1.ks @@ -0,0 +1,28 @@ +@lazyglobal off. +wait until ship:unpacked. +rcs off. + +runoncepath("0:/lib/common.ks"). +runoncepath("0:/lib/stage/thor.ks"). +runoncepath("0:/lib/stage/able.ks"). + +local target_alt is 500_000. +local target_ecc is 0.01. +local hdg is 30. + +thor:launch(hdg, target_alt, 1.4). +stage. +able:yeet(hdg, target_alt). +able:power_down(). +wait 1. +set warpmode to "rails". +set warp to 2. +wait until eta:apoapsis < 180. +set warp to 1. +wait until eta:apoapsis < 150. +set warp to 0. +wait 1. +wait until kuniverse:timewarp:issettled. +able:power_up(). +able:circularize(target_ecc). +wait 1. diff --git a/boot/navsat-2.ks b/boot/navsat-2.ks new file mode 100644 index 0000000..392ba62 --- /dev/null +++ b/boot/navsat-2.ks @@ -0,0 +1,30 @@ +@lazyglobal off. +wait until ship:unpacked. +rcs off. + +runoncepath("0:/lib/common.ks"). +runoncepath("0:/lib/stage/thor.ks"). +runoncepath("0:/lib/stage/able.ks"). + +local target_alt is 800_000. +local target_ecc is 0.0025. +local hdg is launch_azimuth(89, target_alt). + +thor:launch(hdg, target_alt, 5, 300). +stage. +able:yeet(hdg, target_alt). +able:power_down(). +wait 1. +set warpmode to "rails". +set warp to 2. +wait until eta:apoapsis < 180. +set warp to 1. +wait until eta:apoapsis < 150. +set warp to 0. +wait 1. +wait until kuniverse:timewarp:issettled. +able:power_up(). +able:circularize(target_ecc). +wait 1. +stage. + diff --git a/boot/orbit-return.ks b/boot/orbit-return.ks new file mode 100644 index 0000000..4759662 --- /dev/null +++ b/boot/orbit-return.ks @@ -0,0 +1,73 @@ +@lazyglobal off. +wait until ship:unpacked. +rcs off. + +runoncepath("0:/lib/common.ks"). +runoncepath("0:/lib/stage/thor.ks"). +runoncepath("0:/lib/stage/able.ks"). + +local target_inclination is ship:latitude. +local target_alt is 600_000. + +local hdg is launch_azimuth(target_inclination, target_alt). + +thor:launch(hdg, target_alt). +stage. +able:launch(hdg, target_alt). + +set warpmode to "rails". + +warpto(time:seconds + (eta:apoapsis - 20)). +wait until eta:apoapsis < 20. + +// Kick stage. +rcs on. +lock steering to ship:prograde. +wait until eta:apoapsis < 10. +stage. + +// Burn out kick stage +wait until ship:thrust = 0. +stage. + +rcs off. +unlock steering. +unlock throttle. +wait 0. + +// Skip a day for science collection +warpto(time:seconds + 24 * 60 * 60). +wait 24 * 60 * 60 + 1. +wait until kuniverse:timewarp:issettled. + +print "Transferring data to return capsule". +wait until ship:rootpart:getmodule("HardDrive"):hasevent("transfer data here"). +ship:rootpart:getmodule("HardDrive"):doevent("Transfer data here"). + +if eta:apoapsis < 35 { + print "Skipping this orbit". + wait until eta:apoapsis > eta:periapsis. +} + +print "Warping to AP for deorbit". +wait 1. +warpto(time:seconds + eta:apoapsis - 120). +wait until eta:apoapsis < 120. +wait until kuniverse:timewarp:issettled. + +print "Aligning for return". +rcs on. +lock steering to ship:retrograde. +set warpmode to "physics". +set warp to 3. +wait until eta:apoapsis < 5. +set warp to 0. +wait until eta:apoapsis < 1. + +print "Deorbit!". +stage. + +// Stage parachute +wait until ship:altitude < 35000. +print "Parachute deploy". +stage. diff --git a/boot/orbiter.ks b/boot/orbiter.ks new file mode 100644 index 0000000..c835917 --- /dev/null +++ b/boot/orbiter.ks @@ -0,0 +1,42 @@ +@lazyglobal off. +wait until ship:unpacked. + +runoncepath("0:/lib/stage/v2.ks"). +runoncepath("0:/lib/common.ks"). + +// First polar and first solar +//local target_azimuth is 355. +//local target_pitch is 5. + +// First orbit and first scientific +local target_azimuth is 90. +local target_pitch is 6.5. +//local target_pitch is 2.0. + +// First atmospheric analysis +// local target_azimuth is 60. +// local target_pitch is 5. + +rcs off. +v2:launch(target_azimuth, target_pitch). + +wait until eta:apoapsis < 30. + +// Release upper stage and track prograde. +rcs on. +stage. +lock steering to prograde. +wait 1. + +// Stabilize +wait until eta:apoapsis < 10. +local hdg is ship:prograde. +lock steering to hdg. +wait until steering_locked(0.001). + +// Sequence solid motors +stage. +wait 8. +stage. +wait 8. +stage. diff --git a/boot/sun-synchronous.ks b/boot/sun-synchronous.ks new file mode 100644 index 0000000..da3a865 --- /dev/null +++ b/boot/sun-synchronous.ks @@ -0,0 +1,24 @@ +@lazyglobal off. +wait until ship:unpacked. +rcs off. + +runoncepath("0:/lib/common.ks"). +runoncepath("0:/lib/stage/thor.ks"). +runoncepath("0:/lib/stage/able.ks"). + +local target_inclination is 97. +local target_alt is 350_000. + +local hdg is launch_azimuth(target_inclination, target_alt). + +thor:launch(hdg, target_alt). +stage. +able:launch(hdg, target_alt). + +warpto(time:seconds + (eta:apoapsis - 30)). +wait until eta:apoapsis < 30. + +rcs on. +lock steering to ship:prograde. +wait until eta:apoapsis < 10. +stage. diff --git a/boot/tv.ks b/boot/tv.ks new file mode 100644 index 0000000..8a62205 --- /dev/null +++ b/boot/tv.ks @@ -0,0 +1,37 @@ +@lazyglobal off. +wait until ship:unpacked. +rcs off. + +runoncepath("0:/lib/common.ks"). +runoncepath("0:/lib/stage/thor.ks"). +runoncepath("0:/lib/stage/able.ks"). + +local target_alt is 1_200_000. +local target_ecc is 0.0025. +local hdg is launch_azimuth(89, target_alt). + +set steeringmanager:pitchts to 3. +set steeringmanager:yawts to 3. + +thor:launch(hdg, target_alt, 5, 300). +stage. +able:yeet(hdg, target_alt). +able:power_down(). +wait 1. +set warpmode to "rails". +set warp to 2. +wait until eta:apoapsis < 180. +set warp to 1. +wait until eta:apoapsis < 150. +set warp to 0. +wait 1. +wait until kuniverse:timewarp:issettled. +able:power_up(). +able:circularize(target_ecc). +wait 1. +rcs on. +panels on. +lock steering to sun:direction. +wait 1. +wait until steering_locked(). +stage. diff --git a/boot/v2_camera.ks b/boot/v2_camera.ks new file mode 100644 index 0000000..fe4c9a0 --- /dev/null +++ b/boot/v2_camera.ks @@ -0,0 +1,15 @@ +@lazyglobal off. +wait until ship:unpacked. + +runoncepath("0:/lib/stage/v2.ks"). + +local target_azimuth is 90. +v2:launch(target_azimuth). + +wait until ship:verticalspeed < 0 and ship:altitude < 140000. +stage. + +wait until stage:ready. + +wait until ship:altitude < 75000. +stage. \ No newline at end of file diff --git a/boot/wac.ks b/boot/wac.ks new file mode 100644 index 0000000..4eb09ac --- /dev/null +++ b/boot/wac.ks @@ -0,0 +1,17 @@ +@lazyglobal off. +wait until ship:unpacked. +lock throttle to 1.0. + +local sustainer is ship:partsdubbed("ROE-Aerobee")[0]. +//local tim is ship:partsdubbed("TinyTim"). +local ks18 is ship:partsdubbed("ROE-25KS18000"). +local nike is ship:partsdubbed("ROE-NikeM5E1"). +local booster is choose nike[0] if ks18:empty else ks18[0]. + +stage. +wait until stage:ready. +wait until sustainer:thrust > booster:thrust. +stage. + +wait until ship:verticalspeed < 0 and ship:altitude < 75000. +stage. diff --git a/lib/common.ks b/lib/common.ks new file mode 100644 index 0000000..e9c9d4e --- /dev/null +++ b/lib/common.ks @@ -0,0 +1,103 @@ +@lazyglobal off. + +global function steering_locked { + parameter epsilon is 0.1. + local rate_epsilon is epsilon * 0.1. + local angle_good is abs(steeringmanager:pitcherror) < epsilon and abs(steeringmanager:yawerror) < epsilon. + local rate_good is abs(ship:angularvel:x) < rate_epsilon and abs(ship:angularvel:y) < rate_epsilon. + return rate_good and angle_good. +} + +global function launch_azimuth { + // from https://www.orbiterwiki.org/wiki/Launch_Azimuth + parameter target_inclination, target_alt. + + local inertial_hdg is arcsin(cos(target_inclination) / cos(ship:latitude)). + local orbit_vel is sqrt(ship:body:mu / (target_alt + ship:body:radius)). + local body_vel is 2 * constant:pi * ship:body:radius / ship:body:rotationperiod. + local vxrot is orbit_vel * sin(inertial_hdg) - body_vel * cos(ship:latitude). + local vyrot is orbit_vel * cos(inertial_hdg). + return arctan(vxrot / vyrot). +} + +global function ap_prograde { + local nd is node(time:seconds + eta:apoapsis, 0, 0, 1). + add(nd). + local target_hdg is rotatefromto(ship:prograde:forevector, nd:burnvector) * ship:prograde. + remove(nd). + return target_hdg. +} + +global function obt_altitude { + if eta:apoapsis > eta:periapsis { + local since_ap is ship:obt:period - eta:apoapsis. + if since_ap < eta:periapsis { + return ship:obt:periapsis. + } else { + return ship:obt:apoapsis. + } + } else { + local since_pe is ship:obt:period - eta:periapsis. + if since_pe < eta:apoapsis { + ship:obt:apoapsis. + } else { + ship:obt:periapsis. + } + } +} + +global function target_lan { + parameter target_lan, epsilon is 0.1. + local current_lan is mod(earth:rotationangle - ship:longitude - 90 + 360, 360). + + local lan_diff is mod(current_lan - target_lan + 360, 360). + + local target is time:now - 60 * (lan_diff / 4). + warpto(target - 10). + wait until time:now > target. +} + +global function circular_vel { + parameter obt_alt is ship:altitude. + return sqrt(ship:body:mu / (obt_alt + ship:body:radius)). +} + +global function orbital_vel { + parameter obt_alt. + return sqrt(ship:body:mu * (2 / (obt_alt + ship:body:radius) - 1 / ship:obt:semimajoraxis)). +} + +global function circularization_dv { + return circular_vel(ship:obt:apoapsis) - orbital_vel(ship:obt:apoapsis). +} + +global function burn_time { + parameter dv, engine. + + local thrust is engine:possiblethrust. + local exhaust_vel is thrust / engine:maxmassflow. + local initial_mass is ship:mass. + + return initial_mass * exhaust_vel * (1 - CONSTANT:E ^ (0 - dv / exhaust_vel)) / thrust. +} + +global function hohmann_transfer_time { + parameter b, pe, ap. + local r1 is pe + b:radius. + local r2 is ap + b:radius. + return constant:pi * sqrt((r1+r2)*(r1+r2)*(r1+r2)/(8*b:mu)). +} + +global function hohmann_transfer_dv { + parameter b, pe, ap. + local r1 is pe + b:radius. + local r2 is ap + b:radius. + return sqrt(b:mu/r1)*(sqrt(2*r2/(r1 + r2)) - 1). +} + +global function predicted_ap { + local vel is ship:velocity:orbit:mag. + local rp is ship:altitude + ship:obt:body:radius. + local a is rp / 2 - ship:obt:body:mu/(vel*vel). + return (2*a - rp) - ship:obt:body:radius. +} \ No newline at end of file diff --git a/lib/moonmath.ks b/lib/moonmath.ks new file mode 100644 index 0000000..0cc1739 --- /dev/null +++ b/lib/moonmath.ks @@ -0,0 +1,110 @@ +@lazyglobal off. + +global moonmath is lex( + "calculate_launch", calculate_launch@, + "position", moon_position_at_time@ +). + +local function calculate_launch { + parameter target_inclination, azimuth, target_alt. + + + local time_fudge is 0. + + local wait_time is 0. + local orbit_time is 0. + local burn_ra is 0. + local tt is hohmann_transfer_time(earth, target_alt, moon:obt:semimajoraxis). + print "Initial moon distance: " + moon:obt:semimajoraxis. + print "Initial travel time: " + tt. + local moon_vec is moon_position_at_time(time:seconds + tt + time_fudge). + local iterations is 0. + until iterations > 10 { + local next_tt is hohmann_transfer_time(earth, target_alt, moon_vec:mag - earth:radius). + print "Updated moon distance: " + (moon_vec:mag - earth:radius). + print "Updated travel time: " + next_tt. + local next_moon_vec is moon_position_at_time(time:seconds + next_tt + wait_time + orbit_time+time_fudge). + local err is abs((next_moon_vec - moon_vec):mag). + print "Position Error " + iterations + ": " + err. + set moon_vec to next_moon_vec. + set tt to next_tt. + set iterations to iterations + 1. + + local rm is moon_vec:normalized. + local rt is(-1) * rm. + + set burn_ra to mod(arctan2(rt:y,rt:x) + 360, 360). + + + // `w` is the unit vector normal to the launch orbital plane + local w_z is cos(target_inclination). + local w_y_1 is (0 - w_z*rm:y*rm:z + rm:x*sqrt(1 - rm:z*rm:z - w_z*w_z)) / (rm:x*rm:x + rm:y*rm:y). + local w_y_2 is (0 - w_z*rm:y*rm:z - rm:x*sqrt(1 - rm:z*rm:z - w_z*w_z)) / (rm:x*rm:x + rm:y*rm:y). + local w_x_1 is (0 - w_y_1*rm:y - w_z*rm:z)/rm:x. + local w_x_2 is (0 - w_y_2*rm:y - w_z*rm:z)/rm:x. + + + local launch_ra_1_cos is (w_z*w_x_1*sin(ship:latitude) + w_y_1*cos(ship:latitude)*cos(azimuth)) / (w_z*w_z-1)*cos(ship:latitude). + local launch_ra_2_cos is (w_z*w_x_2*sin(ship:latitude) + w_y_2*cos(ship:latitude)*cos(azimuth)) / (w_z*w_z-1)*cos(ship:latitude). + local launch_ra_1_sin is (w_z*w_y_1*sin(ship:latitude) - w_x_1*cos(ship:latitude)*cos(azimuth)) / (w_z*w_z-1)*cos(ship:latitude). + local launch_ra_2_sin is (w_z*w_y_2*sin(ship:latitude) - w_x_1*cos(ship:latitude)*cos(azimuth)) / (w_z*w_z-1)*cos(ship:latitude). + + local launch_right_ascension_1 is arctan2(launch_ra_1_sin, launch_ra_1_cos). + local launch_right_ascension_2 is arctan2(launch_ra_2_sin, launch_ra_2_cos). + + local current_right_ascension is earth:rotationangle + ship:longitude. + local wait_angle_1 is mod(360 + launch_right_ascension_1 - current_right_ascension, 360). + local wait_angle_2 is mod(360 + launch_right_ascension_2 - current_right_ascension, 360). + print "Need to rotate " + wait_angle_1 + " or " + wait_angle_2 + " degrees.". + local wait_angle is min(wait_angle_1, wait_angle_2). + print "Choosing " + wait_angle. + set wait_time to body:rotationperiod * wait_angle / 360. + print "That will take " + wait_time + " seconds.". + + local launch_ra is wait_angle + earth:rotationangle + ship:longitude. + local orbit_angle is mod(burn_ra - launch_ra + 360, 360). + local orbit_frac is orbit_angle / 360. + set orbit_time to orbit_frac * 90 * 60. + + if err < (moon:radius / 100) { + break. + } + } + + return lex( + "launch_time", time:seconds + wait_time, + "moon_altitude", moon_vec:mag - earth:radius, + "burn_longitude", burn_ra + ). +} + +local function moon_position_at_time { + parameter t. + return position_at_time(moon, t). +} + +global function position_at_time { + parameter bod, t. + local bod_orbit is bod:obt. + local delta_t is t - bod_orbit:epoch. + local revolutions is delta_t / bod_orbit:period. + local mean_anomaly is mod(revolutions * 360 + bod_orbit:meananomalyatepoch, 360). + local e is bod_orbit:eccentricity. + local e2 is e*e. + local e3 is e2*e. + local true_anomaly is mean_anomaly + (2*e - e3/4)*sin(mean_anomaly) + 5/4*e2*sin(2*mean_anomaly)+13/12*e3*sin(3*mean_anomaly). + local radius is bod_orbit:semimajoraxis * (1 - e2) / (1 + e*cos(true_anomaly)). + + local sin_lan is sin(bod_orbit:longitudeofascendingnode). + local cos_lan is cos(bod_orbit:longitudeofascendingnode). + local sin_inc is sin(bod_orbit:inclination). + local cos_inc is cos(bod_orbit:inclination). + local sin_anom is sin(bod_orbit:argumentofperiapsis + true_anomaly). + local cos_anom is cos(bod_orbit:argumentofperiapsis + true_anomaly). + + local x is radius * (cos_lan*cos_anom - sin_lan*sin_anom*cos_inc). + local y is radius * (sin_lan*cos_anom + cos_lan*sin_anom*cos_inc). + local z is radius * sin_inc * sin_anom. + + return V(x, y, z). +} diff --git a/lib/stage/able.ks b/lib/stage/able.ks new file mode 100644 index 0000000..68d5ad5 --- /dev/null +++ b/lib/stage/able.ks @@ -0,0 +1,208 @@ +@lazyglobal off. + +global able is lex( + "launch", launch@, + "burn", burn@, + "orbit", do_orbit@, + "circularize", circularize@, + "yeet", yeet@, + "power_down", power_down@, + "power_up", power_up@ +). + +local function engine { + local early is ship:partsdubbed("ROE-AJ10Early"). + local mid is ship:partsdubbed("ROE-AJ10Mid"). + for eng in early { + return eng. + } + for eng in mid { + return eng. + } +} + +local function ignite { + rcs on. + lock throttle to 1.0. + wait 3. + stage. +} + +local function is_ablestar { + return not ship:partsdubbed("ROE-AJ10Mid"):empty. +} + +local function yeet { + parameter hdg, tgt_alt. + + power_down(). + set warpmode to "physics". + set warp to 3. + if is_ablestar() { + wait until eta:apoapsis < 180. + } else { + wait until eta:apoapsis < 100. + } + set warp to 0. + wait until kuniverse:timewarp:issettled. + power_up(). + + rcs on. + local target is heading(hdg, ship:obt:trueanomaly - 180, -hdg). + lock steering to target. + if is_ablestar() { + wait until eta:apoapsis < 150. + } else { + wait until eta:apoapsis < 80. + } + + lock throttle to 1.0. + wait 3. + stage. + wait until ship:obt:apoapsis > tgt_alt. + rcs off. + lock throttle to 0.0. + unlock steering. + wait 0. +} + +local function do_orbit { + parameter hdg, burnout is false. + +// power_down(). + set warpmode to "physics". + set warp to 3. + wait until eta:apoapsis < 100. + set warp to 0. + wait until kuniverse:timewarp:issettled. +// power_up(). + + rcs on. + local target is heading(hdg, ship:obt:trueanomaly - 180, -hdg). + lock steering to target. + wait until eta:apoapsis < 80. + + lock throttle to 1.0. + wait 3. + stage. + if burnout { + wait until engine():flameout. + } else { + wait until ship:velocity:orbit:mag > circular_vel(). + } + // Fine-tune orbital speed w/ RCS fore/aft? + rcs off. + lock throttle to 0.0. + unlock steering. + wait 0. +} + +local function circularize { + parameter target_ecc, max_vel_delta is 0.1. + + power_down(). + set warpmode to "physics". + set warp to 3. + wait until eta:apoapsis < 100. + set warp to 0. + wait until kuniverse:timewarp:issettled. + power_up(). + + rcs on. + lock steering to ship:prograde. + wait until eta:apoapsis < 80. + + local second_burn is engine:ignition. + engine():shutdown(). + lock throttle to 1.0. + wait 3. + engine():activate(). + wait until ship:velocity:orbit:mag > circular_vel(). + lock throttle to 0.0. + lock steering to lookdirup(ship:prograde:forevector, ship:up:forevector). + until false { + local threshold is 0.1. + local p is threshold / max_vel_delta. + local dv is circular_vel() - ship:velocity:orbit:mag. + local vert_vel is ship:verticalspeed * ship:up:forevector. + local vert_vel_d is 0.0 - vert_vel:mag. + local horz_vel_d is circular_vel() - (ship:velocity:orbit - vert_vel):mag. + local horz_factor is horz_vel_d * p. + local vert_factor is vert_vel_d * p. + if ship:obt:eccentricity < target_ecc or (abs(horz_factor) < threshold and abs(vert_factor) < threshold) { + set ship:control:fore to 0. + set ship:control:top to 0. + break. + } + set ship:control:fore to horz_factor. + set ship:control:top to vert_factor. + wait 0. + } + unlock steering. + rcs off. + wait 0. +} + +local function burn { + lock steering to heading(hdg, 0, -hdg). + parameter hdg. + ignite(). + wait 1. + + rcs off. + set warpmode to "physics". + set warp to 3. + + wait until ship:thrust = 0. + unlock steering. + unlock throttle. + set warp to 0. + wait until kuniverse:timewarp:issettled. +} + +local function launch { + parameter hdg, target_alt. + + local pitch_pid is pidloop(0.001, 0, 0, -90, 90, 1). + set pitch_pid:setpoint to target_alt. + local wanted_hdg is ship:facing. + lock steering to wanted_hdg. + + ignite(). + + wait 1. + set warpmode to "physics". + set warp to 3. + + until ship:thrust = 0 or ship:obt:periapsis > target_alt or eta:periapsis < eta:apoapsis { + local wanted_pitch is pitch_pid:update(time:seconds, ship:obt:apoapsis). + local neutral_pitch is ship:obt:trueanomaly / 2 - 90. + set wanted_hdg to heading(hdg, wanted_pitch, -hdg). + wait 0. + } + + if ship:thrust <> 0 { + lock steering to ship:prograde. + wait until ship:thrust = 0. + } + + unlock steering. + unlock throttle. + rcs off. + set warp to 0. + wait until kuniverse:timewarp:issettled. +} + + +local function power_down { + local avionics is ship:partsdubbed("able-avionics")[0]. + local avi_mod is avionics:getmodule("ModuleProceduralAvionics"). + avi_mod:doaction("shutdown avionics", true). +} + +local function power_up { + local avionics is ship:partsdubbed("able-avionics")[0]. + local avi_mod is avionics:getmodule("ModuleProceduralAvionics"). + avi_mod:doaction("activate avionics", true). + +} \ No newline at end of file diff --git a/lib/stage/agena.ks b/lib/stage/agena.ks new file mode 100644 index 0000000..7865a22 --- /dev/null +++ b/lib/stage/agena.ks @@ -0,0 +1,85 @@ +@lazyglobal off. + +runoncepath("0:/lib/common.ks"). + +global agena is lex( + "orbit", do_orbit@, + "power_down", power_down@, + "power_up", power_up@, + "low_power", low_power@, + "separate", separate@, + "transfer_burn", transfer_burn@ +). + +local function do_orbit { + parameter hdg. + + print "Agena startup". + print "Warping to burn". + set warpmode to "physics". + set warp to 3. + wait until eta:apoapsis < 140. + set warp to 0. + wait until kuniverse:timewarp:issettled. + + print "RCS On. Locking heading". + rcs on. + local target is heading(hdg, ship:obt:trueanomaly - 180, -hdg). + lock steering to target. + wait until eta:apoapsis < 120. + + print "Throttle up". + lock throttle to 1.0. + wait 3. + stage. + print "GO GO GO". + wait until ship:velocity:orbit:mag > circular_vel() and ship:obt:periapsis > 140000. + rcs off. + lock throttle to 0.0. + unlock steering. + wait 0. + print "Agena done". +} + +local function power_down { + local avionics is ship:partsdubbed("agena-avionics")[0]. + local avi_mod is avionics:getmodule("ModuleProceduralAvionics"). + avi_mod:doaction("shutdown avionics", true). +} + +local function power_up { + local avionics is ship:partsdubbed("agena-avionics")[0]. + local avi_mod is avionics:getmodule("ModuleProceduralAvionics"). + avi_mod:doaction("activate avionics", true). +} + +local function low_power { + local avionics is ship:partsdubbed("agena-avionics")[0]. + local power is avionics:resources[0]. + return power:amount / power:capacity < 0.1. +} + +local function separate { + rcs on. + lock steering to prograde. + lock throttle to 1.0. + wait 5. + lock throttle to 0.0. + unlock steering. + rcs off. +} + +local function transfer_burn { + parameter target_vel. + + // Shutdown engine for ullage + local engine is ship:partsdubbed("ROE-Agena")[0]. + engine:shutdown(). + lock throttle to 1.0. + wait 3. + // Engine on + engine:activate(). + wait until ship:velocity:orbit:mag >= target_vel. + lock throttle to 0.0. + wait 0. +} \ No newline at end of file diff --git a/lib/stage/atlas.ks b/lib/stage/atlas.ks new file mode 100644 index 0000000..7414fcb --- /dev/null +++ b/lib/stage/atlas.ks @@ -0,0 +1,102 @@ +@lazyglobal off. + +runoncepath("0:/lib/common.ks"). + +global atlas is lex( + "launch", launch@ + ). + +local function launch { + parameter hdg, target_ap, target_pitch is 6. + + lock throttle to 1.0. + + local engine is ship:partsdubbed("ROE-LR89.2")[0]. + stage. + wait until stage:ready. + wait until engine:thrust > (engine:maxthrust * 0.9). + stage. + local booster_drop is time:seconds + 160. + + local target_vel is 150. + lock steering to heading(hdg, 90 - min(target_pitch, target_pitch * (ship:velocity:surface:mag / target_vel)), -hdg). + wait until ship:velocity:surface:mag > target_vel. + print "Heading stable, switching to gravity turn". + set warpmode to "physics". + set warp to 3. + + lock steering to lookdirup(ship:srfprograde:forevector, ship:up:forevector). + + wait until time:seconds > booster_drop. + set warp to 0. + wait until kuniverse:timewarp:issettled. + stage. + wait 2. + set warp to 3. + + wait until ship:altitude > 100000. + print "Dropping Fairings". + if not ship:partsdubbed("SSTUHollowRing"):empty { + set warp to 0. + wait until kuniverse:timewarp:issettled. + print "Dropping Fairings". + stage. + wait 2. + set warp to 3. + } + print "Switching to target PE mode". + lock steering to insert_orbit_pe(hdg, target_ap). + + wait until ship:thrust = 0. + unlock steering. + lock throttle to 0.0. + set warp to 0. + wait until kuniverse:timewarp:issettled. +} + +local function drawvec { + parameter vec, color, desc. + local origin is ship:position. + return vecdraw(origin, origin + vec:normalized, color, desc, 5.0, TRUE, 0.2, TRUE, FALSE). +} + +local function insert_orbit_pe { + parameter azimuth, target_ap. + //clearvecdraws(). + local ap_hdg is ap_prograde(). + local origin is ship:position. + + //drawvec(ship:facing:forevector, RGB(0, 1, 0), "Ship Facing"). + //drawvec(ap_hdg:forevector, RGB(1, 1, 0), "AP Prograde"). + + local ap_delta is ship:orbit:apoapsis - target_ap. + local cur_burn_angle is mod(vang(vxcl(ship:facing:forevector, ap_hdg:starvector), ap_hdg:forevector) + 360, 360). + local ap_burn_ang is symmetric_clamp(ap_delta/3000, 90). + local target_burn_hdg is angleaxis(ap_burn_ang, ap_hdg:starvector) * ap_hdg. + + //drawvec(target_burn_hdg:forevector, RGB(1, 0, 0), "Non-azimuth-corrected burn vector"). + + // Vector pointing exactly towards our azimuth, flat with our orbital position + local azimuth_vector is heading(azimuth, 0, 0):forevector. + //drawvec(azimuth_vector, RGB(0, 1, 1), "Azimuth"). + + // Vector pointing exactly towards AP, flat with our orbital position + local steering_vector is vxcl(ship:up:forevector, target_burn_hdg:forevector). + //drawvec(steering_vector, RGB(1, 0, 1), "AP Steering Vector"). + + // Angle to rotate to bring our AP vector to our azimuth + local azimuth_ang is vang(steering_vector, azimuth_vector). + + local azimuth_adjustment is angleaxis(-azimuth_ang, ship:up:forevector). + local azimuth_burn_hdg is azimuth_adjustment * target_burn_hdg. + //drawvec(azimuth_burn_hdg:forevector, RGB(0, 1, 0), "Azimuth-corrected burn vector"). + + local steering_ang is symmetric_clamp(vang(ship:facing:forevector, azimuth_burn_hdg:forevector), 10). + local steering_hdg is angleaxis(steering_ang, vcrs(ship:facing:forevector, azimuth_burn_hdg:forevector)) * ship:facing. + return steering_hdg. +} + +local function symmetric_clamp { + parameter val, limit. + return min(max(val, -limit), limit). +} \ No newline at end of file diff --git a/lib/stage/centaur.ks b/lib/stage/centaur.ks new file mode 100644 index 0000000..9f36a4d --- /dev/null +++ b/lib/stage/centaur.ks @@ -0,0 +1,172 @@ +@lazyglobal off. + +runoncepath("0:/lib/common.ks"). + +global centaur is lex( + "orbit", do_orbit@, + "power_down", power_down@, + "power_up", power_up@, + "low_power", low_power@, + "separate", separate@, + "transfer_burn", transfer_burn@, + "burn_time", centaur_burn_time@, + "capture_burn", capture_burn@ +). + +local function do_orbit { + parameter hdg, target_ecc is 0.002, max_vel_delta is 0.1. + + print "Centaur startup". + local dv is circularization_dv(). + local circularization_time is centaur_burn_time(dv). + local half_circularization_time is centaur_burn_time(dv / 2). + print "Circularization is " + dv + "m/s over " + circularization_time + "s". + print "Will burn " + half_circularization_time + "s before AP". + + local ignition_time is half_circularization_time. + local ullage_time is ignition_time + 3. + local steering_time is ullage_time + 20. + + print "Warping to burn". + set warpmode to "physics". + set warp to 3. + wait until eta:apoapsis < steering_time. + set warp to 0. + wait 1. + wait until kuniverse:timewarp:issettled. + + print "RCS On. Locking heading". + rcs on. + local target is heading(hdg, ship:obt:trueanomaly - 180, -hdg). + lock steering to target. + wait until eta:apoapsis < ullage_time. + + print "Throttle up". + lock throttle to 1.0. + wait until eta:apoapsis < ignition_time. + stage. + print "GO GO GO". + wait until ship:velocity:orbit:mag > circular_vel() and ship:obt:periapsis > 140000. + lock throttle to 0.0. + lock steering to lookdirup(ship:prograde:forevector, ship:up:forevector). + until false { + local threshold is 0.1. + local p is threshold / max_vel_delta. + local dv is circular_vel() - ship:velocity:orbit:mag. + local vert_vel is ship:verticalspeed * ship:up:forevector. + local vert_vel_d is 0.0 - vert_vel:mag. + local horz_vel_d is circular_vel() - (ship:velocity:orbit - vert_vel):mag. + local horz_factor is horz_vel_d * p. + local vert_factor is vert_vel_d * p. + if ship:obt:eccentricity < target_ecc or (abs(horz_factor) < threshold and abs(vert_factor) < threshold) { + set ship:control:fore to 0. + set ship:control:top to 0. + break. + } + set ship:control:fore to horz_factor. + set ship:control:top to vert_factor. + wait 0. + } + rcs off. + unlock steering. + wait 0. + print "Centaur done". +} + +local function power_down { + local avionics is ship:partsdubbed("centaur-avionics")[0]. + local avi_mod is avionics:getmodule("ModuleProceduralAvionics"). + avi_mod:doaction("shutdown avionics", true). +} + +local function power_up { + local avionics is ship:partsdubbed("centaur-avionics")[0]. + local avi_mod is avionics:getmodule("ModuleProceduralAvionics"). + avi_mod:doaction("activate avionics", true). +} + +local function low_power { + local avionics is ship:partsdubbed("centaur-avionics")[0]. + local power is avionics:resources[0]. + return power:amount / power:capacity < 0.1. +} + +local function separate { + rcs on. + lock steering to prograde. + lock throttle to 1.0. + wait 5. + lock throttle to 0.0. + unlock steering. + rcs off. +} + +local function transfer_burn { + parameter target_ap. + + // Shutdown engine for ullage + local engine is ship:partsdubbed("ROE-RL10Fixed")[0]. + engine:shutdown(). + lock throttle to 1.0. + wait 3. + // Engine on + engine:activate(). + wait until ship:obt:apoapsis > target_ap. + lock throttle to 0.0. + wait 0. +} + +local function centaur_burn_time { + parameter dv. + local engine is ship:partsdubbed("ROE-RL10Fixed")[0]. + return burn_time(dv, engine). +} + +local function capture_burn { + parameter threshold is 250_000. + local engine is ship:partsdubbed("ROE-RL10Fixed")[0]. + engine:shutdown(). + local initial_pe is ship:obt:periapsis. + wait 1. + warpto(eta:periapsis + time:seconds - 30). + wait 1. + wait until kuniverse:timewarp:warp = 0. + wait until kuniverse:timewarp:issettled. + power_up(). + rcs on. + lock steering to ship:retrograde. + wait 1. + wait until steering_locked(). + lock throttle to 1. + wait 3. + engine:activate(). + + if initial_pe > threshold { + wait until ship:obt:periapsis < (threshold/2). + lock throttle to 0. + engine:shutdown(). + power_down(). + unlock steering. + wait 1. + warpto(eta:periapsis + time:seconds - 30). + wait 1. + wait until kuniverse:timewarp:warp = 0. + wait until kuniverse:timewarp:issettled. + wait 1. + power_up(). + lock steering to ship:retrograde. + wait 1. + wait until steering_locked(). + lock throttle to 1. + wait 3. + engine:activate(). + wait until ship:obt:apoapsis < (threshold*2). + } else { + wait until ship:obt:eccentricity < 1 and ship:obt:apoapsis < threshold*2. + } + + engine:shutdown(). + lock throttle to 0. + power_down(). + wait 1. +} \ No newline at end of file diff --git a/lib/stage/probe.ks b/lib/stage/probe.ks new file mode 100644 index 0000000..48d9b76 --- /dev/null +++ b/lib/stage/probe.ks @@ -0,0 +1,72 @@ +@lazyglobal off. + +runoncepath("0:/lib/common.ks"). + +global probe is lex( + "power_down", power_down@, + "power_up", power_up@, + "capture_burn", capture_burn@ +). + +local function capture_burn { + parameter threshold is 250_000. + local engine is ship:partsdubbed("ROE-generic-quarter")[0]. + engine:shutdown(). + local initial_pe is ship:obt:periapsis. + wait 1. + warpto(eta:periapsis + time:seconds - 30). + wait 1. + wait until kuniverse:timewarp:warp = 0. + wait until kuniverse:timewarp:issettled. + power_up(). + rcs on. + lock steering to ship:retrograde. + wait 1. + wait until steering_locked(). + lock throttle to 1. + engine:activate(). + + if initial_pe > threshold { + wait until ship:obt:periapsis < (threshold/2). + lock throttle to 0. + engine:shutdown(). + lock steering to sun:direction. + wait 1. + wait until steering_locked(). + power_down(). + unlock steering. + wait 1. + set warpmode to "rails". + warpto(eta:periapsis + time:seconds - 30). + wait 1. + wait until kuniverse:timewarp:warp = 0. + wait until kuniverse:timewarp:issettled. + wait 1. + power_up(). + lock steering to ship:retrograde. + wait 1. + wait until steering_locked(). + lock throttle to 1. + engine:activate(). + wait until ship:obt:apoapsis < (threshold*2). + } else { + wait until ship:obt:eccentricity < 1 and ship:obt:apoapsis < threshold*2. + } + + engine:shutdown(). + lock throttle to 0. + power_down(). + wait 1. +} + +local function power_down { + local avionics is ship:rootpart. + local avi_mod is avionics:getmodule("ModuleProceduralAvionics"). + avi_mod:doaction("shutdown avionics", true). +} + +local function power_up { + local avionics is ship:rootpart. + local avi_mod is avionics:getmodule("ModuleProceduralAvionics"). + avi_mod:doaction("activate avionics", true). +} \ No newline at end of file diff --git a/lib/stage/thor.ks b/lib/stage/thor.ks new file mode 100644 index 0000000..5488ffc --- /dev/null +++ b/lib/stage/thor.ks @@ -0,0 +1,63 @@ +@lazyglobal off. + +global thor is lex( + "launch", launch@ +). + +local function launch { + parameter hdg, target_alt, target_pitch is 6, target_vel is 150. + + lock throttle to 1.0. + + local engine is ship:partsdubbed("ROE-LR79")[0]. + local boosters is ship:partsdubbed("ROE-Castor1"). + stage. + wait until stage:ready. + wait until engine:thrust > (engine:maxthrust * 0.9). + stage. + + if boosters:length > 0 { + when boosters[0]:thrust < 1 then { + print "Dropping boosters". + stage. + } + } + + + lock steering to heading(hdg, 90 - min(target_pitch, target_pitch * (ship:velocity:surface:mag / target_vel)), -hdg). + wait until ship:velocity:surface:mag > target_vel. +// wait until steering_locked(). + print "Heading stable, switching to gravity turn". + set warp to 3. + + lock steering to lookdirup(ship:srfprograde:forevector, ship:up:forevector). + + wait until ship:altitude > 100000. + if not ship:partsdubbed("SSTUHollowRing"):empty { + set warp to 0. + wait until kuniverse:timewarp:issettled. + print "Dropping Fairings". + stage. + wait 2. + set warp to 3. + } + + +// print "Switching to target AP mode". +// local pitch_pid is pidloop(0.0003, 0, 0, -90, 90, 1). +// set pitch_pid:setpoint to target_alt. +// local wanted_hdg is ship:srfprograde. +// lock steering to wanted_hdg. +// +// until ship:thrust = 0 { +// local wanted_pitch is pitch_pid:update(time:seconds, ship:obt:apoapsis). +// local neutral_pitch is ship:obt:trueanomaly / 2 - 90. +// set wanted_hdg to heading(hdg, wanted_pitch, -hdg). +// } + + wait until ship:thrust = 0. + unlock steering. + lock throttle to 0.0. + set warp to 0. + wait until kuniverse:timewarp:issettled. +} diff --git a/lib/stage/v2.ks b/lib/stage/v2.ks new file mode 100644 index 0000000..bafede3 --- /dev/null +++ b/lib/stage/v2.ks @@ -0,0 +1,37 @@ +@lazyglobal off. + +runoncepath("0:/lib/common.ks"). + +global v2 is lex( + "launch", launch@ +). + +local function launch { + parameter hdg, target_pitch is 10. + + lock throttle to 1.0. + + local engine is 0. +// local a4 is ship:partsdubbed("ROE-A4"). + local xlr41 is ship:partsdubbed("ROE-XLR41"). + local naa75 is ship:partsdubbed("ROE-A7"). + local engine is choose naa75[0] if xlr41:empty else xlr41[0]. + stage. + wait until stage:ready. + wait until engine:thrust > (engine:maxthrust * 0.9). + stage. + + print "Beginning initial pitchover". + local target_vel is 150. + lock steering to heading(hdg, 90 - min(target_pitch, target_pitch * (ship:velocity:surface:mag / target_vel)), -hdg). + + wait until ship:velocity:surface:mag > target_vel. + //wait until steering_locked(). + print "Heading stable, switching to gravity turn". + + lock steering to lookdirup(ship:srfprograde:forevector, ship:up:forevector). + + wait until ship:thrust = 0. + unlock throttle. + unlock steering. +} diff --git a/lib/switch.ks b/lib/switch.ks new file mode 100644 index 0000000..448bc35 --- /dev/null +++ b/lib/switch.ks @@ -0,0 +1,259 @@ +local function iterate { + parameter maneuver. + // `maneuver` is a lexicon of: + // "mass" - vehicle mass at start of maneuver + // "mu" - gravitational constant + // "hmax" - maximum step size + // "itmax" - maximum number of iterations + // "r0" - initial position + // "v0" - initial velocity + // "u0" - initial heading + // "du0" - initial change in heading + // "burns" - list of lexicon + // "start" - burn start time + // "end" - burn end time + // "initial_coast" - either start time of coast, or `false` if none + // "stages" - list of lexicon + // "thrust" - engine thrust + // "massflow" - fuel consumption of engine + // "fuel" - total amount of fuel in the stage + // "boiloff_rate" - how quickly fuel evaporates when not being used + // "dry_mass" - mass lost when vehicle stages + // "c" - target orbit parameters (TODO) + + local num_legs is burns:length * 2. + if initial_coast = false { + set num_legs to num_legs - 1. + } + + for iter in RANGE(itmax) { + local q0 is list(u0:x, u0:y, y0:z, du0:x, du0:y, du0:z). + local x0 is list(r0:x, r0:y, r0:z, v0:x, v0:y, v0:z). + local xf is list(0.0, 0.0, 0.0, 0.0, 0.0, 0.0). + local qf is list(0.0, 0.0, 0.0, 0.0, 0.0, 0.0). + + // Initialization of matrix of partials + // z(i,j) partial of state and costate with respect to initial costate and switching times + // e(i,j) partial of right end variables and switching conditions with respect to initial costate and switching times + local z is list(). + local e is list(). + for i in RANGE(12) { + z:add(list()). + e:add(list()). + for j in RANGE(6 + num_legs) { + z[i]:add(0.0). + e[i]:add(0.0). + } + e[i]:add(0.0). + } + local leg is 0. + local leg5 is 5. + local leg6 is 6. + local leg7 is 7. + local l7 is num_legs+6. + local ump is 0.0. + local uk is maneuver:mu. + local prev_burn is false. + for burn in maneuver:burns { + if (leg <> 0) or (initial_coast <> false) { + local phi is list(). + local dphi is list(). + for i in range(6) { + phi:add(list()). + dphi:add(list()). + for j in range(6) { + phi[i]:add(0.0). + dphi[i]:add(0.0). + } + } + + local start is false. + if prev_burn <> false { + set start to prev_burn:end. + } else { + set start to maneuver:initial_coast. + } + local end is burn:start. + local t is end - start. + // phi(i,j) partial of state at end of coast with respect to state at start of coast + // dphi(i,j) partial of costate at end of coast with respect to state at start of coast + coast (x0, q0, xf, qf, phi, dphi, uk, t, no). + + local dz is list(). + for i in range(12) { + dz:add(list()). + for j in RANGE(leg6) { + dz[i]:add(0.0). + } + } + for i in range(6) { + local i6 is i + 6. + for j in range(leg6) { + for k in range(6) { + set dz[i][j] to dz[i][j] + phi[i][k] * z[k][j]. + set dz[i6][j] to dz[i6][j] + phi[i][k] * z[k+6][j] + dphi[i][k] * z[k][j]. + } + } + } + // Update matrix of partials Z + for i in range(12) { + for j in range(leg6) { + set z[i][j] to dz[i][j]. + } + } + local um is sqrt(qf[0]*qf[0]+qf[1]*qf[1]+qf[2]*qf[2]). + local cbmu is burn:thrust / (mass*um). + for i in range(3) { + set z[i+3][leg6] to -cbmu * qf[i]. + } + if leg <> 0 { + // Calculation of switching condition and corresponding partial + set e[leg5][l7] to ump - um. + for j in range(leg5+1) { + set e[leg5][j] to -e[leg5][j]. + for k in range(3) { + set e[leg5][j] to e[leg5][j] + (qf[k]/um)*z[k+6][j]. + } + } + } + set leg to leg + 1. + set leg5 to leg + 5. + set leg6 to leg + 6. + set leg7 to leg + 7. + + // Calculation of transversality condition and corresponding partial with respect to initial costate and switching times + local r2 is xf[0]*xf[0] + xf[1]*xf[1] + xf[2]*xf[2]. + local rs is xf[0]*qf[0] + xf[1]*qf[1] + xf[2]*qf[2]. + local c3 is -uk / (r2 * sqrt(r2)). + local c4 is -3.0 * c3 * rs / r2. + set e[leg5][l7] to xf[3]*qf[3]+xf[4]*qf[4]+xf[5]*qf[5] - c3*rs - e[leg5][l7]. + set dummy to list(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0). + for i in range(3) { + set dummy[i] to -c3*qf[i]-c4*xf[i]. + set dummy[i+3] to qf[i+3]. + set dummy[i+6] to - c3 * xf[i]. + set dummy[i+9] to xf[i+3]. + } + for j in range(leg7) { + for k in range(12) { + set e[leg5][j] to -dummy[k]*z[k][j] + e[leg5][j]. + } + } + for j in range(leg7) { + set e[leg5][j] to -e[leg5][j]. + } + set e[leg5][leg5] to 0.0. + + set x0 to xf. + set q0 to qf. + set xf to list(0.0, 0.0, 0.0, 0.0, 0.0, 0.0). + set qf to list(0.0, 0.0, 0.0, 0.0, 0.0, 0.0). + } + // burn + set leg to leg + 1. + set leg5 to leg + 5. + set leg6 to leg + 6. + set leg7 to leg + 7. + set prev_burn to burn. + } + // When we have convergeence, break + } +} + +local function coast { + parameter x0, q0, xf, qf, phi, dphi, uk, t, no. + local jump is false. + local rm0 is sqrt(x0[0]*x0[0] + x0[1]*x0[1] + x0[2]*x0[2]). + local drm0 is (x0[0]*q0[0] + x0[1]*q0[1] + x0[2]*q0[2])/rm0. + local sig0 is x0[0]*x0[3] + x0[1]*x0[4] + x0[2]*q0[5]. + local dsig0 is x0[3]*q0[0] + x0[4]*q0[1] + x0[5]*q0[2] + x0[0]*q0[3] + x0[1]*q0[4] + x0[2]*q0[5]. + local alpha is x0[3]*x0[3] + x0[4]*x0[4] + x0[5]*x0[5] - 2.0 * uk / rm0. + local h0 is list( + x0[1]*x0[5] - x0[2]*x0[4], + x0[2]*x0[3] - x0[0]*x0[5], + x0[0]*x0[4] - x0[1]*x0[3] + ). + local p0 is (h0[0]*h0[0] + h0[1]*h0[1] + h0[2]*h0[2])/uk. + local psy is t/p0. + local alpsq is sqrt(-alpha). // This probably blows up for non-eliptical orbits? + local s0 is 0.0. + local s1 is 0.0. + local s2 is 0.0. + local s3 is 0.0. + local ft is t. + local rm is rm0. + until false { + local alpsy is psy * alpsq. + set s0 to cos(alpsy*CONSTANT:RadTodeg). + set s1 to sin(alpsy*CONSTANT:RadToDeg)/alpsq. + set s2 to (s0 - 1.0) / alpha. + set s3 to (s1 - psy) / alpha. + set ft to rm0 * s1 + sig0 * s2 + uk * s3. + set rm to rm0*s0 + sig0*s1 + uk*s2. + if jump { + break. + } + set psy to psy + (t-ft) / rm. + + if abs(t-ft) < abs(t) * 0.00001 { + set jump to true. + } + } + print psy. + print alpha. + print ft. + local fm1 is -uk * s2 / rm0. + local f is 1.0 + fm1. + local fd is -uk * s1 / (rm * rm0). + local g is ft - uk * s3. + local gdm1 is -uk * s2 / rm. + local gd is 1.0 + gdm1. + local ukr3 is uk / (rm * rm * rm). + local ukr03 is uk / (rm0 * rm0 * rm0). + local dalph is 2.0 * (x0[3]*q0[3] + x0[4]*q0[4] + x0[5]*q0[5] + ukr03 * (x0[0]*q0[0] + x0[1]*q0[1] + x0[2]*q0[2])). + local dapa is dalph/alpha. + local dapa2 is dapa/alpha. + local dpsy is -(drm0*s1 + dsig0*s2 + rm0*(psy*s0-s1)*dapa*0.5 + sig0*(psy*s1*0.5 - s2)*dapa + uk*(psy - 1.5*s1 + psy*s0*0.5)*dapa2)/rm. + local ds0 is (alpha*dpsy + 0.5*psy*dalph)*s1. + local ds1 is s0*dpsy + (psy*s0 - s1)*dapa*0.5. + local ds2 is s1*dpsy + (0.5*psy*s1 - s2)*dapa. + local ds3 is s2*dpsy + (psy - 1.5*s1 + 0.5*psy*s0)*dapa2. + local s4 is (s2 - psy*psy*0.5)/alpha. + local ds4 is s3*dpsy + (psy*psy*0.5 - 2.0*s2 + 0.5*psy*s1)*dapa2. + local s5 is (s3 - psy*psy*psy/6.0)/alpha. + local ds5 is s4*dpsy+(psy*psy*psy/6.0 + (2.0*psy - 2.5*s1 + 0.5*psy*20)/alpha)*dapa2. + local u is s2*ft + uk*(psy*s4 - 3.0*s5). + local du is ds2*ft + uk*(dpsy*s4 + psy*ds4 - 3.0*ds5). + local drm is 20*drm0 + ds0*rm0 + s1*dsig0 + ds1*sig0 + uk*ds2. + local df is (-uk*ds2 - fm1*drm0)/rm0. + local dg is -uk*ds3. + local dgd is (-uk*ds2 - gdm1*drm)/rm. + local r01 is rm0*rm. + local dr01 is rm*drm0 + drm*rm0. + local dfd is (-uk*ds1 - fd*dr01)/r01. + for i in range(3) { + set xf[i] to x0[i]*f + x0[i+3]*g. + set xf[i+3] to x0[i]*fd + x0[i+3]*gd. + set qf[i] to x0[i]*df + x0[i+3]*dg + q0[i]*f + q0[i+3]*g. + set qf[i+3] to x0[i]*dfd + x0[i+3]*dgd + q0[i]*fd + q0[i+3]*gd.. + } + + if no = false { + return. + } + // calculation of partials +} + +local function test_coast { + local x0 is list(4551.3085900, 4719.8398400, 25.0576324, 5.5990610, -5.4170895, -0.0118389). + local q0 is list(0.4601788, -0.8868545, 0.0415273, -0.0004394, -0.0010504, -0.0004081). + local uk is 398601.5. + local xf is list(0.0, 0.0, 0.0, 0.0, 0.0, 0.0). + local qf is list(0.0, 0.0, 0.0, 0.0, 0.0, 0.0). + local t is 2047.6868 - 934. + coast(x0, q0, xf, qf, list(), list(), uk, t, false). + print xf. + print qf. +} + +test_coast(). \ No newline at end of file diff --git a/notes.md b/notes.md new file mode 100644 index 0000000..442c7d6 --- /dev/null +++ b/notes.md @@ -0,0 +1,35 @@ +Altitude | dV | Lead Angle | Offset | Status +----------------------------------------------------------- + +Day 0: +391037637 | 3068.9 | 1.50 | 7000000 | Miss +391037637 | 3068.9 | 1.33 | 7000000 | Glancing impact +391037637 | 3068.9 | 1.33 | 6500000 | Glancing impact +391037637 | 3068.9 | 1.25 | 7000000 | Overcorrected impact +391037637 | 3068.9 | 1.25 | 7500000 | Glancing, but better +391037637 | 3068.9 | 1.10 | 7500000 | Overcorrected impact +391037637 | 3068.9 | 1.10 | 8000000 | Clean impact, slightly overcorrected + +Day 4: +399817493 | 3065.4 | 1.10 | 8000000 | Clean impact, slightly overcorrected + +Day 8: +393926503 | 3065.3 | 1.10 | 8000000 | Glancing, maybe burned too early? + +Day 12: +373127715 | 3045.4 | 1.10 | 8000000 | Glancing, maybe burned too early? + +Day 16: +354660048 | 3041.3 | 1.10 | 8000000 | Miss + | 1.50 | 8000000 | Glancing impact + | 1.75 | 8000000 | Clean impact + +Day 20: +361419747 | 3048.6 | 1.10 | 8000000 | Clean impact + +Day 24: + +Day 28: + +LUNAR_AP -> LUNAR_PE +1.10 -> 1.75 \ No newline at end of file diff --git a/todo.md b/todo.md new file mode 100644 index 0000000..deefe2b --- /dev/null +++ b/todo.md @@ -0,0 +1,16 @@ +# Next Session +* Write new ascent guidance program for Gemini & future +* Design and fly a seat-of-our-pants lunar lander + +# Overall Plan +* Lunar lander +* First lunar orbiter/mapper once science unlocks + * Get as much moon science as possible + * Also lots of science in earth orbit here? +* Gemini + +# Optional science stuff +* Get an orbital perturbation probe up just so we have it + * Maybe another lunar probe with orbital perturbation as well? +* Bio capsule in space high +* New experiments when they unlock? \ No newline at end of file