Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add moon rotation #511

Merged
merged 14 commits into from
Oct 12, 2023
18 changes: 14 additions & 4 deletions data/sample/initialize_files/sample_simulation_base.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
19 changes: 11 additions & 8 deletions src/disturbances/lunar_gravity_field.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -87,25 +87,28 @@ 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<double>(std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() / 1000.0);
#else
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 {
Expand Down
1 change: 1 addition & 0 deletions src/environment/global/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
)

Expand Down
17 changes: 10 additions & 7 deletions src/environment/global/celestial_information.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string> 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];
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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<std::string> 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);
Expand Down
57 changes: 54 additions & 3 deletions src/environment/global/celestial_information.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@
#ifndef S2E_ENVIRONMENT_GLOBAL_CELESTIAL_INFORMATION_HPP_
#define S2E_ENVIRONMENT_GLOBAL_CELESTIAL_INFORMATION_HPP_

#include <vector>

#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
Expand All @@ -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<std::string> rotation_mode_list);
/**
* @fn CelestialInformation
* @brief Copy constructor
Expand Down Expand Up @@ -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
Expand All @@ -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
/**
Expand Down Expand Up @@ -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
/**
Expand Down Expand Up @@ -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<std::string> rotation_mode_list_; //!< Rotation mode list for planets

/**
* @fn GetPlanetOrbit
Expand All @@ -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];
}
};

/**
Expand Down
6 changes: 3 additions & 3 deletions src/environment/global/earth_rotation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
53 changes: 53 additions & 0 deletions src/environment/global/moon_rotation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* @file moon_rotation.cpp
* @brief Class to calculate the moon rotation
*/

#include "moon_rotation.hpp"

#include <SpiceUsr.h>

#include <library/math/constants.hpp>
#include <library/planet_rotation/moon_rotation_utilities.hpp>

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;
}
65 changes: 65 additions & 0 deletions src/environment/global/moon_rotation.hpp
Original file line number Diff line number Diff line change
@@ -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_
2 changes: 2 additions & 0 deletions src/library/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading