diff --git a/examples/banananation/src/main/java/gov/nasa/jpl/aerie/banananation/activities/BiteBananaActivity.java b/examples/banananation/src/main/java/gov/nasa/jpl/aerie/banananation/activities/BiteBananaActivity.java index 264a9af2eb..d11206b756 100644 --- a/examples/banananation/src/main/java/gov/nasa/jpl/aerie/banananation/activities/BiteBananaActivity.java +++ b/examples/banananation/src/main/java/gov/nasa/jpl/aerie/banananation/activities/BiteBananaActivity.java @@ -21,7 +21,6 @@ @ActivityType("BiteBanana") public final class BiteBananaActivity { @Parameter - @Banannotation("Specifies the size of bite to take") @Unit("m") public double biteSize = 1.0; diff --git a/examples/banananation/src/main/java/gov/nasa/jpl/aerie/banananation/activities/RussianBanana.java b/examples/banananation/src/main/java/gov/nasa/jpl/aerie/banananation/activities/RussianBanana.java deleted file mode 100644 index 0331d2f998..0000000000 --- a/examples/banananation/src/main/java/gov/nasa/jpl/aerie/banananation/activities/RussianBanana.java +++ /dev/null @@ -1,43 +0,0 @@ -package gov.nasa.jpl.aerie.banananation.activities; - -import gov.nasa.jpl.aerie.banananation.Mission; -import gov.nasa.jpl.aerie.merlin.framework.annotations.ActivityType; -import gov.nasa.jpl.aerie.merlin.framework.annotations.Export; -import gov.nasa.jpl.aerie.merlin.protocol.types.Duration; - -import java.util.List; - -import static gov.nasa.jpl.aerie.banananation.generated.ActivityActions.call; -import static gov.nasa.jpl.aerie.merlin.framework.ModelActions.delay; - -/** - * Russian Banana Encloses Banana - * - * This activity causes a piece of banana to be bitten off and consumed. - * - * @subsystem fruit - * @contact John Doe - */ -@ActivityType("RussianBanana") -public final class RussianBanana { - - @Export.Parameter - public List testints; - - @Export.Parameter - public List biteBananaActivity; - - @Export.Parameter - public PeelBananaActivity peelBananaActivity; - - - @ActivityType.EffectModel - public void run(final Mission mission) { - for (final var bite : biteBananaActivity) { - call(mission, bite); - delay(Duration.of(30, Duration.MINUTE)); - } - call(mission, peelBananaActivity); - } - -} diff --git a/examples/banananation/src/main/java/gov/nasa/jpl/aerie/banananation/activities/RussianNestingBanana.java b/examples/banananation/src/main/java/gov/nasa/jpl/aerie/banananation/activities/RussianNestingBanana.java new file mode 100644 index 0000000000..8a48c7a8da --- /dev/null +++ b/examples/banananation/src/main/java/gov/nasa/jpl/aerie/banananation/activities/RussianNestingBanana.java @@ -0,0 +1,72 @@ +package gov.nasa.jpl.aerie.banananation.activities; + +import gov.nasa.jpl.aerie.banananation.Mission; +import gov.nasa.jpl.aerie.merlin.framework.annotations.ActivityType; +import gov.nasa.jpl.aerie.merlin.framework.annotations.AutoValueMapper; +import gov.nasa.jpl.aerie.merlin.framework.annotations.Export; +import gov.nasa.jpl.aerie.merlin.protocol.types.Duration; + +import java.util.List; +import java.util.Optional; + +import static gov.nasa.jpl.aerie.banananation.generated.ActivityActions.call; +import static gov.nasa.jpl.aerie.merlin.framework.ModelActions.delay; + +/** + * RussianNestingBanana nests activity types as parameters inside an activity + * + * This activity tests the use of activity types as parameters and within compound type parameters. There are a few use cases: + * 1. Basic activity type parameter which is passed through and called without parent level modeling + * 2. List of activity types which are just iterated through and called + * 3. Using a parent level parameter to override information in the call to a child from an activity type parameter + * + * @subsystem fruit + * @contact John Doe + */ +@ActivityType("RussianNestingBanana") +public final class RussianNestingBanana { + + /** Record encapsulating an activity type **/ + @AutoValueMapper.Record + public record pickBananaWithId( + int id, + PickBananaActivity pickBananaActivity + ) {} + + /** Record type parameter encapsulating an activity type **/ + @Export.Parameter + public pickBananaWithId pickBananaActivityRecord; + + /** Parent level override parameter, in this case to override call to peel banana + * found in the pickBannaActivityRecord parameter **/ + @Export.Parameter + public int pickBananaQuantityOverride = 0; + + /** List of activity type parameter example **/ + @Export.Parameter + public List biteBananaActivity; + + /** Vanilla activity type parameter **/ + @Export.Parameter + public PeelBananaActivity peelBananaActivity; + + + @ActivityType.EffectModel + public void run(final Mission mission) { + // if the pickBananaQuantityOverride is preset use that integer instead of the pickBananaActivityRecord + if(pickBananaQuantityOverride != 0) { + PickBananaActivity pickBananaActivity = pickBananaActivityRecord.pickBananaActivity; + pickBananaActivity.quantity = pickBananaQuantityOverride; + call(mission, pickBananaActivity); + } else { // else use the record type parameter supplied + call(mission, pickBananaActivityRecord.pickBananaActivity()); + } + // call a bite banana for each element in the list of biteBanana activities + for (final var bite : biteBananaActivity) { + call(mission, bite); + delay(Duration.of(30, Duration.MINUTE)); + } + // call peel banana activity + call(mission, peelBananaActivity); + } +} diff --git a/examples/banananation/src/main/java/gov/nasa/jpl/aerie/banananation/package-info.java b/examples/banananation/src/main/java/gov/nasa/jpl/aerie/banananation/package-info.java index d14ea407de..977ac5245f 100644 --- a/examples/banananation/src/main/java/gov/nasa/jpl/aerie/banananation/package-info.java +++ b/examples/banananation/src/main/java/gov/nasa/jpl/aerie/banananation/package-info.java @@ -26,7 +26,7 @@ @WithActivityType(ControllableDurationActivity.class) @WithActivityType(RipenBananaActivity.class) @WithActivityType(ExceptionActivity.class) -@WithActivityType(RussianBanana.class) +@WithActivityType(RussianNestingBanana.class) package gov.nasa.jpl.aerie.banananation; import gov.nasa.jpl.aerie.banananation.activities.BakeBananaBreadActivity; @@ -46,7 +46,7 @@ import gov.nasa.jpl.aerie.banananation.activities.PeelBananaActivity; import gov.nasa.jpl.aerie.banananation.activities.PickBananaActivity; import gov.nasa.jpl.aerie.banananation.activities.RipenBananaActivity; -import gov.nasa.jpl.aerie.banananation.activities.RussianBanana; +import gov.nasa.jpl.aerie.banananation.activities.RussianNestingBanana; import gov.nasa.jpl.aerie.banananation.activities.ThrowBananaActivity; import gov.nasa.jpl.aerie.contrib.serialization.rulesets.BasicValueMappers; import gov.nasa.jpl.aerie.merlin.framework.annotations.MissionModel; diff --git a/examples/banananation/src/test/java/gov/nasa/jpl/aerie/banananation/activities/RussianNestingActivityTest.java b/examples/banananation/src/test/java/gov/nasa/jpl/aerie/banananation/activities/RussianNestingActivityTest.java new file mode 100644 index 0000000000..b86f2ba0ab --- /dev/null +++ b/examples/banananation/src/test/java/gov/nasa/jpl/aerie/banananation/activities/RussianNestingActivityTest.java @@ -0,0 +1,65 @@ +package gov.nasa.jpl.aerie.banananation.activities; + +import gov.nasa.jpl.aerie.banananation.Configuration; +import gov.nasa.jpl.aerie.banananation.Mission; +import gov.nasa.jpl.aerie.banananation.SimulationUtility; +import gov.nasa.jpl.aerie.banananation.generated.GeneratedModelType; +import gov.nasa.jpl.aerie.banananation.generated.activities.ParameterTestActivityMapper; +import gov.nasa.jpl.aerie.banananation.generated.activities.RussianNestingBananaMapper; +import gov.nasa.jpl.aerie.contrib.serialization.mappers.DurationValueMapper; +import gov.nasa.jpl.aerie.merlin.driver.DirectiveTypeRegistry; +import gov.nasa.jpl.aerie.merlin.driver.MissionModelBuilder; +import gov.nasa.jpl.aerie.merlin.driver.SerializedActivity; +import gov.nasa.jpl.aerie.merlin.framework.Registrar; +import gov.nasa.jpl.aerie.merlin.framework.junit.MerlinExtension; +import gov.nasa.jpl.aerie.merlin.protocol.types.InstantiationException; +import gov.nasa.jpl.aerie.merlin.protocol.types.SerializedValue; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.nio.file.Path; +import java.time.Instant; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static gov.nasa.jpl.aerie.banananation.generated.ActivityActions.call; +import static gov.nasa.jpl.aerie.merlin.protocol.types.Duration.MILLISECONDS; +import static gov.nasa.jpl.aerie.merlin.protocol.types.Duration.SECONDS; +import static gov.nasa.jpl.aerie.merlin.protocol.types.Duration.duration; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(MerlinExtension.class) +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class RussianNestingActivityTest { + private final RussianNestingBananaMapper mapper; + + public RussianNestingActivityTest() { + this.mapper = new RussianNestingBananaMapper(); + } + + @Test + public void testDefaultSimulationDoesNotThrow() { + final var schedule = SimulationUtility.buildSchedule( + Pair.of( + duration(1100, MILLISECONDS), + new SerializedActivity("RussianNestingBanana", + Map.of("pickBananaActivityRecord", + SerializedValue.of(Map.of("id", SerializedValue.of(2), + "pickBananaActivity", SerializedValue.of(Map.of("quantity", SerializedValue.of(10))))) + , "pickBananaQuantityOverride", SerializedValue.of(0), + "biteBananaActivity", SerializedValue.of(List.of()), + "peelBananaActivity", SerializedValue.of(Map.of("peelDirection", SerializedValue.of("fromStem"))))))); + + final var simulationDuration = duration(5, SECONDS); + + final var simulationResults = SimulationUtility.simulate(schedule, simulationDuration); + + System.out.println(simulationResults.discreteProfiles); + System.out.println(simulationResults.realProfiles); + } + +}