1313#include " absl/strings/str_split.h"
1414#include " base/array.hpp"
1515#include " geometry/orthogonal_map.hpp"
16+ #include " geometry/permutation.hpp"
1617#include " geometry/r3x3_matrix.hpp"
1718#include " geometry/rotation.hpp"
1819#include " geometry/sign.hpp"
@@ -33,6 +34,7 @@ namespace interface {
3334
3435using namespace principia ::base::_array;
3536using namespace principia ::geometry::_orthogonal_map;
37+ using namespace principia ::geometry::_permutation;
3638using namespace principia ::geometry::_r3x3_matrix;
3739using namespace principia ::geometry::_rotation;
3840using namespace principia ::geometry::_sign;
@@ -168,6 +170,16 @@ struct XYZConverter<R3Element<MomentOfInertia>> {
168170 }
169171};
170172
173+ template <>
174+ struct XYZConverter <R3Element<Speed>> {
175+ static constexpr Speed mts_unit = Metre / Second;
176+ static R3Element<Speed> FromXYZ (XYZ const & xyz) {
177+ return R3Element<Speed>(xyz.x * (Metre / Second),
178+ xyz.y * (Metre / Second),
179+ xyz.z * (Metre / Second));
180+ }
181+ };
182+
171183inline bool NaNIndependentEq (double const left, double const right) {
172184 return (left == right) || (std::isnan (left) && std::isnan (right));
173185}
@@ -205,16 +217,7 @@ inline bool operator==(Burn const& left, Burn const& right) {
205217 right.specific_impulse_in_seconds_g0 ) &&
206218 left.frame == right.frame &&
207219 NaNIndependentEq (left.initial_time , right.initial_time ) &&
208- left.delta_v == right.delta_v ;
209- }
210-
211- inline bool operator ==(DeltaV const & left, DeltaV const & right) {
212- return left.coordinate_system == right.coordinate_system &&
213- ((left.spherical_coordinates != nullptr &&
214- right.spherical_coordinates != nullptr &&
215- *left.spherical_coordinates == *right.spherical_coordinates ) ||
216- (left.xyz != nullptr && right.xyz != nullptr &&
217- *left.xyz == *right.xyz ));
220+ left.intensity == right.intensity ;
218221}
219222
220223inline bool operator ==(FlightPlanAdaptiveStepParameters const & left,
@@ -229,6 +232,15 @@ inline bool operator==(FlightPlanAdaptiveStepParameters const& left,
229232 right.speed_integration_tolerance );
230233}
231234
235+ inline bool operator ==(Intensity const & left, Intensity const & right) {
236+ return left.coordinate_system == right.coordinate_system &&
237+ ((left.spherical_coordinates != nullptr &&
238+ right.spherical_coordinates != nullptr &&
239+ *left.spherical_coordinates == *right.spherical_coordinates ) ||
240+ (left.xyz != nullptr && right.xyz != nullptr &&
241+ *left.xyz == *right.xyz ));
242+ }
243+
232244inline bool operator ==(Interval const & left, Interval const & right) {
233245 return NaNIndependentEq (left.min , right.min ) &&
234246 NaNIndependentEq (left.max , right.max );
@@ -522,6 +534,12 @@ inline FromXYZ<R3Element<MomentOfInertia>>(XYZ const& xyz) {
522534 return XYZConverter<R3Element<MomentOfInertia>>::FromXYZ (xyz);
523535}
524536
537+ template <>
538+ R3Element<Speed>
539+ inline FromXYZ<R3Element<Speed>>(XYZ const & xyz) {
540+ return XYZConverter<R3Element<Speed>>::FromXYZ (xyz);
541+ }
542+
525543inline AdaptiveStepParameters ToAdaptiveStepParameters (
526544 physics::_ephemeris::Ephemeris<Barycentric>::AdaptiveStepParameters const &
527545 adaptive_step_parameters) {
@@ -557,6 +575,33 @@ inline FlightPlanAdaptiveStepParameters ToFlightPlanAdaptiveStepParameters(
557575 (Metre / Second)};
558576}
559577
578+ inline Intensity ToIntensity (NavigationManœuvre::Intensity const & intensity) {
579+ if (intensity.has_spherical_coordinates ()) {
580+ switch (intensity.permutation ().coordinate_permutation ()) {
581+ case EvenPermutation::XYZ :
582+ return {.coordinate_system = CoordinateSystem::SPHERICAL_TNB ,
583+ .xyz = nullptr ,
584+ .spherical_coordinates = ToNewSphericalCoordinates (
585+ intensity.Δv_spherical_coordinates ())};
586+ case EvenPermutation::YZX :
587+ return {.coordinate_system = CoordinateSystem::SPHERICAL_NBT ,
588+ .xyz = nullptr ,
589+ .spherical_coordinates = ToNewSphericalCoordinates (
590+ intensity.Δv_spherical_coordinates ())};
591+ case EvenPermutation::ZXY :
592+ return {.coordinate_system = CoordinateSystem::SPHERICAL_BTN ,
593+ .xyz = nullptr ,
594+ .spherical_coordinates = ToNewSphericalCoordinates (
595+ intensity.Δv_spherical_coordinates ())};
596+ }
597+ LOG (FATAL ) << " Unexpected permutation: " << intensity.permutation ();
598+ } else {
599+ return {.coordinate_system = CoordinateSystem::CARTESIAN_TNB ,
600+ .xyz = new XYZ (ToXYZ (intensity.Δv_cartesian_coordinates ())),
601+ .spherical_coordinates = nullptr };
602+ }
603+ }
604+
560605inline KeplerianElements ToKeplerianElements (
561606 physics::_kepler_orbit::KeplerianElements<Barycentric> const &
562607 keplerian_elements) {
@@ -636,6 +681,15 @@ inline Status* ToNewStatus(absl::Status const& status) {
636681 }
637682}
638683
684+ inline SphericalCoordinates* ToNewSphericalCoordinates (
685+ geometry::_r3_element::SphericalCoordinates<Speed> const &
686+ spherical_coordinates) {
687+ return new SphericalCoordinates{
688+ .radius = spherical_coordinates.radius / (Metre / Second),
689+ .latitude_in_degrees = spherical_coordinates.latitude / Degree,
690+ .longitude_in_degrees = spherical_coordinates.longitude / Degree};
691+ }
692+
639693inline WXYZ ToWXYZ (Quaternion const & quaternion) {
640694 return {.w = quaternion.real_part (),
641695 .x = quaternion.imaginary_part ().x ,
@@ -651,6 +705,12 @@ inline XYZ ToXYZ(R3Element<double> const& r3_element) {
651705 return {.x = r3_element.x , .y = r3_element.y , .z = r3_element.z };
652706}
653707
708+ inline XYZ ToXYZ (R3Element<Speed> const & r3_element) {
709+ return {.x = r3_element.x / (Metre / Second),
710+ .y = r3_element.y / (Metre / Second),
711+ .z = r3_element.z / (Metre / Second)};
712+ }
713+
654714inline XYZ ToXYZ (Position<World> const & position) {
655715 return XYZConverter<Position<World>>::ToXYZ (position);
656716}
0 commit comments