Skip to content

Commit dcfd0de

Browse files
authored
fix: within range angular condition, wrapping boundaries (#542)
* fix: angular condition within range across boundaries * chore: style
1 parent f32a854 commit dcfd0de

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

src/OpenSpaceToolkit/Astrodynamics/EventCondition/AngularCondition.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,13 @@ AngularCondition::AngularCondition(
203203
const Real& currentValue, [[maybe_unused]] const Real& previousValue, [[maybe_unused]] const Real& aTarget
204204
) -> bool
205205
{
206+
// For ranges that wrap around 0/360 (when lowerBound > upperBound)
207+
if (lowerBound > upperBound)
208+
{
209+
return (currentValue >= lowerBound) || (currentValue <= upperBound);
210+
}
211+
212+
// Normal range check
206213
return (currentValue >= lowerBound) && (currentValue <= upperBound);
207214
}
208215
),

test/OpenSpaceToolkit/Astrodynamics/EventCondition/AngularCondition.test.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,62 @@ TEST_F(OpenSpaceToolkit_Astrodynamics_EventCondition_AngularCondition, isSatisfi
309309
}
310310
}
311311
}
312+
313+
// Within Range
314+
{
315+
// Regular range (no boundary crossing)
316+
{
317+
const Pair<Angle, Angle> targetRange = {Angle::Degrees(30.0), Angle::Degrees(60.0)};
318+
319+
AngularCondition condition = AngularCondition::WithinRange("RegularRange", defaultEvaluator_, targetRange);
320+
321+
// Inside range
322+
{
323+
const State state = generateState(Angle::Degrees(45.0).inRadians());
324+
EXPECT_TRUE(condition.isSatisfied(state, state));
325+
}
326+
327+
// Outside range
328+
{
329+
const State state = generateState(Angle::Degrees(20.0).inRadians());
330+
EXPECT_FALSE(condition.isSatisfied(state, state));
331+
}
332+
}
333+
334+
// Boundary crossing range (-30 to 30 degrees, which normalizes to 330-30 degrees)
335+
{
336+
const Pair<Angle, Angle> boundaryCrossingRange = {Angle::Degrees(-30.0), Angle::Degrees(30.0)};
337+
338+
AngularCondition condition =
339+
AngularCondition::WithinRange("BoundaryCrossingRange", defaultEvaluator_, boundaryCrossingRange);
340+
341+
// Inside range (positive side)
342+
{
343+
const State state = generateState(Angle::Degrees(15.0).inRadians());
344+
EXPECT_TRUE(condition.isSatisfied(state, state));
345+
}
346+
347+
// Inside range (negative side - will be normalized to 345 degrees)
348+
{
349+
const State state = generateState(Angle::Degrees(-15.0).inRadians());
350+
EXPECT_TRUE(condition.isSatisfied(state, state));
351+
}
352+
353+
// Inside range (exactly at boundary)
354+
{
355+
const State lowerState = generateState(Angle::Degrees(-30.0).inRadians());
356+
const State upperState = generateState(Angle::Degrees(30.0).inRadians());
357+
EXPECT_TRUE(condition.isSatisfied(lowerState, lowerState));
358+
EXPECT_TRUE(condition.isSatisfied(upperState, upperState));
359+
}
360+
361+
// Outside range
362+
{
363+
const State state = generateState(Angle::Degrees(45.0).inRadians());
364+
EXPECT_FALSE(condition.isSatisfied(state, state));
365+
}
366+
}
367+
}
312368
}
313369

314370
TEST_F(OpenSpaceToolkit_Astrodynamics_EventCondition_AngularCondition, Clone)

0 commit comments

Comments
 (0)