Skip to content

Commit

Permalink
Represent instance source as a sum type
Browse files Browse the repository at this point in the history
  • Loading branch information
JoelCourtney committed Sep 6, 2024
1 parent 1ba26bd commit 4d5cb1f
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.microsoft.playwright.Playwright;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.InstanceSourceId;
import gov.nasa.jpl.aerie.e2e.utils.GatewayRequests;
import gov.nasa.jpl.aerie.e2e.utils.HasuraRequests;
import gov.nasa.jpl.aerie.merlin.protocol.types.Duration;
Expand Down Expand Up @@ -118,8 +119,8 @@ void queryActivityInstances() {
assertEquals(1, instances.size());
final var instance = instances.get(0);
assertEquals("BiteBanana", instance.getType());
assert instance.directiveId != null;
assertEquals(activityId, instance.directiveId.id());
assert instance.sourceId instanceof InstanceSourceId.Direct;
assertEquals(activityId, ((InstanceSourceId.Direct) instance.sourceId).from.id());
assertEquals(1, instance.inner.arguments.get("biteSize").asInt().get());
assertEquals(Duration.ZERO, instance.getInterval().duration());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import gov.nasa.ammos.aerie.procedural.timeline.ops.coalesce.CoalesceNoOp
import gov.nasa.ammos.aerie.procedural.timeline.payloads.IntervalLike
import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.Directive
import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.Instance
import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.InstanceSourceId
import gov.nasa.ammos.aerie.procedural.timeline.util.preprocessList
import gov.nasa.jpl.aerie.types.ActivityId

Expand Down Expand Up @@ -71,7 +72,10 @@ data class Violations(private val timeline: Timeline<Violation, Violations>):
) }

