-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update to latest Aerie and reorganize to add scheduling procedures (#8)
* update to gradle 8.7 * update `docker-compose` with latest from `aerie` repo * update .env and build.gradle for newer aerie versions * reorg into model and scheduling submodules * bootstrap `scheduling` submodule * add utils to mission model, consume in procedures * add mission model tutorial completion patch * misc changes * Update README with scheduling procedure * update patch to insert new files * remove `.env` * update README to reference scheduling procedures * remove `SimulationDemo` since it references banananation * link to StayWellFed, as well as update with UI instructions instead of CLI instructions * Update to work with type-utils * use project.aerieVersion --------- Co-authored-by: dandelany <[email protected]> Co-authored-by: Matthew Dailis <[email protected]>
- Loading branch information
1 parent
7966014
commit 343f777
Showing
8 changed files
with
327 additions
and
3 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
diff --git a/missionmodel/src/main/java/missionmodel/CollectData.java b/missionmodel/src/main/java/missionmodel/CollectData.java | ||
new file mode 100644 | ||
index 0000000..4e61911 | ||
--- /dev/null | ||
+++ b/missionmodel/src/main/java/missionmodel/CollectData.java | ||
@@ -0,0 +1,45 @@ | ||
+package missionmodel; | ||
+ | ||
+import gov.nasa.jpl.aerie.contrib.metadata.Unit; | ||
+import gov.nasa.jpl.aerie.contrib.streamline.modeling.discrete.DiscreteEffects; | ||
+import gov.nasa.jpl.aerie.merlin.framework.annotations.ActivityType; | ||
+import gov.nasa.jpl.aerie.merlin.framework.annotations.Export.Parameter; | ||
+import gov.nasa.jpl.aerie.merlin.framework.annotations.Export.Validation; | ||
+ | ||
+ | ||
+import gov.nasa.jpl.aerie.merlin.protocol.types.Duration; | ||
+ | ||
+import static gov.nasa.jpl.aerie.merlin.framework.ModelActions.delay; | ||
+ | ||
+/* Example Activity Type Definition | ||
+ If this activity is moved over to main/java/missionmodel along with the DataModel class and the example model | ||
+ declaration in the Mission class is uncommented, the model should compile. | ||
+ */ | ||
+@ActivityType("CollectData") | ||
+public class CollectData { | ||
+ | ||
+ @Parameter | ||
+ @Unit("Mbps") | ||
+ public double rate = 10.0; // Mbps | ||
+ | ||
+ @Parameter | ||
+ public Duration duration = Duration.duration(1, Duration.HOURS); | ||
+ | ||
+ @Validation("Collection rate is beyond buffer limit of 100.0 Mbps") | ||
+ @Validation.Subject("rate") | ||
+ public boolean validateCollectionRate() { | ||
+ return rate <= 100.0; | ||
+ } | ||
+ | ||
+ @ActivityType.EffectModel | ||
+ public void run(Mission model) { | ||
+ | ||
+ /* | ||
+ Collect data at fixed rate over duration of activity | ||
+ */ | ||
+ DiscreteEffects.increase(model.dataModel.RecordingRate, this.rate); | ||
+ delay(duration); | ||
+ DiscreteEffects.decrease(model.dataModel.RecordingRate, this.rate); | ||
+ | ||
+ } | ||
+} | ||
diff --git a/missionmodel/src/main/java/missionmodel/DataModel.java b/missionmodel/src/main/java/missionmodel/DataModel.java | ||
new file mode 100644 | ||
index 0000000..b0df0d4 | ||
--- /dev/null | ||
+++ b/missionmodel/src/main/java/missionmodel/DataModel.java | ||
@@ -0,0 +1,42 @@ | ||
+package missionmodel; | ||
+ | ||
+import gov.nasa.jpl.aerie.contrib.serialization.mappers.DoubleValueMapper; | ||
+import gov.nasa.jpl.aerie.contrib.streamline.core.MutableResource; | ||
+import gov.nasa.jpl.aerie.contrib.streamline.modeling.Registrar; | ||
+import gov.nasa.jpl.aerie.contrib.streamline.modeling.discrete.Discrete; | ||
+import gov.nasa.jpl.aerie.contrib.streamline.modeling.discrete.DiscreteEffects; | ||
+import gov.nasa.jpl.aerie.merlin.protocol.types.Duration; | ||
+ | ||
+import static gov.nasa.jpl.aerie.contrib.metadata.UnitRegistrar.withUnit; | ||
+import static gov.nasa.jpl.aerie.contrib.streamline.core.MutableResource.resource; | ||
+import static gov.nasa.jpl.aerie.contrib.streamline.core.Resources.currentValue; | ||
+import static gov.nasa.jpl.aerie.contrib.streamline.modeling.discrete.Discrete.discrete; | ||
+import static gov.nasa.jpl.aerie.merlin.framework.ModelActions.delay; | ||
+ | ||
+/* Example Mission Model delegate class | ||
+ This class includes two resource declarations and a method that can be spawned via a daemon task | ||
+ If this activity is moved over to main/java/missionmodel and the example model declaration in the Mission class | ||
+ is uncommented, the model should compile. | ||
+ */ | ||
+public class DataModel { | ||
+ | ||
+ public MutableResource<Discrete<Double>> RecordingRate; // Megabits/s | ||
+ | ||
+ public MutableResource<Discrete<Double>> SSR_Volume_Sampled; // Gigabits | ||
+ | ||
+ public DataModel(Registrar registrar, Configuration config) { | ||
+ RecordingRate = resource(discrete(0.0)); | ||
+ registrar.discrete("RecordingRate", RecordingRate, withUnit("Mbps", new DoubleValueMapper())); | ||
+ } | ||
+ | ||
+ public void integrateDataRate() { | ||
+ Duration INTEGRATION_SAMPLE_INTERVAL = Duration.duration(60, Duration.SECONDS); | ||
+ while(true) { | ||
+ delay(INTEGRATION_SAMPLE_INTERVAL); | ||
+ Double currentRecordingRate = currentValue(RecordingRate); | ||
+ DiscreteEffects.increase(SSR_Volume_Sampled, currentRecordingRate * | ||
+ INTEGRATION_SAMPLE_INTERVAL.ratioOver(Duration.SECONDS) / 1000.0); // Mbit -> Gbit | ||
+ } | ||
+ } | ||
+ | ||
+} | ||
diff --git a/missionmodel/src/main/java/missionmodel/Mission.java b/missionmodel/src/main/java/missionmodel/Mission.java | ||
index d7eb103..e2b3da5 100644 | ||
--- a/missionmodel/src/main/java/missionmodel/Mission.java | ||
+++ b/missionmodel/src/main/java/missionmodel/Mission.java | ||
@@ -25,7 +25,7 @@ public final class Mission { | ||
// public MutableResource<Discrete<Double>> ExampleResource; | ||
|
||
// Example model declaration | ||
- //public final DataModel dataModel; | ||
+ public final DataModel dataModel; | ||
|
||
public Mission(final gov.nasa.jpl.aerie.merlin.framework.Registrar registrar, final Configuration config) { | ||
this.errorRegistrar = new Registrar(registrar, Registrar.ErrorBehavior.Log); | ||
@@ -35,10 +35,10 @@ public final class Mission { | ||
// errorRegistrar.discrete("ExampleResource", ExampleResource, new DoubleValueMapper()); | ||
|
||
// Example model instantiation | ||
- //this.dataModel = new DataModel(this.errorRegistrar, config); | ||
+ this.dataModel = new DataModel(this.errorRegistrar, config); | ||
|
||
// Example daemon task call | ||
- // spawn(dataModel::integrateDataRate); | ||
+ spawn(dataModel::integrateDataRate); | ||
|
||
} | ||
} | ||
diff --git a/missionmodel/src/main/java/missionmodel/package-info.java b/missionmodel/src/main/java/missionmodel/package-info.java | ||
index 314ae30..f0d67da 100644 | ||
--- a/missionmodel/src/main/java/missionmodel/package-info.java | ||
+++ b/missionmodel/src/main/java/missionmodel/package-info.java | ||
@@ -1,8 +1,8 @@ | ||
@MissionModel(model = Mission.class) | ||
@WithMappers(BasicValueMappers.class) | ||
@WithConfiguration(Configuration.class) | ||
-// @WithActivityType(ActivityType.class) // for new activity type | ||
-// @WithMetadata(name = "unit", annotation = gov.nasa.jpl.aerie.contrib.metadata.Unit.class) // for unit support | ||
+@WithActivityType(CollectData.class) // for new activity type | ||
+@WithMetadata(name = "unit", annotation = gov.nasa.jpl.aerie.contrib.metadata.Unit.class) // for unit support | ||
package missionmodel; | ||
|
||
import gov.nasa.jpl.aerie.contrib.serialization.rulesets.BasicValueMappers; |
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,7 @@ | ||
package missionmodel; | ||
|
||
public class Utils { | ||
public static String getCollectDataActivityName() { | ||
return "CollectData"; | ||
} | ||
} |
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,100 @@ | ||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar | ||
|
||
plugins { | ||
id 'java' | ||
id 'io.github.goooler.shadow' version '8.1.7' | ||
} | ||
|
||
java { | ||
toolchain { | ||
languageVersion = JavaLanguageVersion.of(21) | ||
} | ||
} | ||
|
||
dependencies { | ||
// pull in any helper / utils from the mission model | ||
implementation project(":missionmodel") | ||
|
||
// procedural scheduling libraries | ||
annotationProcessor "gov.nasa.ammos.aerie.procedural:processor:" + project.aerieVersion | ||
implementation "gov.nasa.ammos.aerie.procedural:scheduling:" + project.aerieVersion | ||
implementation "gov.nasa.ammos.aerie.procedural:timeline:" + project.aerieVersion | ||
implementation "gov.nasa.ammos.aerie.procedural:constraints:" + project.aerieVersion | ||
|
||
// standard aerie deps | ||
implementation 'gov.nasa.jpl.aerie:merlin-framework:' + project.aerieVersion | ||
implementation 'gov.nasa.jpl.aerie:contrib:' + project.aerieVersion | ||
implementation 'gov.nasa.jpl.aerie:type-utils:' + project.aerieVersion | ||
|
||
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.10.0' | ||
} | ||
|
||
test { | ||
useJUnitPlatform() | ||
} | ||
|
||
tasks.register('buildAllSchedulingProcedureJars') { | ||
group = 'SchedulingProcedureJars' | ||
|
||
dependsOn "generateSchedulingProcedureJarTasks" | ||
dependsOn { | ||
tasks.findAll { task -> task.name.startsWith('buildSchedulingProcedureJar_') } | ||
} | ||
} | ||
|
||
tasks.create("generateSchedulingProcedureJarTasks") { | ||
group = 'SchedulingProcedureJars' | ||
|
||
final proceduresDir = findFirstMatchingBuildDir("generated/procedures") | ||
|
||
if (proceduresDir == null) { | ||
println "No generated procedures found yet, make sure you have procedure source files in src/.../procedures" | ||
return | ||
} | ||
println "Generating jar tasks for the following procedures directory: ${proceduresDir}" | ||
|
||
final files = file(proceduresDir).listFiles() | ||
if (files.length == 0) { | ||
println "No procedures available within folder ${proceduresDir}" | ||
return | ||
} | ||
|
||
files.toList().each { file -> | ||
final nameWithoutExtension = file.name.replace(".java", "") | ||
final taskName = "buildSchedulingProcedureJar_${nameWithoutExtension}" | ||
|
||
println "Generating ${taskName} task, which will build ${nameWithoutExtension}.jar" | ||
|
||
tasks.create(taskName, ShadowJar) { | ||
group = 'SchedulingProcedureJars' | ||
configurations = [project.configurations.compileClasspath] | ||
from sourceSets.main.output | ||
archiveBaseName = "" // clear | ||
archiveClassifier.set(nameWithoutExtension) // set output jar name | ||
manifest { | ||
attributes 'Main-Class': getMainClassFromGeneratedFile(file) | ||
} | ||
minimize() | ||
dependencies { | ||
// exclude project(':procedural:timeline') | ||
// exclude dependency(":kotlin.*") | ||
} | ||
} | ||
} | ||
} | ||
|
||
private String findFirstMatchingBuildDir(String pattern) { | ||
String found = null | ||
final generatedDir = file("build/generated/sources") | ||
generatedDir.mkdirs() | ||
generatedDir.eachDirRecurse { dir -> if (dir.path.contains(pattern)) found = dir.path } | ||
return found | ||
} | ||
|
||
private static String getMainClassFromGeneratedFile(File file) { | ||
final fileString = file.toString() | ||
final prefix = "build/generated/sources/annotationProcessor/java/main/" | ||
final index = fileString.indexOf(prefix) + prefix.length() | ||
final trimmed = fileString.substring(index).replace(".java", "") | ||
return trimmed.replace("/", ".") | ||
} |
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 scheduling.procedures; | ||
|
||
import gov.nasa.ammos.aerie.procedural.scheduling.Goal; | ||
import gov.nasa.ammos.aerie.procedural.scheduling.plan.EditablePlan; | ||
import gov.nasa.ammos.aerie.procedural.scheduling.annotations.SchedulingProcedure; | ||
import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.DirectiveStart; | ||
import gov.nasa.jpl.aerie.merlin.protocol.types.Duration; | ||
|
||
import missionmodel.Utils; | ||
|
||
import java.util.Map; | ||
|
||
@SchedulingProcedure | ||
public record SampleProcedure(int quantity) implements Goal { | ||
@Override | ||
public void run(EditablePlan plan) { | ||
final var firstTime = Duration.hours(0); | ||
final var step = Duration.hours(6); | ||
|
||
var currentTime = firstTime; | ||
for (var i = 0; i < quantity; i++) { | ||
plan.create( | ||
Utils.getCollectDataActivityName(), | ||
new DirectiveStart.Absolute(currentTime), | ||
Map.of() | ||
); | ||
currentTime = currentTime.plus(step); | ||
} | ||
plan.commit(); | ||
// var results = plan.simulate(new SimulateOptions()); | ||
// var size = results.instances().collect().size(); | ||
} | ||
} |
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,5 @@ | ||
@WithMappers(BasicValueMappers.class) | ||
package scheduling; | ||
|
||
import gov.nasa.jpl.aerie.contrib.serialization.rulesets.BasicValueMappers; | ||
import gov.nasa.ammos.aerie.procedural.scheduling.annotations.WithMappers; |
Empty file.
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 |
---|---|---|
@@ -1,2 +1,3 @@ | ||
rootProject.name = 'aerie-template' | ||
include('missionmodel') | ||
include('scheduling') |