diff --git a/data/sample/initialize_files/sample_simulation_base.ini b/data/sample/initialize_files/sample_simulation_base.ini index 0b9cbde89..d0b4f7ce5 100644 --- a/data/sample/initialize_files/sample_simulation_base.ini +++ b/data/sample/initialize_files/sample_simulation_base.ini @@ -85,10 +85,6 @@ inertial_frame = J2000 center_object = EARTH aberration_correction = NONE -// Earth Rotation model -// Idle:no motion, Simple:Z-axis rotation only, Full:full-dynamics -earth_rotation_mode = Simple - // Definition of calculation celestial bodies number_of_selected_body = 3 selected_body_name(0) = EARTH @@ -103,6 +99,20 @@ selected_body_name(8) = URANUS selected_body_name(9) = NEPTUNE selected_body_name(10) = PLUTO +// Celestial rotation mode +// Currently, s2e-core supports Earth and Moon only +rotation_mode(0) = FULL // EARTH IDLE:no motion, SIMPLE:Z-axis rotation only, FULL:full-dynamics +rotation_mode(1) = DISABLE +rotation_mode(2) = SIMPLE // MOON IDLE:no motion, SIMPLE:Mean Earth and Principal Axis, IAU_MOON: IAU_MOON frame by SPICE +rotation_mode(3) = DISABLE +rotation_mode(4) = DISABLE +rotation_mode(5) = DISABLE +rotation_mode(6) = DISABLE +rotation_mode(7) = DISABLE +rotation_mode(8) = DISABLE +rotation_mode(9) = DISABLE +rotation_mode(10) = DISABLE + [CSPICE_KERNELS] // CSPICE Kernel files definition tls = EXT_LIB_DIR_FROM_EXE/cspice/generic_kernels/lsk/naif0010.tls diff --git a/src/disturbances/lunar_gravity_field.cpp b/src/disturbances/lunar_gravity_field.cpp index 335a0db3c..26adc70ad 100644 --- a/src/disturbances/lunar_gravity_field.cpp +++ b/src/disturbances/lunar_gravity_field.cpp @@ -15,7 +15,7 @@ #include "../library/logger/log_utility.hpp" #include "../library/utilities/macros.hpp" -#define DEBUG_LUNAR_GRAVITY_FIELD +// #define DEBUG_LUNAR_GRAVITY_FIELD LunarGravityField::LunarGravityField(const int degree, const std::string file_path, const bool is_calculation_enabled) : Disturbance(is_calculation_enabled, false), degree_(degree) { @@ -87,14 +87,19 @@ bool LunarGravityField::ReadCoefficientsGrgm1200a(std::string file_name) { } void LunarGravityField::Update(const LocalEnvironment &local_environment, const Dynamics &dynamics) { - libra::Vector<3> position_mcmf_m = dynamics.GetOrbit().GetPosition_ecef_m(); + const CelestialInformation global_celestial_information = local_environment.GetCelestialInformation().GetGlobalInformation(); + libra::Matrix<3, 3> dcm_mci2mcmf_ = global_celestial_information.GetMoonRotation().GetDcmJ2000ToMcmf(); + + libra::Vector<3> spacecraft_position_mci_m = dynamics.GetOrbit().GetPosition_i_m(); + libra::Vector<3> spacecraft_position_mcmf_m = dcm_mci2mcmf_ * spacecraft_position_mci_m; + #ifdef DEBUG_LUNAR_GRAVITY_FIELD std::chrono::system_clock::time_point start, end; start = std::chrono::system_clock::now(); - position_mcmf_m = debug_pos_mcmf_m_; + spacecraft_position_mcmf_m = debug_pos_mcmf_m_; #endif - acceleration_mcmf_m_s2_ = lunar_potential_.CalcAcceleration_xcxf_m_s2(position_mcmf_m); + acceleration_mcmf_m_s2_ = lunar_potential_.CalcAcceleration_xcxf_m_s2(spacecraft_position_mcmf_m); #ifdef DEBUG_LUNAR_GRAVITY_FIELD end = std::chrono::system_clock::now(); time_ms_ = static_cast(std::chrono::duration_cast(end - start).count() / 1000.0); @@ -102,10 +107,8 @@ void LunarGravityField::Update(const LocalEnvironment &local_environment, const UNUSED(time_ms_); #endif - libra::Matrix<3, 3> trans_eci2mcmf_ = - local_environment.GetCelestialInformation().GetGlobalInformation().GetEarthRotation().GetDcmJ2000ToEcef(); // FIXME: use moon rotation - libra::Matrix<3, 3> trans_mcmf2eci = trans_eci2mcmf_.Transpose(); - acceleration_i_m_s2_ = trans_mcmf2eci * acceleration_mcmf_m_s2_; + libra::Matrix<3, 3> dcm_mcmf2i = dcm_mci2mcmf_.Transpose(); + acceleration_i_m_s2_ = dcm_mcmf2i * acceleration_mcmf_m_s2_; } std::string LunarGravityField::GetLogHeader() const { diff --git a/src/environment/global/CMakeLists.txt b/src/environment/global/CMakeLists.txt index c1f297bf6..bc64cef0e 100644 --- a/src/environment/global/CMakeLists.txt +++ b/src/environment/global/CMakeLists.txt @@ -9,6 +9,7 @@ add_library(${PROJECT_NAME} STATIC simulation_time.cpp clock_generator.cpp earth_rotation.cpp + moon_rotation.cpp initialize_gnss_satellites.cpp ) diff --git a/src/environment/global/celestial_information.cpp b/src/environment/global/celestial_information.cpp index 2554023d7..9e7a2c71a 100644 --- a/src/environment/global/celestial_information.cpp +++ b/src/environment/global/celestial_information.cpp @@ -19,13 +19,14 @@ #include "library/logger/log_utility.hpp" CelestialInformation::CelestialInformation(const std::string inertial_frame_name, const std::string aberration_correction_setting, - const std::string center_body_name, const EarthRotationMode earth_rotation_mode, - const unsigned int number_of_selected_body, int* selected_body_ids) + const std::string center_body_name, const unsigned int number_of_selected_body, int* selected_body_ids, + const std::vector rotation_mode_list) : number_of_selected_bodies_(number_of_selected_body), selected_body_ids_(selected_body_ids), inertial_frame_name_(inertial_frame_name), center_body_name_(center_body_name), - aberration_correction_setting_(aberration_correction_setting) { + aberration_correction_setting_(aberration_correction_setting), + rotation_mode_list_(rotation_mode_list) { // Initialize list unsigned int num_of_state = number_of_selected_bodies_ * 3; celestial_body_position_from_center_i_m_ = new double[num_of_state]; @@ -63,7 +64,8 @@ CelestialInformation::CelestialInformation(const std::string inertial_frame_name } // Initialize rotation - earth_rotation_ = new EarthRotation(earth_rotation_mode); + earth_rotation_ = new EarthRotation(ConvertEarthRotationMode(GetRotationMode("EARTH"))); + moon_rotation_ = new MoonRotation(*this, ConvertMoonRotationMode(GetRotationMode("MOON"))); } CelestialInformation::CelestialInformation(const CelestialInformation& obj) @@ -124,6 +126,8 @@ void CelestialInformation::UpdateAllObjectsInformation(const SimulationTime& sim // Update earth rotation earth_rotation_->Update(simulation_time.GetCurrentTime_jd()); + // Update moon rotation + moon_rotation_->Update(simulation_time); } int CelestialInformation::CalcBodyIdFromName(const char* body_name) const { @@ -230,11 +234,10 @@ CelestialInformation* InitCelestialInformation(std::string file_name) { } // Read Rotation setting - std::string rotation_mode_string = ini_file.ReadString(section, "earth_rotation_mode"); - EarthRotationMode rotation_mode = ConvertEarthRotationMode(rotation_mode_string); + std::vector rotation_mode_list = ini_file.ReadVectorString(section, "rotation_mode", num_of_selected_body); CelestialInformation* celestial_info; - celestial_info = new CelestialInformation(inertial_frame, aber_cor, center_obj, rotation_mode, num_of_selected_body, selected_body); + celestial_info = new CelestialInformation(inertial_frame, aber_cor, center_obj, num_of_selected_body, selected_body, rotation_mode_list); // log setting celestial_info->is_log_enabled_ = ini_file.ReadEnable(section, INI_LOG_LABEL); diff --git a/src/environment/global/celestial_information.hpp b/src/environment/global/celestial_information.hpp index 7436db97c..7c4afa854 100644 --- a/src/environment/global/celestial_information.hpp +++ b/src/environment/global/celestial_information.hpp @@ -7,11 +7,16 @@ #ifndef S2E_ENVIRONMENT_GLOBAL_CELESTIAL_INFORMATION_HPP_ #define S2E_ENVIRONMENT_GLOBAL_CELESTIAL_INFORMATION_HPP_ +#include + #include "earth_rotation.hpp" #include "library/logger/loggable.hpp" #include "library/math/vector.hpp" +#include "moon_rotation.hpp" #include "simulation_time.hpp" +class MoonRotation; + /** * @class CelestialInformation * @brief Class to manage the information related with the celestial bodies @@ -25,12 +30,12 @@ class CelestialInformation : public ILoggable { * @param [in] inertial_frame_name: Definition of inertial frame * @param [in] aberration_correction_setting: Stellar aberration correction * @param [in] center_body_name: Center body name of inertial frame - * @param [in] earth_rotation_mode: Designation of rotation model * @param [in] number_of_selected_body: Number of selected body * @param [in] selected_body_ids: SPICE IDs of selected bodies + * @param [in] rotation_mode_list: Rotation mode list for planets */ CelestialInformation(const std::string inertial_frame_name, const std::string aberration_correction_setting, const std::string center_body_name, - const EarthRotationMode earth_rotation_mode, const unsigned int number_of_selected_body, int* selected_body_ids); + const unsigned int number_of_selected_body, int* selected_body_ids, const std::vector rotation_mode_list); /** * @fn CelestialInformation * @brief Copy constructor @@ -83,6 +88,20 @@ class CelestialInformation : public ILoggable { int id = CalcBodyIdFromName(body_name); return GetPositionFromCenter_i_m(id); } + /** + * @fn GetPositionFromSelectedBody_i_m + * @brief Return position from the selected reference body in the inertial frame [m] + * @param [in] target_body_name: Name of the target body defined in the SPICE + * @param [in] reference_body_name: Name of the reference body defined in the SPICE + */ + inline libra::Vector<3> GetPositionFromSelectedBody_i_m(const char* target_body_name, const char* reference_body_name) const { + int target_id = CalcBodyIdFromName(target_body_name); + libra::Vector<3> target_body_position_i_m = GetPositionFromCenter_i_m(target_id); + int reference_id = CalcBodyIdFromName(reference_body_name); + libra::Vector<3> reference_body_position_i_m = GetPositionFromCenter_i_m(reference_id); + + return target_body_position_i_m - reference_body_position_i_m; + } /** * @fn GetVelocityFromCenter_i_m_s @@ -104,6 +123,20 @@ class CelestialInformation : public ILoggable { int id = CalcBodyIdFromName(body_name); return GetVelocityFromCenter_i_m_s(id); } + /** + * @fn GetVelocityFromSelectedBody_i_m_s + * @brief Return position from the selected reference body in the inertial frame [m] + * @param [in] target_body_name: Name of the target body defined in the SPICE + * @param [in] reference_body_name: Name of the reference body defined in the SPICE + */ + inline libra::Vector<3> GetVelocityFromSelectedBody_i_m_s(const char* target_body_name, const char* reference_body_name) const { + int target_id = CalcBodyIdFromName(target_body_name); + libra::Vector<3> target_body_velocity_i_m_s = GetVelocityFromCenter_i_m_s(target_id); + int reference_id = CalcBodyIdFromName(reference_body_name); + libra::Vector<3> reference_body_velocity_i_m_s = GetVelocityFromCenter_i_m_s(reference_id); + + return target_body_velocity_i_m_s - reference_body_velocity_i_m_s; + } // Gravity constants /** @@ -175,6 +208,11 @@ class CelestialInformation : public ILoggable { * @brief Return EarthRotation information */ inline EarthRotation GetEarthRotation(void) const { return *earth_rotation_; }; + /** + * @fn GetMoonRotation + * @brief Return MoonRotation information + */ + inline MoonRotation& GetMoonRotation(void) const { return *moon_rotation_; }; // Calculation /** @@ -210,7 +248,9 @@ class CelestialInformation : public ILoggable { // Y-axis equal to the cross product of the unit Z-axis and X-axis vectors // Rotational Motion of each planets - EarthRotation* earth_rotation_; //!< Instance of Earth rotation + EarthRotation* earth_rotation_; //!< Instance of Earth rotation + MoonRotation* moon_rotation_; //!< Instance of Moon rotation + std::vector rotation_mode_list_; //!< Rotation mode list for planets /** * @fn GetPlanetOrbit @@ -221,6 +261,17 @@ class CelestialInformation : public ILoggable { * @param [out] orbit: Cartesian state vector representing the position and velocity of the target body relative to the specified observer. */ void GetPlanetOrbit(const char* planet_name, const double et, double orbit[6]); + + /** + * @fn GetRotationMode + * @brief Return rotation mode + * @param [in] body_name: Name of the body defined in the SPICE + */ + inline std::string GetRotationMode(const char* body_name) const { + size_t id = CalcBodyIdFromName(body_name); + if (id >= number_of_selected_bodies_) return "Idle"; + return rotation_mode_list_[id]; + } }; /** diff --git a/src/environment/global/earth_rotation.cpp b/src/environment/global/earth_rotation.cpp index cb25d6bfd..2f8218dde 100644 --- a/src/environment/global/earth_rotation.cpp +++ b/src/environment/global/earth_rotation.cpp @@ -262,11 +262,11 @@ libra::Matrix<3, 3> EarthRotation::PolarMotion(const double x_p, const double y_ EarthRotationMode ConvertEarthRotationMode(const std::string mode) { EarthRotationMode rotation_mode; - if (mode == "Idle") { + if (mode == "IDLE") { rotation_mode = EarthRotationMode::kIdle; - } else if (mode == "Simple") { + } else if (mode == "SIMPLE") { rotation_mode = EarthRotationMode::kSimple; - } else if (mode == "Full") { + } else if (mode == "FULL") { rotation_mode = EarthRotationMode::kFull; } else // if rotation_mode is neither Idle, Simple, nor Full, set rotation_mode to Idle { diff --git a/src/environment/global/moon_rotation.cpp b/src/environment/global/moon_rotation.cpp new file mode 100644 index 000000000..75ede8b33 --- /dev/null +++ b/src/environment/global/moon_rotation.cpp @@ -0,0 +1,53 @@ +/** + * @file moon_rotation.cpp + * @brief Class to calculate the moon rotation + */ + +#include "moon_rotation.hpp" + +#include + +#include +#include + +MoonRotation::MoonRotation(const CelestialInformation& celestial_information, MoonRotationMode mode) + : mode_(mode), celestial_information_(celestial_information) { + dcm_j2000_to_mcmf_ = libra::MakeIdentityMatrix<3>(); +} + +void MoonRotation::Update(const SimulationTime& simulation_time) { + if (mode_ == MoonRotationMode::kSimple) { + libra::Vector<3> moon_position_eci_m = celestial_information_.GetPositionFromSelectedBody_i_m("MOON", "EARTH"); + libra::Vector<3> moon_velocity_eci_m_s = celestial_information_.GetVelocityFromSelectedBody_i_m_s("MOON", "EARTH"); + dcm_j2000_to_mcmf_ = CalcDcmEciToPrincipalAxis(moon_position_eci_m, moon_velocity_eci_m_s); + } else if (mode_ == MoonRotationMode::kIauMoon) { + ConstSpiceChar from[] = "J2000"; + ConstSpiceChar to[] = "IAU_MOON"; + SpiceDouble et = simulation_time.GetCurrentEphemerisTime(); + SpiceDouble state_transition_matrix[6][6]; + sxform_c(from, to, et, state_transition_matrix); + for (size_t i = 0; i < 3; i++) { + for (size_t j = 0; j < 3; j++) { + dcm_j2000_to_mcmf_[i][j] = state_transition_matrix[i][j]; + } + } + } else { + dcm_j2000_to_mcmf_ = libra::MakeIdentityMatrix<3>(); + } +} + +MoonRotationMode ConvertMoonRotationMode(const std::string mode) { + MoonRotationMode rotation_mode; + if (mode == "IDLE") { + rotation_mode = MoonRotationMode::kIdle; + } else if (mode == "SIMPLE") { + rotation_mode = MoonRotationMode::kSimple; + } else if (mode == "IAU_MOON") { + rotation_mode = MoonRotationMode::kIauMoon; + } else // if rotation_mode is neither Idle, Simple, nor Full, set rotation_mode to Idle + { + rotation_mode = MoonRotationMode::kIdle; + } + + return rotation_mode; +} \ No newline at end of file diff --git a/src/environment/global/moon_rotation.hpp b/src/environment/global/moon_rotation.hpp new file mode 100644 index 000000000..74d8eb64e --- /dev/null +++ b/src/environment/global/moon_rotation.hpp @@ -0,0 +1,65 @@ +/** + * @file moon_rotation.hpp + * @brief Class to calculate the moon rotation + */ + +#ifndef S2E_ENVIRONMENT_GLOBAL_MOON_ROTATION_HPP_ +#define S2E_ENVIRONMENT_GLOBAL_MOON_ROTATION_HPP_ + +#include "celestial_information.hpp" +#include "library/math/matrix.hpp" +#include "library/math/vector.hpp" +#include "simulation_time.hpp" + +class CelestialInformation; + +/** + * @enum MoonRotationMode + * @brief Definition of calculation mode of moon rotation + */ +enum class MoonRotationMode { + kIdle, //!< No rotation + kSimple, //!< Mean Earth and Principal Axis calculation + kIauMoon, //!< IAU_MOON frame given by SPICE +}; +/** + * @fn ConvertMoonRotationMode + * @brief Convert string to MoonRotationMode + * @param[in] mode: mode name in string + */ +MoonRotationMode ConvertMoonRotationMode(const std::string mode); + +/** + * @class MoonRotation + * @brief Class to calculate the moon rotation + */ +class MoonRotation { + public: + /** + * @fn MoonRotation + * @brief Constructor + */ + MoonRotation(const CelestialInformation &celestial_information, MoonRotationMode mode = MoonRotationMode::kIdle); + + /** + * @fn Update + * @brief Update rotation + * @param [in] simulation_time: simulation_time + */ + void Update(const SimulationTime &simulation_time); + + /** + * @fn GetDcmJ2000ToMcmf + * @brief Return the DCM between J2000 inertial frame and the Moon Centered Moon Fixed frame + * @note Because this is just a DCM, users need to consider the origin of the vector, which you want to convert with this matrix. + */ + inline const libra::Matrix<3, 3> GetDcmJ2000ToMcmf() const { return dcm_j2000_to_mcmf_; }; + + private: + MoonRotationMode mode_; //!< Rotation mode + libra::Matrix<3, 3> dcm_j2000_to_mcmf_; //!< Direction Cosine Matrix J2000 to MCMF (Moon Centered Moon Fixed) + + const CelestialInformation &celestial_information_; //!< Celestial Information to get moon orbit +}; + +#endif // S2E_ENVIRONMENT_GLOBAL_MOON_ROTATION_HPP_ diff --git a/src/library/CMakeLists.txt b/src/library/CMakeLists.txt index b8ac55f89..4b495bb0f 100644 --- a/src/library/CMakeLists.txt +++ b/src/library/CMakeLists.txt @@ -31,6 +31,8 @@ add_library(${PROJECT_NAME} STATIC orbit/kepler_orbit.cpp orbit/relative_orbit_models.cpp + planet_rotation/moon_rotation_utilities.cpp + external/igrf/igrf.cpp external/inih/ini.c external/inih/cpp/INIReader.cpp diff --git a/src/library/initialize/initialize_file_access.cpp b/src/library/initialize/initialize_file_access.cpp index 0bc8dc24f..82d555ea5 100644 --- a/src/library/initialize/initialize_file_access.cpp +++ b/src/library/initialize/initialize_file_access.cpp @@ -174,6 +174,16 @@ std::string IniAccess::ReadString(const char* section_name, const char* key_name return value; } +std::vector IniAccess::ReadVectorString(const char* section_name, const char* key_name, const size_t num) { + std::vector data; + for (size_t i = 0; i < num; i++) { + std::stringstream edited_key_name; + edited_key_name << key_name << "(" << i << ")"; + data.push_back(ReadString(section_name, edited_key_name.str().c_str())); + } + return data; +} + bool IniAccess::ReadEnable(const char* section_name, const char* key_name) { std::string enable_string = ReadString(section_name, key_name); if (enable_string.compare("ENABLE") == 0) return true; diff --git a/src/library/initialize/initialize_file_access.hpp b/src/library/initialize/initialize_file_access.hpp index 1d1025fc4..3d537b2ee 100644 --- a/src/library/initialize/initialize_file_access.hpp +++ b/src/library/initialize/initialize_file_access.hpp @@ -144,6 +144,15 @@ class IniAccess { * @return Read string data */ std::string ReadString(const char* section_name, const char* key_name); + /** + * @fn ReadVectorString + * @brief Read a vector number as string type + * @param[in] section_name: Section name + * @param[in] key_name: Key name + * @param[in] num: Number of elements of the array + * @return Read data + */ + std::vector ReadVectorString(const char* section_name, const char* key_name, const size_t num); /** * @fn ReadEnable diff --git a/src/library/planet_rotation/moon_rotation_utilities.cpp b/src/library/planet_rotation/moon_rotation_utilities.cpp new file mode 100644 index 000000000..d3d339ee7 --- /dev/null +++ b/src/library/planet_rotation/moon_rotation_utilities.cpp @@ -0,0 +1,47 @@ +/** + * @file moon_rotation_utilities.cpp + * @brief Functions to calculate the moon rotation frame conversion + * @note Ref: A Standardized Lunar Coordinate System for the Lunar Reconnaissance Orbiter and Lunar Datasets + * https://lunar.gsfc.nasa.gov/library/LunCoordWhitePaper-10-08.pdf + * https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/de430_moon_coord.pdf + */ + +#include "moon_rotation_utilities.hpp" + +#include + +libra::Matrix<3, 3> CalcDcmEciToPrincipalAxis(const libra::Vector<3> moon_position_eci_m, const libra::Vector<3> moon_velocity_eci_m_s) { + libra::Matrix<3, 3> dcm_eci2me = CalcDcmEciToMeanEarth(moon_position_eci_m, moon_velocity_eci_m_s); + libra::Matrix<3, 3> dcm_me2pa = CalcDcmMeanEarthToPrincipalAxis(); + + return dcm_me2pa * dcm_eci2me; +} + +libra::Matrix<3, 3> CalcDcmEciToMeanEarth(const libra::Vector<3> moon_position_eci_m, const libra::Vector<3> moon_velocity_eci_m_s) { + libra::Vector<3> me_ex_eci = -1.0 * moon_position_eci_m.CalcNormalizedVector(); + + libra::Vector<3> moon_orbit_norm = libra::OuterProduct(moon_position_eci_m, moon_velocity_eci_m_s); + libra::Vector<3> me_ez_eci = moon_orbit_norm.CalcNormalizedVector(); + + libra::Vector<3> me_ey_eci = libra::OuterProduct(me_ez_eci, me_ex_eci); + + libra::Matrix<3, 3> dcm_eci_to_me; + for (size_t i = 0; i < 3; i++) { + dcm_eci_to_me[0][i] = me_ex_eci[i]; + dcm_eci_to_me[1][i] = me_ey_eci[i]; + dcm_eci_to_me[2][i] = me_ez_eci[i]; + } + + return dcm_eci_to_me; +} + +libra::Matrix<3, 3> CalcDcmMeanEarthToPrincipalAxis() { + const double theta_x_rad = 0.285 * libra::arcsec_to_rad; + const double theta_y_rad = 78.580 * libra::arcsec_to_rad; + const double theta_z_rad = 67.573 * libra::arcsec_to_rad; + + libra::Matrix<3, 3> dcm_me_pa = + libra::MakeRotationMatrixZ(theta_z_rad) * libra::MakeRotationMatrixY(theta_y_rad) * libra::MakeRotationMatrixX(theta_x_rad); + + return dcm_me_pa; +} diff --git a/src/library/planet_rotation/moon_rotation_utilities.hpp b/src/library/planet_rotation/moon_rotation_utilities.hpp new file mode 100644 index 000000000..08e208704 --- /dev/null +++ b/src/library/planet_rotation/moon_rotation_utilities.hpp @@ -0,0 +1,37 @@ +/** + * @file moon_rotation_utilities.hpp + * @brief Functions to calculate the moon rotation frame conversion + * @note Ref: A Standardized Lunar Coordinate System for the Lunar Reconnaissance Orbiter and Lunar Datasets + * https://lunar.gsfc.nasa.gov/library/LunCoordWhitePaper-10-08.pdf + * https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/de430_moon_coord.pdf + */ + +#ifndef S2E_LIBRARY_PLANET_ROTATION_MOON_MEAN_EARTH_PRINCIPAL_AXIS_FRAME_HPP_ +#define S2E_LIBRARY_PLANET_ROTATION_MOON_MEAN_EARTH_PRINCIPAL_AXIS_FRAME_HPP_ + +#include "library/math/matrix.hpp" +#include "library/math/vector.hpp" + +/** + * @fn CalcDcmEciToPrincipalAxis + * @brief Calculate DCM from ECI to PA (Principal Axis) moon fixed frame + * @param[in] moon_position_eci_m: Moon position vector @ ECI frame [m] + * @param[in] moon_velocity_eci_m_s: Moon velocity vector @ ECI frame [m/s] + */ +libra::Matrix<3, 3> CalcDcmEciToPrincipalAxis(const libra::Vector<3> moon_position_eci_m, const libra::Vector<3> moon_velocity_eci_m_s); + +/** + * @fn CalcDcmEciToMeanEarth + * @brief Calculate DCM from ECI to ME (Mean Earth) moon fixed frame + * @param[in] moon_position_eci_m: Moon position vector @ ECI frame [m] + * @param[in] moon_velocity_eci_m_s: Moon velocity vector @ ECI frame [m/s] + */ +libra::Matrix<3, 3> CalcDcmEciToMeanEarth(const libra::Vector<3> moon_position_eci_m, const libra::Vector<3> moon_velocity_eci_m_s); + +/** + * @fn CalcDcmMeToPrincipalAxis + * @brief Calculate DCM from ME (Mean Earth) moon fixed frame to PA (Principal Axis) moon fixed frame + */ +libra::Matrix<3, 3> CalcDcmMeanEarthToPrincipalAxis(); + +#endif // S2E_LIBRARY_PLANET_ROTATION_MOON_MEAN_EARTH_PRINCIPAL_AXIS_FRAME_HPP_