diff --git a/src/main/jastadd/Ros2Rag.ast b/src/main/jastadd/Ros2Rag.ast new file mode 100644 index 0000000000000000000000000000000000000000..3e88bb7e66ce2c2ecee71df70d03289ec0ca12e6 --- /dev/null +++ b/src/main/jastadd/Ros2Rag.ast @@ -0,0 +1,10 @@ +Ros2Rag ::= MappingDefinition* SyncDefinition* Program; //MqttRoot ; + +abstract SyncDefinition ::= <AlwaysApply:Boolean> ; +abstract TokenWritingSyncDefinition : SyncDefinition ::= TargetType:SimpleTypeUse <TargetChild> ; +UpdateDefinition : TokenWritingSyncDefinition ::= <SourceAttribute> [MappingDefinitionUse] ; +ReadFromMqttDefinition : TokenWritingSyncDefinition ::= [MappingDefinitionUse] ; +WriteToMqttDefinition : SyncDefinition ::= SourceType:SimpleTypeUse <SourceChild> [MappingDefinitionUse] ; + +MappingDefinition ::= <ID> From:SimpleTypeUse To:SimpleTypeUse <Content> ; +MappingDefinitionUse ::= <ID> ; diff --git a/src/main/jastadd/backend/Aspect.jadd b/src/main/jastadd/backend/Aspect.jadd index 76b74a88b6e16cdc511350f75b53041441d399f1..61247c819d00e8be9a8618b5a8d5ed1657474e63 100644 --- a/src/main/jastadd/backend/Aspect.jadd +++ b/src/main/jastadd/backend/Aspect.jadd @@ -8,6 +8,7 @@ aspect Aspect { return sb.toString(); } + @Deprecated public void Program.generateAspect(StringBuilder sb) { sb.append("aspect ROS2RAG {\n"); @@ -16,4 +17,58 @@ aspect Aspect { sb.append("}\n"); } + + public String Ros2Rag.generateAspect() { + StringBuilder sb = new StringBuilder(); + generateAspect(sb); + return sb.toString(); + } + + // from "[always] read Joint.CurrentPosition using PoseToPosition;" generate method connectTo +// Joint j; +// j.getCurrentPosition().connectTo("/robot/joint2/pos"); + + public void Ros2Rag.generateAspect(StringBuilder sb) { + sb.append("aspect ROS2RAG {\n"); + + for (SyncDefinition def : getSyncDefinitionList()) { + def.generateAspect(sb); + } + + sb.append("}\n"); + } + + abstract void SyncDefinition.generateAspect(StringBuilder sb); + @Override + void UpdateDefinition.generateAspect(StringBuilder sb) { + // TODO + } + + // will be "addConnectionJoint_CurrentPosition" in example +/* // see discussion in codimd (InstanceLocation), why this won't work here + Position.connectTo(String topic) { + mqttUpdater().addConnectionJoint_CurrentPosition(this, topic); + } + MqttUpdater.addConnectionJoint_CurrentPosition(Position target, String topic) { + // either + topicActionMap.put(topic, new Action(JOINT_CURRENTPOSITION, target)); + // or + topicForJoint_CurrentPosition.put(topic, target); + } + */ + */ + @Override + void ReadFromMqttDefinition.generateAspect(StringBuilder sb) { + sb.append("public void ").append(type).append(".connectTo(String topic) {\n") + .append(aspectIndent).append("mqttUpdater().addConnection") + .append(getTargetType().getID()).append("_") + .append(getTargetChild()) + .append("(this, topic);\n") + .append("}\n"); + } + + @Override + void WriteToMqttDefinition.generateAspect(StringBuilder sb) { + // TODO + } } diff --git a/src/main/java/org/jastadd/ros2rag/compiler/SimpleMain.java b/src/main/java/org/jastadd/ros2rag/compiler/SimpleMain.java new file mode 100644 index 0000000000000000000000000000000000000000..e31a423afb7367177695dac5501c807b9382e89e --- /dev/null +++ b/src/main/java/org/jastadd/ros2rag/compiler/SimpleMain.java @@ -0,0 +1,83 @@ +package org.jastadd.ros2rag.compiler; + +import beaver.Parser; +import org.jastadd.ros2rag.ast.*; +import org.jastadd.ros2rag.parser.RelAstParser; +import org.jastadd.ros2rag.scanner.RelAstScanner; + +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * Testing Ros2Rag without parser. + * + * @author rschoene - Initial contribution + */ +public class SimpleMain { + public static void main(String[] args) { + /* + // as soon as the cache of isInSafetyZone is invalidated, update the value of Robot.ShouldUseLowSpeed with its value + [always] update Robot.ShouldUseLowSpeed with isInSafetyZone() using transformation(); + + // when a (new?) value for ShouldUseLowSpeed is set, send it over via mqtt + [always] write Robot.ShouldUseLowSpeed; + + // when an update of pose is read via mqtt, then update current position + [always] read Joint.CurrentPosition using PoseToPosition; + + // PBPose is a datatype defined in protobuf + PoseToPosition: map PBPose to Position using + pose.position.x += sqrt(.5 * size.x) + MAP round(2) + x = x / 100 + IGNORE_IF_SAME + ; + + --- using generated methods --- + Joint j; + j.getCurrentPosition().connectTo("/robot/joint2/pos"); + + RobotArm r; + // this should not be required + r.getShouldUseLowSpeed().addObserver(j.getCurrentPosition()); + r.getShouldUseLowSpeed().connectTo("/robot/config/speed"); + */ + Ros2Rag model = new Ros2Rag(); + Program program = parseProgram(Paths.get("src", "test", "resources", "MinimalExample.relast")); + model.setProgram(program); + + MappingDefinition mappingDefinition = new MappingDefinition(); + mappingDefinition.setID("PoseToPosition"); + mappingDefinition.setFrom(new SimpleTypeUse("PBPose")); + mappingDefinition.setTo(new SimpleTypeUse("Position")); + mappingDefinition.setContent(" pose.position.x += sqrt(.5 * size.x)\n" + + " MAP round(2)\n" + + " x = x / 100\n" + + " IGNORE_IF_SAME\n" + + " ;"); + model.addMappingDefinition(mappingDefinition); + + ReadFromMqttDefinition readFromMqttDefinition = new ReadFromMqttDefinition(); + readFromMqttDefinition.setAlwaysApply(false); + readFromMqttDefinition.setTargetType(new SimpleTypeUse("Joint")); + readFromMqttDefinition.setTargetChild("CurrentPosition"); + readFromMqttDefinition.setMappingDefinitionUse(new MappingDefinitionUse("PoseToPosition")); + model.addSyncDefinition(readFromMqttDefinition); + + System.out.println(model.generateAspect()); + } + + private static Program parseProgram(Path path) { + try (BufferedReader reader = Files.newBufferedReader(path)) { + RelAstScanner scanner = new RelAstScanner(reader); + RelAstParser parser = new RelAstParser(); + return (Program) parser.parse(scanner); + } catch (IOException | Parser.Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/src/test/resources/MinimalExample.relast b/src/test/resources/MinimalExample.relast index c9cf30085267ac7df5b2d2a13fbdb31e9321d626..b7f34c9cfb78e60e51d7947c145a66824afb1faf 100644 --- a/src/test/resources/MinimalExample.relast +++ b/src/test/resources/MinimalExample.relast @@ -1,12 +1,13 @@ Model ::= RobotArm ZoneModel ; -ZoneModel ::= <Size:Position> SafetyZone:Zone*; +ZoneModel ::= Size:Position SafetyZone:Zone*; Zone ::= Position*; RobotArm ::= Joint* EndEffector /<ShouldUseLowSpeed:Boolean>/ ; -Joint ::= <Name> <CurrentPosition:Position>; +Joint ::= <Name> ; +rel Join.CurrentPosition -> Position ; EndEffector : Joint;