Skip to content

Commit

Permalink
Use Plan in place of SimulationMessage
Browse files Browse the repository at this point in the history
With the changes made, a Plan now contains all of the information necessary to simulate.

Additionally, since this class will be more relevant to external users via the Orchestration package, comment and privatize fields.

Additionally, prevent the sim config and activity directive maps from being null.

Co-authored-by: Ryan Goetz <[email protected]>
  • Loading branch information
Mythicaeda and goetzrrGit committed Aug 30, 2024
1 parent 77b3f19 commit 20248a8
Show file tree
Hide file tree
Showing 15 changed files with 151 additions and 153 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -328,10 +328,10 @@ private void validatePlan(final Context ctx) {
final var planId = parseJson(ctx.body(), hasuraPlanActionP).input().planId();

final var plan = this.planService.getPlanForValidation(planId);
final var activities = plan.activityDirectives.entrySet().stream().collect(Collectors.toMap(
final var activities = plan.activityDirectives().entrySet().stream().collect(Collectors.toMap(
Map.Entry::getKey,
e -> e.getValue().serializedActivity()));
final var failures = this.missionModelService.validateActivityInstantiations(plan.missionModelId, activities);
final var failures = this.missionModelService.validateActivityInstantiations(plan.missionModelId(), activities);

ctx.result(ResponseSerializers.serializeUnconstructableActivityFailures(failures).toString());
} catch (final InvalidJsonException ex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,7 @@ public InMemoryRevisionData getPlanRevisionData(final PlanId planId) throws NoSu
public CreatedPlan storePlan(final Plan other) {
final PlanId planId = new PlanId(this.nextPlanId++);
final Plan plan = new Plan(other);
final List<ActivityDirectiveId> activityIds =
other.activityDirectives != null ? List.copyOf(plan.activityDirectives.keySet()) : List.of();
if (other.activityDirectives == null) plan.activityDirectives = new HashMap<>();
final List<ActivityDirectiveId> activityIds = List.copyOf(plan.activityDirectives().keySet());

this.plans.put(planId, Pair.of(0L, plan));
return new CreatedPlan(planId, activityIds);
Expand All @@ -101,7 +99,7 @@ public ActivityDirectiveId createActivity(final PlanId planId, final ActivityDir
final var revision = entry.getLeft() + 1;

final ActivityDirectiveId activityId = new ActivityDirectiveId(this.nextActivityId++);
plan.activityDirectives.put(activityId, activity);
plan.activityDirectives().put(activityId, activity);
this.plans.put(planId, Pair.of(revision, plan));

return activityId;
Expand All @@ -114,7 +112,7 @@ public void deleteAllActivities(final PlanId planId) throws NoSuchPlanException
final var plan = entry.getRight();
final var revision = entry.getLeft() + 1;

plan.activityDirectives.clear();
plan.activityDirectives().clear();
this.plans.put(planId, Pair.of(revision, plan));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,53 +5,61 @@
import gov.nasa.jpl.aerie.merlin.protocol.types.Duration;
import gov.nasa.jpl.aerie.merlin.protocol.types.SerializedValue;

import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
* A representation of a grounded plan. Contains the necessary information to be simulated.
*/
public final class Plan {
public String name;
public MissionModelId missionModelId;
public Timestamp startTimestamp;
public Timestamp endTimestamp;
public Map<ActivityDirectiveId, ActivityDirective> activityDirectives;
public Map<String, SerializedValue> configuration = new HashMap<>();
// Set-once fields
private final String name;
private final MissionModelId missionModelId;
private final Timestamp startTimestamp;
private final Timestamp endTimestamp;
private final Map<ActivityDirectiveId, ActivityDirective> activityDirectives;
private final Map<String, SerializedValue> configuration;

// Simulation start and end times can be freely updated
public Timestamp simulationStartTimestamp;
public Timestamp simulationEndTimestamp;

public Plan() {}

public Plan(final Plan other) {
this.name = other.name;
this.missionModelId = other.missionModelId;
this.startTimestamp = other.startTimestamp;
this.endTimestamp = other.endTimestamp;
this.simulationStartTimestamp = other.simulationStartTimestamp;
this.simulationEndTimestamp = other.simulationEndTimestamp;

if (other.activityDirectives != null) {
this.activityDirectives = new HashMap<>();
this.activityDirectives.putAll(other.activityDirectives);
}

if (other.configuration != null) this.configuration = new HashMap<>(other.configuration);
}

public Plan(
final String name,
final MissionModelId missionModelId,
final Timestamp startTimestamp,
final Timestamp endTimestamp,
final Map<ActivityDirectiveId, ActivityDirective> activityDirectives
) {
this.name = name;
this.missionModelId = missionModelId;
this.startTimestamp = startTimestamp;
this.endTimestamp = endTimestamp;
this.activityDirectives = (activityDirectives != null) ? Map.copyOf(activityDirectives) : null;
this.configuration = null;
this.simulationStartTimestamp = startTimestamp;
this.simulationEndTimestamp = endTimestamp;
this(
name,
missionModelId,
startTimestamp,
endTimestamp,
activityDirectives,
null,
startTimestamp,
endTimestamp);
}

public Plan(
String name,
Timestamp startTimestamp,
Timestamp endTimestamp,
Map<ActivityDirectiveId, ActivityDirective> activityDirectives,
Map<String, SerializedValue> simulationConfig
) {
this(
name,
null,
startTimestamp,
endTimestamp,
activityDirectives,
simulationConfig,
startTimestamp,
endTimestamp);
}

public Plan(
Expand All @@ -68,31 +76,74 @@ public Plan(
this.missionModelId = missionModelId;
this.startTimestamp = startTimestamp;
this.endTimestamp = endTimestamp;
this.activityDirectives = (activityDirectives != null) ? Map.copyOf(activityDirectives) : null;
if (configuration != null) this.configuration = new HashMap<>(configuration);
this.activityDirectives = (activityDirectives != null) ? new HashMap<>(activityDirectives) : new HashMap<>();
this.configuration = (configuration != null) ? new HashMap<>(configuration) : new HashMap<>();
this.simulationStartTimestamp = simulationStartTimestamp;
this.simulationEndTimestamp = simulationEndTimestamp;
}

public Plan(
String name,
Timestamp startTimestamp,
Timestamp endTimestamp,
Map<ActivityDirectiveId, ActivityDirective> activityDirectives,
Map<String, SerializedValue> simulationConfig) {
this.name = name;
this.startTimestamp = startTimestamp;
this.endTimestamp = endTimestamp;
this.activityDirectives = activityDirectives;
this.configuration = simulationConfig;
this.simulationStartTimestamp = startTimestamp;
this.simulationEndTimestamp = endTimestamp;
public Plan(final Plan other) {
this.name = other.name;
this.missionModelId = other.missionModelId;
this.startTimestamp = other.startTimestamp;
this.endTimestamp = other.endTimestamp;
this.simulationStartTimestamp = other.simulationStartTimestamp;
this.simulationEndTimestamp = other.simulationEndTimestamp;
this.activityDirectives = new HashMap<>(other.activityDirectives);
this.configuration = new HashMap<>(other.configuration);
}

/**
* Get the plan's name.
*/
public String name() {return name;}

/**
* Get the id of the mission model this plan will work with.
*/
public MissionModelId missionModelId() {return missionModelId;}

/**
* Get the start of the plan as an Instant.
*/
public Instant planStartInstant() {return startTimestamp.toInstant();}

/**
* Get the duration of the plan.
*/
public Duration duration() {
return Duration.of(startTimestamp.microsUntil(endTimestamp), Duration.MICROSECOND);
}

/**
* Get the map of grounded activity directives in this plan.
*/
public Map<ActivityDirectiveId, ActivityDirective> activityDirectives() {return activityDirectives;}

/**
* Get the requested simulation configuration.
*/
public Map<String, SerializedValue> simulationConfiguration() {return configuration;}

/**
* Get the requested simulation start time as an Instant.
*/
public Instant simulationStartInstant() {return simulationStartTimestamp.toInstant();}

/**
* Get the requested simulation duration.
*/
public Duration simulationDuration() {
return Duration.of(simulationStartTimestamp.microsUntil(simulationEndTimestamp), Duration.MICROSECOND);
}

/**
* Get the offset between the start time of the plan and the requested start time of simulation.
*/
public Duration simulationOffset() {
return Duration.of(startTimestamp.microsUntil(simulationStartTimestamp), Duration.MICROSECOND);
}

@Override
public boolean equals(final Object object) {
if (!(object instanceof final Plan other)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,11 @@ public Map<Constraint, Fallible<?>> getViolations(final PlanId planId, final Opt
if (!constraintCode.isEmpty()) {
final var simStartTime = resultsHandle$
.map(gov.nasa.jpl.aerie.merlin.server.models.SimulationResultsHandle::startTime)
.orElse(plan.startTimestamp.toInstant());
.orElse(plan.simulationStartInstant());
final var simDuration = resultsHandle$
.map(SimulationResultsHandle::duration)
.orElse(Duration.of(
plan.simulationStartTimestamp.toInstant().until(plan.simulationEndTimestamp.toInstant(), ChronoUnit.MICROS),
Duration.MICROSECONDS));
final var simOffset = Duration.of(
plan.startTimestamp.toInstant().until(simStartTime, ChronoUnit.MICROS),
Duration.MICROSECONDS);
.orElse(plan.simulationDuration());
final var simOffset = plan.simulationOffset();

final var activities = new ArrayList<ActivityInstance>();
final var simulatedActivities = resultsHandle$
Expand Down Expand Up @@ -138,7 +134,7 @@ public Map<Constraint, Fallible<?>> getViolations(final PlanId planId, final Opt
final ConstraintsDSLCompilationService.ConstraintsDSLCompilationResult constraintCompilationResult;
try {
constraintCompilationResult = constraintsDSLCompilationService.compileConstraintsDSL(
plan.missionModelId,
plan.missionModelId(),
Optional.of(planId),
Optional.of(simDatasetId),
constraint.definition()
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import gov.nasa.jpl.aerie.merlin.driver.SerializedActivity;
import gov.nasa.jpl.aerie.merlin.driver.SimulationDriver;
import gov.nasa.jpl.aerie.merlin.driver.SimulationResults;
import gov.nasa.jpl.aerie.merlin.driver.engine.ProfileSegment;
import gov.nasa.jpl.aerie.merlin.driver.resources.SimulationResourceManager;
import gov.nasa.jpl.aerie.merlin.protocol.model.InputType.Parameter;
import gov.nasa.jpl.aerie.merlin.protocol.model.InputType.ValidationNotice;
Expand All @@ -20,6 +19,7 @@
import gov.nasa.jpl.aerie.merlin.server.models.ActivityType;
import gov.nasa.jpl.aerie.merlin.server.models.MissionModelId;
import gov.nasa.jpl.aerie.merlin.server.models.MissionModelJar;
import gov.nasa.jpl.aerie.merlin.server.models.Plan;
import gov.nasa.jpl.aerie.merlin.server.remotes.MissionModelRepository;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
Expand Down Expand Up @@ -280,19 +280,19 @@ public Map<String, SerializedValue> getModelEffectiveArguments(final MissionMode
/**
* Validate that a set of activity parameters conforms to the expectations of a named mission model.
*
* @param message The parameters defining the simulation to perform.
* @param plan The plan to be simulated. Contains the parameters defining the simulation to perform.
* @return A set of samples over the course of the simulation.
* @throws NoSuchMissionModelException If no mission model is known by the given ID.
*/
@Override
public SimulationResults runSimulation(
final CreateSimulationMessage message,
final Plan plan,
final Consumer<Duration> simulationExtentConsumer,
final Supplier<Boolean> canceledListener,
final SimulationResourceManager resourceManager)
throws NoSuchMissionModelException
{
final var config = message.configuration();
final var config = plan.simulationConfiguration();
if (config.isEmpty()) {
log.warn(
"No mission model configuration defined for mission model. Simulations will receive an empty set of configuration arguments.");
Expand All @@ -301,14 +301,14 @@ public SimulationResults runSimulation(
// TODO: [AERIE-1516] Teardown the mission model after use to release any system resources (e.g. threads).
return SimulationDriver.simulate(
loadAndInstantiateMissionModel(
message.missionModelId(),
message.simulationStartTime(),
plan.missionModelId(),
plan.planStartInstant(),
SerializedValue.of(config)),
message.activityDirectives(),
message.simulationStartTime(),
message.simulationDuration(),
message.planStartTime(),
message.planDuration(),
plan.activityDirectives(),
plan.simulationStartInstant(),
plan.simulationDuration(),
plan.planStartInstant(),
plan.duration(),
canceledListener,
simulationExtentConsumer,
resourceManager);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import gov.nasa.jpl.aerie.merlin.driver.MissionModelLoader;
import gov.nasa.jpl.aerie.merlin.driver.SerializedActivity;
import gov.nasa.jpl.aerie.merlin.driver.SimulationResults;
import gov.nasa.jpl.aerie.merlin.driver.engine.ProfileSegment;
import gov.nasa.jpl.aerie.merlin.driver.resources.SimulationResourceManager;
import gov.nasa.jpl.aerie.merlin.protocol.model.InputType.Parameter;
import gov.nasa.jpl.aerie.merlin.protocol.model.InputType.ValidationNotice;
Expand All @@ -15,8 +14,8 @@
import gov.nasa.jpl.aerie.merlin.server.models.ActivityType;
import gov.nasa.jpl.aerie.merlin.server.models.MissionModelId;
import gov.nasa.jpl.aerie.merlin.server.models.MissionModelJar;
import gov.nasa.jpl.aerie.merlin.server.models.Plan;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
Expand Down Expand Up @@ -66,7 +65,7 @@ Map<String, SerializedValue> getModelEffectiveArguments(MissionModelId missionMo
InstantiationException;

SimulationResults runSimulation(
final CreateSimulationMessage message,
final Plan plan,
final Consumer<Duration> writer,
final Supplier<Boolean> canceledListener,
final SimulationResourceManager resourceManager
Expand Down
Loading

0 comments on commit 20248a8

Please sign in to comment.