I'm trying to use EUROPA to model a simple satellite that has a camera, battery and memory to store data. I have a few questions about issues I've had when trying to model this - I'm new to both planning and EUROPA so sorry if these are very simple questions!
1. I have an action where data is being downlinked. Because the memory resource is set up with min/max levels specified, I didn't think it would be necessary to put a constraint within the action such that the data is only downlinked (consumed) when the memory level is > 0. However, it appears that the memory is able to go below the minimum level (0) specified in the initial state (as shown in the attached screenshot). I was wondering why this is possible when a min/max has been set? I've tried to add in another constraint in for this but wasn't sure how to refer to the current memory level (something like contained_by(object.nanosat.memory.ll_min > 0) ?). The action I have at the moment is below.Transmitter::downlinkData{after(object.nanosat.camera.takePhoto);contained_by(condition object.window.Available);contains(effect object.nanosat.memory.consume data);eq(data.quantity, duration);}
The short version is that I think it’s because of the flexibility in the duration of Transmitter::downlinkData, the Solver not having any way to resolve the flaw, and printMemoryLevels only looking at the lower bound.
Resource profiles have an upper and lower bound that is guaranteed to envelop all possible grounded levels for the plan. That is, for every feasible assignment to all of the time and quantity variables, for all times t in the plan, lowerBound(t) <= level(t) <= upperBound(t). Min and max are constraints on those bounds. The plan contains a flaw if, at any point, lowerBound(t) < min or upperBound(t) > max. It contains a violation if lowerBound(t) > max or upperBound(t) < min.
I think what you’re seeing is a flaw, but because printMemoryLevels only prints the lower bound of the profile, it’s hard to tell. I think the flaw remains because everything that might resolve it has been filtered out of the Solver. The default Solver configuration filters out all temporal variables (start, end, duration, and time) as well as quantity variables on resources. Actually, I think it’s possible that flaws on all resources may be filtered out as well. Can you send that config file?
2. It seems I can have the quantity of data downlinked/battery consumed to be equal to the duration of the action as above, however when I try to introduce a constant I get an error (e.g. eq(data.quantity, duration*12) - I've tried this in a few different ways such as initialising the constant in the action or in the camera or resource classes). It seems like this should be possible but is there a way I should be implementing it that I'm missing?
3. What would be the best way to go about generating a single example plan from EUROPA? At the moment, my model outputs a schedule which gives ranges for actions, e.g. the take photo action can start in the range [3,47]. I was wondering if there was a way to instead output a feasible plan that has each action at a specific time rather than a range? I'm using a similar table format to your Shopping example to visualise the schedule (shown in the screenshot).
I've also attached my model, initial state and bsh files as it might help to clarify where I'm going wrong.I've had a look through the wiki and this group which are both really helpful - I don't think these questions have been asked before but apologies if I've missed something!
Thanks so much for your help!
Hi Michael,Thank you for getting back to me so quickly!
That makes sense - I didn't quite understand how the upper/lower bound stuff worked previously so thanks for explaining! Yes I think it is a flaw. I've updated my print statement to look at both the upper and lower bounds (screenshot attached) and it looks like at some points the lower bound < min (for the memory) and the upper bound > max (for the battery). I've attached the config file and it appears that there are filters on time and quantity there for the resources. I've tried removing these but it appears that for the battery at least the upper bound is still > max.Also, is there a way to look at just the resource level at a certain time point rather than the upper and lower bounds? I had a look through the PSResource classes but wasn't able to find anything.
For adding in the constant, using mulEq(duration, 12, data.quantity) worked, and I've changed the configuration as you suggested to get the grounded schedule.
Thanks again for all your help!
Hi again Michael! Hope you're well. I was wondering if there's a way to make an action continuous over a period of time? For example, I want to downlink data throughout the entire window that I've specified in my initial state or until the memory level reaches the lower limit of 0, whichever comes first. The way I have it at the moment (below), the action only occurs for one timestep even though I have a variable duration of [0,30]. Is it possible to do something like foreach(timestep in horizon) or while(memory > 0)? I'm not sure what the syntax for these types of statements would be in NDDL.Thanks,Jivanclass Transmitter{Nanosatellite nanosat;Window window;Transmitter(Nanosatellite n){nanosat = n;window = new Window();}action downlinkData{eq([0,30], duration);}}
Transmitter::downlinkData{after(object.nanosat.camera.takePhoto);contained_by(condition object.window.Available);contains(effect object.nanosat.memory.consume data);
mulEq(duration, 5, data.quantity);}
Hi Michael,Thank you for the explanations of all these options! :) I've implemented the resource transactions with the dynamic loops for now as you suggested, though I've structured them a bit differently to get it to work.I'm encountering some issues with the downlinking action that seems to be associated with adding in goals. For example, if I have one "takePhoto" goal the schedule output is as I would expect (the amount of loops I would expect to generate/consume the resources), but if I add a "measureRadiaton" goal or a second "takePhoto" goal starting at a different time, the amount of data downlinked always stops after 5 timesteps, even if the loop should be continuing (the time window is not over and there is still enough memory to allow additional downlink). Strangely this doesn't seem to be occurring for the battery resource though the power generation/consumption is structured similarly. Do you know why this might be? I'm not sure if I am specifying that the loop should continue in the right way. This is what I've added to the configuration file: <FlawHandler class="Transmitter" predicate="downlinkData" variable="continueLoop" component="Max"/> and the action is below.Transmitter::downlinkData{contained_by(condition object.window.Available);bool continueLoop;if(continueLoop) {meets(effect object.downlinkData next);next.end <= 90;starts(effect object.nanosat.memory.consume data);mulEq(duration, 5, data.quantity);starts(effect object.nanosat.mainBattery.consume consumption);mulEq(duration, 2, consumption.quantity);}}Thanks again,Jivan
Jivan, I'm glad to see you're still sticking with Europa! The short answer to your question is "no", but the short answer is a little wrong. Before I get to that, though, is there a limitation to the existing resource model that's being problematic for you?
Europa core resource transactions are instantaneous, so their quantities have to be a constant*. This lets (or forces, if you like) you to choose a discretization of the quantity if you want something more complicated than having the entire quantity transacted somewhere in the available time. There's a fixed and a dynamic way to do this.
The fixed way is to pick a number of transactions and manually decompose it in the model:Transmitter::downlinkData{contains(effect object.nanosat.memory.consume data1);
contains(effect object.nanosat.memory.consume data2);
contains(effect object.nanosat.memory.consume data3);
int quantity;mulEq(duration, 5, quantity);
addEq(data1.quantity, data2.quantity, data3.quantity, quantity);
Happy to help!Hi Michael,Thank you for getting back to me so quickly!That makes sense - I didn't quite understand how the upper/lower bound stuff worked previously so thanks for explaining! Yes I think it is a flaw. I've updated my print statement to look at both the upper and lower bounds (screenshot attached) and it looks like at some points the lower bound < min (for the memory) and the upper bound > max (for the battery). I've attached the config file and it appears that there are filters on time and quantity there for the resources. I've tried removing these but it appears that for the battery at least the upper bound is still > max.Also, is there a way to look at just the resource level at a certain time point rather than the upper and lower bounds? I had a look through the PSResource classes but wasn't able to find anything.
The upper and lower bounds are the resource level. If you're seeing different values for those bounds in your profile, then there's some flexibility in your plan, either in time or quantity. Looking more closely at your model and Solver config, you've got a few different actions that use their duration to determine how much battery or data gets transacted.
Another one of those highly problem- and model-dependent choices is whether it's better to have the Solver decide the durations of those activities (which will propagate to the quantities) or decide the quantities (which will propagate back to the durations). However, there are filters on duration and quantity that are preventing it from deciding either.Did you try `data.quantity = duration * 12;`? If it doesn't work, that's a bug.For adding in the constant, using mulEq(duration, 12, data.quantity) worked, and I've changed the configuration as you suggested to get the grounded schedule.You're most welcome!Thanks again for all your help!
~MJI
Hi Michael,Thank you for getting back to me so quickly!That makes sense - I didn't quite understand how the upper/lower bound stuff worked previously so thanks for explaining! Yes I think it is a flaw. I've updated my print statement to look at both the upper and lower bounds (screenshot attached) and it looks like at some points the lower bound < min (for the memory) and the upper bound > max (for the battery). I've attached the config file and it appears that there are filters on time and quantity there for the resources. I've tried removing these but it appears that for the battery at least the upper bound is still > max.Also, is there a way to look at just the resource level at a certain time point rather than the upper and lower bounds? I had a look through the PSResource classes but wasn't able to find anything.For adding in the constant, using mulEq(duration, 12, data.quantity) worked, and I've changed the configuration as you suggested to get the grounded schedule.Thanks again for all your help!
Jivan
Sorry, I'm not 100% sure how to find this out! I find the solver stepping tool a bit confusing but looking at the solver open decisions, the open decision count seems to drop off after around time point 65 which is when the schedule ends unexpectedly (screenshot attached).Thanks,Jivan
July 11, 2016 at 9:55 AM