Skip to content

Commit 96ab388

Browse files
authored
feat: target velocity profile target type (#548)
* feat: target velocity profile target type * feat: address feedback
1 parent 40c3021 commit 96ab388

File tree

6 files changed

+246
-22
lines changed

6 files changed

+246
-22
lines changed

bindings/python/src/OpenSpaceToolkitAstrodynamicsPy/Flight/Profile.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ inline void OpenSpaceToolkitAstrodynamicsPy_Flight_Profile(pybind11::module& aMo
5555

5656
.value("GeocentricNadir", Profile::TargetType::GeocentricNadir, "Geocentric nadir")
5757
.value("GeodeticNadir", Profile::TargetType::GeodeticNadir, "Geodetic nadir")
58-
.value("Trajectory", Profile::TargetType::Trajectory, "Trajectory")
58+
.value("Trajectory", Profile::TargetType::Trajectory, "Trajectory") // Deprecated in favor of TargetPosition
59+
.value("TargetPosition", Profile::TargetType::TargetPosition, "Target position")
60+
.value("TargetVelocity", Profile::TargetType::TargetVelocity, "Target velocity")
5961
.value("Sun", Profile::TargetType::Sun, "Sun")
6062
.value("Moon", Profile::TargetType::Moon, "Moon")
6163
.value("VelocityECI", Profile::TargetType::VelocityECI, "Velocity in ECI")
@@ -121,10 +123,32 @@ inline void OpenSpaceToolkitAstrodynamicsPy_Flight_Profile(pybind11::module& aMo
121123
arg("anti_direction") = false
122124
)
123125

126+
.def_static(
127+
"target_position",
128+
&Profile::TrajectoryTarget::TargetPosition,
129+
R"doc(
130+
Create a target, which produces a vector pointing from the observer to the target position.
131+
)doc",
132+
arg("trajectory"),
133+
arg("axis"),
134+
arg("anti_direction") = false
135+
)
136+
137+
.def_static(
138+
"target_velocity",
139+
&Profile::TrajectoryTarget::TargetVelocity,
140+
R"doc(
141+
Create a target, which produces a vector pointing along the target velocity.
142+
)doc",
143+
arg("trajectory"),
144+
arg("axis"),
145+
arg("anti_direction") = false
146+
)
147+
124148
.def_readonly(
125149
"trajectory",
126150
&Profile::TrajectoryTarget::trajectory,
127-
"The trajectory of the target. Required only if the target type is `Trajectory`."
151+
"The trajectory of the target. Used to compute the target position or velocity."
128152
)
129153

130154
;
@@ -156,7 +180,7 @@ inline void OpenSpaceToolkitAstrodynamicsPy_Flight_Profile(pybind11::module& aMo
156180
.def_readonly(
157181
"orientation_profile",
158182
&Profile::OrientationProfileTarget::orientationProfile,
159-
"The orientation profile of the target"
183+
"The orientation profile of the target."
160184
)
161185

162186
;
@@ -188,7 +212,7 @@ inline void OpenSpaceToolkitAstrodynamicsPy_Flight_Profile(pybind11::module& aMo
188212
.def_readonly(
189213
"orientation_generator",
190214
&Profile::CustomTarget::orientationGenerator,
191-
"The orientation generator of the target"
215+
"The orientation generator of the target."
192216
)
193217

194218
;

bindings/python/test/flight/test_profile.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,11 @@ def profile(request) -> Profile:
9797
@pytest.fixture(
9898
params=[
9999
Profile.Target(Profile.TargetType.GeocentricNadir, Profile.Axis.X),
100-
Profile.TrajectoryTarget(
100+
Profile.TrajectoryTarget.target_position(
101+
Trajectory.position(Position.meters((0.0, 0.0, 0.0), Frame.ITRF())),
102+
Profile.Axis.X,
103+
),
104+
Profile.TrajectoryTarget.target_velocity(
101105
Trajectory.position(Position.meters((0.0, 0.0, 0.0), Frame.ITRF())),
102106
Profile.Axis.X,
103107
),

include/OpenSpaceToolkit/Astrodynamics/Flight/Profile.hpp

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ using ostk::physics::time::Interval;
6565
using ostk::physics::unit::Angle;
6666

6767
using ostk::astrodynamics::flight::profile::Model;
68-
using ostk::astrodynamics::Trajectory;
6968
using ostk::astrodynamics::trajectory::State;
7069

7170
/// @brief Spacecraft flight profile
@@ -94,6 +93,8 @@ class Profile
9493
GeocentricNadir, /// Negative of the position vector of the satellite in the ECI frame
9594
GeodeticNadir, /// Negative of the geodetic normal of the satellite in the ECI frame
9695
Trajectory, /// Points towards the provided trajectory, eg. Ground Station in ECEF
96+
TargetPosition, /// Points towards the provided target position
97+
TargetVelocity, /// Points along the target velocity vector
9798
Sun, /// The position of the Sun
9899
Moon, /// The position of the Moon
99100
VelocityECI, /// The velocity vector in the ECI frame
@@ -128,9 +129,44 @@ class Profile
128129
/// @param aTrajectory The trajectory to point towards.
129130
/// @param anAxis The axis of the target.
130131
/// @param isAntiDirection Whether the target is in the anti-direction.
131-
TrajectoryTarget(const Trajectory& aTrajectory, const Axis& anAxis, const bool& isAntiDirection = false);
132+
[[deprecated("Use TrajectoryTarget::TargetPosition instead.")]]
133+
TrajectoryTarget(
134+
const ostk::astrodynamics::Trajectory& aTrajectory, const Axis& anAxis, const bool& isAntiDirection = false
135+
);
136+
137+
/// @brief Constructs a TrajectoryTarget object of type Trajectory, pointing towards a specific position.
138+
///
139+
/// @param aTrajectory The trajectory to point towards.
140+
/// @param anAxis The axis of the target.
141+
/// @param isAntiDirection Whether the target is in the anti-direction.
142+
static TrajectoryTarget TargetPosition(
143+
const ostk::astrodynamics::Trajectory& aTrajectory, const Axis& anAxis, const bool& isAntiDirection = false
144+
);
145+
146+
/// @brief Constructs a TrajectoryTarget object of type TargetVelocity, pointing along the scan direction.
147+
///
148+
/// @param aTrajectory The trajectory to point towards.
149+
/// @param anAxis The axis of the target.
150+
/// @param isAntiDirection Whether the target is in the anti-direction.
151+
static TrajectoryTarget TargetVelocity(
152+
const ostk::astrodynamics::Trajectory& aTrajectory, const Axis& anAxis, const bool& isAntiDirection = false
153+
);
154+
155+
ostk::astrodynamics::Trajectory trajectory; ///< The trajectory to point towards.
132156

133-
Trajectory trajectory; ///< The trajectory to point towards.
157+
private:
158+
/// @brief Constructs a TrajectoryTarget object.
159+
///
160+
/// @param aType The type of the target.
161+
/// @param aTrajectory The trajectory to point towards.
162+
/// @param anAxis The axis of the target.
163+
/// @param isAntiDirection Whether the target is in the anti-direction.
164+
TrajectoryTarget(
165+
const TargetType& aType,
166+
const ostk::astrodynamics::Trajectory& aTrajectory,
167+
const Axis& anAxis,
168+
const bool& isAntiDirection = false
169+
);
134170
};
135171

136172
/// @brief Represents a target that points towards a profile of orientations.
@@ -285,7 +321,7 @@ class Profile
285321
/// @param aTrajectory A trajectory
286322
/// @param aQuaternion A pointing in GCRF
287323
/// @return Flight profile
288-
static Profile InertialPointing(const Trajectory& aTrajectory, const Quaternion& aQuaternion);
324+
static Profile InertialPointing(const ostk::astrodynamics::Trajectory& aTrajectory, const Quaternion& aQuaternion);
289325

290326
/// @brief Constructs a flight profile with local orbital frame pointing
291327
///
@@ -340,7 +376,9 @@ class Profile
340376

341377
static Vector3d ComputeGeodeticNadirDirectionVector(const State& aState);
342378

343-
static Vector3d ComputeTargetDirectionVector(const State& aState, const Trajectory& aTrajectory);
379+
static Vector3d ComputeTargetDirectionVector(
380+
const State& aState, const ostk::astrodynamics::Trajectory& aTrajectory
381+
);
344382

345383
static Vector3d ComputeCelestialDirectionVector(const State& aState, const Celestial& aCelestial);
346384

@@ -350,6 +388,10 @@ class Profile
350388

351389
static Vector3d ComputeOrbitalMomentumDirectionVector(const State& aState);
352390

391+
static Vector3d ComputeTargetVelocityVector(
392+
const State& aState, const ostk::astrodynamics::Trajectory& aTrajectory
393+
);
394+
353395
static Vector3d ComputeClockingAxisVector(const Vector3d& anAlignmentAxisVector, const Vector3d& aClockingVector);
354396

355397
static Quaternion ComputeBodyToECIQuaternion(

src/OpenSpaceToolkit/Astrodynamics/Flight/Profile.cpp

Lines changed: 74 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Profile::Target::Target(const TargetType& aType, const Axis& anAxis, const bool&
3939
}
4040

4141
Profile::TrajectoryTarget::TrajectoryTarget(
42-
const Trajectory& aTrajectory, const Axis& anAxis, const bool& isAntiDirection
42+
const ostk::astrodynamics::Trajectory& aTrajectory, const Axis& anAxis, const bool& isAntiDirection
4343
)
4444
: Target(TargetType::Trajectory, anAxis, isAntiDirection),
4545
trajectory(aTrajectory)
@@ -50,6 +50,47 @@ Profile::TrajectoryTarget::TrajectoryTarget(
5050
}
5151
}
5252

53+
Profile::TrajectoryTarget Profile::TrajectoryTarget::TargetPosition(
54+
const ostk::astrodynamics::Trajectory& aTrajectory, const Axis& anAxis, const bool& isAntiDirection
55+
)
56+
{
57+
return TrajectoryTarget(TargetType::TargetPosition, aTrajectory, anAxis, isAntiDirection);
58+
}
59+
60+
Profile::TrajectoryTarget Profile::TrajectoryTarget::TargetVelocity(
61+
const ostk::astrodynamics::Trajectory& aTrajectory, const Axis& anAxis, const bool& isAntiDirection
62+
)
63+
{
64+
return TrajectoryTarget(TargetType::TargetVelocity, aTrajectory, anAxis, isAntiDirection);
65+
}
66+
67+
Profile::TrajectoryTarget::TrajectoryTarget(
68+
const TargetType& aType,
69+
const ostk::astrodynamics::Trajectory& aTrajectory,
70+
const Axis& anAxis,
71+
const bool& isAntiDirection
72+
)
73+
: Target(aType, anAxis, isAntiDirection),
74+
trajectory(aTrajectory)
75+
{
76+
if (!trajectory.isDefined())
77+
{
78+
throw ostk::core::error::runtime::Undefined("Trajectory");
79+
}
80+
81+
if (aType == TargetType::Trajectory)
82+
{
83+
throw ostk::core::error::RuntimeError(
84+
"TrajectoryTarget::Trajectory is deprecated. Use TrajectoryTarget::TargetPosition instead."
85+
);
86+
}
87+
88+
if (aType != TargetType::TargetPosition && aType != TargetType::TargetVelocity)
89+
{
90+
throw ostk::core::error::runtime::Wrong("Target type");
91+
}
92+
}
93+
5394
Profile::OrientationProfileTarget::OrientationProfileTarget(
5495
const Array<Pair<Instant, Vector3d>>& anOrientationProfile, const Axis& anAxis, const bool& isAntiDirection
5596
)
@@ -211,7 +252,7 @@ Profile Profile::Undefined()
211252
return {};
212253
}
213254

214-
Profile Profile::InertialPointing(const Trajectory& aTrajectory, const Quaternion& aQuaternion)
255+
Profile Profile::InertialPointing(const ostk::astrodynamics::Trajectory& aTrajectory, const Quaternion& aQuaternion)
215256
{
216257
return {TransformModel::InertialPointing(aTrajectory, aQuaternion)};
217258
}
@@ -303,12 +344,22 @@ std::function<Quaternion(const State&)> Profile::AlignAndConstrain(
303344
case TargetType::GeodeticNadir:
304345
return Profile::ComputeGeodeticNadirDirectionVector;
305346
case TargetType::Trajectory:
347+
case TargetType::TargetPosition:
306348
{
307-
const Shared<const TrajectoryTarget> trajectoryTargetSPtr =
349+
const Shared<const TrajectoryTarget> targetPositionSPtr =
308350
std::static_pointer_cast<const TrajectoryTarget>(aTargetSPtr);
309-
return [trajectoryTargetSPtr](const State& aState) -> Vector3d
351+
return [targetPositionSPtr](const State& aState) -> Vector3d
310352
{
311-
return Profile::ComputeTargetDirectionVector(aState, trajectoryTargetSPtr->trajectory);
353+
return Profile::ComputeTargetDirectionVector(aState, targetPositionSPtr->trajectory);
354+
};
355+
}
356+
case TargetType::TargetVelocity:
357+
{
358+
const Shared<const TrajectoryTarget> targetVelocitySPtr =
359+
std::static_pointer_cast<const TrajectoryTarget>(aTargetSPtr);
360+
return [targetVelocitySPtr](const State& aState) -> Vector3d
361+
{
362+
return Profile::ComputeTargetVelocityVector(aState, targetVelocitySPtr->trajectory);
312363
};
313364
}
314365
case TargetType::Sun:
@@ -411,20 +462,32 @@ Vector3d Profile::ComputeGeodeticNadirDirectionVector(const State& aState)
411462
return ITRF_GCRF_transform.applyToVector(nadir).normalized();
412463
}
413464

414-
Vector3d Profile::ComputeTargetDirectionVector(const State& aState, const Trajectory& aTrajectory)
465+
Vector3d Profile::ComputeTargetDirectionVector(const State& aState, const ostk::astrodynamics::Trajectory& aTrajectory)
415466
{
416-
if (!aTrajectory.isDefined())
417-
{
418-
throw ostk::core::error::runtime::Undefined("Trajectory");
419-
}
420-
421467
const Vector3d targetPositionCoordinates =
422468
aTrajectory.getStateAt(aState.accessInstant()).inFrame(Frame::GCRF()).getPosition().accessCoordinates();
423469
const Vector3d satellitePositionCoordinates = aState.getPosition().accessCoordinates();
424470

425471
return (targetPositionCoordinates - satellitePositionCoordinates).normalized();
426472
}
427473

474+
Vector3d Profile::ComputeTargetVelocityVector(const State& aState, const ostk::astrodynamics::Trajectory& aTrajectory)
475+
{
476+
const Transform ITRF_GCRF_transform = Frame::ITRF()->getTransformTo(Frame::GCRF(), aState.accessInstant());
477+
478+
const State slidingTargetState_GCRF = aTrajectory.getStateAt(aState.accessInstant());
479+
const State slidingTargetState_ITRF = slidingTargetState_GCRF.inFrame(Frame::ITRF());
480+
481+
const Vector3d relativePositionDirection =
482+
(slidingTargetState_GCRF.getPosition().getCoordinates() - aState.getPosition().getCoordinates()).normalized();
483+
const Vector3d relativeVelocityDirection =
484+
ITRF_GCRF_transform.applyToVector(slidingTargetState_ITRF.getVelocity().getCoordinates()).normalized();
485+
486+
const Vector3d relativeNormalDirection = relativePositionDirection.cross(relativeVelocityDirection).normalized();
487+
488+
return relativeNormalDirection.cross(relativePositionDirection);
489+
}
490+
428491
Vector3d Profile::ComputeCelestialDirectionVector(const State& aState, const Celestial& aCelestial)
429492
{
430493
const Vector3d celestialPositionCoordinates =

src/OpenSpaceToolkit/Astrodynamics/Trajectory.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,8 @@ Array<State> Trajectory::computeStates(
294294
Vector3d velocityCoordinates = Vector3d::Zero();
295295
for (Size i = 0; i < anInstantArray.getSize(); i++)
296296
{
297-
physics::coordinate::Position currentPosition = aPositionFunction(anInstantArray.at(i));
298297
const Instant currentInstant = anInstantArray.at(i);
298+
physics::coordinate::Position currentPosition = aPositionFunction(currentInstant);
299299

300300
if (i == 0)
301301
{

0 commit comments

Comments
 (0)