-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add InstantClock and VariableInstantClock support
Adds "Instant" counterparts to Clock and VariableClock, which report absolute times as Java instants, but still step time according to an Aerie duration. Also adds some minimal interoperability between absolute and relative clocks, and some useful derivations including comparisons. Using these, also adds a global Instant-based clock to Resources, along with exposing both the duration- and instant-based clocks as resources. In doing so, we add a new parameter for the plan's start time to Resources.init(). This in turn required refactoring some unit tests, and I took the opportunity to clean up the test construction a little bit as well. This revealed a way to correctly initialize Resources, i.e., to call Resources.init() exactly once per initialization of each test model. As a result, I refactored the clock handling to remove the awkward reinitialization pattern, since that pattern was added to handle test code.
- Loading branch information
David Legg
committed
Oct 30, 2024
1 parent
524474c
commit 7e85f30
Showing
15 changed files
with
291 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
...rib/src/main/java/gov/nasa/jpl/aerie/contrib/streamline/modeling/clocks/InstantClock.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package gov.nasa.jpl.aerie.contrib.streamline.modeling.clocks; | ||
|
||
import gov.nasa.jpl.aerie.contrib.streamline.core.Dynamics; | ||
import gov.nasa.jpl.aerie.merlin.protocol.types.Duration; | ||
|
||
import java.time.Instant; | ||
import java.time.temporal.ChronoUnit; | ||
|
||
import static gov.nasa.jpl.aerie.merlin.protocol.types.Duration.addToInstant; | ||
|
||
/** | ||
* A variation on {@link Clock} that represents an absolute {@link Instant} | ||
* instead of a relative {@link Duration}. | ||
*/ | ||
public record InstantClock(Instant extract) implements Dynamics<Instant, InstantClock> { | ||
@Override | ||
public InstantClock step(Duration t) { | ||
return new InstantClock(addToInstant(extract, t)); | ||
} | ||
|
||
static Duration durationBetween(Instant start, Instant end) { | ||
return Duration.of(ChronoUnit.MICROS.between(start, end), Duration.MICROSECONDS); | ||
} | ||
} |
56 changes: 56 additions & 0 deletions
56
...ain/java/gov/nasa/jpl/aerie/contrib/streamline/modeling/clocks/InstantClockResources.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package gov.nasa.jpl.aerie.contrib.streamline.modeling.clocks; | ||
|
||
import gov.nasa.jpl.aerie.contrib.streamline.core.*; | ||
import gov.nasa.jpl.aerie.contrib.streamline.core.monads.ResourceMonad; | ||
import gov.nasa.jpl.aerie.contrib.streamline.modeling.discrete.Discrete; | ||
import gov.nasa.jpl.aerie.merlin.protocol.types.Duration; | ||
|
||
import java.time.Instant; | ||
|
||
import static gov.nasa.jpl.aerie.contrib.streamline.core.MutableResource.resource; | ||
import static gov.nasa.jpl.aerie.contrib.streamline.core.monads.ResourceMonad.map; | ||
import static gov.nasa.jpl.aerie.contrib.streamline.debugging.Naming.name; | ||
import static gov.nasa.jpl.aerie.contrib.streamline.modeling.discrete.DiscreteResources.constant; | ||
|
||
public class InstantClockResources { | ||
/** | ||
* Create an absolute clock that starts now at the given start time. | ||
*/ | ||
public static MutableResource<InstantClock> absoluteClock(Instant startTime) { | ||
return resource(new InstantClock(startTime)); | ||
} | ||
|
||
public static Resource<InstantClock> addToInstant(Instant zeroTime, Resource<Clock> relativeClock) { | ||
return addToInstant(constant(zeroTime), relativeClock); | ||
} | ||
|
||
public static Resource<InstantClock> addToInstant(Resource<Discrete<Instant>> zeroTime, Resource<Clock> relativeClock) { | ||
return name( | ||
map(zeroTime, relativeClock, (zero, clock) -> | ||
new InstantClock(Duration.addToInstant(zero.extract(), clock.extract()))), | ||
"%s + %s", | ||
zeroTime, | ||
relativeClock); | ||
} | ||
|
||
public static Resource<Clock> relativeTo(Resource<InstantClock> clock, Resource<Discrete<Instant>> zeroTime) { | ||
return name(ResourceMonad.map(clock, zeroTime, (c, t) -> new Clock(InstantClock.durationBetween(t.extract(), c.extract()))), | ||
"%s relative to %s", clock, zeroTime); | ||
} | ||
|
||
public static Resource<Discrete<Boolean>> lessThan(Resource<InstantClock> clock, Resource<Discrete<Instant>> threshold) { | ||
return ClockResources.lessThan(relativeTo(clock, threshold), constant(Duration.ZERO)); | ||
} | ||
|
||
public static Resource<Discrete<Boolean>> lessThanOrEquals(Resource<InstantClock> clock, Resource<Discrete<Instant>> threshold) { | ||
return ClockResources.lessThanOrEquals(relativeTo(clock, threshold), constant(Duration.ZERO)); | ||
} | ||
|
||
public static Resource<Discrete<Boolean>> greaterThan(Resource<InstantClock> clock, Resource<Discrete<Instant>> threshold) { | ||
return ClockResources.greaterThan(relativeTo(clock, threshold), constant(Duration.ZERO)); | ||
} | ||
|
||
public static Resource<Discrete<Boolean>> greaterThanOrEquals(Resource<InstantClock> clock, Resource<Discrete<Instant>> threshold) { | ||
return ClockResources.greaterThanOrEquals(relativeTo(clock, threshold), constant(Duration.ZERO)); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
...main/java/gov/nasa/jpl/aerie/contrib/streamline/modeling/clocks/VariableInstantClock.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package gov.nasa.jpl.aerie.contrib.streamline.modeling.clocks; | ||
|
||
import gov.nasa.jpl.aerie.contrib.streamline.core.Dynamics; | ||
import gov.nasa.jpl.aerie.merlin.protocol.types.Duration; | ||
|
||
import java.time.Instant; | ||
|
||
import static gov.nasa.jpl.aerie.merlin.protocol.types.Duration.addToInstant; | ||
|
||
/** | ||
* A variation on {@link VariableClock} that represents an absolute {@link Instant} | ||
* instead of a relative {@link Duration}. | ||
*/ | ||
public record VariableInstantClock(Instant extract, int multiplier) implements Dynamics<Instant, VariableInstantClock> { | ||
@Override | ||
public VariableInstantClock step(Duration t) { | ||
return new VariableInstantClock(addToInstant(extract, t.times(multiplier)), multiplier); | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
...va/gov/nasa/jpl/aerie/contrib/streamline/modeling/clocks/VariableInstantClockEffects.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package gov.nasa.jpl.aerie.contrib.streamline.modeling.clocks; | ||
|
||
import gov.nasa.jpl.aerie.contrib.streamline.core.MutableResource; | ||
|
||
import java.time.Instant; | ||
|
||
import static gov.nasa.jpl.aerie.contrib.streamline.core.monads.DynamicsMonad.effect; | ||
import static gov.nasa.jpl.aerie.contrib.streamline.debugging.Naming.name; | ||
|
||
public final class VariableInstantClockEffects { | ||
private VariableInstantClockEffects() {} | ||
|
||
/** | ||
* Stop the clock without affecting the current time. | ||
*/ | ||
public static void pause(MutableResource<VariableInstantClock> clock) { | ||
clock.emit("Pause", effect($ -> new VariableInstantClock($.extract(), 0))); | ||
} | ||
|
||
/** | ||
* Start the clock without affecting the current time. | ||
*/ | ||
public static void start(MutableResource<VariableInstantClock> clock) { | ||
clock.emit("Start", effect($ -> new VariableInstantClock($.extract(), 1))); | ||
} | ||
|
||
/** | ||
* Reset the clock to the given time, without affecting how fast it's running. | ||
*/ | ||
public static void reset(MutableResource<VariableInstantClock> clock, Instant newTime) { | ||
clock.emit(name(effect($ -> new VariableInstantClock(newTime, $.multiplier())), "Reset to %s", newTime)); | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
.../gov/nasa/jpl/aerie/contrib/streamline/modeling/clocks/VariableInstantClockResources.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package gov.nasa.jpl.aerie.contrib.streamline.modeling.clocks; | ||
|
||
import gov.nasa.jpl.aerie.contrib.streamline.core.Resource; | ||
import gov.nasa.jpl.aerie.contrib.streamline.modeling.discrete.Discrete; | ||
import gov.nasa.jpl.aerie.merlin.protocol.types.Duration; | ||
|
||
import java.time.Instant; | ||
|
||
import static gov.nasa.jpl.aerie.contrib.streamline.core.monads.ResourceMonad.map; | ||
import static gov.nasa.jpl.aerie.contrib.streamline.debugging.Naming.name; | ||
import static gov.nasa.jpl.aerie.contrib.streamline.modeling.clocks.InstantClock.durationBetween; | ||
import static gov.nasa.jpl.aerie.contrib.streamline.modeling.discrete.DiscreteResources.constant; | ||
|
||
public final class VariableInstantClockResources { | ||
private VariableInstantClockResources() {} | ||
|
||
public static Resource<VariableClock> relativeTo(Resource<VariableInstantClock> clock, Resource<Discrete<Instant>> zeroTime) { | ||
return name(map(clock, zeroTime, (c, t) -> | ||
new VariableClock(durationBetween(c.extract(), t.extract()), c.multiplier())), | ||
"%s relative to %s", clock, zeroTime); | ||
} | ||
|
||
public static Resource<Discrete<Boolean>> lessThan(Resource<VariableInstantClock> clock, Resource<Discrete<Instant>> threshold) { | ||
return VariableClockResources.lessThan(relativeTo(clock, threshold), constant(Duration.ZERO)); | ||
} | ||
|
||
public static Resource<Discrete<Boolean>> lessThanOrEquals(Resource<VariableInstantClock> clock, Resource<Discrete<Instant>> threshold) { | ||
return VariableClockResources.lessThanOrEquals(relativeTo(clock, threshold), constant(Duration.ZERO)); | ||
} | ||
|
||
public static Resource<Discrete<Boolean>> greaterThan(Resource<VariableInstantClock> clock, Resource<Discrete<Instant>> threshold) { | ||
return VariableClockResources.greaterThan(relativeTo(clock, threshold), constant(Duration.ZERO)); | ||
} | ||
|
||
public static Resource<Discrete<Boolean>> greaterThanOrEquals(Resource<VariableInstantClock> clock, Resource<Discrete<Instant>> threshold) { | ||
return VariableClockResources.greaterThanOrEquals(relativeTo(clock, threshold), constant(Duration.ZERO)); | ||
} | ||
|
||
public static Resource<VariableClock> between(Resource<VariableInstantClock> start, Resource<VariableInstantClock> end) { | ||
return map(start, end, (s, e) -> new VariableClock(durationBetween(s.extract(), e.extract()), e.multiplier() - s.multiplier())); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.