private fun <V: IntervalLike<V>> V.getActivityId(): ActivityId? = when (this) {
is Instance<*> -> if (directiveId != null) directiveId else id
is Instance<*> -> when (val s = sourceId) {
is InstanceSourceId.Direct -> s.from
is InstanceSourceId.Spawned -> s.from
}
is Directive<*> -> id
else -> null
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package gov.nasa.ammos.aerie.procedural.examples.fooprocedures.procedures;

import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.InstanceSourceId;
import gov.nasa.jpl.aerie.merlin.protocol.types.Duration;
import gov.nasa.jpl.aerie.merlin.protocol.types.SerializedValue;
import gov.nasa.ammos.aerie.procedural.scheduling.Goal;
Expand Down Expand Up @@ -38,13 +39,19 @@ public void run(@NotNull final EditablePlan plan) {

for (final var connection: connections) {
assert connection.to != null;
DirectiveStart start;
if (connection.to.sourceId instanceof InstanceSourceId.Direct d) {
start = new DirectiveStart.Anchor(
d.from,
Duration.minutes(30),
DirectiveStart.Anchor.AnchorPoint.End
);
} else {
start = new DirectiveStart.Absolute(connection.to.getInterval().end.plus(Duration.minutes(30)));
}
plan.create(
"GrowBanana",
new DirectiveStart.Anchor(
connection.to.directiveId,
Duration.minutes(30),
DirectiveStart.Anchor.AnchorPoint.End
),
start,
Map.of(
"quantity", SerializedValue.of(1),
"growingDuration", SerializedValue.of(Duration.HOUR.dividedBy(Duration.MICROSECOND))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import gov.nasa.ammos.aerie.procedural.timeline.collections.Instances
import gov.nasa.ammos.aerie.procedural.timeline.ops.coalesce.CoalesceSegmentsOp
import gov.nasa.ammos.aerie.procedural.timeline.payloads.Segment
import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.Instance
import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.InstanceSourceId
import gov.nasa.ammos.aerie.procedural.timeline.plan.Plan
import gov.nasa.ammos.aerie.procedural.timeline.plan.SimulationResults
import gov.nasa.jpl.aerie.types.ActivityDirectiveId
Expand Down Expand Up @@ -168,8 +169,9 @@ data class AeriePostgresSimulationResults(
deserializer(attributes),
response.getString(4),
ActivityInstanceId(id),
directiveId?.let { ActivityDirectiveId(it) },
if (parentId == 0L) null else ActivityInstanceId(parentId),
directiveId?.let { InstanceSourceId.Direct(ActivityDirectiveId(it)) }
?: if (parentId != 0L) InstanceSourceId.Spawned(ActivityInstanceId(parentId))
else throw IllegalStateException("all activities must either be directly created or spawned."),
between(start, start.plus(Duration.parseISO8601(response.getString(2))))
))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ package gov.nasa.ammos.aerie.procedural.scheduling.simulation
// The following two options will be uncommented when checkpoint simulation is released.
// val checkPointGeneration: CheckpointGeneration = CheckpointGeneration.None,
// val checkpointRetention: CheckpointRetention = CheckpointRetention.All,
/** When the simulation should pause. */
val pause: PauseBehavior = PauseBehavior.AtEnd,
)
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ data class BaseTimeline<V: IntervalLike<V>, TL: Timeline<V, TL>>(
return specialize()
}

/** Create an iterator by calling [collect]. */
override fun iterator(): Iterator<V> = collect().iterator()

override fun collect(opts: CollectOptions) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package gov.nasa.ammos.aerie.procedural.timeline.payloads.activities

import gov.nasa.ammos.aerie.procedural.timeline.Interval
import gov.nasa.jpl.aerie.merlin.protocol.types.Duration
import gov.nasa.jpl.aerie.types.ActivityDirectiveId
import gov.nasa.jpl.aerie.types.ActivityInstanceId

/** A wrapper of any type of activity instance containing common data. */
Expand All @@ -14,17 +13,13 @@ data class Instance<A: Any>(
/** The instance id. */
@JvmField val id: ActivityInstanceId,

/**
* The maybe-null id of the directive associated with this instance.
*
* Will be `null` if this is a child activity.
*/
@JvmField val directiveId: ActivityDirectiveId?,
@JvmField val parentId: ActivityInstanceId?,
/** The source id; the directive or instance that caused this instance. */
@JvmField val sourceId: InstanceSourceId,

override val interval: Interval,
): Activity<Instance<A>> {
override val startTime: Duration
get() = interval.start

override fun withNewInterval(i: Interval) = Instance(inner, type, id, directiveId, parentId, i)
override fun withNewInterval(i: Interval) = Instance(inner, type, id, sourceId, i)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package gov.nasa.ammos.aerie.procedural.timeline.payloads.activities

import gov.nasa.jpl.aerie.types.ActivityDirectiveId
import gov.nasa.jpl.aerie.types.ActivityInstanceId

/**
* Stores the id of a directive or instance that caused an instance to be simulated,
* and the relationship of the instance to it.
*/
sealed interface InstanceSourceId {
/** The instance was directly created by a directive. */
data class Direct(/***/ @JvmField val from: ActivityDirectiveId): InstanceSourceId

/** The instance was spawned by another activity, which may itself have been spawned. */
data class Spawned(/***/ @JvmField val from: ActivityInstanceId): InstanceSourceId
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package gov.nasa.jpl.aerie.scheduler.plan

import gov.nasa.jpl.aerie.merlin.driver.engine.ProfileSegment
import gov.nasa.jpl.aerie.merlin.protocol.types.Duration
import gov.nasa.jpl.aerie.merlin.protocol.types.SerializedValue
import gov.nasa.ammos.aerie.procedural.timeline.Interval
import gov.nasa.ammos.aerie.procedural.timeline.collections.Instances
import gov.nasa.ammos.aerie.procedural.timeline.util.duration.rangeTo
import gov.nasa.ammos.aerie.procedural.timeline.ops.coalesce.CoalesceSegmentsOp
import gov.nasa.ammos.aerie.procedural.timeline.payloads.Segment
import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.Activity
import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.Instance
import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.InstanceSourceId
import gov.nasa.ammos.aerie.procedural.timeline.plan.Plan
import gov.nasa.ammos.aerie.procedural.timeline.plan.SimulationResults
import gov.nasa.ammos.aerie.procedural.timeline.util.duration.rangeTo
import gov.nasa.jpl.aerie.merlin.driver.engine.ProfileSegment
import gov.nasa.jpl.aerie.merlin.protocol.types.Duration
import gov.nasa.jpl.aerie.merlin.protocol.types.SerializedValue
import gov.nasa.jpl.aerie.types.ActivityDirectiveId
import gov.nasa.jpl.aerie.types.ActivityInstanceId
import java.time.Instant
Expand Down Expand Up @@ -113,8 +113,9 @@ class MerlinToProcedureSimulationResultsAdapter(
deserializer(serializedActivity),
a.type,
a.instanceId,
a.directiveId,
a.parentId,
a.directiveId?.let { InstanceSourceId.Direct(it) }
?: a.parentId?.let { InstanceSourceId.Spawned(it) }
?: throw IllegalStateException("all activities must either be directly created or spawned."),
Interval(startTime, endTime)
))
}
Expand Down

0 comments on commit 4d5cb1f

Please sign in to comment.