From fe2c004913444109eccc7d7dff5f0664042b0b3c Mon Sep 17 00:00:00 2001 From: Johannes Mey <johannes.mey@tu-dresden.de> Date: Fri, 16 Sep 2022 14:26:57 +0200 Subject: [PATCH] festival updatesfestival updatesfestival updatesfestival updatesfestival updatesfestival updatesfestival updatesfestival updates --- src/main/jastadd/cleanup/Tracing.jadd | 33 ++++--- src/main/jastadd/common/Tracing.jadd | 5 +- .../java/de/tudresden/inf/st/mg/Main.java | 99 +++++++++++++------ .../inf/st/mg/common/ColorDeserializer.java | 3 +- .../inf/st/mg/common/DiagramProvider.java | 57 +++++++---- .../inf/st/mg/common/MotionGrammarParser.java | 8 +- .../de/tudresden/inf/st/mg/ParserTest.java | 12 +-- 7 files changed, 140 insertions(+), 77 deletions(-) diff --git a/src/main/jastadd/cleanup/Tracing.jadd b/src/main/jastadd/cleanup/Tracing.jadd index 70ef06b..806fc83 100644 --- a/src/main/jastadd/cleanup/Tracing.jadd +++ b/src/main/jastadd/cleanup/Tracing.jadd @@ -2,26 +2,20 @@ aspect Tracing { refine public void Pose.setX(double x) { - World.printContextOf("Pose.setX()-BEFORE", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.REMOVE_COLOR); refined(x); World.printContextOf("Pose.setX()-AFTER", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.ADD_COLOR); - World.printContextOf("Pose.setX()-DONE", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.DEFAULT_COLOR); } refine public void Pose.setY(double y) { - World.printContextOf("Pose.setY()-BEFORE", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.REMOVE_COLOR); refined(y); World.printContextOf("Pose.setY()-AFTER", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.ADD_COLOR); - World.printContextOf("Pose.setY()-DONE", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.DEFAULT_COLOR); } refine public void Pose.setZ(double z) { - World.printContextOf("Pose.setZ()-BEFORE", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.REMOVE_COLOR); refined(z); World.printContextOf("Pose.setZ()-AFTER", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.ADD_COLOR); - World.printContextOf("Pose.setZ()-DONE", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.DEFAULT_COLOR); } refine @@ -34,45 +28,52 @@ aspect Tracing { // this is probably never called because each child overrides the setter method refine public PhysicalObject PhysicalObject.setPose(Pose p) { - World.printContextOf("PhysicalObject.setPose()-BEFORE", getPose(), de.tudresden.inf.st.mg.common.MotionGrammarConfig.REMOVE_COLOR); refined(p); World.printContextOf("PhysicalObject.setPose()-AFTER", getPose(), de.tudresden.inf.st.mg.common.MotionGrammarConfig.ADD_COLOR); - World.printContextOf("PhysicalObject.setPose()-DONE", getPose(), de.tudresden.inf.st.mg.common.MotionGrammarConfig.DEFAULT_COLOR); return this; } refine public MovableObject MovableObject.setPose(Pose p) { - World.printContextOf("MovableObject.setPose()-BEFORE", getPose(), de.tudresden.inf.st.mg.common.MotionGrammarConfig.REMOVE_COLOR); refined(p); World.printContextOf("MovableObject.setPose()-AFTER", getPose(), de.tudresden.inf.st.mg.common.MotionGrammarConfig.ADD_COLOR); - World.printContextOf("MovableObject.setPose()-DONE", getPose(), de.tudresden.inf.st.mg.common.MotionGrammarConfig.DEFAULT_COLOR); return this; } refine public void Robot.setIsIdle(boolean b) { - World.printContextOf("Robot.setIsIdle()-BEFORE", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.REMOVE_COLOR); refined(b); World.printContextOf("Robot.setIsIdle()-AFTER", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.ADD_COLOR); - World.printContextOf("Robot.setIsIdle()-DONE", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.DEFAULT_COLOR); } refine RelAstAPI public Robot Robot.setAttachedItem(MovableObject o) { - World.printContextOf("Robot.setAttachedItem()-BEFORE", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.REMOVE_COLOR); var result = refined(o); World.printContextOf("Robot.setAttachedItem()-AFTER", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.ADD_COLOR); - World.printContextOf("Robot.setAttachedItem()-DONE", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.DEFAULT_COLOR); return result; } refine RelAstAPI public MovableObject MovableObject.setAttachedRobot(Robot r) { - World.printContextOf("MovableObject.setAttachedRobot()-BEFORE", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.REMOVE_COLOR); var result = refined(r); World.printContextOf("MovableObject.setAttachedRobot()-AFTER", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.ADD_COLOR); - World.printContextOf("MovableObject.setAttachedRobot()-DONE", this, de.tudresden.inf.st.mg.common.MotionGrammarConfig.DEFAULT_COLOR); + return result; + } + + // refine + // public RobotWorld RobotWorld.addSelection(Selection s) { + // RobotWorld w = refined(s); + // World.printContextOf("Robot.addSelection()-AFTER", s, de.tudresden.inf.st.mg.common.MotionGrammarConfig.ADD_COLOR); + // World.printContextOf("Robot.addSelection()-DONE", s, de.tudresden.inf.st.mg.common.MotionGrammarConfig.DEFAULT_COLOR); + // return w; + // } + + refine + public JastAddList<T> JastAddList.addChild(T node) { + JastAddList<T> result = refined(node); + if (node != null && node instanceof Selection && getParent() != null) { + World.printContextOf("Robot.addSelection()-AFTER", node, de.tudresden.inf.st.mg.common.MotionGrammarConfig.ADD_COLOR); + } return result; } diff --git a/src/main/jastadd/common/Tracing.jadd b/src/main/jastadd/common/Tracing.jadd index bc80715..628082f 100644 --- a/src/main/jastadd/common/Tracing.jadd +++ b/src/main/jastadd/common/Tracing.jadd @@ -30,6 +30,8 @@ aspect Tracing { } } String worldName = world.getClass().getSimpleName(); + java.util.Date now = new java.util.Date(); + java.nio.file.Path svgPath = de.tudresden.inf.st.mg.common.MotionGrammarConfig.astDiagramDir.resolve("Context-" + worldName + "-" + new java.text.SimpleDateFormat("yyyy.MM.dd.HH.mm.ss.SSS").format(now) + "-" + step + ".svg"); try { de.tudresden.inf.st.jastadd.dumpAst.ast.Dumper.read(world) @@ -39,10 +41,11 @@ aspect Tracing { .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() - .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")); + .dumpAsSVG(svgPath); } catch (java.io.IOException e) { e.printStackTrace(); } + de.tudresden.inf.st.mg.common.DiagramProvider.getInstance().publish(now, 0, step, svgPath, "context"); } } diff --git a/src/main/java/de/tudresden/inf/st/mg/Main.java b/src/main/java/de/tudresden/inf/st/mg/Main.java index 9dcea61..60829c7 100644 --- a/src/main/java/de/tudresden/inf/st/mg/Main.java +++ b/src/main/java/de/tudresden/inf/st/mg/Main.java @@ -5,9 +5,11 @@ import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.google.protobuf.util.JsonFormat; import de.tudresden.inf.st.ceti.Scene; +import de.tudresden.inf.st.mg.common.DiagramProvider; import de.tudresden.inf.st.mg.common.MotionGrammarConfig; import de.tudresden.inf.st.mg.common.MotionGrammarParser; import de.tudresden.inf.st.mg.common.TableDeserializer; +import de.tudresden.inf.st.mg.jastadd.model.JastAddList; import de.tudresden.inf.st.mg.jastadd.model.RobotWorld; import de.tudresden.inf.st.mg.jastadd.model.Table; import de.tudresden.inf.st.mg.jastadd.model.World; @@ -18,61 +20,83 @@ import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Comparator; +import java.util.Random; public class Main { public static final Path TIDY_AST_DIAGRAM_DIR = Path.of("src", "gen", "resources", "diagrams", "parsing", "tidy"); - /** - * Runs the parser on the actual robot. For this to work, a robot controller must be connected to an MQTT server running - * on localhost:1883 - */ - public static void main(String[] args) { + private final RobotWorld world; + public Main(boolean simulate) { MotionGrammarConfig.astDiagramDir = TIDY_AST_DIAGRAM_DIR; try { Files.walk(TIDY_AST_DIAGRAM_DIR).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); Files.createDirectories(TIDY_AST_DIAGRAM_DIR); - } catch (IOException e) { - // do nothing + } catch (IOException ignored) { } - RobotWorld world = RobotWorld.initialWorld(); - + if (simulate) { + world = RobotWorld.initialWorld(new Random(1)); + } else { + world = RobotWorld.initialWorld(); + } try { SimpleModule module = new SimpleModule(); module.addDeserializer(Table.class, new TableDeserializer()); ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); mapper.registerModule(module); world.setDemonstrationTable(mapper.readValue(Main.class.getResourceAsStream("config_scene_virtual-table.yaml"), Table.class)); - } catch (IOException ignored) { - ignored.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); } World.enableContextPrinting(true); world.printContext("initial"); - org.fusesource.mqtt.client.MQTT handler = new org.fusesource.mqtt.client.MQTT(); - try { - handler.setHost("tcp://localhost:1883"); - } catch (URISyntaxException e) { - e.printStackTrace(); - } - world.connection = handler.blockingConnection(); - try { - world.connection.connect(); - } catch (Exception e) { - e.printStackTrace(); + if (!simulate) { + org.fusesource.mqtt.client.MQTT handler = new org.fusesource.mqtt.client.MQTT(); + try { + handler.setHost("tcp://localhost:1883"); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + world.connection = handler.blockingConnection(); + try { + world.connection.connect(); + } catch (Exception e) { + e.printStackTrace(); + } + + System.err.println(world.connection.isConnected()); + + try { + world.connectTable("mqtt://localhost//ceti_cell_empty/scene/update"); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + world.connectSelection("mqtt://localhost/vr_selection"); + } catch (IOException e) { + e.printStackTrace(); + } } - System.err.println(world.connection.isConnected()); + } - try { - world.connectTable("mqtt://localhost//ceti_cell_empty/scene/update"); - } catch (IOException e) { - e.printStackTrace(); + private Thread parse; + + public void startParse() { + if (parse != null && parse.isAlive()) { + parse.interrupt(); // if not working replace by stop() } + parse = new Thread(this::parse); + parse.start(); + } + public void parse() { + System.out.println("starting to parse"); // create a parser using the world RobotParser parser = new RobotParser(world); @@ -82,12 +106,27 @@ public class Main { } catch (MotionGrammarParser.ParseException e) { throw new RuntimeException(e); } + System.out.println("parsing completed!"); + } + + public void resetSelections() { + world.setSelectionList(new JastAddList<>()); + } + /** + * Runs the parser on the actual robot. For this to work, a robot controller must be connected to an MQTT server running + * on localhost:1883 + */ + public static void main(String[] args) { + DiagramProvider webController = DiagramProvider.getInstance(); + webController.setController(new Main(false)); try { - Thread.sleep(100000 * 1000); - } catch (InterruptedException e) { - e.printStackTrace(); + Thread.sleep(Long.MAX_VALUE); + } catch (InterruptedException ignored) { } } + public void printContext(String message) { + world.printContext(message); + } } diff --git a/src/main/java/de/tudresden/inf/st/mg/common/ColorDeserializer.java b/src/main/java/de/tudresden/inf/st/mg/common/ColorDeserializer.java index 437aac1..2af744d 100644 --- a/src/main/java/de/tudresden/inf/st/mg/common/ColorDeserializer.java +++ b/src/main/java/de/tudresden/inf/st/mg/common/ColorDeserializer.java @@ -26,7 +26,6 @@ public class ColorDeserializer extends JsonDeserializer<String> { Long g = nodeG == null ? 0 : Math.round(nodeG.asDouble() * 255); JsonNode nodeB = node.get("b"); Long b = nodeB == null ? 0 : Math.round(nodeB.asDouble() * 255); - System.out.println("#" + String.format("%02X%02X%02X", r, g, b)); - return "\"#" + String.format("%02X%02X%02X", r, g, b) + "\""; // FIXME remove quotes + return "#" + String.format("%02x%02x%02x", r, g, b); } } diff --git a/src/main/java/de/tudresden/inf/st/mg/common/DiagramProvider.java b/src/main/java/de/tudresden/inf/st/mg/common/DiagramProvider.java index d7c7881..1a3d247 100644 --- a/src/main/java/de/tudresden/inf/st/mg/common/DiagramProvider.java +++ b/src/main/java/de/tudresden/inf/st/mg/common/DiagramProvider.java @@ -1,11 +1,14 @@ package de.tudresden.inf.st.mg.common; +import de.tudresden.inf.st.mg.Main; import io.javalin.Javalin; +import io.javalin.core.JavalinConfig; import io.javalin.websocket.WsContext; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.time.Instant; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -16,6 +19,8 @@ public class DiagramProvider { private static DiagramProvider INSTANCE; + private Main controller; + private static final Map<WsContext, String> clients = new ConcurrentHashMap<>(); public static DiagramProvider getInstance() { @@ -25,16 +30,22 @@ public class DiagramProvider { return INSTANCE; } - private final List<AST> asts; + private AST ast; + private AST context; private DiagramProvider() { - asts = new ArrayList<>(); + ast = new AST(new Date(), 0, "<no rule>", "", "ast"); + context = new AST(Date.from(Instant.now()), 0, "<no rule>", "", "context"); + + Javalin app = Javalin.create(JavalinConfig::enableCorsForAllOrigins).start(7070); + app.get("/", ctx -> ctx.result("the context is delivered at /context and the ast is delivered at /ast")); - Javalin app = Javalin.create(config -> config.enableCorsForOrigin("http://localhost:3000")).start(7070); - app.get("/", ctx -> ctx.result("Hello World")); + app.get("/ast/", ctx -> { + ctx.json(ast); + }); - app.get("/asts/", ctx -> { - ctx.json(asts); + app.get("/context/", ctx -> { + ctx.json(context); }); app.ws("ast-events", ws -> { @@ -47,27 +58,34 @@ public class DiagramProvider { clients.remove(ctx); }); ws.onMessage(ctx -> { - System.err.println("somebody sent us a message: " + ctx.message()); + System.out.println("got message " + ctx.message()); + if ("parse".equals(ctx.message()) && controller != null) { + controller.startParse(); + } else if ("reset".equals(ctx.message()) && controller != null) { + controller.resetSelections(); + controller.printContext("reset selection"); + } }); }); } - public void publishAst(Date timestamp, int step, String parseRule, Path diagramPath) { - System.err.println("publishing AST"); + public void publish(Date timestamp, int step, String parseRule, Path diagramPath, String type) { try { - asts.add(new AST(timestamp, step, parseRule, Files.readString(diagramPath))); - clients.keySet().forEach(session -> { - System.err.println("sending"); - session.send(asts.get(asts.size() - 1)); - }); + if ("ast".equals(type)) { + ast = new AST(timestamp, step, parseRule, Files.readString(diagramPath), type); + clients.keySet().forEach(session -> session.send(ast)); + } else if ("context".equals(type)) { + context = new AST(timestamp, step, parseRule, Files.readString(diagramPath), type); + clients.keySet().forEach(session -> session.send(context)); + } } catch (IOException e) { - System.err.println("Unable to read AST diagram file " + diagramPath); + System.err.println("Unable to read " + type + " diagram file " + diagramPath); e.printStackTrace(); } } - public void publishContext() { - + public void setController(Main controller) { + this.controller = controller; } public static class AST { @@ -76,11 +94,14 @@ public class DiagramProvider { public String parseRule; public String diagram; - public AST(Date timestamp, int step, String parseRule, String diagram) { + public String type; + + public AST(Date timestamp, int step, String parseRule, String diagram, String type) { this.timestamp = timestamp; this.step = step; this.parseRule = parseRule; this.diagram = diagram; + this.type = type; } } 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 c88be6d..6a536e5 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,8 +22,10 @@ public abstract class MotionGrammarParser<T extends MotionGrammarElement> { protected static void waitSomeTime() { try { - Thread.sleep(1000/*ms*/); - } catch(InterruptedException ignored) { + Thread.sleep(100/*ms*/); + } catch(InterruptedException e) { + System.err.println("received interruption while parsing"); + Thread.currentThread().stop(); } } @@ -73,7 +75,7 @@ public abstract class MotionGrammarParser<T extends MotionGrammarElement> { .skinParam(SkinParamBooleanSetting.Shadowing, false) .skinParam(SkinParamStringSetting.backgroundColor, "white") .dumpAsSVG(svgPath); - DiagramProvider.getInstance().publishAst(new Date(), timeStep_, step, svgPath); + DiagramProvider.getInstance().publish(new Date(), timeStep_, step, svgPath, "ast"); timeStep_++; } catch (IOException e) { e.printStackTrace(); 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 9ad07f0..cc683a6 100644 --- a/src/test/java/de/tudresden/inf/st/mg/ParserTest.java +++ b/src/test/java/de/tudresden/inf/st/mg/ParserTest.java @@ -56,7 +56,11 @@ 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.printContext("initial"); + + // create a parser using the world + RobotParser parser = new RobotParser(world); + parser.setDebugDiagramDir(TIDY_AST_DIAGRAM_DIR); world.addSelection(new Selection().setObject("boxRed").setTimeStamp(java.time.Instant.now())) .addSelection(new Selection().setObject("boxGreen").setTimeStamp(java.time.Instant.now())) @@ -65,12 +69,6 @@ public class ParserTest { .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); - parser.setDebugDiagramDir(TIDY_AST_DIAGRAM_DIR); - // parse (synchronously, long-running) var result = parser.parse(); -- GitLab