From 986574a73a9478ddf31f33afdd80f1c9f545abe9 Mon Sep 17 00:00:00 2001 From: cinnaboot Date: Wed, 27 Jul 2022 07:47:35 -0400 Subject: [PATCH] add circularize impulse types --- src/game.cpp | 25 +++++++++++++++++++------ src/game.h | 4 +++- src/main.cpp | 19 +++++++++++-------- src/orbits.cpp | 11 +++++++++++ src/orbits.h | 4 ++++ 5 files changed, 48 insertions(+), 15 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 6504f0e..5e7610d 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -139,7 +139,6 @@ getFreeManeuver(GameState* gs) return nullptr; } -// TODO: appendManeuver(orbit, node) would be better bool addManeuver(GameState* gs, GameOrbit* orbit, @@ -152,7 +151,10 @@ addManeuver(GameState* gs, return false; } - if (impulse_delta_v == 0.f) { + if (impulse_type != ImpulseType::CIRCULARIZE_RAISING + && impulse_type != ImpulseType::CIRCULARIZE_LOWERING + && impulse_delta_v == 0.f) + { LOGF(Warning, "refusing to add maneuver with 0 dv\n"); return false; } @@ -172,9 +174,12 @@ addManeuver(GameState* gs, node->impulse_type = impulse_type; // TODO: thrust calculations //double flight_path_angle = orbit->system.sat.gamma; - //node.impulse_vector.x = ... + //node->impulse_vector.x = ... - if (node->impulse_type == ImpulseType::PROGRADE) { + if (node->impulse_type == ImpulseType::PROGRADE + || node->impulse_type == ImpulseType::CIRCULARIZE_RAISING + || node->impulse_type == ImpulseType::CIRCULARIZE_LOWERING) + { node->true_anomaly = true_anomaly; node->impulse_delta_v = impulse_delta_v; node->active = true; @@ -222,8 +227,16 @@ applyManeuver(GameOrbit* orbit, ManeuverNode* maneuver) TwoBodySystem& sys = orbit->system; assert(maneuver); - // FIXME: assuming prograde impulse vector - assert(maneuver->impulse_type == ImpulseType::PROGRADE); + // TODO: other impulse types + assert(maneuver->impulse_type == ImpulseType::PROGRADE + || maneuver->impulse_type != ImpulseType::CIRCULARIZE_RAISING + || maneuver->impulse_type != ImpulseType::CIRCULARIZE_LOWERING); + + if (maneuver->impulse_type == ImpulseType::CIRCULARIZE_RAISING) { + maneuver->impulse_delta_v = orbitGetCircVelocity(orbit->system); + } else if (maneuver->impulse_type == ImpulseType::CIRCULARIZE_LOWERING) { + maneuver->impulse_delta_v = orbitGetCircVelocity(orbit->system, false); + } // re-calculate state vectors at the maneuver node double theta = maneuver->true_anomaly; diff --git a/src/game.h b/src/game.h index f4d80af..10102d1 100644 --- a/src/game.h +++ b/src/game.h @@ -27,6 +27,8 @@ enum struct ImpulseType NONE, PROGRADE, RETROGRADE, + CIRCULARIZE_RAISING, + CIRCULARIZE_LOWERING, INCLINATION_CHANGE, GENERAL_PLANE_CHANGE, OTHER, @@ -96,7 +98,7 @@ bool addManeuver(GameState* gs, GameOrbit* orbit, ImpulseType impulse_type, double true_anomaly, - double impulse_delta_v); + double impulse_delta_v = 0.f); bool testManeuverStep(ManeuverNode* maneuver, double previous_theta, diff --git a/src/main.cpp b/src/main.cpp index 34d1470..7020b1e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -251,19 +251,22 @@ loadScene(GameState* gs, RenderState* rs) gs->coord_overlay = addCoordinateOverlay(rs); OrbitalElements el1 = orbitInit(8000, 0, 0, 0, 0, DEG2RAD(-90)); - GameOrbit* go_1 = loadOrbit(gs, rs, body, el1, rg, "sat_01"); + loadOrbit(gs, rs, body, el1, rg, "sat_01"); + //GameOrbit* go_1 = loadOrbit(gs, rs, body, el1, rg, "sat_01"); OrbitalElements el2 = orbitInit(20000, 0, 0, 0, 0, 0); - loadOrbit(gs, rs, body, el2, rg, "sat_02"); - //GameOrbit* go_2 = loadOrbit(gs, rs, body, el2, rg, "sat_02"); + //loadOrbit(gs, rs, body, el2, rg, "sat_02"); + GameOrbit* go_2 = loadOrbit(gs, rs, body, el2, rg, "sat_02"); +#if 0 double v_transfer = orbitGetTransferVelocity(go_1->system, el2); addManeuver(gs, go_1, ImpulseType::PROGRADE, DEG2RAD(180), v_transfer); - // FIXME: can't get circularization here unless we simulate the transfer - // orbit ahead of time, eg) applyManeuver to a dummy orbit - // could also add a ImpulseType::CIRCULARIZE and calculate in - // applyManeuver() - addManeuver(gs, go_1, ImpulseType::PROGRADE, DEG2RAD(180), 0.500); + addManeuver(gs, go_1, ImpulseType::CIRCULARIZE_RAISING, DEG2RAD(180)); +#else + double v_transfer = orbitGetTransferVelocity(go_2->system, el1); + addManeuver(gs, go_2, ImpulseType::PROGRADE, DEG2RAD(180), v_transfer); + addManeuver(gs, go_2, ImpulseType::CIRCULARIZE_LOWERING, DEG2RAD(0)); +#endif return true; } diff --git a/src/orbits.cpp b/src/orbits.cpp index f2c70ea..465080c 100644 --- a/src/orbits.cpp +++ b/src/orbits.cpp @@ -343,6 +343,17 @@ orbitGetTransferVelocity(const TwoBodySystem& sys, return vt - v1; } +double +orbitGetCircVelocity(const TwoBodySystem& sys, bool raise_apoapse) +{ + double r = (raise_apoapse) ? sys.r_apoapsis : sys.r_periapsis; + double mu = sys.body.mu; + double epsilon_target = orbitGetSpecificEnergy(r, mu); + double v = orbitGetVelocity(epsilon_target, mu, r); + + return v - sys.sat.v; +} + // internal diff --git a/src/orbits.h b/src/orbits.h index bbea848..1fab44c 100644 --- a/src/orbits.h +++ b/src/orbits.h @@ -258,3 +258,7 @@ orbitGetTimeOfFlight(TwoBodySystem sys, double theta_begin, double theta_end); // NOTE return impulse magnitute for Hohmann transfer orbit double orbitGetTransferVelocity(const TwoBodySystem& sys, const OrbitalElements& target); + +// NOTE: return impulse magnitude for orbit circularization +double +orbitGetCircVelocity(const TwoBodySystem& sys, bool raise_apoapse = true);