-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a mission model behavioral framework #1364
Comments
Some prototyping happening on branch https://github.com/NASA-AMMOS/aerie/tree/1364-dependency-framework |
For the FooActivity activity type @EffectModel
public void run(final Mission mission) {
final var data = mission.data;
final var complexData = mission.complexData;
complexData.beginImaging(ImagerMode.HI_RES, 60);
if (y.equals("test")) {
data.rate.add(x);
} else if (y.equals("spawn")) {
call(mission, new FooActivity());
}
spawn(l);
data.rate.add(1.0);
delay(1, SECOND);
waitUntil(data.isBetween(50.0, 100.0));
mission.simpleData.downlinkData();
data.rate.add(2.0);
data.rate.add(data.rate.get());
delay(10, SECOND);
complexData.endImaging();
mission.simpleData.a.deactivate();
mission.simpleData.b.deactivate();
delay(1, SECOND);
mission.activitiesExecuted.add(1);
} Here is an example of dependencies that could be written : public List<Dependency> dependencies(Mission mission){
//unsupported : downlinkdata/beginimaging/endimaging
final var self = "foo";
final var dependencies = new ArrayList<Dependency>();
dependencies.addAll(ActivityBehavior.modelCall(mission.complexData, "beginImaging"));
dependencies.addAll(List.of(
//anonymousTask(l),
//line 54 with if from line 53
ActivityBehavior.increases(self, mission.data.rate, "x", "y", atStart()),
//line 55 and 56
ActivityBehavior.generates(self,"FooActivity", atStart(), "y"),
//line 59
ActivityBehavior.increases(self, mission.data.rate, 1.0, atStart()),
//line 62
ActivityBehavior.increases(self, mission.data.rate, 2.0, offsetBeforeEnd(Duration.of(11, SECONDS))),
//line 66
ActivityBehavior.increases(self, mission.data.rate, mission.data.rate, offsetBeforeEnd(Duration.of(11, SECONDS))),
//line 76
ActivityBehavior.increases(self, mission.activitiesExecuted, 1.0, atEnd())
));
return dependencies;
} with @Override
public List<Dependency> getDependencies(String methodName){
switch(methodName){
case "downlinkData":
return List.of(
Dependency.resourceWrite(object(this), object(this.a), EffectType.undefinedEffect()),
Dependency.resourceWrite(object(this), object(this.b), EffectType.undefinedEffect())
);
default:
return List.of();
}
} |
Note: the temporal arguments are mainly to get the ability to build activities from a behavior definition only (without user-defined |
Summary of a conversation some time ago with @adrienmaillard : |
@jmdelfa and I discussed and did not find that this was in the scope for the MVP of #1073. This is attached to provide a declarative behavior of the activities, resources and models in mission models. The MVP of #1073 will require a disjoint set of knowledge about hierarchy/sub-tasks/temporal constraints between sub-tasks. Beyond MVP, there will be some overlaps as we will need declarative information about the behavior of primitive activities but not before. |
This is the second version of this ticket. This writeup is as much of a plan as it is a basis for my own reflection, sorry for the endless rambling. This is in coordination with the grouping work #1073 #1451 #870 as it also involves declarative modelling in the mission model.
We believe Aerie needs a declarative task framework to allow for better automated reasoning which will lead to a better performance and will also allow us to move from low-level goal specification (current goals based on batch insertion of activities) to high-level goal specification (e.g. state based).
What’s not declarative right now ?
the behavior of a task is pretty much entirely contained in its
run()
method. There’s no way of knowing what an activity is doing without simulating it. And simulating it in one set of initial conditions is not sufficient to know all of its potential behaviors, as conditional statements are allowed and may change the behavior of the task. Let's qualify the current task specification framework as procedural. The behavior of a task is not explicitly modeled, it’s the result of the execution of a piece of code.As I see it, there are two sides to this work, the aspects related to changes in the mission model and the aspects related to the uses of this new knowledge about tasks in the scheduler (and planner in the future hopefully).
On the mission model side
What do we need to express in this framework ?
The behavior of a task, what it does.
And we need to record the relationships/dependencies between resources and tasks.
In a traditional/academic planning and scheduling language, this is straightforward because there is a small number of well defined ways of expressing task behaviors and resource types. And these languages have been slowly improved/enriched year after year, their creators having in mind the consequences of adding each new block to the language. In our case, we start from the full expressivity of java and the endless imagination of mission modelers. Let's say right away that we won't be able to represent the current expressivity of mission models, as we would not be able to perform tractable reasoning over all the java constructs and so on and so on.
Let's talk first about resources. I looked at our toy models and David Legg also helped me look at what Clipper does with resources. What we found is that:
This is a problem as an activity might reference an anonymous resource for its behavior. So how can we make sure to reference all resources affected by an activity ?
I exclude the following technical approaches:
run()
methods and calls.Here, there is a design decision point:
The current path I am following is inspired by David Legg’s work on dependencies in the streamline framework and is more in line with item 1 above:
Dependencies
classRegistrar
to be able to reference resource object by nameI have tried prototyping what it could look like for the
FooActivity
activity type which is interestingly complex for this purpose. Here is itsrun()
method :It has:
mission.simpleData.downlinkData()
orcomplexData.endImaging()
), parts of behaviors that are not directly in the activity, and highlights that the whole model needs to be supplemented with declarative knowledgedelay
). Note that effects can be applied not only at the start or end of a task but at any time during the duration of the task.waitUtil
) as it might depend on other activities/model in the planFor future reference, in traditional planning, conditional behavior + resource effects is denoted as conditional effects. I think we could call it that way here as well but I am wondering if there can be conditional behavior that does not end up in effects.
Here is an example of how some of the behaviors could be written:
Some notes:
getBehaviors
method has theMission
object as argument to mimic therun()
method and allow to access the same elements. The intent is that the translation fromrun()
togetBehaviors()
would be more straightforward this way.run()
method from a list ofActivityBehavior
-
ActivityBehavior.modelCall
would extract dependencies (recursively) from model classes. The model class could implement anIntrospectable
interface that would allow querying runtime dependencies for each method. An example for theSimpleData
class of the foo mission model:It's a little bit cumbersome as the user has to discriminate between names...
There are a number of things unsupported so far. It's a work in progress at this point.
I think there is more work to be done on the modelling of resources. Right now, it's a little bit abstract, we are not describing their behavior but more of their dependencies. It is desirable for the user to be able to model any kind of resource but it would also be desirable to have a sizeable subset of defined resource types that we could reason about.
Resource types to consider
On the scheduler’s side
From all of this information about the behaviors of tasks and relationships between resources, we can build a dependency graph that can be accessed from outside the mission model via the
SchedulerModel
.The constraints/goals would be augmented with more dependency introspection. Basically the
extractResources
would be transformed into anextractDependencies
that would track various types of dependencies (resources but also activity type (mutexes), time (for valueAt…)).This information allows to build another dependency graph between resources, activities and expressions/constraints/goals.
With that, after inserting a new activity A in the plan and before evaluating anything afterwards, we could check whether A would have any impact on what we want to evaluate/do before doing any simulation. Some examples:
Risks
An issue might be that there is a disconnect between what the run() method is doing and what resources these methods provide:
To me, there’s 2 ways of doing this:
What happens at the limits of this framework ?
Let's say we don't cover some resource types and resource R is one of them. Basically, the only (low-level) information we would get is that R is being written and/or read. We don't know what is the essence of these read and writes (as opposed to higher level info such as
increases
decreases
orsets
).The text was updated successfully, but these errors were encountered: