diff --git a/ros3rag.placeB/src/main/jastadd/BFS/BFS.jrag b/ros3rag.placeB/src/main/jastadd/BFS/BFS.jrag index 13efe23f74e1706da1bb866893d30492661cb285..d59de4fa0aa754a46085e640eff698831da30728 100644 --- a/ros3rag.placeB/src/main/jastadd/BFS/BFS.jrag +++ b/ros3rag.placeB/src/main/jastadd/BFS/BFS.jrag @@ -1,6 +1,7 @@ import java.util.*; aspect BFS { + //--- BFS --- syn List<Edge> Vertex.BFS(Vertex goal) { Map<Vertex, Edge> pred = new HashMap<>(); Queue<Vertex> Q = new LinkedList<>(); @@ -36,7 +37,9 @@ aspect BFS { return null; } + //--- reconstructFrom --- private List<Edge> Vertex.reconstructFrom(Vertex goal, Map<Vertex, Edge> pred) { + // used at the end of BFS to back-track path from goal to start List<Edge> result = new ArrayList<>(); Vertex current = goal; while (!current.equals(this)) { @@ -49,6 +52,7 @@ aspect BFS { return result; } + //--- prettyPrint --- public String Graph.prettyPrint() { StringJoiner sj = new StringJoiner("\n", "Graph {\n", "\n}"); if (!hasVertex()) { sj.add("<no vertices>"); } diff --git a/ros3rag.placeB/src/main/jastadd/RobotReachabilityToBFS.jrag b/ros3rag.placeB/src/main/jastadd/RobotReachabilityToBFS.jrag index 7dd4ee10fbe6bad66d3a5dc7542af09e486a374e..7515b509b746b6af4c807371b59cbdbef151c405 100644 --- a/ros3rag.placeB/src/main/jastadd/RobotReachabilityToBFS.jrag +++ b/ros3rag.placeB/src/main/jastadd/RobotReachabilityToBFS.jrag @@ -1,4 +1,5 @@ aspect RobotReachabilityToBFS { + //--- toReachabilityGraph --- syn nta Graph WorldModelB.toReachabilityGraph() { Graph result = new Graph(); if (!hasMyScene()) { @@ -37,6 +38,7 @@ aspect RobotReachabilityToBFS { return result; } + //--- correspondingVertex --- syn Optional<Vertex> LogicalObjectOfInterest.correspondingVertex() { if (!worldModelB().hasMyScene()) { return Optional.empty(); diff --git a/ros3rag.placeB/src/main/jastadd/WorldModelB.connect b/ros3rag.placeB/src/main/jastadd/WorldModelB.connect index 3da080fb1a8643e37b1244231e7a5e92ca29d257..374830424811e961e9a541705e7e21da49bf1ba3 100644 --- a/ros3rag.placeB/src/main/jastadd/WorldModelB.connect +++ b/ros3rag.placeB/src/main/jastadd/WorldModelB.connect @@ -1,6 +1,7 @@ // --- receiving --- receive tree WorldModelB.MyScene using ParseScene, ConvertScene ; -receive tree WorldModelB.OtherScene ; +receive tree WorldModelB.OtherScene1 ; +receive tree WorldModelB.OtherScene2 ; receive tree Robot.CanReachObjectOfInterestWrapper using ParseReachability, ConvertReachability ; // --- sending --- diff --git a/ros3rag.placeB/src/main/jastadd/WorldModelB.jadd b/ros3rag.placeB/src/main/jastadd/WorldModelB.jadd index 3c43e9ba77dfae3daf1622b93cf93abac913a651..f8631c36bdf5bf550bffb0d486b0fcfd1c3a842a 100644 --- a/ros3rag.placeB/src/main/jastadd/WorldModelB.jadd +++ b/ros3rag.placeB/src/main/jastadd/WorldModelB.jadd @@ -1,15 +1,81 @@ aspect Computation { + //--- unspecifiedLocation --- syn nta LogicalDropOffLocation WorldModelB.unspecifiedLocation() = new LogicalDropOffLocation().setName("<unspecified>"); + //--- getOtherSceneList --- + syn JastAddList<LogicalScene> WorldModelB.getOtherSceneList() { + JastAddList<LogicalScene> result = new JastAddList<>(); + if (hasOtherScene1()) { + result.add(getOtherScene1()); + } + if (hasOtherScene2()) { + result.add(getOtherScene2()); + } + return result; + } + + //--- mergedOtherScene --- + syn nta LogicalScene WorldModelB.mergedOtherScene() { + // return empty scene, if there are no other scenes (yet) + if (!hasOtherScene()) { + return new LogicalScene(); + } + // return scene, if there is exactly one. (TODO: check if copy is needed here) + if (getNumOtherScene() == 1) { + return getOtherScene(0); + } + var result = new LogicalScene(); + // use getOtherSceneList() and merge by name all locations, objects and relations into one new, unified scene + Map<String, LogicalDropOffLocation> mergedLocations = new HashMap<>(); + Map<String, LogicalMovableObject> mergedObjects = new HashMap<>(); + // first create all locations + for (LogicalScene scene : getOtherSceneList()) { + for (LogicalDropOffLocation loc : scene.getLogicalDropOffLocationList()) { + if (!mergedLocations.containsKey(loc.getName())) { + LogicalDropOffLocation copyOfLoc = new LogicalDropOffLocation(); + copyOfLoc.setName(loc.getName()); + mergedLocations.put(loc.getName(), copyOfLoc); + result.addLogicalDropOffLocation(copyOfLoc); + } + } + } + // then create all objects, and set LocatedAt relation (checking for possible conflicts) + for (LogicalScene scene : getOtherSceneList()) { + for (LogicalMovableObject obj : scene.getLogicalMovableObjectList()) { + if (mergedObjects.containsKey(obj.getName())) { + // object already known + LogicalMovableObject copyOfObj = mergedObjects.get(obj.getName()); + if (obj.hasLocatedAt()) { + String locationName = obj.getLocatedAt().getName(); + LogicalDropOffLocation copyOfLoc = mergedLocations.get(locationName); + if (copyOfObj.hasLocatedAt() && !obj.getLocatedAt().getName().equals(copyOfObj.getLocatedAt().getName())) { + System.err.println("Overriding located-at of " + obj.getName() + " while merging (" + locationName + "," + copyOfObj.getLocatedAt().getName() + ")"); + } + copyOfObj.setLocatedAt(copyOfLoc); + } + } else { + LogicalMovableObject copyOfObj = new LogicalMovableObject(); + copyOfObj.setName(obj.getName()); + if (obj.hasLocatedAt()) { + copyOfObj.setLocatedAt(mergedLocations.get(obj.getLocatedAt().getName())); + } + mergedObjects.put(obj.getName(), copyOfObj); + result.addLogicalMovableObject(copyOfObj); + } + } + } + return result; + } + //--- diffScenes --- syn nta JastAddList<Difference> WorldModelB.diffScenes() { var result = new JastAddList<Difference>(); if (!hasMyScene() || !hasOtherScene()) { - // without both scenes, there are no differences + // without my and at least one other scene, there are no differences return result; } var myLogicalScene = getMyScene().getLogicalScene(); - for (LogicalMovableObject otherObject : getOtherScene().getLogicalMovableObjectList()) { + for (LogicalMovableObject otherObject : mergedOtherScene().getLogicalMovableObjectList()) { LogicalObjectOfInterest myGenericObject = myLogicalScene.resolveLogicalObjectOfInterest(otherObject.getName()); if (myGenericObject == null) { // new object, currently not handled @@ -125,6 +191,7 @@ aspect Computation { return false; } + //--- reachableObjects --- syn List<LogicalObjectOfInterest> Robot.reachableObjects() { if (!worldModelB().hasMyScene()) { return Collections.emptyList(); diff --git a/ros3rag.placeB/src/main/jastadd/WorldModelB.relast b/ros3rag.placeB/src/main/jastadd/WorldModelB.relast index 3263e7ff0b6d8b9de31237299829ed48abce0292..d474353f51d2f96183a30ed438208fab5c1bbc8d 100644 --- a/ros3rag.placeB/src/main/jastadd/WorldModelB.relast +++ b/ros3rag.placeB/src/main/jastadd/WorldModelB.relast @@ -1,4 +1,5 @@ -WorldModelB ::= Robot* [MyScene:Scene] [OtherScene:LogicalScene] /NextOperation:Operation/ ; +WorldModelB ::= Robot* [MyScene:Scene] [OtherScene1:LogicalScene] [OtherScene2:LogicalScene] /OtherScene:LogicalScene*/ /NextOperation:Operation/ ; +// workaround with NTA OtherSceneList as receiving lists is not possible yet Robot ::= <Name:String> CanReachObjectOfInterestWrapper ; diff --git a/ros3rag.placeB/src/main/java/de/tudresden/inf/st/placeB/MainB.java b/ros3rag.placeB/src/main/java/de/tudresden/inf/st/placeB/MainB.java index 930b0480187c00b0228164e97e392af1ceca118a..0c193b3e77021dd6d6bcff534443a1d197d269d3 100644 --- a/ros3rag.placeB/src/main/java/de/tudresden/inf/st/placeB/MainB.java +++ b/ros3rag.placeB/src/main/java/de/tudresden/inf/st/placeB/MainB.java @@ -82,7 +82,7 @@ public class MainB extends SharedMainParts<MqttHandler, WorldModelB> { @Override protected void connectEndpoints() throws IOException { model.connectMyScene(mqttUri(TOPIC_MY_SCENE_UPDATE_FROM_ROS, config)); - model.connectOtherScene(mqttUri(TOPIC_OTHER_SCENE_UPDATE_FROM_PLACE_A, config)); + model.connectOtherScene1(mqttUri(TOPIC_OTHER_SCENE_UPDATE_FROM_PLACE_A, config)); model.connectNextOperation(mqttUri(TOPIC_COMMAND, config), false); } diff --git a/ros3rag.placeB/src/main/java/de/tudresden/inf/st/placeB/SimpleMainB.java b/ros3rag.placeB/src/main/java/de/tudresden/inf/st/placeB/SimpleMainB.java index aef39306bb03ae1f7ff15d8682b6c3535c112e03..b8023e726595aff10197fecbb8d07bc1850b3e5e 100644 --- a/ros3rag.placeB/src/main/java/de/tudresden/inf/st/placeB/SimpleMainB.java +++ b/ros3rag.placeB/src/main/java/de/tudresden/inf/st/placeB/SimpleMainB.java @@ -188,7 +188,7 @@ public class SimpleMainB { /// Connect endpoints model.connectMyScene(mqttUri("TOPIC_MY_SCENE_UPDATE_FROM_ROS", config)); - model.connectOtherScene(mqttUri("TOPIC_OTHER_SCENE_UPDATE_FROM_PLACE_A", config)); + model.connectOtherScene1(mqttUri("TOPIC_OTHER_SCENE_UPDATE_FROM_PLACE_A", config)); model.connectNextOperation(mqttUri("TOPIC_COMMANDS", config), false); System.out.println("before"); @@ -264,7 +264,7 @@ public class SimpleMainB { LogicalDropOffLocation otherGamma = new LogicalDropOffLocation().setName("placeGamma"); otherGamma.addContainedObject(otherObj1); otherScene.addLogicalDropOffLocation(otherGamma); - model.setOtherScene(otherScene); + model.setOtherScene1(otherScene); // printing and testing printModelInfos(model); diff --git a/ros3rag.placeB/src/main/java/de/tudresden/inf/st/placeB/UtilB.java b/ros3rag.placeB/src/main/java/de/tudresden/inf/st/placeB/UtilB.java index b837ab3c1a4572d2a7a88ee249e73fc71049498a..b68cd908f8c48d62adcff4e0569a59ffc68cb9c2 100644 --- a/ros3rag.placeB/src/main/java/de/tudresden/inf/st/placeB/UtilB.java +++ b/ros3rag.placeB/src/main/java/de/tudresden/inf/st/placeB/UtilB.java @@ -117,7 +117,7 @@ public class UtilB { } sb.append("otherScene:"); if (model.hasOtherScene()) { - sb.append("\n").append(model.getOtherScene().prettyPrint()); + sb.append("\n").append(model.mergedOtherScene().prettyPrint()); } else { sb.append(" (unset)\n"); } diff --git a/ros3rag.placeB/src/test/java/de/tudresden/inf/st/placeB/TestComputeOperations.java b/ros3rag.placeB/src/test/java/de/tudresden/inf/st/placeB/TestComputeOperations.java index 26681503def3124be05fe7d15a25c61451c3426a..fe53722780e481e0c6c086de7e4c4374205cea1d 100644 --- a/ros3rag.placeB/src/test/java/de/tudresden/inf/st/placeB/TestComputeOperations.java +++ b/ros3rag.placeB/src/test/java/de/tudresden/inf/st/placeB/TestComputeOperations.java @@ -33,7 +33,7 @@ public class TestComputeOperations { LogicalMovableObject x = logicalScene.resolveLogicalObjectOfInterest("x").asLogicalMovableObject(); LogicalDropOffLocation red = logicalScene.resolveLogicalObjectOfInterest("red").asLogicalDropOffLocation(); LogicalDropOffLocation green = logicalScene.resolveLogicalObjectOfInterest("green").asLogicalDropOffLocation(); - DifferenceObjectAtWrongPlace diff = new DifferenceObjectAtWrongPlace(x, emptyPreviousLocation ? null : red, green); + DifferenceObjectAtWrongPlace diff = createDifferenceObjectAtWrongPlace(x, emptyPreviousLocation ? null : red, green); List<Operation> operations = diff.computeOperations(); assertThat(operations).isNotEmpty(); @@ -60,7 +60,7 @@ public class TestComputeOperations { LogicalDropOffLocation red = logicalScene.resolveLogicalObjectOfInterest("red").asLogicalDropOffLocation(); LogicalDropOffLocation blue = logicalScene.resolveLogicalObjectOfInterest("blue").asLogicalDropOffLocation(); Robot arm1 = model.findRobot("arm1").orElseThrow(); - DifferenceObjectAtWrongPlace diff = new DifferenceObjectAtWrongPlace(x, emptyPreviousLocation ? null : red, blue); + DifferenceObjectAtWrongPlace diff = createDifferenceObjectAtWrongPlace(x, emptyPreviousLocation ? null : red, blue); List<Operation> operations = diff.computeOperations(); assertThat(operations).isNotEmpty(); @@ -90,7 +90,7 @@ public class TestComputeOperations { LogicalDropOffLocation green = logicalScene.resolveLogicalObjectOfInterest("green").asLogicalDropOffLocation(); Robot arm1 = model.findRobot("arm1").orElseThrow(); Robot arm2 = model.findRobot("arm2").orElseThrow(); - DifferenceObjectAtWrongPlace diff = new DifferenceObjectAtWrongPlace(x, emptyPreviousLocation ? null : red, green); + DifferenceObjectAtWrongPlace diff = createDifferenceObjectAtWrongPlace(x, emptyPreviousLocation ? null : red, green); List<Operation> operations = diff.computeOperations(); assertThat(operations).isNotEmpty(); @@ -137,7 +137,7 @@ public class TestComputeOperations { Robot arm2 = model.findRobot("arm2").orElseThrow(); Robot arm4 = model.findRobot("arm4").orElseThrow(); Robot arm5 = model.findRobot("arm5").orElseThrow(); - DifferenceObjectAtWrongPlace diff = new DifferenceObjectAtWrongPlace(x, emptyPreviousLocation ? null : red, purple); + DifferenceObjectAtWrongPlace diff = createDifferenceObjectAtWrongPlace(x, emptyPreviousLocation ? null : red, purple); List<Operation> operations = diff.computeOperations(); assertThat(operations).isNotEmpty(); @@ -164,4 +164,12 @@ public class TestComputeOperations { assertEquals(x, pickAndPlace3.getObjectToPick()); assertEquals(purple, pickAndPlace3.getTargetLocation()); } + + private DifferenceObjectAtWrongPlace createDifferenceObjectAtWrongPlace(LogicalMovableObject x, LogicalDropOffLocation previousLocation, LogicalDropOffLocation newLocation) { + DifferenceObjectAtWrongPlace result = new DifferenceObjectAtWrongPlace(); + result.setObject(x); + result.setPreviousLocation(previousLocation); + result.setNewLocation(newLocation); + return result; + } } diff --git a/ros3rag.placeB/src/test/java/de/tudresden/inf/st/placeB/TestDifference.java b/ros3rag.placeB/src/test/java/de/tudresden/inf/st/placeB/TestDifference.java index 5c98b039d1c8d973a8e89297cfb75ad2c3e78139..fb2ffaae2f255e8e5ffd7cc5210d365e5864743b 100644 --- a/ros3rag.placeB/src/test/java/de/tudresden/inf/st/placeB/TestDifference.java +++ b/ros3rag.placeB/src/test/java/de/tudresden/inf/st/placeB/TestDifference.java @@ -31,17 +31,15 @@ public class TestDifference { LogicalMovableObject x = myLogicalScene.resolveLogicalObjectOfInterest("x").asLogicalMovableObject(); assertFalse(x.hasLocatedAt()); - LogicalDropOffLocation otherRed = model.getOtherScene().resolveLogicalObjectOfInterest("red").asLogicalDropOffLocation(); - JastAddList<Difference> diffs = model.diffScenes(); assertNotNull(diffs); assertEquals(1, diffs.getNumChild()); Difference diff = diffs.getChild(0); assertThat(diff).isInstanceOf(DifferenceObjectAtWrongPlace.class); DifferenceObjectAtWrongPlace wrongPlace = (DifferenceObjectAtWrongPlace) diff; - assertEquals(x, wrongPlace.getObject()); + assertEquals("x", wrongPlace.getObject().getName()); assertNull(wrongPlace.getPreviousLocation()); - assertEquals(otherRed, wrongPlace.getNewLocation()); + assertEquals("red", wrongPlace.getNewLocation().getName()); } @Test @@ -58,9 +56,7 @@ public class TestDifference { LogicalScene myLogicalScene = model.getMyScene().getLogicalScene(); LogicalMovableObject x = myLogicalScene.resolveLogicalObjectOfInterest("x").asLogicalMovableObject(); - LogicalDropOffLocation blue = myLogicalScene.resolveLogicalObjectOfInterest("blue").asLogicalDropOffLocation(); - assertEquals(blue, x.getLocatedAt()); - LogicalDropOffLocation otherRed = model.getOtherScene().resolveLogicalObjectOfInterest("red").asLogicalDropOffLocation(); + assertEquals("blue", x.getLocatedAt().getName()); JastAddList<Difference> diffs = model.diffScenes(); assertNotNull(diffs); @@ -68,9 +64,9 @@ public class TestDifference { Difference diff = diffs.getChild(0); assertThat(diff).isInstanceOf(DifferenceObjectAtWrongPlace.class); DifferenceObjectAtWrongPlace wrongPlace = (DifferenceObjectAtWrongPlace) diff; - assertEquals(x, wrongPlace.getObject()); - assertEquals(blue, wrongPlace.getPreviousLocation()); - assertEquals(otherRed, wrongPlace.getNewLocation()); + assertEquals("x", wrongPlace.getObject().getName()); + assertEquals("blue", wrongPlace.getPreviousLocation().getName()); + assertEquals("red", wrongPlace.getNewLocation().getName()); } @Test @@ -86,8 +82,7 @@ public class TestDifference { LogicalScene myLogicalScene = model.getMyScene().getLogicalScene(); LogicalMovableObject x = myLogicalScene.resolveLogicalObjectOfInterest("x").asLogicalMovableObject(); - LogicalDropOffLocation red = myLogicalScene.resolveLogicalObjectOfInterest("red").asLogicalDropOffLocation(); - assertEquals(red, x.getLocatedAt()); + assertEquals("red", x.getLocatedAt().getName()); JastAddList<Difference> diffs = model.diffScenes(); assertNotNull(diffs); @@ -95,8 +90,8 @@ public class TestDifference { Difference diff = diffs.getChild(0); assertThat(diff).isInstanceOf(DifferenceObjectMisplaced.class); DifferenceObjectMisplaced misplaced = (DifferenceObjectMisplaced) diff; - assertEquals(x, misplaced.getObject()); - assertEquals(red, misplaced.getPreviousLocation()); + assertEquals("x", misplaced.getObject().getName()); + assertEquals("red", misplaced.getPreviousLocation().getName()); } @Test @@ -116,7 +111,7 @@ public class TestDifference { JastAddList<Difference> diffs = model.diffScenes(); assertNotNull(diffs); - assertEquals(0, diffs.getNumChild()); + assertThat(diffs).isEmpty(); } @Test @@ -133,12 +128,11 @@ public class TestDifference { LogicalScene myLogicalScene = model.getMyScene().getLogicalScene(); LogicalMovableObject x = myLogicalScene.resolveLogicalObjectOfInterest("x").asLogicalMovableObject(); - LogicalDropOffLocation red = myLogicalScene.resolveLogicalObjectOfInterest("red").asLogicalDropOffLocation(); - assertEquals(red, x.getLocatedAt()); + assertEquals("red", x.getLocatedAt().getName()); JastAddList<Difference> diffs = model.diffScenes(); assertNotNull(diffs); - assertEquals(0, diffs.getNumChild()); + assertThat(diffs).isEmpty(); } @Test @@ -154,15 +148,13 @@ public class TestDifference { LogicalScene myLogicalScene = model.getMyScene().getLogicalScene(); assertNull(myLogicalScene.resolveLogicalObjectOfInterest("x")); - LogicalMovableObject otherX = model.getOtherScene().resolveLogicalObjectOfInterest("x").asLogicalMovableObject(); - JastAddList<Difference> diffs = model.diffScenes(); assertNotNull(diffs); assertEquals(1, diffs.getNumChild()); Difference diff = diffs.getChild(0); assertThat(diff).isInstanceOf(DifferenceNewObject.class); DifferenceNewObject diffNewObject = (DifferenceNewObject) diff; - assertEquals(otherX, diffNewObject.getObject()); + assertEquals("x", diffNewObject.getObject().getName()); } @Test @@ -182,21 +174,17 @@ public class TestDifference { LogicalScene myLogicalScene = model.getMyScene().getLogicalScene(); LogicalMovableObject x = myLogicalScene.resolveLogicalObjectOfInterest("x").asLogicalMovableObject(); LogicalMovableObject y = myLogicalScene.resolveLogicalObjectOfInterest("y").asLogicalMovableObject(); - LogicalDropOffLocation blue = myLogicalScene.resolveLogicalObjectOfInterest("blue").asLogicalDropOffLocation(); - LogicalDropOffLocation green = myLogicalScene.resolveLogicalObjectOfInterest("green").asLogicalDropOffLocation(); - assertEquals(blue, x.getLocatedAt()); - assertEquals(green, y.getLocatedAt()); - - LogicalDropOffLocation otherRed = model.getOtherScene().resolveLogicalObjectOfInterest("red").asLogicalDropOffLocation(); - + assertEquals("blue", x.getLocatedAt().getName()); + assertEquals("green", y.getLocatedAt().getName()); JastAddList<Difference> diffs = model.diffScenes(); assertNotNull(diffs); assertEquals(2, diffs.getNumChild()); assertThat(diffs).allMatch(d -> d instanceof DifferenceObjectAtWrongPlace); + //noinspection unchecked assertThat(diffs).map(diff -> (DifferenceObjectAtWrongPlace) diff) - .extracting("Object", "PreviousLocation", "NewLocation") - .containsOnly(tuple(x, blue, otherRed), - tuple(y, green, otherRed)); + .extracting(d -> d.getObject().getName(), d -> d.getPreviousLocation().getName(), d -> d.getNewLocation().getName()) + .containsOnly(tuple("x", "blue", "red"), + tuple("y", "green", "red")); } } diff --git a/ros3rag.placeB/src/test/java/de/tudresden/inf/st/placeB/TestMultiScenes.java b/ros3rag.placeB/src/test/java/de/tudresden/inf/st/placeB/TestMultiScenes.java new file mode 100644 index 0000000000000000000000000000000000000000..dc1080a5f69832879c19ba4ad849c729fdcf9776 --- /dev/null +++ b/ros3rag.placeB/src/test/java/de/tudresden/inf/st/placeB/TestMultiScenes.java @@ -0,0 +1,142 @@ +package de.tudresden.inf.st.placeB; + +import de.tudresden.inf.st.placeB.ast.LogicalDropOffLocation; +import de.tudresden.inf.st.placeB.ast.LogicalMovableObject; +import de.tudresden.inf.st.placeB.ast.LogicalScene; +import de.tudresden.inf.st.placeB.ast.WorldModelB; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import java.util.Collections; + +import static de.tudresden.inf.st.placeB.TestUtils.newModel; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Testing merging of multiple (other) scenes. + * + * @author rschoene - Initial contribution + */ +public class TestMultiScenes { + + @Test + public void noOtherScenes() { + WorldModelB model = newModel(); + + LogicalScene actual = model.mergedOtherScene(); + + assertThat(actual.getLogicalDropOffLocationList()).isEmpty(); + assertThat(actual.getLogicalMovableObjectList()).isEmpty(); + } + + @ParameterizedTest(name = "twoScenesContains [scene1 = {argumentsWithNames}]") + @ValueSource(booleans = {true, false}) + public void oneSceneNoContains(boolean scene1) { + WorldModelB model = newModel(); + TestUtils.addOtherLocations(scene1 ? model.getOtherScene1() : model.getOtherScene2(), "red"); + TestUtils.addOtherObjects(scene1 ? model.getOtherScene1() : model.getOtherScene2(), "a"); + + LogicalScene actual = model.mergedOtherScene(); + + assertThat(actual.getLogicalDropOffLocationList()) + .extracting("Name").containsOnly("red"); + assertThat(actual.getLogicalMovableObjectList()) + .extracting("Name").containsOnly("a"); + } + + @Test + public void twoScenesNoContains() { + WorldModelB model = newModel(); + TestUtils.addOtherLocations(model, "red"); + TestUtils.addOtherObjects(model, "a"); + TestUtils.addOtherLocations(model.getOtherScene2(), "blue"); + TestUtils.addOtherObjects(model.getOtherScene2(), "b"); + + LogicalScene actual = model.mergedOtherScene(); + + assertThat(actual.getLogicalDropOffLocationList()) + .size().isEqualTo(2); + assertThat(actual.getLogicalDropOffLocationList()) + .doesNotContainAnyElementsOf(model.getOtherScene1().getLogicalDropOffLocationList()) + .doesNotContainAnyElementsOf(model.getOtherScene2().getLogicalDropOffLocationList()) + .extracting("Name").containsOnly("red", "blue"); + assertThat(actual.getLogicalDropOffLocationList()) + .extracting("ContainedObjects").containsOnly(Collections.emptyList()); + + assertThat(actual.getLogicalMovableObjectList()) + .size().isEqualTo(2); + assertThat(actual.getLogicalMovableObjectList()) + .doesNotContainAnyElementsOf(model.getOtherScene1().getLogicalMovableObjectList()) + .doesNotContainAnyElementsOf(model.getOtherScene2().getLogicalMovableObjectList()) + .extracting("Name").containsOnly("a", "b"); + assertThat(actual.getLogicalMovableObjectList()) + .extracting("LocatedAt").containsOnly((LogicalDropOffLocation) null); + } + + @ParameterizedTest(name = "twoScenesContains [scene1 = {argumentsWithNames}]") + @ValueSource(booleans = {true, false}) + public void twoScenesContains1(boolean scene1) { + WorldModelB model = newModel(); + TestUtils.addOtherLocations(model, "red", "blue"); + TestUtils.addOtherObjects(model, "a", "b"); + model.getOtherScene2().addLogicalDropOffLocation(new LogicalDropOffLocation().setName("red")); + model.getOtherScene2().addLogicalMovableObject(new LogicalMovableObject().setName("a")); + TestUtils.addContainedObjects(scene1 ? model.getOtherScene1() : model.getOtherScene2(), + "red", "a"); + + LogicalScene actual = model.mergedOtherScene(); + + assertThat(actual.getLogicalDropOffLocationList()) + .size().isEqualTo(2); + assertThat(actual.getLogicalDropOffLocationList()) + .doesNotContainAnyElementsOf(model.getOtherScene1().getLogicalDropOffLocationList()) + .doesNotContainAnyElementsOf(model.getOtherScene2().getLogicalDropOffLocationList()) + .extracting("Name").containsExactly("red", "blue"); + LogicalDropOffLocation red = actual.resolveLogicalObjectOfInterest("red").asLogicalDropOffLocation(); + assertThat(red.getContainedObjectList()) + .extracting("Name").containsOnly("a"); + + assertThat(actual.getLogicalMovableObjectList()) + .size().isEqualTo(2); + assertThat(actual.getLogicalMovableObjectList()) + .doesNotContainAnyElementsOf(model.getOtherScene1().getLogicalMovableObjectList()) + .extracting("Name").containsOnly("a", "b"); + LogicalMovableObject a = actual.resolveLogicalObjectOfInterest("a").asLogicalMovableObject(); + assertThat(a.getLocatedAt()) + .extracting("Name").isEqualTo("red"); + } + + @Test + public void twoScenesRedContainsATwice() { + WorldModelB model = newModel(); + TestUtils.addOtherLocations(model, "red", "blue"); + TestUtils.addOtherObjects(model, "a", "b"); + TestUtils.addContainedObjects(model, "red", "a"); + + TestUtils.addOtherLocations(model.getOtherScene2(), "red"); + TestUtils.addOtherObjects(model.getOtherScene2(), "a", "b"); + TestUtils.addContainedObjects(model.getOtherScene2(), "red", "a"); + + LogicalScene actual = model.mergedOtherScene(); + + assertThat(actual.getLogicalDropOffLocationList()) + .size().isEqualTo(2); + assertThat(actual.getLogicalDropOffLocationList()) + .doesNotContainAnyElementsOf(model.getOtherScene1().getLogicalDropOffLocationList()) + .doesNotContainAnyElementsOf(model.getOtherScene2().getLogicalDropOffLocationList()) + .extracting("Name").containsExactly("red", "blue"); + LogicalDropOffLocation red = actual.resolveLogicalObjectOfInterest("red").asLogicalDropOffLocation(); + assertThat(red.getContainedObjectList()) + .extracting("Name").containsOnly("a"); + + assertThat(actual.getLogicalMovableObjectList()) + .size().isEqualTo(2); + assertThat(actual.getLogicalMovableObjectList()) + .doesNotContainAnyElementsOf(model.getOtherScene1().getLogicalMovableObjectList()) + .extracting("Name").containsOnly("a", "b"); + LogicalMovableObject a = actual.resolveLogicalObjectOfInterest("a").asLogicalMovableObject(); + assertThat(a.getLocatedAt()) + .extracting("Name").isEqualTo("red"); + } +} diff --git a/ros3rag.placeB/src/test/java/de/tudresden/inf/st/placeB/TestUtils.java b/ros3rag.placeB/src/test/java/de/tudresden/inf/st/placeB/TestUtils.java index 699e3e32c54c18234ef562fb4dc526e2f70b3474..6e5f8fe77601bf88ef82f6f3ef0764c60e932e7c 100644 --- a/ros3rag.placeB/src/test/java/de/tudresden/inf/st/placeB/TestUtils.java +++ b/ros3rag.placeB/src/test/java/de/tudresden/inf/st/placeB/TestUtils.java @@ -12,8 +12,8 @@ public class TestUtils { WorldModelB model = new WorldModelB(); Scene scene = new Scene(); model.setMyScene(scene); - LogicalScene otherScene = new LogicalScene(); - model.setOtherScene(otherScene); + model.setOtherScene1(new LogicalScene()); + model.setOtherScene2(new LogicalScene()); return model; } @@ -70,21 +70,33 @@ public class TestUtils { } public static void addOtherObjects(WorldModelB model, String... names) { + addOtherObjects(model.getOtherScene1(), names); + } + + public static void addOtherObjects(LogicalScene scene, String... names) { for (String name : names) { - model.getOtherScene().addLogicalMovableObject(new LogicalMovableObject().setName(name)); + scene.addLogicalMovableObject(new LogicalMovableObject().setName(name)); } } public static void addOtherLocations(WorldModelB model, String... names) { + addOtherLocations(model.getOtherScene1(), names); + } + + public static void addOtherLocations(LogicalScene scene, String... names) { for (String name : names) { - model.getOtherScene().addLogicalDropOffLocation(new LogicalDropOffLocation().setName(name)); + scene.addLogicalDropOffLocation(new LogicalDropOffLocation().setName(name)); } } public static void addContainedObjects(WorldModelB model, String locationName, String... objectNames) { - LogicalDropOffLocation location = model.getOtherScene().resolveLogicalObjectOfInterest(locationName).asLogicalDropOffLocation(); + addContainedObjects(model.getOtherScene1(), locationName, objectNames); + } + + public static void addContainedObjects(LogicalScene scene, String locationName, String... objectNames) { + LogicalDropOffLocation location = scene.resolveLogicalObjectOfInterest(locationName).asLogicalDropOffLocation(); for (String objectName : objectNames) { - location.addContainedObject(model.getOtherScene().resolveLogicalObjectOfInterest(objectName).asLogicalMovableObject()); + location.addContainedObject(scene.resolveLogicalObjectOfInterest(objectName).asLogicalMovableObject()); } }