diff --git a/src/main/jastadd/cleanup/Cleanup.jrag b/src/main/jastadd/cleanup/Cleanup.jrag index 7e44ce3e84a5f677870ab6453a0218c2d4d6091e..8d3f8e46abfd0ac42b24bc1f351053fe72c67ccd 100644 --- a/src/main/jastadd/cleanup/Cleanup.jrag +++ b/src/main/jastadd/cleanup/Cleanup.jrag @@ -4,16 +4,17 @@ aspect CleanupAttributes { inh String PickUpObject.object(); inh String RightPlace.object(); inh String DropObjectAtRightPlace.object(); - eq MoveObjectToCorrectPlace.getPickUpObject().object() = getObjectAtWrongPlace().getObject(); - eq MoveObjectToCorrectPlace.getDropObjectAtRightPlace().object() = getObjectAtWrongPlace().getObject(); - eq Tidy.getMoveObjectToCorrectPlace(int i).object() = getMoveObjectToCorrectPlace(i).getObjectAtWrongPlace().getObject(); + eq MoveObjectToCorrectPlace.getPickUpObject().object() = getMisplacedObject().getAvailableObject().getObject(); + eq MoveObjectToCorrectPlace.getDropObjectAtRightPlace().object() = getMisplacedObject().getAvailableObject().getObject(); + eq Tidy.getMoveObjectToCorrectPlace(int i).object() = getMoveObjectToCorrectPlace(i).getMisplacedObject().getAvailableObject().getObject(); eq Tidy.getChild().object() { throw new UnsupportedOperationException("Invalid use of attribute object():String"); } - syn String ASTNode.place(); // TODO can this be avoided? - eq DropObjectAtRightPlace.place() = getRightPlace().getPlace(); - eq ASTNode.place() { + inh String ASTNode.place(); // TODO can this be avoided? + inh String DropObjectAtRightPlace.place(); + eq MoveObjectToCorrectPlace.getDropObjectAtRightPlace().place() = getMisplacedObject().getRightPlace().getPlace(); + eq ASTNode.getChild().place() { throw new UnsupportedOperationException("Invalid use of attribute place():String"); } diff --git a/src/main/jastadd/cleanup/Cleanup.relast b/src/main/jastadd/cleanup/Cleanup.relast index 39318151d87bd941bdbd63280d897f38cdb35778..cd22ce5fcffa7fcbe63268e7d78e1d91138d3bb1 100644 --- a/src/main/jastadd/cleanup/Cleanup.relast +++ b/src/main/jastadd/cleanup/Cleanup.relast @@ -1,12 +1,12 @@ Tidy : MotionGrammarElement ::= NotEmptyTable MoveObjectToCorrectPlace* EmptyTable; -MoveObjectToCorrectPlace : MotionGrammarElement ::= ObjectAtWrongPlace/*provides object*/ PickUpObject/*uses object*/ DropObjectAtRightPlace/*uses object*/; -PickUpObject/*requires object*/ : MotionGrammarElement ::= RobotIsReadyToPickToken; -DropObjectAtRightPlace/*requires object*/ : MotionGrammarElement ::= RobotIsReadyToDropToken RightPlace/*uses object, provides place*/; +MoveObjectToCorrectPlace : MotionGrammarElement ::= MisplacedObject/*provides object, place*/ PickUpObject/*uses object*/ DropObjectAtRightPlace/*uses object*/ RobotIsReadyToPickToken; +PickUpObject/*requires object*/ : MotionGrammarElement; +DropObjectAtRightPlace/*requires object, place*/ : MotionGrammarElement ::= RobotIsReadyToDropToken; // Tokens EmptyTable : Token; NotEmptyTable : Token; // TODO should be improved to express EmptyTable can not be parsed -ObjectAtWrongPlace : Token ::= <Object:String>; // the Object is a variable of the token +AvailableObject : Token ::= <Object:String>; // the object is a variable of the token RobotIsReadyToPickToken : Token ::= RobotIsIdle RobotHasNoItemAttached; // combined token. both individual tokens are parsed in parallel RobotIsNotReadyToPickToken : Token ::= [RobotIsNotIdle] /*or*/ [RobotHasItemAttached]; // TODO negated RobotIsReadyToPickToken RobotIsReadyToDropToken : Token ::= RobotIsIdle RobotHasItemAttached; // combined token. both individual tokens are parsed in parallel @@ -16,3 +16,4 @@ RobotIsNotIdle : Token; // TODO negated RobotIsIdle RobotHasItemAttached : Token; RobotHasNoItemAttached : Token; // TODO negated RobotHasItemAttached RightPlace/*requires object*/ : Token ::= <Place:String>; +MisplacedObject : Token ::= AvailableObject RightPlace <Object:String> <Place:String>; // TODO not so nice that the tokens depend on each other; also, object and place propagation... diff --git a/src/main/jastadd/cleanup/DecisionTree.jadd b/src/main/jastadd/cleanup/DecisionTree.jadd new file mode 100644 index 0000000000000000000000000000000000000000..3e692a94090cfb4df8560690b3a3484f4456b49f --- /dev/null +++ b/src/main/jastadd/cleanup/DecisionTree.jadd @@ -0,0 +1,49 @@ +aspect DecisionTree { + + public Node Node.getOrCreateColorSelection(String color) { + throw new UnsupportedOperationException("Unable to create a color selection in a node that is not a Selection node"); + } + public Node SelectionNode.getOrCreateColorSelection(String color) { + for (Node child : getNodeList()) { + if (child.isColorSelection() && child.asColorSelection().getColor().equals(color)) { + return child; + } + } + ColorSelection newColorSelection = new ColorSelection(); + newColorSelection.setColor(color); + addNode(newColorSelection); + return newColorSelection; + } + + public Node Node.getOrCreateSizeSelection(String size) { + throw new UnsupportedOperationException("Unable to create a size selection in a node that is not a Selection node"); + } + public Node SelectionNode.getOrCreateSizeSelection(String size) { + for (Node child : getNodeList()) { + if (child.isSizeSelection() && child.asSizeSelection().getSize().equals(size)) { + return child; + } + } + SizeSelection newSizeSelection = new SizeSelection(); + newSizeSelection.setSize(size); + addNode(newSizeSelection); + return newSizeSelection; + } + + public Node Node.getOrCreateDecision(String decision) { + throw new UnsupportedOperationException("Unable to create a decision selection in a node that is not a Selection node"); + } + public Node SelectionNode.getOrCreateDecision(String decision) { + for (Node child : getNodeList()) { + if (child.isDecision()) { + child.asDecision().setTarget(decision); + return child; + } + } + Decision newDecision = new Decision(); + newDecision.setTarget(decision); + addNode(newDecision); + return newDecision; + } + +} diff --git a/src/main/jastadd/cleanup/DecisionTree.jrag b/src/main/jastadd/cleanup/DecisionTree.jrag new file mode 100644 index 0000000000000000000000000000000000000000..9c72e3d7463c76e71cff3f7996acbff75ac745cb --- /dev/null +++ b/src/main/jastadd/cleanup/DecisionTree.jrag @@ -0,0 +1,48 @@ +aspect DecisionTree { + + syn boolean Node.isColorSelection() = false; + eq ColorSelection.isColorSelection() = true; + + syn ColorSelection Node.asColorSelection() = null; + eq ColorSelection.asColorSelection() = this; + + syn boolean Node.isSizeSelection() = false; + eq SizeSelection.isSizeSelection() = true; + + syn SizeSelection Node.asSizeSelection() = null; + eq SizeSelection.asSizeSelection() = this; + + syn boolean Node.isDecision() = false; + eq Decision.isDecision() = true; + + syn Decision Node.asDecision() = null; + eq Decision.asDecision() = this; + + inh DecisionTree PhysicalObject.decisionTree(); + eq RobotWorld.getTable().decisionTree() = getDecisionTree(); + + syn String MovableObject.rightPlace() = decisionTree().processElement(this).orElse(null); + + syn java.util.Optional<String> Node.processElement(MovableObject object); + eq Decision.processElement(MovableObject object) = java.util.Optional.of(getTarget()); + eq SelectionNode.processElement(MovableObject object) { + for (Node child: getNodeList()) { + if (child.check(object)) { + return child.processElement(object); + } + } + return java.util.Optional.empty(); + } + syn boolean Node.check(MovableObject object) = true; + eq ColorSelection.check(MovableObject object) = getColor().equals(object.getColor()); + eq SizeSelection.check(MovableObject object) { + if (object.getName().startsWith("big") | object.getName().startsWith("large")) { + return getSize() == "large"; + } else if (object.getName().startsWith("small")) { + return getSize() == "small"; + } else { + return getSize() == "medium"; + } + } + +} diff --git a/src/main/jastadd/cleanup/RobotWorld.connect b/src/main/jastadd/cleanup/RobotWorld.connect index 7db72610d35cb68f974dab3aeaed0b6dcc97c462..c67a12d7d715e2f1179a47ff0d215682449c8251 100644 --- a/src/main/jastadd/cleanup/RobotWorld.connect +++ b/src/main/jastadd/cleanup/RobotWorld.connect @@ -1,5 +1,5 @@ // --- receiving --- -receive RobotWorld.Table using ParseScene, ConvertScene ; +receive RobotWorld.Table using ParseScene, ConvertScene; ParseScene maps byte[] bytes to de.tudresden.inf.st.ceti.Scene {: return de.tudresden.inf.st.ceti.Scene.parseFrom(bytes); @@ -34,3 +34,16 @@ ConvertScene maps de.tudresden.inf.st.ceti.Scene pbScene to Table {: } return result; :} + +receive indexed with add RobotWorld.Selection using ParseSelection, ConvertSelection; + +ParseSelection maps byte[] bytes to de.tudresden.inf.st.ceti.Selection {: + return de.tudresden.inf.st.ceti.Selection.parseFrom(bytes); +:} + +ConvertSelection maps de.tudresden.inf.st.ceti.Selection pbSelection to Selection {: + var result = new Selection(); + result.setObject(pbSelection.getId()); + result.setTimeStamp(java.time.Instant.now()); + return result; +:} diff --git a/src/main/jastadd/cleanup/RobotWorld.jadd b/src/main/jastadd/cleanup/RobotWorld.jadd index edadbe3640db841bfb6a1f281f6dca1e75b84947..3283a5ed76482927ac18009ec7545c28cabb2b75 100644 --- a/src/main/jastadd/cleanup/RobotWorld.jadd +++ b/src/main/jastadd/cleanup/RobotWorld.jadd @@ -13,7 +13,7 @@ aspect RobotWorld { Robot r = new Robot(); r.setIsIdle(true); t.setRobot(r); - return new RobotWorld(t); + return new RobotWorld(t, t.treeCopy(), new JastAddList<>()); } public static RobotWorld RobotWorld.initialWorld() { @@ -21,14 +21,14 @@ aspect RobotWorld { r.setIsIdle(true); Table t = new Table(); t.setRobot(r); - RobotWorld result = new RobotWorld(t); + RobotWorld result = new RobotWorld(t, new Table(), new JastAddList<>()); result.simulated = false; return result; } public static TokenType EmptyTable.type() { return TokenType.of("EMPTY_TABLE"); } public static TokenType NotEmptyTable.type() { return TokenType.of("NOT_EMPTY_TABLE"); } - public static TokenType ObjectAtWrongPlace.type() { return TokenType.of("OBJECT_AT_WRONG_PLACE"); } + public static TokenType AvailableObject.type() { return TokenType.of("AVAILABLE_OBJECT"); } public static TokenType RobotIsReadyToPickToken.type() { return TokenType.of("ROBOT_IS_READY_TO_PICK_TOKEN"); } public static TokenType RobotIsNotReadyToPickToken.type() { return TokenType.of("ROBOT_IS_NOT_READY_TO_PICK_TOKEN"); } public static TokenType RobotIsReadyToDropToken.type() { return TokenType.of("ROBOT_IS_READY_TO_DROP_TOKEN"); } @@ -38,6 +38,7 @@ aspect RobotWorld { public static TokenType RobotHasItemAttached.type() { return TokenType.of("ROBOT_HAS_ITEM_ATTACHED"); } public static TokenType RobotHasNoItemAttached.type() { return TokenType.of("ROBOT_HAS_NO_ITEM_ATTACHED"); } public static TokenType RightPlace.type() { return TokenType.of("RIGHT_PLACE"); } + public static TokenType MisplacedObject.type() { return TokenType.of("MISPLACED_OBJECT"); } public static Pose Pose.of(double x, double y, double z) { return new Pose(x, y, z, 0, 0, 0, 1); @@ -80,17 +81,13 @@ aspect RobotWorld { } } - public ObjectAtWrongPlace World.parseObjectAtWrongPlace(Tidy context) { + public AvailableObject World.parseAvailableObject() { return null; } - public ObjectAtWrongPlace RobotWorld.parseObjectAtWrongPlace(Tidy context) { - System.out.print("Trying to parse token <ObjectAtWrongPlace>... "); - // TODO get a *random* object? - for (PhysicalObject o : getTable().getPhysicalObjectList()) { - if (!context.inPlan(o.getName()) && o.isMovableObject() && !o.asMovableObject().isInBin()) { - System.out.println("success"); - return new ObjectAtWrongPlace(o.getName()); - } + public AvailableObject RobotWorld.parseAvailableObject() { + System.out.print("Trying to parse token <AvailableObject>... "); + if (getTable().getNumPhysicalObject() > 0) { + return new AvailableObject(getTable().getPhysicalObject(new java.util.Random().nextInt(getTable().getNumPhysicalObject())).getName()); } System.out.println("failure"); return null; @@ -224,17 +221,35 @@ aspect RobotWorld { MovableObject o = getTable().getMovableObjectByName(objectName); if (o != null) { - for (PhysicalObject b : getTable().getPhysicalObjectList()) { - if (b.isBin() && o.fitsIn(b.asBin())) { - System.out.println("success"); - return new RightPlace(b.getName()); - } + Bin rightPlace = getTable().getBinByName(o.rightPlace()); + if (rightPlace == null) { + System.out.println("failure (no matching bin found)"); + return null; } - System.out.println("failure (no matching bin found)"); - return null; + return new RightPlace(rightPlace.getName()); } else { System.out.println("failure (object does not exist)"); return null; } } + + public MisplacedObject World.parseMisplacedObject() { + return null; + } + public MisplacedObject RobotWorld.parseMisplacedObject() { + System.out.println("Trying to parse token <MisplacedObject> by parsing ALL sub-tokens..."); + AvailableObject availableObject = parseAvailableObject(); + if (availableObject == null) { + System.out.println("Trying to parse token <RobotIsReadyToDropToken> by parsing ALL sub-tokens... failure"); + return null; + } + RightPlace rightPlace = parseRightPlace(availableObject.getObject()); + if (rightPlace != null) { + System.out.println("Trying to parse token <RobotIsReadyToDropToken> by parsing ALL sub-tokens... success"); + return new MisplacedObject(availableObject, rightPlace, availableObject.getObject(), rightPlace.getPlace()); + } else { + System.out.println("Trying to parse token <RobotIsReadyToDropToken> by parsing ALL sub-tokens... failure"); + return null; + } + } } diff --git a/src/main/jastadd/cleanup/RobotWorld.jrag b/src/main/jastadd/cleanup/RobotWorld.jrag index 19d41ce4be7fade2a38c02aa69e9622ae0adc17d..f38216e958da207347466310b4677a2468df23de 100644 --- a/src/main/jastadd/cleanup/RobotWorld.jrag +++ b/src/main/jastadd/cleanup/RobotWorld.jrag @@ -78,7 +78,89 @@ aspect RobotWorld { } } - syn boolean MovableObject.fitsIn(Bin b) { - return getColor().equals(b.getColor()); + syn boolean ASTNode.inDemonstrationTable() = false; + inh boolean Pose.inDemonstrationTable(); + inh boolean Robot.inDemonstrationTable(); + inh boolean MovableObject.inDemonstrationTable(); + eq RobotWorld.getDemonstrationTable().inDemonstrationTable() = true; + eq RobotWorld.getTable().inDemonstrationTable() = false; + + syn nta DecisionTree RobotWorld.getDecisionTree() { + DecisionTree t = new DecisionTree(); + + MovableObject objectSelected = null; + Bin targetSelected = null; + + for (Selection selection : getSelectionList()) { + + PhysicalObject newSelection = getDemonstrationTable().getPhysicalObjectByName(selection.getObject()); + + if (newSelection == null) { + System.out.println("Selected unknown object " + selection.getObject()); + } else if (objectSelected == null && targetSelected == null) { + if (newSelection.isMovableObject()) { + objectSelected = newSelection.asMovableObject(); + } else if (newSelection.isBin()) { + targetSelected = newSelection.asBin(); + } + } else if (objectSelected != null && targetSelected == null) { + if (newSelection.isMovableObject()) { + if (objectSelected == newSelection) { + // unselect + objectSelected = null; + } else { + // change selection + objectSelected = newSelection.asMovableObject(); + } + } else if (newSelection.isBin()) { + // we have a full selection, add it to the tree + targetSelected = newSelection.asBin(); + + String color = objectSelected.getColor(); + String size = "medium"; + if (objectSelected.getName().startsWith("big") | objectSelected.getName().startsWith("large")) { + size = "large"; + } else if (objectSelected.getName().startsWith("small")) { + size = "small"; + } + Node n = t.getOrCreateSizeSelection(size) + .getOrCreateColorSelection(color) + .getOrCreateDecision(targetSelected.getName()); + + objectSelected = null; + targetSelected = null; + } + } else if (objectSelected == null && targetSelected != null) { + if (newSelection.isBin()) { + if (targetSelected == newSelection) { + // unselect + targetSelected = null; + } else { + // change selection + targetSelected = newSelection.asBin(); + } + } else if (newSelection.isMovableObject()) { + // we have a full selection, add it to the tree + objectSelected = newSelection.asMovableObject(); + + String color = objectSelected.getColor(); + String size = "medium"; + if (objectSelected.getName().startsWith("big") | objectSelected.getName().startsWith("large")) { + size = "large"; + } else if (objectSelected.getName().startsWith("small")) { + size = "small"; + } + Node n = t.getOrCreateSizeSelection(size) + .getOrCreateColorSelection(color) + .getOrCreateDecision(targetSelected.getName()); + + objectSelected = null; + targetSelected = null; + } + } else { + // this should not happen + } + } + return t; } } diff --git a/src/main/jastadd/cleanup/RobotWorld.relast b/src/main/jastadd/cleanup/RobotWorld.relast index 2c9c1dbd598d007aee96944f54d3b68d6e69b2b2..4269f94616c41a4f0b1212f05d34efb7c0638ea6 100644 --- a/src/main/jastadd/cleanup/RobotWorld.relast +++ b/src/main/jastadd/cleanup/RobotWorld.relast @@ -1,6 +1,15 @@ // World Model of the Motion Grammar -RobotWorld : World ::= Table; +RobotWorld : World ::= Table DemonstrationTable:Table Selection* /DecisionTree/; + +abstract Node; +abstract SelectionNode : Node ::= Node*; +abstract DecisionNode : Node; +DecisionTree : SelectionNode; +ColorSelection : SelectionNode ::= <Color>; +SizeSelection : SelectionNode ::= <Size>; +Decision : DecisionNode ::= <Target>; + Table ::= PhysicalObject* Robot; abstract PhysicalObject ::= <Name> Pose <Color>; @@ -10,4 +19,6 @@ Bin : PhysicalObject; Pose ::= <X:double> <Y:double> <Z:double> <QX:double> <QY:double> <QZ:double> <QW:double>; Robot ::= <IsIdle:boolean>; -rel Robot.attachedItem? <-> MovableObject.attachedRobot?; +rel Robot.AttachedItem? <-> MovableObject.AttachedRobot?; + +Selection ::= <Object> <TimeStamp:java.time.Instant>; diff --git a/src/main/jastadd/cleanup/SemanticActions.jadd b/src/main/jastadd/cleanup/SemanticActions.jadd index 0de455177803a8c3a47c6365011e5045a697eed6..bde32f54c87db665e586bd24f296c6194b99e55a 100644 --- a/src/main/jastadd/cleanup/SemanticActions.jadd +++ b/src/main/jastadd/cleanup/SemanticActions.jadd @@ -2,7 +2,7 @@ aspect SemanticActions { public void PickUpObject.action(World world) { RobotWorld scene = world.asRobotWorld(); - System.out.println("performing semantic action for element Pick"); + System.out.println("performing semantic action for element PickUpObject"); String objectName = object(); if (scene.simulated) { @@ -31,7 +31,7 @@ aspect SemanticActions { public void DropObjectAtRightPlace.action(World world) { RobotWorld scene = world.asRobotWorld(); - System.out.println("performing semantic action for element Pick"); + System.out.println("performing semantic action for element DropObjectAtRightPlace"); String objectName = object(); String placeName = place(); if (scene.simulated) { @@ -42,8 +42,8 @@ aspect SemanticActions { } catch (InterruptedException e) { /* ignore */ } MovableObject object = scene.getTable().getMovableObjectByName(objectName); Bin bin = scene.getTable().getBinByName(placeName); - object.setPose(Pose.of(bin.getPose())); scene.getTable().getRobot().setAttachedItem(null); + object.removeSelf(); try { Thread.sleep(3000); } catch (InterruptedException e) { /* ignore */ } diff --git a/src/main/jastadd/common/Helpers.jadd b/src/main/jastadd/common/Helpers.jadd new file mode 100644 index 0000000000000000000000000000000000000000..34cd3ad3c773adbcd4e8385970803aca3cb9d9ab --- /dev/null +++ b/src/main/jastadd/common/Helpers.jadd @@ -0,0 +1,14 @@ +aspect Helpers { + public void ASTNode.removeSelf() { + if (getParent() == null) { + throw new RuntimeException("Unable to remove object (no parent)"); + } + for (int i=0; i<getParent().numChildren();i++) { + if (getParent().getChild(i) == this) { + getParent().removeChild(i); + return; + } + } + throw new RuntimeException("Unable to remove object (wrong parent relation)"); + } +} diff --git a/src/main/jastadd/common/Tracing.jadd b/src/main/jastadd/common/Tracing.jadd index fdbe3392de01fc25f76e83423e143d5f95a2b1cf..cce799e68e276a4a8fe2a0f922355f6cca0bd95c 100644 --- a/src/main/jastadd/common/Tracing.jadd +++ b/src/main/jastadd/common/Tracing.jadd @@ -1,6 +1,6 @@ aspect Tracing { - public static void World.printContextOf(String step, ASTNode<?> highlightNode, String highlightColor) { + synchronized public static void World.printContextOf(String step, ASTNode<?> highlightNode, String highlightColor) { final String DEFAULT_COLOR = de.tudresden.inf.st.mg.common.MotionGrammarConfig.DEFAULT_COLOR; @@ -17,7 +17,11 @@ aspect Tracing { de.tudresden.inf.st.jastadd.dumpAst.ast.Dumper.read(world) .setNameMethod(o -> o == null ? "null" : o.getClass().getSimpleName()) .setBackgroundColorMethod(n -> (n == highlightNode ? highlightColor : DEFAULT_COLOR)) - .excludeTokens("Q.") // FIXME remove domain-specific code + .includeTokensWhen((node, tokenName, value) -> !tokenName.matches("Q.") && !tokenName.equals("TimeStamp")) // FIXME remove domain-specific code + .includeAttributeWhen((node, attributeName, isNTA, value) -> isNTA) + .<ASTNode>includeChildWhen((parentNode, childNode, contextName) -> !((contextName.equals("Pose") || contextName.equals("Robot")) && childNode.inDemonstrationTable())) + .<ASTNode>includeRelationsWhen((sourceNode, targetNode, roleName) -> !roleName.equals("AttachedRobot") && !(sourceNode != null && sourceNode.inDemonstrationTable()) && !(targetNode != null && targetNode.inDemonstrationTable())) // !sourceNode.inDemonstrationTable() +// .excludeRelations("AttachedRobot") .dumpAsSVG(de.tudresden.inf.st.mg.common.MotionGrammarConfig.astDiagramDir.resolve("Context-" + worldName + "-" + new java.text.SimpleDateFormat("yyyy.MM.dd.HH.mm.ss.SSS").format(new java.util.Date()) + "-" + step + ".svg")); } catch (java.io.IOException e) { e.printStackTrace(); diff --git a/src/main/java/de/tudresden/inf/st/mg/RobotParser.java b/src/main/java/de/tudresden/inf/st/mg/RobotParser.java index 8cbe2fc7f87e12de20db4be864880447b40d21d9..22ae88aa89d512f7b3edab500f112bc7ab6a1899 100644 --- a/src/main/java/de/tudresden/inf/st/mg/RobotParser.java +++ b/src/main/java/de/tudresden/inf/st/mg/RobotParser.java @@ -75,23 +75,23 @@ public final class RobotParser extends MotionGrammarParser<Tidy> { printAST("parseNotEmptyTable", result); } - private ObjectAtWrongPlace peekedObjectAtWrongPlace_ = null; + private AvailableObject peekedAvailableObject_ = null; - private boolean peekObjectAtWrongPlace(Tidy context) { - peekedObjectAtWrongPlace_ = getWorld().parseObjectAtWrongPlace(context); - return peekedObjectAtWrongPlace_ != null; + private boolean peekAvailableObject() { + peekedAvailableObject_ = getWorld().parseAvailableObject(); + return peekedAvailableObject_ != null; } - private void parseObjectAtWrongPlace(ASTNode<?> parent, int index, Tidy context) throws ParseException { - ObjectAtWrongPlace result; + private void parseAvailableObject(ASTNode<?> parent, int index, Tidy context) throws ParseException { + AvailableObject result; - if (peekedObjectAtWrongPlace_ != null) { - result = peekedObjectAtWrongPlace_; - peekedObjectAtWrongPlace_ = null; // TODO check if all peeked values are actually parsed afterwards + if (peekedAvailableObject_ != null) { + result = peekedAvailableObject_; + peekedAvailableObject_ = null; // TODO check if all peeked values are actually parsed afterwards } else { - result = getWorld().parseObjectAtWrongPlace(context); + result = getWorld().parseAvailableObject(); if (result == null) { - throw new ParseException(ObjectAtWrongPlace.type()); + throw new ParseException(AvailableObject.type()); } } @@ -99,7 +99,7 @@ public final class RobotParser extends MotionGrammarParser<Tidy> { // semantic action for ObjectAtWrongPlace result.action(getWorld()); - printAST("parseObjectAtWrongPlace", result); + printAST("parseAvailableObject", result); } private RobotIsReadyToPickToken peekedRobotIsReadyToPickToken_ = null; @@ -333,6 +333,32 @@ public final class RobotParser extends MotionGrammarParser<Tidy> { printAST("parseRightPlace", result); } + private MisplacedObject peekedMisplacedObject_ = null; + private boolean peekMisplacedObject() { + peekedMisplacedObject_ = getWorld().parseMisplacedObject(); + return peekedMisplacedObject_ != null; + } + + private void parseMisplacedObject(ASTNode<?> parent, int index) throws ParseException { + MisplacedObject result; + + if (peekedMisplacedObject_ != null) { + result = peekedMisplacedObject_; + peekedMisplacedObject_ = null; // TODO check if all peeked values are actually parsed afterwards + } else { + result = getWorld().parseMisplacedObject(); + if (result == null) { + throw new ParseException(MisplacedObject.type()); + } + } + + parent.setChild(result, index); + + // semantic action for MisplacedObject + result.action(getWorld()); + printAST("parseMisplacedObject", result); + } + private void parseTidy(ASTNode<?> parent, int index) throws ParseException { Tidy result = new Tidy(); result.parser = this; @@ -341,12 +367,13 @@ public final class RobotParser extends MotionGrammarParser<Tidy> { peekNotEmptyTable(); while (peekedNotEmptyTable_ == null) { waitSomeTime(); + peekNotEmptyTable(); } parseNotEmptyTable(result, 0); while (true) { - peekObjectAtWrongPlace(result); - if (peekedObjectAtWrongPlace_ != null) { + peekMisplacedObject(); + if (peekedMisplacedObject_ != null) { int i = result.getNumMoveObjectToCorrectPlace(); result.addMoveObjectToCorrectPlace(null); parseMoveObjectToCorrectPlace(result.getMoveObjectToCorrectPlaceList(), i); @@ -372,9 +399,15 @@ public final class RobotParser extends MotionGrammarParser<Tidy> { result.parser = this; parent.setChild(result, index); - parseObjectAtWrongPlace(result, 0, parent.containingTidy()); + parseMisplacedObject(result, 0); parsePickUpObject(result, 1); parseDropObjectAtRightPlace(result, 2); + peekRobotIsReadyToPickToken(); + while (peekedRobotIsReadyToPickToken_ == null) { + waitSomeTime(); + peekRobotIsReadyToPickToken(); + } + parseRobotIsReadyToPickToken(result, 3); // semantic action for MoveObjectToCorrectPlace result.action(getWorld()); @@ -390,11 +423,10 @@ public final class RobotParser extends MotionGrammarParser<Tidy> { peekRobotIsReadyToDropToken(); while (peekedRobotIsReadyToDropToken_ == null) { waitSomeTime(); + peekRobotIsReadyToDropToken(); } parseRobotIsReadyToDropToken(result, 0); - parseRightPlace(result, 1); - // semantic action for DropObjectAtRightPlace result.action(getWorld()); printAST("parseDropObjectAtRightPlace", result); @@ -405,12 +437,6 @@ public final class RobotParser extends MotionGrammarParser<Tidy> { result.parser = this; parent.setChild(result, index); - peekRobotIsReadyToPickToken(); - while (peekedRobotIsReadyToPickToken_ == null) { - waitSomeTime(); - } - parseRobotIsReadyToPickToken(result, 0); - // semantic action for PickUpObject result.action(getWorld()); printAST("parsePickUpObject", result); diff --git a/src/main/java/de/tudresden/inf/st/mg/common/MotionGrammarParser.java b/src/main/java/de/tudresden/inf/st/mg/common/MotionGrammarParser.java index 1122a4a877310f5199601615ff090e2252f77ba3..c88be6d966f9e5116d64abf49e09427b1cac67f8 100644 --- a/src/main/java/de/tudresden/inf/st/mg/common/MotionGrammarParser.java +++ b/src/main/java/de/tudresden/inf/st/mg/common/MotionGrammarParser.java @@ -22,7 +22,7 @@ public abstract class MotionGrammarParser<T extends MotionGrammarElement> { protected static void waitSomeTime() { try { - Thread.sleep(100/*ms*/); + Thread.sleep(1000/*ms*/); } catch(InterruptedException ignored) { } } diff --git a/src/test/java/de/tudresden/inf/st/mg/ParserTest.java b/src/test/java/de/tudresden/inf/st/mg/ParserTest.java index 7cfbe9573765e445a000108d19acda9a2b8feaa7..35414ad9224b3d71b8397bbf3f02d1e8d313d4d7 100644 --- a/src/test/java/de/tudresden/inf/st/mg/ParserTest.java +++ b/src/test/java/de/tudresden/inf/st/mg/ParserTest.java @@ -1,10 +1,7 @@ package de.tudresden.inf.st.mg; import de.tudresden.inf.st.mg.common.MotionGrammarParser; -import de.tudresden.inf.st.mg.jastadd.model.Container; -import de.tudresden.inf.st.mg.jastadd.model.RobotWorld; -import de.tudresden.inf.st.mg.jastadd.model.T1; -import de.tudresden.inf.st.mg.jastadd.model.Tidy; +import de.tudresden.inf.st.mg.jastadd.model.*; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -57,6 +54,16 @@ public class ParserTest { // for some reason, the best random seed value here is 1 and not 0??? RobotWorld world = RobotWorld.initialWorld(new Random(1)); + World.printContextOf("initial", null, ""); + + world.addSelection(new Selection().setObject("boxRed").setTimeStamp(java.time.Instant.now())) + .addSelection(new Selection().setObject("boxGreen").setTimeStamp(java.time.Instant.now())) + .addSelection(new Selection().setObject("binGreen").setTimeStamp(java.time.Instant.now())) + .addSelection(new Selection().setObject("binRed").setTimeStamp(java.time.Instant.now())) + .addSelection(new Selection().setObject("boxRed").setTimeStamp(java.time.Instant.now())) + .addSelection(new Selection().setObject("boxRed").setTimeStamp(java.time.Instant.now())); + + World.printContextOf("initial-with-selection", null, ""); // create a parser using the world RobotParser parser = new RobotParser(world);