Skip to content
Snippets Groups Projects
Commit b5bb1c02 authored by René Schöne's avatar René Schöne
Browse files

more work to get relations converted to terminals

parent a13921e8
Branches
Tags
No related merge requests found
Pipeline #13517 failed
......@@ -103,7 +103,7 @@ aspect Computation {
logicalRegion.setName(region.getName());
result.addLogicalRegion(logicalRegion);
for (MovableObject movableObject : getMovableObjectList()) {
for (DropOffLocation location : region.getLocationList()) {
for (DropOffLocation location : region.locationList()) {
if (movableObject.isLocatedAt(location)) {
LogicalMovableObject logicalObject = objects.get(movableObject);
logicalRegion.addContainedObject(logicalObject);
......@@ -168,6 +168,26 @@ aspect Navigation {
// must be "implemented" in concrete world models, i.e., an equation must be defined
inh JastAddList<Region> Scene.regionList();
syn List<Region> DropOffLocation.containedInRegion() {
List<Region> result = new ArrayList<>();
for (Region region : containingScene().regionList()) {
List<String> locationNames = Arrays.asList(region.getLocationNames().split(","));
if (locationNames.contains(getName())) {
result.add(region);
}
}
return result;
}
protected static List<String> ASTNode.arrayAsList(String array) {
if (array == null || array.length() == 0) {
return new ArrayList<>();
}
return new ArrayList<>(Arrays.asList(array.split(",")));
}
syn List<String> Region.locationNamesAsList() = arrayAsList(getLocationNames()) ;
syn List<DropOffLocation> Region.locationList();
}
aspect Printing {
......
......@@ -23,8 +23,8 @@ rel LogicalRegion.ContainedObject* <-> LogicalMovableObject.LocatedAt* ;
// TODO could lead to problems when including this information and sending it
//rel LogicalMovableObject.MyLocation? -> DropOffLocation ;
Region ::= <Name:String> ;
rel Region.Location* <-> DropOffLocation.ContainedInRegion* ;
Region ::= <Name:String> <LocationNames> ;
//rel Region.Location* <-> DropOffLocation.ContainedInRegion* ;
// TODO should this be only in site-B??
CollaborationZone : DropOffLocation ;
......@@ -3,7 +3,7 @@ receive WorldModelB.MyScene using ParseScene, ConvertScene ;
receive indexed WorldModelB.OtherScene ;
receive WorldModelB.TestingOtherScene ;
receive Robot.CanReachObjectOfInterestWrapper using ParseReachability, ConvertReachability ;
receive Robot.DummyOwnedCollaborationZone using ConfigChangeCommandCheckForOwnedCollaborationZone ;
receive Robot.OwnedCollaborationZoneNames using ConfigChangeCommandCheckForOwnedCollaborationZone ;
receive Robot.Busy using ConfigChangeCommandCheckForBusy ;
// --- sending ---
......@@ -35,18 +35,20 @@ ConfigChangeCommandCheckForOwnedCollaborationZone maps byte[] bytes to String {:
DropOffLocation loc = obj.asDropOffLocation();
CollaborationZone cz = loc.asCollaborationZone();
Robot thisRobot = (Robot) this;
if (thisRobot.getName().equals(cc.getIdRobotNewOwner()) && !thisRobot.getOwnedCollaborationZoneList().contains(cz)) {
List<String> collaborationZoneNames = thisRobot.ownedCollaborationZonesAsList();
boolean robotIsNewOwner = thisRobot.getName().equals(cc.getIdRobotNewOwner());
boolean collaborationZoneAlreadyOwned = collaborationZoneNames.contains(cc.getIdCollaborationZone());
if (robotIsNewOwner && !collaborationZoneAlreadyOwned) {
// config change is for this robot, add collaboration zone
thisRobot.addOwnedCollaborationZone(cz);
reject();
}
if (!thisRobot.getName().equals(cc.getIdRobotNewOwner()) && thisRobot.getOwnedCollaborationZoneList().contains(cz)) {
collaborationZoneNames.add(cc.getIdCollaborationZone());
} else if (!robotIsNewOwner && collaborationZoneAlreadyOwned) {
// config change is for another robot, remove collaboration zone
thisRobot.removeOwnedCollaborationZone(cz);
collaborationZoneNames.remove(cc.getIdCollaborationZone());
} else {
// otherwise don't change
reject();
}
// need return to make compiler happy
return "";
return String.join(",", collaborationZoneNames);
:}
ConfigChangeCommandCheckForBusy maps byte[] bytes to boolean {:
......
......@@ -138,7 +138,7 @@ aspect Computation {
try {
previousLocation.correspondingVertex();
} catch (NullPointerException e) {
return error("Could not resolve WorldModelB");
return error("Could not resolve WorldModelB linked to previousLocation " + previousLocation.nameAndHash());
}
return previousLocation.correspondingVertex().map(previousVertex -> {
Region region = getNewRegion().realRegion();
......@@ -146,10 +146,16 @@ aspect Computation {
return error("No region found for " + getNewRegion().nameAndHash());
}
// pick location from newRegion, that is free
return region.getLocationList().stream()
return region.locationList().stream()
.filter(location -> location.getObjectLocatedHere() == null)
.findFirst()
.map(newLocation -> {
// (workaround) check if WorldModelB is not null ... could happen if scene has no parent
try {
newLocation.correspondingVertex();
} catch (NullPointerException e) {
return error("Could not resolve WorldModelB linked to newLocation " + newLocation.nameAndHash());
}
return newLocation.correspondingVertex().map(newVertex -> {
List<Edge> shortestPath = previousVertex.BFS(newVertex);
if (shortestPath == null || shortestPath.isEmpty()) {
......@@ -170,10 +176,10 @@ aspect Computation {
*/
CollaborationZone cz = targetLocation.asCollaborationZone();
// order is important here, first add Evacuate, then ConfigChange
if (cz.hasOccupient() && !cz.getOccupient().equals(executingRobot)) {
result.add(Evacuate.of(cz.getOccupient(), cz));
if (cz.hasOccupient() && !cz.occupient().equals(executingRobot)) {
result.add(Evacuate.of(cz.occupient(), cz));
}
if (!cz.hasOwner() || (cz.hasOwner() && !cz.getOwner().equals(executingRobot))) {
if (!cz.hasOwner() || (cz.hasOwner() && !cz.owner().equals(executingRobot))) {
result.add(ConfigChange.of(executingRobot, cz));
}
}
......@@ -259,7 +265,7 @@ aspect Computation {
}
syn DropOffLocation Region.firstFreeDropOffLocation() {
for (DropOffLocation location : getLocationList()) {
for (DropOffLocation location : locationList()) {
if (location.getObjectLocatedHere() == null) {
return location;
}
......@@ -346,6 +352,33 @@ aspect Navigation {
//--- allMappings ---
// inh LocationMapping LogicalDropOffLocation.allMappings();
// eq WorldModelB.getChild().allMappings() = getLocationMapping();
syn boolean CollaborationZone.hasOccupient() = occupient() != null;
syn Robot CollaborationZone.occupient() {
for (Robot robot : worldModelB().getRobotList()) {
if (getName().equals(robot.getOccupiedCollaborationZoneName())) {
return robot;
}
}
return null;
}
syn boolean CollaborationZone.hasOwner() = owner() != null;
syn Robot CollaborationZone.owner() {
for (Robot robot : worldModelB().getRobotList()) {
List<String> collaborationZoneNames = Arrays.asList(robot.getOwnedCollaborationZoneNames().split(","));
if (collaborationZoneNames.contains(getName())) {
return robot;
}
}
return null;
}
syn List<String> Robot.ownedCollaborationZonesAsList() = arrayAsList(getOwnedCollaborationZoneNames());
eq Region.locationList() {
List<DropOffLocation> result = new ArrayList<>();
for (String locationName : locationNamesAsList()) {
result.add(worldModelB().getMyScene().resolveObjectOfInterest(locationName).asDropOffLocation());
}
return result;
}
}
aspect GlueForShared {
......
WorldModelB ::= Region* Robot* [MyScene:Scene] OtherScene:LogicalScene* /NextOperation:Operation/ TestingOtherScene:LogicalScene* ;
Robot ::= <Name:String> CanReachObjectOfInterestWrapper <Busy:boolean> <DummyOwnedCollaborationZone> ;
rel Robot.OwnedCollaborationZone* <-> CollaborationZone.Owner? ;
rel Robot.OccupiedCollaborationZone? <-> CollaborationZone.Occupient? ;
// FIXME inline CanReachObjectOfInterestWrapper
Robot ::= <Name:String> CanReachObjectOfInterestWrapper <Busy:boolean> <OwnedCollaborationZoneNames> <OccupiedCollaborationZoneName> ;
// relations into nodes received by RagConnect are not allowed
//rel Robot.OwnedCollaborationZone* <-> CollaborationZone.Owner? ;
//rel Robot.OccupiedCollaborationZone? <-> CollaborationZone.Occupient? ;
abstract Difference ;
rel Difference.Object -> LogicalMovableObject ;
......
......@@ -113,7 +113,7 @@ public class SimpleMainB {
model.connectMyScene(Util.mqttUri(topicSceneUpdateB, config));
for (Robot robot : model.getRobotList()) {
robot.connectBusy(Util.mqttUri(topicCommand, config));
robot.connectDummyOwnedCollaborationZone(Util.mqttUri(topicCommand, config));
robot.connectOwnedCollaborationZoneNames(Util.mqttUri(topicCommand, config));
}
model.connectNextOperation(Util.mqttUri(topicCommand, config), true);
......
......@@ -12,6 +12,7 @@ import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Collectors;
/**
* Static utility methods used only for place B.
......@@ -143,9 +144,7 @@ public class UtilB {
for (RegionDefinition def : config.regions) {
Region region = new Region();
region.setName(def.name);
for (String position : def.positions) {
region.addLocation(model.getMyScene().resolveObjectOfInterest(position).asDropOffLocation());
}
region.setLocationNames(String.join(",", def.positions));
result.add(region);
}
model.setRegionList(result);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment