/Tudat/Astrodynamics/Ephemerides/approximatePlanetPositions.cpp

https://github.com/Tudat/tudat · C++ · 161 lines · 96 code · 27 blank · 38 comment · 1 complexity · 128c0b80e8f44d30e9527b5f5c591ce4 MD5 · raw file

  1. /* Copyright (c) 2010-2019, Delft University of Technology
  2. * All rigths reserved
  3. *
  4. * This file is part of the Tudat. Redistribution and use in source and
  5. * binary forms, with or without modification, are permitted exclusively
  6. * under the terms of the Modified BSD license. You should have received
  7. * a copy of the license with this file. If not, please or visit:
  8. * http://tudat.tudelft.nl/LICENSE.
  9. *
  10. * References
  11. * Standish, E.M. Keplerian Elements for Approximate Positions of the Major Planets,
  12. * http://ssd.jpl.nasa.gov/txt/aprx_pos_planets.pdf, last accessed: 24 February, 2011.
  13. *
  14. */
  15. #include <cmath>
  16. #include "Tudat/Astrodynamics/BasicAstrodynamics/orbitalElementConversions.h"
  17. #include "Tudat/Astrodynamics/BasicAstrodynamics/unitConversions.h"
  18. #include "Tudat/Astrodynamics/BasicAstrodynamics/timeConversions.h"
  19. #include "Tudat/Astrodynamics/BasicAstrodynamics/stateVectorIndices.h"
  20. #include "Tudat/Astrodynamics/Ephemerides/approximatePlanetPositions.h"
  21. namespace tudat
  22. {
  23. namespace ephemerides
  24. {
  25. //! Get state from ephemeris.
  26. Eigen::Vector6d ApproximatePlanetPositions::getCartesianState(
  27. const double secondsSinceEpoch)
  28. {
  29. // Convert planet elements in Keplerian elements to Cartesian elements.
  30. return orbital_element_conversions::
  31. convertKeplerianToCartesianElements(
  32. getKeplerianStateFromEphemeris( secondsSinceEpoch ),
  33. sunGravitationalParameter_ + planetGravitationalParameter_ );
  34. }
  35. //! Get keplerian state from ephemeris.
  36. Eigen::Vector6d ApproximatePlanetPositions::getKeplerianStateFromEphemeris(
  37. const double secondsSinceEpoch )
  38. {
  39. using std::pow;
  40. using std::sin;
  41. using std::cos;
  42. using namespace orbital_element_conversions;
  43. // Set Julian date.
  44. julianDate_ = basic_astrodynamics::convertSecondsSinceEpochToJulianDay(
  45. secondsSinceEpoch, basic_astrodynamics::JULIAN_DAY_ON_J2000 );
  46. // Compute number of centuries past J2000.
  47. numberOfCenturiesPastJ2000_ = ( julianDate_ - 2451545.0 ) / 36525.0;
  48. // Compute and set semi-major axis of planet at given Julian date.
  49. planetKeplerianElementsAtGivenJulianDate_( semiMajorAxisIndex )
  50. = approximatePlanetPositionsDataContainer_.semiMajorAxis_
  51. + ( approximatePlanetPositionsDataContainer_
  52. .rateOfChangeOfSemiMajorAxis_ * numberOfCenturiesPastJ2000_ );
  53. // Compute and set eccentricity of planet at given Julian date.
  54. planetKeplerianElementsAtGivenJulianDate_( eccentricityIndex )
  55. = approximatePlanetPositionsDataContainer_.eccentricity_
  56. + ( approximatePlanetPositionsDataContainer_
  57. .rateOfChangeOfEccentricity_ * numberOfCenturiesPastJ2000_ );
  58. // Compute and set inclination of planet at given Julian date.
  59. planetKeplerianElementsAtGivenJulianDate_( inclinationIndex )
  60. = approximatePlanetPositionsDataContainer_.inclination_
  61. + ( approximatePlanetPositionsDataContainer_
  62. .rateOfChangeOfInclination_ * numberOfCenturiesPastJ2000_ );
  63. // Compute and set longitude of ascending node of planet at given Julian date.
  64. planetKeplerianElementsAtGivenJulianDate_( longitudeOfAscendingNodeIndex )
  65. = approximatePlanetPositionsDataContainer_.longitudeOfAscendingNode_
  66. + ( approximatePlanetPositionsDataContainer_
  67. .rateOfChangeOfLongitudeOfAscendingNode_ * numberOfCenturiesPastJ2000_ );
  68. // Compute longitude of perihelion of planet at given Julian date.
  69. longitudeOfPerihelionAtGivenJulianDate_
  70. = approximatePlanetPositionsDataContainer_.longitudeOfPerihelion_
  71. + ( approximatePlanetPositionsDataContainer_.rateOfChangeOfLongitudeOfPerihelion_
  72. * numberOfCenturiesPastJ2000_ );
  73. // Compute and set argument of periapsis of planet at given Julian date.
  74. planetKeplerianElementsAtGivenJulianDate_( argumentOfPeriapsisIndex )
  75. = longitudeOfPerihelionAtGivenJulianDate_
  76. - planetKeplerianElementsAtGivenJulianDate_( longitudeOfAscendingNodeIndex );
  77. // Compute mean longitude of planet at given Julian date.
  78. meanLongitudeAtGivenJulianDate_ = approximatePlanetPositionsDataContainer_.meanLongitude_
  79. + ( approximatePlanetPositionsDataContainer_.rateOfChangeOfMeanLongitude_
  80. * numberOfCenturiesPastJ2000_ );
  81. // Compute mean anomaly of planet at given Julian date.
  82. meanAnomalyAtGivenJulianDate_ = meanLongitudeAtGivenJulianDate_
  83. - longitudeOfPerihelionAtGivenJulianDate_
  84. + ( approximatePlanetPositionsDataContainer_.additionalTermB_
  85. * pow( numberOfCenturiesPastJ2000_, 2.0 ) )
  86. + ( approximatePlanetPositionsDataContainer_.additionalTermC_
  87. * cos( unit_conversions::convertDegreesToRadians(approximatePlanetPositionsDataContainer_.additionalTermF_ *
  88. numberOfCenturiesPastJ2000_ )) )
  89. + ( approximatePlanetPositionsDataContainer_.additionalTermS_
  90. * sin( unit_conversions::convertDegreesToRadians(approximatePlanetPositionsDataContainer_.additionalTermF_ *
  91. numberOfCenturiesPastJ2000_) ) );
  92. // Compute modulo of mean anomaly for interval :
  93. // 0 <= meanAnomalyAtGivenJulianDate_ < 360.
  94. meanAnomalyAtGivenJulianDate_ = basic_mathematics::computeModulo(
  95. meanAnomalyAtGivenJulianDate_, 360.0 );
  96. // Translate mean anomaly to:
  97. // -180 < meanAnomalyAtGivenJulianDate_ <= 180 bounds.
  98. if ( meanAnomalyAtGivenJulianDate_ > 180.0 )
  99. {
  100. meanAnomalyAtGivenJulianDate_ -= 360.0;
  101. }
  102. // Convert mean anomaly to eccentric anomaly.
  103. eccentricAnomalyAtGivenJulianDate_ = convertMeanAnomalyToEccentricAnomaly(
  104. planetKeplerianElementsAtGivenJulianDate_( eccentricityIndex ),
  105. unit_conversions::convertDegreesToRadians(
  106. meanAnomalyAtGivenJulianDate_ ) );
  107. // Convert eccentric anomaly to true anomaly and set in planet elements.
  108. trueAnomalyAtGivenJulianData_
  109. = orbital_element_conversions::convertEccentricAnomalyToTrueAnomaly(
  110. eccentricAnomalyAtGivenJulianDate_,
  111. planetKeplerianElementsAtGivenJulianDate_( eccentricityIndex ) );
  112. planetKeplerianElementsAtGivenJulianDate_( trueAnomalyIndex )
  113. = trueAnomalyAtGivenJulianData_;
  114. // Convert Keplerian elements to standard units.
  115. // Convert semi-major axis from AU to meters.
  116. planetKeplerianElementsAtGivenJulianDate_( semiMajorAxisIndex )
  117. = unit_conversions::convertAstronomicalUnitsToMeters(
  118. planetKeplerianElementsAtGivenJulianDate_( semiMajorAxisIndex ) );
  119. // Convert inclination from degrees to radians.
  120. planetKeplerianElementsAtGivenJulianDate_( inclinationIndex )
  121. = unit_conversions::convertDegreesToRadians(
  122. planetKeplerianElementsAtGivenJulianDate_( inclinationIndex ) );
  123. // Convert longitude of ascending node from degrees to radians.
  124. planetKeplerianElementsAtGivenJulianDate_( longitudeOfAscendingNodeIndex )
  125. = unit_conversions::convertDegreesToRadians(
  126. planetKeplerianElementsAtGivenJulianDate_( longitudeOfAscendingNodeIndex ) );
  127. // Convert argument of periapsis from degrees to radians.
  128. planetKeplerianElementsAtGivenJulianDate_( argumentOfPeriapsisIndex )
  129. = unit_conversions::convertDegreesToRadians(
  130. planetKeplerianElementsAtGivenJulianDate_( argumentOfPeriapsisIndex ) );
  131. return planetKeplerianElementsAtGivenJulianDate_;
  132. }
  133. } // namespace ephemerides
  134. } // namespace tudat