diff --git a/bindings/python/src/OpenSpaceToolkitAstrodynamicsPy/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMean.cpp b/bindings/python/src/OpenSpaceToolkitAstrodynamicsPy/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMean.cpp index 78555cfd6..80ee5297c 100644 --- a/bindings/python/src/OpenSpaceToolkitAstrodynamicsPy/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMean.cpp +++ b/bindings/python/src/OpenSpaceToolkitAstrodynamicsPy/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMean.cpp @@ -1,9 +1,15 @@ /// Apache License 2.0 #include + #include +using namespace pybind11; + +using ostk::core::types::Real; +using ostk::physics::units::Length; using ostk::physics::units::Angle; + using ostk::astro::trajectory::orbit::models::kepler::COE; using ostk::astro::trajectory::orbit::models::kepler::BrouwerLyddaneMean; @@ -11,49 +17,51 @@ using ostk::astro::trajectory::orbit::models::kepler::BrouwerLyddaneMean; class PyBrouwerLyddaneMean : public BrouwerLyddaneMean { public: + using BrouwerLyddaneMean::BrouwerLyddaneMean; + // Trampoline (need one for each virtual function) Angle getMeanAnomaly() const { - PYBIND11_OVERRIDE_PURE_NAME( - Angle, BrouwerLyddaneMean, "get_mean_anomaly", getMeanAnomaly - ); + PYBIND11_OVERRIDE_NAME(Angle, BrouwerLyddaneMean, "get_mean_anomaly", getMeanAnomaly); } Angle getTrueAnomaly() const { - PYBIND11_OVERRIDE_PURE_NAME( - Angle, BrouwerLyddaneMean, "get_true_anomaly", getTrueAnomaly - ); + PYBIND11_OVERRIDE_NAME(Angle, BrouwerLyddaneMean, "get_true_anomaly", getTrueAnomaly); } Angle getEccentricAnomaly() const { - PYBIND11_OVERRIDE_PURE_NAME( - Angle, BrouwerLyddaneMean, "get_eccentric_anomaly", getEccentricAnomaly - ); + PYBIND11_OVERRIDE_NAME(Angle, BrouwerLyddaneMean, "get_eccentric_anomaly", getEccentricAnomaly); } COE toCOE() const { - PYBIND11_OVERRIDE_PURE_NAME( - COE, BrouwerLyddaneMean, "to_coe", toCOE - ); + PYBIND11_OVERRIDE_PURE_NAME(COE, BrouwerLyddaneMean, "to_coe", toCOE); } -} ; - +}; inline void OpenSpaceToolkitAstrodynamicsPy_Trajectory_Orbit_Models_Kepler_BrouwerLyddaneMean(pybind11::module& aModule) { - using namespace pybind11; - - using ostk::core::types::Real; - using ostk::core::types::Shared; - using ostk::physics::units::Length; - - class_> brouwerLyddaneMean(aModule, "BrouwerLyddaneMean"); + class_ brouwerLyddaneMean(aModule, "BrouwerLyddaneMean"); brouwerLyddaneMean - .def("get_cartesian_state", &BrouwerLyddaneMean::getCartesianState, arg("gravitational_parameter"), arg("frame")); + .def( + init(), + arg("semi_major_axis"), + arg("eccentricity"), + arg("inclination"), + arg("raan"), + arg("aop"), + arg("mean_anomaly") + ) + + .def("get_mean_anomaly", &BrouwerLyddaneMean::getMeanAnomaly) + .def("get_true_anomaly", &BrouwerLyddaneMean::getTrueAnomaly) + .def("get_eccentric_anomaly", &BrouwerLyddaneMean::getEccentricAnomaly) + .def( + "get_cartesian_state", &BrouwerLyddaneMean::getCartesianState, arg("gravitational_parameter"), arg("frame") + ); } diff --git a/bindings/python/src/OpenSpaceToolkitAstrodynamicsPy/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanLong.cpp b/bindings/python/src/OpenSpaceToolkitAstrodynamicsPy/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanLong.cpp index 943954dba..4d307f10e 100644 --- a/bindings/python/src/OpenSpaceToolkitAstrodynamicsPy/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanLong.cpp +++ b/bindings/python/src/OpenSpaceToolkitAstrodynamicsPy/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanLong.cpp @@ -2,7 +2,9 @@ #include -inline void OpenSpaceToolkitAstrodynamicsPy_Trajectory_Orbit_Models_Kepler_BrouwerLyddaneMeanLong(pybind11::module& aModule) +inline void OpenSpaceToolkitAstrodynamicsPy_Trajectory_Orbit_Models_Kepler_BrouwerLyddaneMeanLong( + pybind11::module& aModule +) { using namespace pybind11; @@ -11,9 +13,10 @@ inline void OpenSpaceToolkitAstrodynamicsPy_Trajectory_Orbit_Models_Kepler_Brouw using ostk::physics::units::Angle; using ostk::physics::units::Length; + using ostk::astro::trajectory::orbit::models::kepler::BrouwerLyddaneMean; using ostk::astro::trajectory::orbit::models::kepler::BrouwerLyddaneMeanLong; - class_ brouwerLyddaneMeanLong(aModule, "BrouwerLyddaneMeanLong"); + class_ brouwerLyddaneMeanLong(aModule, "BrouwerLyddaneMeanLong"); brouwerLyddaneMeanLong @@ -27,15 +30,13 @@ inline void OpenSpaceToolkitAstrodynamicsPy_Trajectory_Orbit_Models_Kepler_Brouw arg("mean_anomaly") ) + .def("to_coe", &BrouwerLyddaneMeanLong::toCOE) + .def_static( - "cartesian", - &BrouwerLyddaneMeanLong::Cartesian, - arg("cartersian_state"), - arg("gravitational_parameter") + "cartesian", &BrouwerLyddaneMeanLong::Cartesian, arg("cartersian_state"), arg("gravitational_parameter") ) - .def_static( - "undefined", - &BrouwerLyddaneMeanLong::Undefined - ); + .def_static("undefined", &BrouwerLyddaneMeanLong::Undefined) + + ; } diff --git a/bindings/python/src/OpenSpaceToolkitAstrodynamicsPy/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanShort.cpp b/bindings/python/src/OpenSpaceToolkitAstrodynamicsPy/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanShort.cpp index ae7dd0f43..99655498b 100644 --- a/bindings/python/src/OpenSpaceToolkitAstrodynamicsPy/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanShort.cpp +++ b/bindings/python/src/OpenSpaceToolkitAstrodynamicsPy/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanShort.cpp @@ -2,7 +2,9 @@ #include -inline void OpenSpaceToolkitAstrodynamicsPy_Trajectory_Orbit_Models_Kepler_BrouwerLyddaneMeanShort(pybind11::module& aModule) +inline void OpenSpaceToolkitAstrodynamicsPy_Trajectory_Orbit_Models_Kepler_BrouwerLyddaneMeanShort( + pybind11::module& aModule +) { using namespace pybind11; @@ -13,7 +15,7 @@ inline void OpenSpaceToolkitAstrodynamicsPy_Trajectory_Orbit_Models_Kepler_Brouw using ostk::astro::trajectory::orbit::models::kepler::BrouwerLyddaneMeanShort; - class_> brouwerLyddaneMeanShort(aModule, "BrouwerLyddaneMeanShort"); + class_ brouwerLyddaneMeanShort(aModule, "BrouwerLyddaneMeanShort"); brouwerLyddaneMeanShort @@ -25,17 +27,13 @@ inline void OpenSpaceToolkitAstrodynamicsPy_Trajectory_Orbit_Models_Kepler_Brouw arg("raan"), arg("aop"), arg("mean_anomaly") - ); + ) + + .def("to_coe", &BrouwerLyddaneMeanShort::toCOE) .def_static( - "cartesian", - &BrouwerLyddaneMeanLong::Cartesian, - arg("cartersian_state"), - arg("gravitational_parameter") + "cartesian", &BrouwerLyddaneMeanShort::Cartesian, arg("cartersian_state"), arg("gravitational_parameter") ) - .def_static( - "undefined", - &BrouwerLyddaneMeanLong::Undefined - ); + .def_static("undefined", &BrouwerLyddaneMeanShort::Undefined); } diff --git a/bindings/python/src/OpenSpaceToolkitAstrodynamicsPy/Trajectory/Orbit/Models/Kepler/COE.cpp b/bindings/python/src/OpenSpaceToolkitAstrodynamicsPy/Trajectory/Orbit/Models/Kepler/COE.cpp index c2d594933..2c3d3d5b6 100644 --- a/bindings/python/src/OpenSpaceToolkitAstrodynamicsPy/Trajectory/Orbit/Models/Kepler/COE.cpp +++ b/bindings/python/src/OpenSpaceToolkitAstrodynamicsPy/Trajectory/Orbit/Models/Kepler/COE.cpp @@ -14,7 +14,7 @@ inline void OpenSpaceToolkitAstrodynamicsPy_Trajectory_Orbit_Models_Kepler_COE(p using ostk::astro::trajectory::orbit::models::kepler::COE; - class_> coe(aModule, "COE"); + class_ coe(aModule, "COE"); coe @@ -44,6 +44,9 @@ inline void OpenSpaceToolkitAstrodynamicsPy_Trajectory_Orbit_Models_Kepler_COE(p .def("get_true_anomaly", &COE::getTrueAnomaly) .def("get_mean_anomaly", &COE::getMeanAnomaly) .def("get_eccentric_anomaly", &COE::getEccentricAnomaly) + .def("get_periapsis_radius", &COE::getPeriapsisRadius) + .def("get_periapsis_altitude", &COE::getPeriapsisRadius) + .def("get_SI_vector", &COE::getSIVector, arg("anomaly_type")) .def("get_mean_motion", &COE::getMeanMotion, arg("gravitational_parameter")) @@ -51,10 +54,15 @@ inline void OpenSpaceToolkitAstrodynamicsPy_Trajectory_Orbit_Models_Kepler_COE(p .def("get_cartesian_state", &COE::getCartesianState, arg("gravitational_parameter"), arg("frame")) + .def("to_brouwer_lyddane_mean_long", &COE::toBrouwerLyddaneMeanLong) + .def("to_brouwer_lyddane_mean_short", &COE::toBrouwerLyddaneMeanShort) + .def_static("undefined", &COE::Undefined) .def_static("cartesian", &COE::Cartesian, arg("cartesian_state"), arg("gravitational_parameter")) + .def_static("from_SI_vector", &COE::FromSIVector, arg("vector"), arg("anomaly_type")) + .def_static( "eccentric_anomaly_from_true_anomaly", &COE::EccentricAnomalyFromTrueAnomaly, @@ -84,6 +92,14 @@ inline void OpenSpaceToolkitAstrodynamicsPy_Trajectory_Orbit_Models_Kepler_COE(p arg("tolerance") ) + .def_static( + "true_anomaly_from_mean_anomaly", + &COE::TrueAnomalyFromMeanAnomaly, + arg("mean_anomaly"), + arg("eccentricity"), + arg("tolerance") + ) + .def_static("string_from_element", &COE::StringFromElement, arg("element")) ; @@ -99,5 +115,13 @@ inline void OpenSpaceToolkitAstrodynamicsPy_Trajectory_Orbit_Models_Kepler_COE(p .value("MeanAnomaly", COE::Element::MeanAnomaly) .value("EccentricAnomaly", COE::Element::EccentricAnomaly) + ; + + enum_(coe, "AnomalyType") + + .value("TrueAnomaly", COE::AnomalyType::True) + .value("MeanAnomaly", COE::AnomalyType::Mean) + .value("EccentricAnomaly", COE::AnomalyType::Eccentric) + ; } diff --git a/bindings/python/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean.py b/bindings/python/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean.py new file mode 100644 index 000000000..882e4b1c6 --- /dev/null +++ b/bindings/python/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean.py @@ -0,0 +1,65 @@ +# Apache License 2.0 + +import pytest + +from ostk.physics.units import Length +from ostk.physics.units import Angle + +from ostk.astrodynamics.trajectory.orbit.models.kepler import BrouwerLyddaneMean + + +@pytest.fixture +def semi_major_axis() -> Length: + return Length.kilometers(7000.0) + + +@pytest.fixture +def eccentricity() -> float: + return 1e-3 + + +@pytest.fixture +def inclination() -> Angle: + return Angle.degrees(35.0) + + +@pytest.fixture +def raan() -> Angle: + return Angle.degrees(40.0) + + +@pytest.fixture +def aop() -> Angle: + return Angle.degrees(50.0) + + +@pytest.fixture +def mean_anomaly() -> Angle: + return Angle.degrees(60.0) + + +@pytest.fixture +def brouwer_lyddane_mean( + semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly +): + class BrouwerLyddaneMeanMock(BrouwerLyddaneMean): + def __init__( + self, semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly + ): + super().__init__( + semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly + ) + + def to_coe(): + return 0.0 + + return BrouwerLyddaneMeanMock( + semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly + ) + + +class TestBrouwerLyddaneMean: + def test_getters(self, brouwer_lyddane_mean: BrouwerLyddaneMean): + assert isinstance(brouwer_lyddane_mean.get_mean_anomaly(), Angle) + assert isinstance(brouwer_lyddane_mean.get_true_anomaly(), Angle) + assert isinstance(brouwer_lyddane_mean.get_eccentric_anomaly(), Angle) diff --git a/bindings/python/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_long.py b/bindings/python/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_long.py new file mode 100644 index 000000000..6e9a2a1c4 --- /dev/null +++ b/bindings/python/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_long.py @@ -0,0 +1,84 @@ +# Apache License 2.0 + +import pytest + +from ostk.physics.units import Length +from ostk.physics.units import Angle +from ostk.physics.environment.gravitational import Earth + +from ostk.physics.coordinate import Frame +from ostk.physics.coordinate import Position +from ostk.physics.coordinate import Velocity + +from ostk.astrodynamics.trajectory.orbit.models.kepler import BrouwerLyddaneMeanLong + + +@pytest.fixture +def semi_major_axis() -> Length: + return Length.kilometers(7000.0) + + +@pytest.fixture +def eccentricity() -> float: + return 1e-3 + + +@pytest.fixture +def inclination() -> Angle: + return Angle.degrees(35.0) + + +@pytest.fixture +def raan() -> Angle: + return Angle.degrees(40.0) + + +@pytest.fixture +def aop() -> Angle: + return Angle.degrees(50.0) + + +@pytest.fixture +def mean_anomaly() -> Angle: + return Angle.degrees(60.0) + + +@pytest.fixture +def cartesian_state() -> tuple[Position, Velocity]: + return ( + Position.meters( + [6596407.223662058, 2281266.582975321, -10540.61521486086], Frame.GCRF() + ), + Velocity.meters_per_second( + [337.7269674273224, -969.7192552349448, 7488.702816619139], Frame.GCRF() + ), + ) + + +@pytest.fixture +def gravitational_parameter(): + return Earth.EGM2008.gravitational_parameter + + +@pytest.fixture +def brouwer_lyddane_mean_long( + semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly +): + return BrouwerLyddaneMeanLong( + semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly + ) + + +class TestBrouwerLyddaneMeanLong: + def test_to_coe(self, brouwer_lyddane_mean_long: BrouwerLyddaneMeanLong): + assert brouwer_lyddane_mean_long.to_coe().is_defined() + + def test_cartesian( + self, cartesian_state: tuple[Position, Velocity], gravitational_parameter + ): + assert BrouwerLyddaneMeanLong.cartesian( + cartesian_state, gravitational_parameter + ).is_defined() + + def test_undefined(self): + assert BrouwerLyddaneMeanLong.undefined().is_defined() is False diff --git a/bindings/python/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_short.py b/bindings/python/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_short.py new file mode 100644 index 000000000..37698a4ed --- /dev/null +++ b/bindings/python/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_short.py @@ -0,0 +1,84 @@ +# Apache License 2.0 + +import pytest + +from ostk.physics.units import Length +from ostk.physics.units import Angle +from ostk.physics.environment.gravitational import Earth + +from ostk.physics.coordinate import Frame +from ostk.physics.coordinate import Position +from ostk.physics.coordinate import Velocity + +from ostk.astrodynamics.trajectory.orbit.models.kepler import BrouwerLyddaneMeanShort + + +@pytest.fixture +def semi_major_axis() -> Length: + return Length.kilometers(7000.0) + + +@pytest.fixture +def eccentricity() -> float: + return 1e-3 + + +@pytest.fixture +def inclination() -> Angle: + return Angle.degrees(35.0) + + +@pytest.fixture +def raan() -> Angle: + return Angle.degrees(40.0) + + +@pytest.fixture +def aop() -> Angle: + return Angle.degrees(50.0) + + +@pytest.fixture +def mean_anomaly() -> Angle: + return Angle.degrees(60.0) + + +@pytest.fixture +def cartesian_state() -> tuple[Position, Velocity]: + return ( + Position.meters( + [6596407.223662058, 2281266.582975321, -10540.61521486086], Frame.GCRF() + ), + Velocity.meters_per_second( + [337.7269674273224, -969.7192552349448, 7488.702816619139], Frame.GCRF() + ), + ) + + +@pytest.fixture +def gravitational_parameter(): + return Earth.EGM2008.gravitational_parameter + + +@pytest.fixture +def brouwer_lyddane_mean_short( + semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly +): + return BrouwerLyddaneMeanShort( + semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly + ) + + +class TestBrouwerLyddaneMeanShort: + def test_to_coe(self, brouwer_lyddane_mean_short: BrouwerLyddaneMeanShort): + assert brouwer_lyddane_mean_short.to_coe().is_defined() + + def test_cartesian( + self, cartesian_state: tuple[Position, Velocity], gravitational_parameter + ): + assert BrouwerLyddaneMeanShort.cartesian( + cartesian_state, gravitational_parameter + ).is_defined() + + def test_undefined(self): + assert BrouwerLyddaneMeanShort.undefined().is_defined() is False diff --git a/bindings/python/test/trajectory/orbit/models/kepler/test_coe.py b/bindings/python/test/trajectory/orbit/models/kepler/test_coe.py index e3e968c40..91aac69e4 100644 --- a/bindings/python/test/trajectory/orbit/models/kepler/test_coe.py +++ b/bindings/python/test/trajectory/orbit/models/kepler/test_coe.py @@ -1,5 +1,7 @@ # Apache License 2.0 +import pytest + from ostk.physics.units import Length from ostk.physics.units import Angle from ostk.physics.environment.gravitational import Earth @@ -97,16 +99,51 @@ def test_getters( assert coe.get_eccentric_anomaly() is not None assert coe.get_mean_motion(Earth.EGM2008.gravitational_parameter) is not None assert coe.get_orbital_period(Earth.EGM2008.gravitational_parameter) is not None + assert coe.get_periapsis_radius() is not None + assert coe.get_apoapsis_radius() is not None + assert coe.get_si_vector(COE.AnomalyType.TrueAnomaly) is not None + assert coe.get_si_vector(COE.AnomalyType.MeanAnomaly) is not None + assert coe.get_si_vector(COE.AnomalyType.EccentricAnomaly) is not None - def test_static_constructors( - self + def test_to_brouwer_lyddane_mean( + self, + coe: COE, ): + assert coe.to_brouwer_lyddane_mean_long() is not None + assert coe.to_brouwer_lyddane_mean_short() is not None - assert COE.eccentric_anomaly_from_true_anomaly(Angle.degrees(0.0), 0.0) is not None - assert COE.true_anomaly_from_eccentric_anomaly(Angle.degrees(0.0), 0.0) is not None - assert COE.mean_anomaly_from_eccentric_anomaly(Angle.degrees(0.0), 0.0) is not None + def test_anomaly_conversions(self): + assert ( + COE.eccentric_anomaly_from_true_anomaly(Angle.degrees(0.0), 0.0) is not None + ) assert ( - COE.eccentric_anomaly_from_mean_anomaly(Angle.degrees(0.0), 0.0, 0.0) is not None + COE.true_anomaly_from_eccentric_anomaly(Angle.degrees(0.0), 0.0) is not None + ) + assert ( + COE.mean_anomaly_from_eccentric_anomaly(Angle.degrees(0.0), 0.0) is not None + ) + assert ( + COE.eccentric_anomaly_from_mean_anomaly(Angle.degrees(0.0), 0.0, 0.0) + is not None + ) + + def test_from_SI_vector( + self, + coe: COE, + semi_major_axis: Length, + eccentricity: float, + inclination: Angle, + raan: Angle, + aop: Angle, + true_anomaly: Angle, + ): + assert coe == COE.from_SI_vector( + semi_major_axis.inMeters(), + eccentricity, + inclination.inRadians(), + raan.inRadians(), + aop.inRadians(), + true_anomaly.inRadians(), ) def test_string_from_element(self): diff --git a/include/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMean.hpp b/include/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMean.hpp index 3817a670e..203c4a906 100644 --- a/include/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMean.hpp +++ b/include/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMean.hpp @@ -59,6 +59,23 @@ using ostk::astro::trajectory::orbit::models::kepler::COE; class BrouwerLyddaneMean : public COE { public: + /// @brief Constructor + /// + /// @param [in] aSemiMajorAxis A semi-major axis + /// @param [in] anEccentricity An eccentricity + /// @param [in] anInclination An inclination + /// @param [in] aRaan A raan + /// @param [in] anAop An aop + /// @param [in] aMeanAnomaly A mean anomaly + + BrouwerLyddaneMean( + const Length &aSemiMajorAxis, + const Real &anEccentricity, + const Angle &anInclination, + const Angle &aRaan, + const Angle &anAop, + const Angle &aMeanAnomaly + ); /// @brief Get Mean anomaly /// @@ -90,25 +107,6 @@ class BrouwerLyddaneMean : public COE virtual COE toCOE() const = 0; protected: - - /// @brief Constructor - /// - /// @param [in] aSemiMajorAxis A semi-major axis - /// @param [in] anEccentricity An eccentricity - /// @param [in] anInclination An inclination - /// @param [in] aRaan A raan - /// @param [in] anAop An aop - /// @param [in] aMeanAnomaly A mean anomaly - - BrouwerLyddaneMean( - const Length &aSemiMajorAxis, - const Real &anEccentricity, - const Angle &anInclination, - const Angle &aRaan, - const Angle &anAop, - const Angle &aMeanAnomaly - ); - /// @brief Convert cartesian state to Vector /// /// @param [in] aCartesianState A cartesian state @@ -125,7 +123,7 @@ class BrouwerLyddaneMean : public COE /// /// @return Vector - Vector6d getVector() const; + Vector6d getSIVector() const; }; } // namespace kepler diff --git a/include/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanLong.hpp b/include/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanLong.hpp index 015c48859..0cbd44e0b 100644 --- a/include/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanLong.hpp +++ b/include/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanLong.hpp @@ -61,7 +61,6 @@ using ostk::astro::trajectory::orbit::models::kepler::BrouwerLyddaneMean; class BrouwerLyddaneMeanLong : public BrouwerLyddaneMean { public: - /// @brief Constructor /// /// @param [in] aSemiMajorAxis A semi-major axis @@ -102,12 +101,11 @@ class BrouwerLyddaneMeanLong : public BrouwerLyddaneMean static BrouwerLyddaneMeanLong Undefined(); private: - /// @brief Constructor /// /// @param [in] aVector A vector - static BrouwerLyddaneMeanLong FromVector(const Vector6d &aVector); + static BrouwerLyddaneMeanLong FromSIVector(const Vector6d &aVector); }; } // namespace kepler diff --git a/include/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanShort.hpp b/include/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanShort.hpp index 4689bea7e..3757f4bd9 100644 --- a/include/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanShort.hpp +++ b/include/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanShort.hpp @@ -106,7 +106,7 @@ class BrouwerLyddaneMeanShort : public BrouwerLyddaneMean /// /// @param [in] aVector A vector - static BrouwerLyddaneMeanShort FromVector(const Vector6d &aVector); + static BrouwerLyddaneMeanShort FromSIVector(const Vector6d &aVector); }; } // namespace kepler diff --git a/include/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/COE.hpp b/include/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/COE.hpp index c54d05308..b0aaf55fa 100644 --- a/include/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/COE.hpp +++ b/include/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/COE.hpp @@ -46,6 +46,9 @@ using ostk::physics::units::Angle; using ostk::physics::units::Derived; using ostk::physics::units::Length; +class BrouwerLyddaneMeanLong; // Forward declaration +class BrouwerLyddaneMeanShort; // Forward declaration + /// @brief Classical Orbital Elements (COE) /// /// @ref https://en.wikipedia.org/wiki/Orbital_elements @@ -206,12 +209,24 @@ class COE COE::CartesianState getCartesianState(const Derived& aGravitationalParameter, const Shared& aFrameSPtr) const; - /// @brief Get vector + /// @brief Get vector of elements in SI units /// /// @param [in] anAnomalyType An anomaly type /// @return Vector - Vector6d getVector(const AnomalyType& anAnomalyType) const; + Vector6d getSIVector(const AnomalyType& anAnomalyType) const; + + /// @brief Get Brouwer-Lyddane Mean short orbital elements + /// + /// @return Brouwer-Lyddane Mean short orbital elements + + BrouwerLyddaneMeanShort toBrouwerLyddaneMeanShort() const; + + /// @brief Get Brouwer-Lyddane Mean long orbital elements + /// + /// @return Brouwer-Lyddane Mean long orbital elements + + BrouwerLyddaneMeanLong toBrouwerLyddaneMeanLong() const; /// @brief Print COE /// @@ -244,7 +259,7 @@ class COE /// @param [in] anAnomalyType An anomaly type /// @return COE - static COE FromVector(const Vector6d& aCOEVector, const AnomalyType& anAnomalyType); + static COE FromSIVector(const Vector6d& aCOEVector, const AnomalyType& anAnomalyType); /// @brief Convert True anomaly to Eccentric anomaly /// @@ -328,7 +343,6 @@ class COE const AnomalyType& anAnomalyType); private: - /// @brief Convert anomaly /// /// @param [in] anAnomaly An anomaly diff --git a/src/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMean.cpp b/src/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMean.cpp index e254a8c54..689865a78 100644 --- a/src/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMean.cpp +++ b/src/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMean.cpp @@ -22,6 +22,18 @@ namespace kepler using ostk::core::types::Size; using ostk::core::types::Integer; +BrouwerLyddaneMean::BrouwerLyddaneMean( + const Length &aSemiMajorAxis, + const Real &anEccentricity, + const Angle &anInclination, + const Angle &aRaan, + const Angle &anAop, + const Angle &aMeanAnomaly +) + : COE(aSemiMajorAxis, anEccentricity, anInclination, aRaan, anAop, aMeanAnomaly, COE::AnomalyType::Mean) +{ +} + Angle BrouwerLyddaneMean::getMeanAnomaly() const { if (!this->isDefined()) @@ -60,18 +72,6 @@ COE::CartesianState BrouwerLyddaneMean::getCartesianState( return coe.getCartesianState(aGravitationalParameter, aFrameSPtr); } -BrouwerLyddaneMean::BrouwerLyddaneMean( - const Length &aSemiMajorAxis, - const Real &anEccentricity, - const Angle &anInclination, - const Angle &aRaan, - const Angle &anAop, - const Angle &aMeanAnomaly -) - : COE(aSemiMajorAxis, anEccentricity, anInclination, aRaan, anAop, aMeanAnomaly, COE::AnomalyType::Mean) -{ -} - Vector6d BrouwerLyddaneMean::Cartesian( const COE::CartesianState &aCartesianState, const Derived &aGravitationalParameter, @@ -133,7 +133,7 @@ Vector6d BrouwerLyddaneMean::Cartesian( cartesian.segment(0, 3) = aCartesianState.first.accessCoordinates(); cartesian.segment(3, 3) = aCartesianState.second.accessCoordinates(); - Vector6d coeVector = coe.getVector(COE::AnomalyType::Mean); + Vector6d coeVector = coe.getSIVector(COE::AnomalyType::Mean); Integer pseudostate = 0; if (coeVector[2] > 3.0543261909900763) @@ -142,7 +142,7 @@ Vector6d BrouwerLyddaneMean::Cartesian( coeVector[3] = -coeVector[3]; // RAAN = - RAAN Position position = Position::Undefined(); Velocity velocity = Velocity::Undefined(); - std::tie(position, velocity) = COE::FromVector(coeVector, COE::AnomalyType::Mean) + std::tie(position, velocity) = COE::FromSIVector(coeVector, COE::AnomalyType::Mean) .getCartesianState(aGravitationalParameter, Frame::GCRF()); cartesian.segment(0, 3) = position.getCoordinates(); cartesian.segment(3, 3) = velocity.getCoordinates(); @@ -217,7 +217,7 @@ Vector6d BrouwerLyddaneMean::Cartesian( brouwerLyddaneMean = brouwerLyddaneMeanFromMEE(modifiedEquinoctialElementsMean_2); coeVector_2 = toCOEVector(brouwerLyddaneMean); - const COE coe_2 = COE::FromVector(coeVector_2, COE::AnomalyType::Mean); + const COE coe_2 = COE::FromSIVector(coeVector_2, COE::AnomalyType::Mean); Position position2 = Position::Undefined(); Velocity velocity2 = Velocity::Undefined(); std::tie(position2, velocity2) = coe_2.getCartesianState(aGravitationalParameter, Frame::GCRF()); @@ -266,7 +266,7 @@ Vector6d BrouwerLyddaneMean::Cartesian( return brouwerLyddaneMean; } -Vector6d BrouwerLyddaneMean::getVector() const +Vector6d BrouwerLyddaneMean::getSIVector() const { if (!this->isDefined()) { diff --git a/src/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanLong.cpp b/src/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanLong.cpp index 6f3fd61ac..9d5494041 100644 --- a/src/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanLong.cpp +++ b/src/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanLong.cpp @@ -374,7 +374,7 @@ COE BrouwerLyddaneMeanLong::toCOE() const raan = Real::TwoPi() - raan; } - return COE::FromVector( + return COE::FromSIVector( { sma * equatorialRadius, ecc, @@ -393,10 +393,10 @@ BrouwerLyddaneMeanLong BrouwerLyddaneMeanLong::Cartesian( { const auto toCOEVector = [](const Vector6d &aVector) -> Vector6d { - return BrouwerLyddaneMeanLong::FromVector(aVector).toCOE().getVector(COE::AnomalyType::Mean); + return BrouwerLyddaneMeanLong::FromSIVector(aVector).toCOE().getSIVector(COE::AnomalyType::Mean); }; - return BrouwerLyddaneMeanLong::FromVector( + return BrouwerLyddaneMeanLong::FromSIVector( BrouwerLyddaneMean::Cartesian(aCartesianState, aGravitationalParameter, toCOEVector) ); } @@ -413,7 +413,7 @@ BrouwerLyddaneMeanLong BrouwerLyddaneMeanLong::Undefined() }; } -BrouwerLyddaneMeanLong BrouwerLyddaneMeanLong::FromVector(const Vector6d &aVector) +BrouwerLyddaneMeanLong BrouwerLyddaneMeanLong::FromSIVector(const Vector6d &aVector) { return { Length::Meters(aVector[0]), diff --git a/src/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanShort.cpp b/src/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanShort.cpp index 01e8fbe18..2bb232c13 100644 --- a/src/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanShort.cpp +++ b/src/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/BrouwerLyddaneMeanShort.cpp @@ -263,7 +263,7 @@ COE BrouwerLyddaneMeanShort::toCOE() const aop += Real::TwoPi(); } - return COE::FromVector( + return COE::FromSIVector( { sma * equatorialRadius, ecc1, @@ -282,10 +282,10 @@ BrouwerLyddaneMeanShort BrouwerLyddaneMeanShort::Cartesian( { const auto toCOEVector = [](const Vector6d &aVector) -> Vector6d { - return BrouwerLyddaneMeanShort::FromVector(aVector).toCOE().getVector(COE::AnomalyType::Mean); + return BrouwerLyddaneMeanShort::FromSIVector(aVector).toCOE().getSIVector(COE::AnomalyType::Mean); }; - return BrouwerLyddaneMeanShort::FromVector( + return BrouwerLyddaneMeanShort::FromSIVector( BrouwerLyddaneMean::Cartesian(aCartesianState, aGravitationalParameter, toCOEVector) ); } @@ -302,7 +302,7 @@ BrouwerLyddaneMeanShort BrouwerLyddaneMeanShort::Undefined() }; } -BrouwerLyddaneMeanShort BrouwerLyddaneMeanShort::FromVector(const Vector6d &aVector) +BrouwerLyddaneMeanShort BrouwerLyddaneMeanShort::FromSIVector(const Vector6d &aVector) { return { Length::Meters(aVector[0]), diff --git a/src/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/COE.cpp b/src/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/COE.cpp index fcc872097..ea300f67f 100644 --- a/src/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/COE.cpp +++ b/src/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/COE.cpp @@ -6,6 +6,10 @@ #include +#include + +#include +#include #include namespace ostk @@ -24,6 +28,10 @@ namespace kepler using ostk::physics::units::Derived; using ostk::physics::units::Length; using ostk::physics::units::Time; +using EarthGravitationalModel = ostk::physics::environment::gravitational::Earth; + +using ostk::astro::trajectory::orbit::models::kepler::BrouwerLyddaneMeanShort; +using ostk::astro::trajectory::orbit::models::kepler::BrouwerLyddaneMeanLong; static const Real Tolerance = 1e-30; static const Derived::Unit GravitationalParameterSIUnit = @@ -299,7 +307,7 @@ COE::CartesianState COE::getCartesianState( } } -Vector6d COE::getVector(const COE::AnomalyType& anAnomalyType) const +Vector6d COE::getSIVector(const COE::AnomalyType& anAnomalyType) const { return { semiMajorAxis_.inMeters(), @@ -311,6 +319,32 @@ Vector6d COE::getVector(const COE::AnomalyType& anAnomalyType) const }; } +BrouwerLyddaneMeanShort COE::toBrouwerLyddaneMeanShort() const +{ + if (!this->isDefined()) + { + throw ostk::core::error::runtime::Undefined("COE"); + } + + const COE::CartesianState cartesianState = + this->getCartesianState(EarthGravitationalModel::EGM2008.gravitationalParameter_, Frame::GCRF()); + + return BrouwerLyddaneMeanShort::Cartesian(cartesianState, EarthGravitationalModel::EGM2008.gravitationalParameter_); +} + +BrouwerLyddaneMeanLong COE::toBrouwerLyddaneMeanLong() const +{ + if (!this->isDefined()) + { + throw ostk::core::error::runtime::Undefined("COE"); + } + + const COE::CartesianState cartesianState = + this->getCartesianState(EarthGravitationalModel::EGM2008.gravitationalParameter_, Frame::GCRF()); + + return BrouwerLyddaneMeanLong::Cartesian(cartesianState, EarthGravitationalModel::EGM2008.gravitationalParameter_); +} + void COE::print(std::ostream& anOutputStream, bool displayDecorator) const { using ostk::core::types::String; @@ -570,7 +604,7 @@ COE COE::Cartesian(const COE::CartesianState& aCartesianState, const Derived& aG }; } -COE COE::FromVector(const Vector6d& aCOEVector, const AnomalyType& anAnomalyType) +COE COE::FromSIVector(const Vector6d& aCOEVector, const AnomalyType& anAnomalyType) { return { Length::Meters(aCOEVector[0]), diff --git a/test/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/COE.test.cpp b/test/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/COE.test.cpp index 05194fe1a..eef61c1aa 100644 --- a/test/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/COE.test.cpp +++ b/test/OpenSpaceToolkit/Astrodynamics/Trajectory/Orbit/Models/Kepler/COE.test.cpp @@ -11,6 +11,8 @@ #include #include +#include +#include #include #include @@ -33,6 +35,8 @@ using ostk::physics::units::Derived; using ostk::physics::units::Length; using ostk::astro::trajectory::orbit::models::kepler::COE; +using ostk::astro::trajectory::orbit::models::kepler::BrouwerLyddaneMeanLong; +using ostk::astro::trajectory::orbit::models::kepler::BrouwerLyddaneMeanShort; TEST(OpenSpaceToolkit_Astrodynamics_Trajectory_Orbit_Models_Kepler_COE, Constructor) { @@ -540,7 +544,7 @@ TEST(OpenSpaceToolkit_Astrodynamics_Trajectory_Orbit_Models_Kepler_COE, GetVecto trueAnomaly.inRadians(), }; - EXPECT_TRUE(((coeVector - coe.getVector(COE::AnomalyType::True)).sum() < 1e-15)); + EXPECT_TRUE(((coeVector - coe.getSIVector(COE::AnomalyType::True)).sum() < 1e-15)); } } @@ -648,7 +652,7 @@ TEST(OpenSpaceToolkit_Astrodynamics_Trajectory_Orbit_Models_Kepler_COE, Cartesia } } -TEST(OpenSpaceToolkit_Astrodynamics_Trajectory_Orbit_Models_Kepler_COE, FromVector) +TEST(OpenSpaceToolkit_Astrodynamics_Trajectory_Orbit_Models_Kepler_COE, FromSIVector) { { const Length semiMajorAxis = Length::Kilometers(7000.0); @@ -667,12 +671,64 @@ TEST(OpenSpaceToolkit_Astrodynamics_Trajectory_Orbit_Models_Kepler_COE, FromVect trueAnomaly.inRadians(), }; - const COE coeFromVector = COE::FromVector(coeVector, COE::AnomalyType::True); + const COE coeFromVector = COE::FromSIVector(coeVector, COE::AnomalyType::True); const COE coe = {semiMajorAxis, eccentricity, inclination, raan, aop, trueAnomaly}; EXPECT_TRUE(coeFromVector == coe); } } +TEST(OpenSpaceToolkit_Astrodynamics_Trajectory_Orbit_Models_Kepler_COE, ToBrouwerLyddaneMeanShort) +{ + { + const COE coe = COE::FromSIVector( + { + 6973741.699984478, + 0.001199999999844802, + 1.7064084094998029, + 0.3385938748853645, + 1.5707969061472655, + 4.7144827961294755, + }, + COE::AnomalyType::Mean + ); + + const BrouwerLyddaneMeanShort blmsoe = coe.toBrouwerLyddaneMeanShort(); + + EXPECT_NEAR(6964438.445277286, blmsoe.getSemiMajorAxis().inMeters(), 1e-2); + EXPECT_NEAR(0.001288698830945117, blmsoe.getEccentricity(), 1e-5); + EXPECT_NEAR(1.7064996355392392, blmsoe.getInclination().inRadians(0.0, Real::TwoPi()), 1e-5); + EXPECT_NEAR(0.33859455527023724, blmsoe.getRaan().inRadians(0.0, Real::TwoPi()), 1e-5); + EXPECT_NEAR(1.9439702698998091, blmsoe.getAop().inRadians(0.0, Real::TwoPi()), 1e-5); + EXPECT_NEAR(4.34130730475872, blmsoe.getMeanAnomaly().inRadians(0.0, Real::TwoPi()), 1e-5); + } +} + +TEST(OpenSpaceToolkit_Astrodynamics_Trajectory_Orbit_Models_Kepler_COE, ToBrouwerLyddaneMeanLong) +{ + { + const COE coe = COE::FromSIVector( + { + 6973741.699984478, + 0.001199999999844802, + 1.7064084094998029, + 0.3385938748853645, + 1.5707969061472655, + 4.7144827961294755, + }, + COE::AnomalyType::Mean + ); + + const BrouwerLyddaneMeanLong blmloe = coe.toBrouwerLyddaneMeanLong(); + + EXPECT_NEAR(6964438.543901746, blmloe.getSemiMajorAxis().inMeters(), 1e-2); + EXPECT_NEAR(0.000473008790410975, blmloe.getEccentricity(), 1e-5); + EXPECT_NEAR(1.7064996261909862, blmloe.getInclination().inRadians(0.0, Real::TwoPi()), 1e-5); + EXPECT_NEAR(0.3385940722800471, blmloe.getRaan().inRadians(0.0, Real::TwoPi()), 1e-5); + EXPECT_NEAR(3.028029950209483, blmloe.getAop().inRadians(0.0, Real::TwoPi()), 1e-5); + EXPECT_NEAR(3.2572466384121426, blmloe.getMeanAnomaly().inRadians(0.0, Real::TwoPi()), 1e-5); + } +} + // TEST (OpenSpaceToolkit_Astrodynamics_Trajectory_Orbit_Models_Kepler_COE, EccentricAnomalyFromTrueAnomaly) // { @@ -820,19 +876,21 @@ TEST(OpenSpaceToolkit_Astrodynamics_Trajectory_Orbit_Models_Kepler_COE, ConvertA { { EXPECT_DOUBLE_EQ( - COE::FromVector({7.0e6, 0.0, 0.0, 0.0, 0.0, 0.0}, COE::AnomalyType::True).getTrueAnomaly().inDegrees(), 0.0 + COE::FromSIVector({7.0e6, 0.0, 0.0, 0.0, 0.0, 0.0}, COE::AnomalyType::True).getTrueAnomaly().inDegrees(), + 0.0 ); } { EXPECT_DOUBLE_EQ( - COE::FromVector({7.0e6, 0.0, 0.0, 0.0, 0.0, 0.0}, COE::AnomalyType::Mean).getMeanAnomaly().inDegrees(), 0.0 + COE::FromSIVector({7.0e6, 0.0, 0.0, 0.0, 0.0, 0.0}, COE::AnomalyType::Mean).getMeanAnomaly().inDegrees(), + 0.0 ); } { EXPECT_DOUBLE_EQ( - COE::FromVector({7.0e6, 0.0, 0.0, 0.0, 0.0, 0.0}, COE::AnomalyType::Eccentric) + COE::FromSIVector({7.0e6, 0.0, 0.0, 0.0, 0.0, 0.0}, COE::AnomalyType::Eccentric) .getEccentricAnomaly() .inDegrees(), 0.0