.. _program_listing_file_conversions_state_converter.cc: Program Listing for File state_converter.cc =========================================== |exhale_lsh| :ref:`Return to documentation for file ` (``conversions/state_converter.cc``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "lupnt/conversions/state_converter.h" #include #include #include #include "lupnt/conversions/state_conversions.h" #include "lupnt/environment/body.h" #include "lupnt/numerics/graphs.h" #include "lupnt/states/state.h" #define ABSOLUTE_CONVERSION(from, to, func) \ {{from, to}, [](const State& x, Real GM) -> State { return func(x, GM); }} #define RELATIVE_CONVERSION(from, to, func) \ {{from, to}, [](const State& x, const State& y) -> State { return func(x, y); }} namespace lupnt { std::map, std::function> absolute_conversions = { ABSOLUTE_CONVERSION(Cart6::TYPE, ClassicalOE::TYPE, CartToClassical), ABSOLUTE_CONVERSION(ClassicalOE::TYPE, Cart6::TYPE, ClassicalToCart), ABSOLUTE_CONVERSION(ClassicalOE::TYPE, QuasiNonsingularOE::TYPE, ClassicalToQuasiNonsing), ABSOLUTE_CONVERSION(ClassicalOE::TYPE, EquinoctialOE::TYPE, ClassicalToEquinoctial), ABSOLUTE_CONVERSION(ClassicalOE::TYPE, DelaunayOE::TYPE, ClassicalToDelaunay), ABSOLUTE_CONVERSION(QuasiNonsingularOE::TYPE, ClassicalOE::TYPE, QuasiNonsingToClassical), ABSOLUTE_CONVERSION(EquinoctialOE::TYPE, ClassicalOE::TYPE, EquinoctialToClassical), ABSOLUTE_CONVERSION(DelaunayOE::TYPE, ClassicalOE::TYPE, DelaunayToClassical), }; std::map, std::function> relative_conversions = { RELATIVE_CONVERSION(Cart6::TYPE, RelCart6::TYPE, InertialToSynodic), RELATIVE_CONVERSION(QuasiNonsingularOE::TYPE, ClassicalOE::TYPE, RelQuasiNonsingToClassical), }; State ConvertState(const State& x, StateType type_out) { if (x.GetType() == type_out) return x; return ConvertState(x, type_out, GetBodyGM(GetFrameCenter(x.GetFrame()))); } State ConvertState(Real t_tdb, const State& x, StateType type_out, Frame frame_out) { if (x.GetType() == type_out && x.GetFrame() == frame_out) return x; State state = ConvertState(x, type_out); return ConvertFrame(t_tdb, state, frame_out); } State ConvertState(const State& x, StateType type_out, Real GM) { if (x.GetType() == type_out) return x; std::vector path = FindShortestPath(x.GetType(), type_out, absolute_conversions); State state = x; for (size_t i = 0; i < path.size() - 1; i++) state = absolute_conversions[{path[i], path[i + 1]}](state, GM); return state; } bool IsAbsolute(const State& x) { StateType type = x.GetType(); if (type == RelCart6::TYPE || SingularROE::TYPE == type || type == QuasiNonsingROE::TYPE) return false; return true; } State ConvertState(const State& x, const State& y, StateType type_out, Real GM) { bool y_absolute = IsAbsolute(y); for (const auto& entry : relative_conversions) { const auto& [type_1, type_2] = entry.first; auto func = entry.second; if (y_absolute && type_2 == type_out) { auto x_abs = ConvertState(x, type_1, GM); auto y_abs = ConvertState(y, type_1, GM); return func(x_abs, y_abs); } else if (!y_absolute && type_1 == y.GetType()) { auto x_abs = ConvertState(x, type_2, GM); auto y_abs = func(x_abs, y); return ConvertState(y_abs, type_out, GM); } } LUPNT_CHECK(false, "Conversion not found for the given input.", "OrbitStateConverter"); } } // namespace lupnt