Program Listing for File state_converter.cc¶
↰ Return to documentation for file (conversions/state_converter.cc)
#include "lupnt/conversions/state_converter.h"
#include <functional>
#include <map>
#include <vector>
#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::pair<StateType, StateType>, std::function<State(const State&, Real)>>
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::pair<StateType, StateType>, std::function<State(const State&, const State&)>>
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<StateType> 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