From 8b3024a1a02e9fc57173569fa7aa113150bffdb7 Mon Sep 17 00:00:00 2001
From: Johannes Mey <johannes.mey@tu-dresden.de>
Date: Thu, 31 Mar 2022 13:08:59 +0200
Subject: [PATCH] add parse methods for robot world
---
build.gradle | 2 +-
src/main/jastadd/Cleanup.relast | 21 +++
src/main/jastadd/Robot.relast | 21 ---
src/main/jastadd/World.jadd | 125 +++++++++++++++++-
src/main/jastadd/World.jrag | 43 ++++++
src/main/jastadd/World.relast | 12 +-
.../de/tudresden/inf/st/mg/RobotParser.java | 54 ++++++++
.../de/tudresden/inf/st/mg/WorldParser.java | 2 +-
.../inf/st/mg/common/MotionGrammarParser.java | 7 +-
9 files changed, 257 insertions(+), 30 deletions(-)
create mode 100644 src/main/jastadd/Cleanup.relast
delete mode 100644 src/main/jastadd/Robot.relast
create mode 100644 src/main/java/de/tudresden/inf/st/mg/RobotParser.java
diff --git a/build.gradle b/build.gradle
index 6fbc69c..8855bbd 100644
--- a/build.gradle
+++ b/build.gradle
@@ -84,7 +84,7 @@ jar {
duplicatesStrategy = DuplicatesStrategy.FAIL
}
-def relastFiles = ['./src/main/jastadd/common/MotionGrammar.relast', './src/main/jastadd/World.relast', './src/main/jastadd/LoadUnload.relast', './src/main/jastadd/Robot.relast']
+def relastFiles = ['./src/main/jastadd/common/MotionGrammar.relast', './src/main/jastadd/World.relast', './src/main/jastadd/LoadUnload.relast', './src/main/jastadd/Cleanup.relast']
def grammarPrefix = './src/gen/jastadd/MotionGrammar'
def grammarDiagramFile = './src/gen/resources/diagrams/grammar/uml.png'
def jastAddListName = 'JastAddList'
diff --git a/src/main/jastadd/Cleanup.relast b/src/main/jastadd/Cleanup.relast
new file mode 100644
index 0000000..fcc087b
--- /dev/null
+++ b/src/main/jastadd/Cleanup.relast
@@ -0,0 +1,21 @@
+Tidy : MotionGrammarElement ::= MoveObjectToCorrectPlace* EmptyTable;
+MoveObjectToCorrectPlace : MotionGrammarElement ::= ObjectAtWrongPlace/*provides object*/ PickUpObject/*uses object*/ DropObjectAtRightPlace/*uses object*/;
+PickUpObject/*requires object*/ : MotionGrammarElement ::= RobotIsReadyToPick Pick/*uses object*/;
+abstract RobotIsReadyToPick : MotionGrammarElement;
+RobotIsReallyReadyToPick : RobotIsReadyToPick ::= RobotIsFree;
+RobotIsNotReadyToPick : RobotIsReadyToPick ::= RobotIsBusy Wait/*uses const "1sec"*/ RobotIsReadyToPick;
+DropObjectAtRightPlace/*requires object*/ : MotionGrammarElement ::= RightPlace/*uses object, provides place*/ Drop/*requires place*/;
+
+// Tokens
+EmptyTable : Token;
+ObjectAtWrongPlace : Token ::= <Object:String>; // the Object is a variable of the token
+Pick/*requires object*/ : Token;
+RobotIsFree : Token ::= RobotIsIdle RobotHasNoItemAttached; // combined token. both individual tokens are parsed in parallel
+RobotIsBusy : Token; // TODO should be improved to express RobotIsFree can not be parsed
+RobotIsIdle : Token;
+RobotHasNoItemAttached : Token;
+Wait/*requires time*/ : Token; // artificial token, which parsing takes a specified amount of time
+RightPlace/*requires object*/ : Token ::= <Place:String>;
+Drop/*requires object and place*/ : Token;
+
+
diff --git a/src/main/jastadd/Robot.relast b/src/main/jastadd/Robot.relast
deleted file mode 100644
index 6a8b7a8..0000000
--- a/src/main/jastadd/Robot.relast
+++ /dev/null
@@ -1,21 +0,0 @@
-Tidy ::= MoveObjectToCorrectPlace* EmptyTable;
-MoveObjectToCorrectPlace ::= ObjectAtWrongPlace/*provides object*/ PickUpObject/*uses object*/ DropObjectAtRightPlace/*uses object*/;
-PickUpObject/*requires object*/ ::= RobotIsReadyToPick Pick/*uses object*/;
-abstract RobotIsReadyToPick;
-RobotIsReallyReadyToPick : RobotIsReadyToPick ::= RobotIsFree;
-RobotIsNotReadyToPick : RobotIsReadyToPick ::= RobotIsBusy Wait/*uses const "1sec"*/ RobotIsReadyToPick;
-DropObjectAtRightPlace/*requires object*/ ::= RightPlace/*uses object, provides place*/ Drop/*requires place*/;
-
-// Tokens
-EmptyTable : Token;
-ObjectAtWrongPlace : Token ::= <Object:String>; // the Object is a variable of the token
-Pick/*requires object*/ : Token;
-RobotIsFree : Token ::= RobotIsIdle RobotHasNoItemAttached; // combined token. both individual tokens are parsed in parallel
-RobotIsBusy : Token; // TODO should be improved to express RobotIsFree can not be parsed
-RobotIsIdle : Token;
-RobotHasNoItemAttached : Token;
-Wait/*requires time*/ : Token; // artificial token, which parsing takes a specified amount of time
-RightPlace/*requires object*/ : Token ::= <Place:String>;
-Drop/*requires object*/ : Token;
-
-
diff --git a/src/main/jastadd/World.jadd b/src/main/jastadd/World.jadd
index e11153e..e1a676a 100644
--- a/src/main/jastadd/World.jadd
+++ b/src/main/jastadd/World.jadd
@@ -6,7 +6,19 @@ aspect World {
Container c = new Container();
c.setCapacity(r.nextInt(MAX_CAPACITY - 1) + 1);
c.setElementCount(r.nextInt(c.getCapacity()));
- return new World(c);
+ Table t = new Table();
+ t.addBin(new Bin("binRed", Pose.of(-10, -10, 0), "red"));
+ t.addBin(new Bin("binGreen", Pose.of(-10, 0, 0), "green"));
+ t.addBin(new Bin("binBlue", Pose.of(-10, 10, 0), "blue"));
+ t.addMovableObject(new MovableObject("boxRed", Pose.of(-5, -10, 0), "red"));
+ t.addMovableObject(new MovableObject("boxGreen", Pose.of(-5, 0, 0), "green"));
+ t.addMovableObject(new MovableObject("boxBlue", Pose.of(-5, 10, 0), "blue"));
+ Robot b = new Robot();
+ return new World(c, t, b);
+ }
+
+ public static Pose Pose.of(double x, double y, double z) {
+ return new Pose(x,y,z,0,0,0,1);
}
@Override
@@ -44,4 +56,115 @@ aspect World {
System.out.println("success");
return new Unload();
}
+
+ public EmptyTable World.parseEmptyTable() {
+ System.out.print("Trying to parse token <EmptyTable>... ");
+ if (getTable().isEmpty()) {
+ System.out.println("success");
+ return new EmptyTable();
+ } else {
+ System.out.println("failure");
+ return null;
+ }
+ }
+
+ public ObjectAtWrongPlace World.parseObjectAtWrongPlace() {
+ System.out.print("Trying to parse token <ObjectAtWrongPlace>... ");
+ // TODO get a *random* object?
+ for (MovableObject o : getTable().getMovableObjectList()) {
+ if (!o.isInBin()) {
+ System.out.println("success");
+ return new ObjectAtWrongPlace(o.getName());
+ }
+ }
+ System.out.println("failure");
+ return null;
+ }
+
+ public Pick World.parsePick(String objectName) {
+ System.out.print("Trying to parse token <Pick> for Object \"" + objectName + "\"... ");
+ MovableObject o = getTable().getMovableObjectByName(objectName);
+
+ if (o != null) {
+ System.out.println("success");
+ return new Pick();
+ } else {
+ System.out.println("failure");
+ return null;
+ }
+ }
+
+ public RobotIsFree World.parseRobotIsFree() {
+ System.out.print("Trying to parse token <RobotIsFree>... ");
+ RobotIsIdle idle = parseRobotIsIdle();
+ RobotHasNoItemAttached noItem = parseRobotHasNoItemAttached();
+ if (idle != null && noItem != null) {
+ System.out.println("success");
+ return new RobotIsFree(idle, noItem);
+ } else {
+ System.out.println("failure");
+ return null;
+ }
+ }
+
+ public RobotIsIdle World.parseRobotIsIdle() {
+ System.out.print("Trying to parse token <RobotIsIdle>... ");
+ if (getRobot().getIsIdle()) {
+ System.out.println("success");
+ return new RobotIsIdle();
+ } else {
+ System.out.println("failure");
+ return null;
+ }
+ }
+
+ public RobotHasNoItemAttached World.parseRobotHasNoItemAttached() {
+ System.out.print("Trying to parse token <RobotHasNoItemAttached>... ");
+ if (!getRobot().hasAttachedItem()) {
+ System.out.println("success");
+ return new RobotHasNoItemAttached();
+ } else {
+ System.out.println("failure");
+ return null;
+ }
+ }
+
+ public Wait World.parseWait(double time) {
+ System.out.print("Trying to parse token <Wait> for " + time + " seconds... ");
+ System.out.println("success");
+ return new Wait();
+ }
+
+ public RightPlace World.parseRightPlace(String objectName) {
+ System.out.print("Trying to parse token <RightPlace> for Object \"" + objectName + "\"... ");
+ MovableObject o = getTable().getMovableObjectByName(objectName);
+
+ if (o != null) {
+ for (Bin b : getTable().getBinList()) {
+ if (o.fitsIn(b)) {
+ System.out.println("success");
+ return new RightPlace(b.getName());
+ }
+ }
+ System.out.println("failure (no matching bin found)");
+ return null;
+ } else {
+ System.out.println("failure (object does not exist)");
+ return null;
+ }
+ }
+
+ public Drop World.parseDrop(String objectName, String placeName) {
+ System.out.print("Trying to parse token <Drop> for Object \"" + objectName + "\" and Bin \"" + placeName + "\"... ");
+ MovableObject o = getTable().getMovableObjectByName(objectName);
+ Bin b = getTable().getBinByName(placeName);
+
+ if (o != null && b != null) {
+ System.out.println("success");
+ return new Drop();
+ } else {
+ System.out.println("failure");
+ return null;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/main/jastadd/World.jrag b/src/main/jastadd/World.jrag
index b6b2243..c0558b4 100644
--- a/src/main/jastadd/World.jrag
+++ b/src/main/jastadd/World.jrag
@@ -1,4 +1,47 @@
aspect World {
syn String World.print() = "[World " + getContainer().print() + "]";
syn String Container.print() = "[Container " + getElementCount() + "/" + getCapacity() + "]";
+
+ inh Table PhysicalObject.containingTable();
+ eq Table.getChild().containingTable() = this;
+
+ syn boolean MovableObject.isInBin() {
+ for (Bin b : containingTable().getBinList()) {
+ if (getPose().getX() == b.getPose().getX() && getPose().getY() == b.getPose().getY() && getPose().getZ() == b.getPose().getZ()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ syn boolean Table.isEmpty() {
+ for (MovableObject o : getMovableObjectList()) {
+ if (!o.isInBin()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ syn MovableObject Table.getMovableObjectByName(String name) {
+ for (MovableObject o : getMovableObjectList()) {
+ if (o.getName().equals(name)) {
+ return o;
+ }
+ }
+ return null;
+ }
+
+ syn Bin Table.getBinByName(String name) {
+ for (Bin b : getBinList()) {
+ if (b.getName().equals(name)) {
+ return b;
+ }
+ }
+ return null;
+ }
+
+ syn boolean MovableObject.fitsIn(Bin b) {
+ return getColor().equals(b.getColor());
+ }
}
\ No newline at end of file
diff --git a/src/main/jastadd/World.relast b/src/main/jastadd/World.relast
index 7fcedd7..946dd81 100644
--- a/src/main/jastadd/World.relast
+++ b/src/main/jastadd/World.relast
@@ -1,5 +1,15 @@
// World Model of the Motion Grammar
// The world contains one container with a maximum capacity and a current number of contained elements
-World ::= Container;
+World ::= Container Table Robot;
Container ::= <Capacity:int> <ElementCount:int>;
+
+Table ::= MovableObject* Bin*;
+abstract PhysicalObject ::= <Name> Pose <Color>;
+MovableObject : PhysicalObject;
+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?;
diff --git a/src/main/java/de/tudresden/inf/st/mg/RobotParser.java b/src/main/java/de/tudresden/inf/st/mg/RobotParser.java
new file mode 100644
index 0000000..2c285f6
--- /dev/null
+++ b/src/main/java/de/tudresden/inf/st/mg/RobotParser.java
@@ -0,0 +1,54 @@
+package de.tudresden.inf.st.mg;
+
+import de.tudresden.inf.st.mg.common.MotionGrammarParser;
+import de.tudresden.inf.st.mg.jastadd.model.*;
+
+
+public final class RobotParser extends MotionGrammarParser<Tidy> {
+
+ private static final String WORLD = "World";
+
+ private Load peekedLoad_ = null;
+ private Unload peekedUnload_ = null;
+ private Full peekedFull_ = null;
+
+ public RobotParser(World world) {
+ context_.put(WORLD, world);
+ }
+
+ private World getWorld() {
+ return (World) context_.get(WORLD);
+ }
+
+ /**
+ * Parse a motion grammar with root T
+ *
+ * @return the parsed AST of type T
+ */
+ public Tidy parseTidy() throws ParseException {
+ // don't try this at home
+ rootContainer_ = new ASTNode<>();
+ if (rootContainer_.getNumChild() == 0) {
+ rootContainer_.addChild(null);
+ }
+ printAST("initial", null);
+ parseTidy(rootContainer_, 0);
+ Tidy result = rootContainer_.getChild(0);
+ printAST("complete", null);
+ result.setParent(null);
+ rootContainer_.setChild(null, 0);
+ return result;
+ }
+
+ private void parseTidy(ASTNode<?> parent, int index) throws ParseException {
+ Tidy result;
+
+ if (true) {
+ throw new ParseException("T", Load.type(), Full.type());
+ }
+
+ // semantic action for T
+ result.action(getWorld());
+ printAST("parseT", result);
+ }
+}
diff --git a/src/main/java/de/tudresden/inf/st/mg/WorldParser.java b/src/main/java/de/tudresden/inf/st/mg/WorldParser.java
index 1e646e3..e5e634f 100644
--- a/src/main/java/de/tudresden/inf/st/mg/WorldParser.java
+++ b/src/main/java/de/tudresden/inf/st/mg/WorldParser.java
@@ -5,7 +5,7 @@ import de.tudresden.inf.st.mg.jastadd.model.*;
-public final class WorldParser extends MotionGrammarParser {
+public final class WorldParser extends MotionGrammarParser<T> {
private static final String WORLD = "World";
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 239c462..ae6f4d6 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
@@ -2,10 +2,7 @@ package de.tudresden.inf.st.mg.common;
import de.tudresden.inf.st.jastadd.dumpAst.ast.Dumper;
import de.tudresden.inf.st.jastadd.dumpAst.ast.SkinParamBooleanSetting;
-import de.tudresden.inf.st.mg.jastadd.model.ASTNode;
-import de.tudresden.inf.st.mg.jastadd.model.T;
-import de.tudresden.inf.st.mg.jastadd.model.Token;
-import de.tudresden.inf.st.mg.jastadd.model.TokenType;
+import de.tudresden.inf.st.mg.jastadd.model.*;
import java.io.IOException;
import java.nio.file.Path;
@@ -14,7 +11,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
-public abstract class MotionGrammarParser {
+public abstract class MotionGrammarParser<T extends MotionGrammarElement> {
protected final Map<String, ASTNode<?>> context_ = new HashMap<>();
protected ASTNode<T> rootContainer_;
--
GitLab