Commit e3e8ea60 authored by Johannes Mey's avatar Johannes Mey
Browse files

Merge branch '19-poc-use-mustache-as-template-engine' into 'master'

Resolve "PoC: Use mustache as template engine"

Closes #19

See merge request jastadd/ros2rag!2
parents 2e3c1b05 972f9aea
Pipeline #7203 passed with stages
in 5 minutes and 50 seconds
...@@ -30,9 +30,10 @@ dependencies { ...@@ -30,9 +30,10 @@ dependencies {
baseRuntimeClasspath project (':ros2rag.base') baseRuntimeClasspath project (':ros2rag.base')
implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: "${jackson_version}" implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: "${jackson_version}"
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "${jackson_version}" implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "${jackson_version}"
implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: "${jackson_version}"
implementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11' implementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
compile 'com.google.protobuf:protobuf-java:3.0.0' implementation group: 'com.google.protobuf', name: 'protobuf-java', version: '3.0.0'
compile group: 'org.fusesource.mqtt-client', name: 'mqtt-client', version: '1.15' implementation group: 'org.fusesource.mqtt-client', name: 'mqtt-client', version: '1.15'
jastadd2 "org.jastadd:jastadd:2.3.4" jastadd2 "org.jastadd:jastadd:2.3.4"
} }
......
aspect Computation { aspect Computation {
syn boolean RobotArm.isInSafetyZone() { syn boolean RobotArm.isInSafetyZone() {
System.out.println("isInSafetyZone()"); System.out.println("isInSafetyZone()");
for (Joint joint : getJointList()) { for (Link link : getLinkList()) {
if (model().getZoneModel().isInSafetyZone(joint.getCurrentPosition())) { if (model().getZoneModel().isInSafetyZone(link.getCurrentPosition())) {
return true; return true;
} }
} }
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
* Version 2020-05-28 * Version 2020-05-28
*/ */
// --- update definitions --- // --- update definitions ---
read Joint.CurrentPosition using ParseLinkState, LinkStateToIntPosition ; read Link.CurrentPosition using ParseLinkState, LinkStateToIntPosition ;
write RobotArm.AppropriateSpeed using CreateSpeedMessage, SerializeRobotConfig ; write RobotArm.AppropriateSpeed using CreateSpeedMessage, SerializeRobotConfig ;
// --- dependency definitions --- // --- dependency definitions ---
RobotArm.AppropriateSpeed canDependOn Joint.CurrentPosition as dependency1 ; RobotArm.AppropriateSpeed canDependOn Link.CurrentPosition as dependency1 ;
// --- mapping definitions --- // --- mapping definitions ---
ParseLinkState maps byte[] bytes to panda.Linkstate.PandaLinkState {: ParseLinkState maps byte[] bytes to panda.Linkstate.PandaLinkState {:
......
...@@ -2,7 +2,7 @@ aspect Navigation { ...@@ -2,7 +2,7 @@ aspect Navigation {
inh Model RobotArm.model(); inh Model RobotArm.model();
eq Model.getRobotArm().model() = this; eq Model.getRobotArm().model() = this;
inh RobotArm Joint.containingRobotArm(); inh RobotArm Link.containingRobotArm();
eq RobotArm.getJoint().containingRobotArm() = this; eq RobotArm.getLink().containingRobotArm() = this;
eq RobotArm.getEndEffector().containingRobotArm() = this; eq RobotArm.getEndEffector().containingRobotArm() = this;
} }
...@@ -4,10 +4,10 @@ ZoneModel ::= SafetyZone:Zone* ; ...@@ -4,10 +4,10 @@ ZoneModel ::= SafetyZone:Zone* ;
Zone ::= Coordinate* ; Zone ::= Coordinate* ;
RobotArm ::= Joint* EndEffector /<AppropriateSpeed:double>/ ; RobotArm ::= Link* EndEffector /<AppropriateSpeed:double>/ ;
Joint ::= <Name:String> <CurrentPosition:IntPosition> ; Link ::= <Name:String> <CurrentPosition:IntPosition> ;
EndEffector : Joint; EndEffector : Link;
Coordinate ::= <Position:IntPosition> ; Coordinate ::= <Position:IntPosition> ;
package de.tudresden.inf.st.ros2rag.starter; package de.tudresden.inf.st.ros2rag.starter;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import config.Dataconfig; import config.Dataconfig;
import de.tudresden.inf.st.ros2rag.starter.ast.*; import de.tudresden.inf.st.ros2rag.starter.ast.*;
import de.tudresden.inf.st.ros2rag.starter.data.DataConfiguration; import de.tudresden.inf.st.ros2rag.starter.data.DataConfiguration;
import de.tudresden.inf.st.ros2rag.starter.data.DataJoint; import de.tudresden.inf.st.ros2rag.starter.data.DataConfiguration.ActualConfiguration;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
...@@ -25,26 +28,26 @@ public class StarterMain { ...@@ -25,26 +28,26 @@ public class StarterMain {
private Model model; private Model model;
public void run(String[] args) throws IOException, InterruptedException { public void run(String[] args) throws IOException, InterruptedException {
File configFile = new File(args[0]); File configFile = new File(args.length == 0 ? "./src/main/resources/config.yaml" : args[0]);
final int[][] safetyZoneCoordinates = {
{1, 1, 0},
{-1, -1, 1}
};
// --- No configuration below this line --- // --- No configuration below this line ---
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
System.out.println("Using config file: " + configFile.getAbsolutePath()); System.out.println("Using config file: " + configFile.getAbsolutePath());
DataConfiguration config = mapper.readValue(configFile, DataConfiguration.class); ActualConfiguration config = mapper.readValue(configFile, DataConfiguration.class).panda_mqtt_connector;
model = new Model(); model = new Model();
model.MqttSetHost(config.mqttHost); Util.setMqttHost(model::MqttSetHost, config);
ZoneModel zoneModel = new ZoneModel(); ZoneModel zoneModel = new ZoneModel();
Zone safetyZone = new Zone(); Zone safetyZone = new Zone();
for (int[] coordinate : safetyZoneCoordinates) { for (String zone : config.zones) {
int[] coordinate = {0, 0, 0};
String[] zoneSplit = zone.split(" ");
for (int i = 0; i < zoneSplit.length; i++) {
coordinate[i] = Integer.parseInt(zoneSplit[i]);
}
safetyZone.addCoordinate(new Coordinate( safetyZone.addCoordinate(new Coordinate(
IntPosition.of(coordinate[0], coordinate[1], coordinate[2]))); IntPosition.of(coordinate[0], coordinate[1], coordinate[2])));
} }
...@@ -55,24 +58,23 @@ public class StarterMain { ...@@ -55,24 +58,23 @@ public class StarterMain {
RobotArm robotArm = new RobotArm(); RobotArm robotArm = new RobotArm();
model.setRobotArm(robotArm); model.setRobotArm(robotArm);
for (DataJoint dataJoint : config.joints) { Util.iterateLinks((isEndEffector, topic, name) -> {
final Joint jointOrEndEffector; Link link;
if (dataJoint.isEndEffector) { if (isEndEffector) {
EndEffector endEffector = new EndEffector(); EndEffector endEffector = new EndEffector();
robotArm.setEndEffector(endEffector); robotArm.setEndEffector(endEffector);
jointOrEndEffector = endEffector; link = endEffector;
} else { } else {
Joint joint = new Joint(); link = new Link();
robotArm.addJoint(joint); robotArm.addLink(link);
jointOrEndEffector = joint;
} }
jointOrEndEffector.setName(dataJoint.name); link.setName(name);
jointOrEndEffector.setCurrentPosition(makePosition(0, 0, 0)); link.setCurrentPosition(makePosition(0, 0, 0));
robotArm.addDependency1(jointOrEndEffector); link.containingRobotArm().addDependency1(link);
jointOrEndEffector.connectCurrentPosition(dataJoint.topic); link.connectCurrentPosition(topic);
} }, config);
robotArm.connectAppropriateSpeed(config.robotConfigTopic, true); robotArm.connectAppropriateSpeed(config.topics.robotConfig, true);
logStatus("Start", robotArm); logStatus("Start", robotArm);
CountDownLatch exitCondition = new CountDownLatch(1); CountDownLatch exitCondition = new CountDownLatch(1);
...@@ -81,12 +83,12 @@ public class StarterMain { ...@@ -81,12 +83,12 @@ public class StarterMain {
logger.info("To exit the system cleanly, send a message to the topic 'exit', or use Ctrl+C."); logger.info("To exit the system cleanly, send a message to the topic 'exit', or use Ctrl+C.");
mainHandler = new MqttUpdater("mainHandler"); mainHandler = new MqttUpdater("mainHandler");
mainHandler.setHost(config.mqttHost); Util.setMqttHost(mainHandler, config);
mainHandler.waitUntilReady(2, TimeUnit.SECONDS); mainHandler.waitUntilReady(2, TimeUnit.SECONDS);
mainHandler.newConnection("exit", bytes -> exitCondition.countDown()); mainHandler.newConnection("exit", bytes -> exitCondition.countDown());
mainHandler.newConnection("model", bytes -> logStatus(new String(bytes), robotArm)); mainHandler.newConnection("model", bytes -> logStatus(new String(bytes), robotArm));
sendInitialDataConfig(mainHandler, config.dataConfigTopic); sendInitialDataConfig(mainHandler, config.topics.dataConfig);
Runtime.getRuntime().addShutdownHook(new Thread(this::close)); Runtime.getRuntime().addShutdownHook(new Thread(this::close));
...@@ -110,7 +112,7 @@ public class StarterMain { ...@@ -110,7 +112,7 @@ public class StarterMain {
StringBuilder sb = new StringBuilder(prefix).append("\n") StringBuilder sb = new StringBuilder(prefix).append("\n")
.append("robotArm.isInSafetyZone: ").append(robotArm.isInSafetyZone()) .append("robotArm.isInSafetyZone: ").append(robotArm.isInSafetyZone())
.append(", robotArm.getAppropriateSpeed = ").append(robotArm.getAppropriateSpeed()).append("\n"); .append(", robotArm.getAppropriateSpeed = ").append(robotArm.getAppropriateSpeed()).append("\n");
for (Joint joint : robotArm.getJointList()) { for (Link joint : robotArm.getLinkList()) {
sb.append(joint.getName()).append(": ").append(joint.getCurrentPosition()).append("\n"); sb.append(joint.getName()).append(": ").append(joint.getCurrentPosition()).append("\n");
} }
sb.append("endEffector ").append(robotArm.getEndEffector().getName()).append(": ") sb.append("endEffector ").append(robotArm.getEndEffector().getName()).append(": ")
......
package de.tudresden.inf.st.ros2rag.starter;
import de.tudresden.inf.st.ros2rag.starter.ast.Link;
import de.tudresden.inf.st.ros2rag.starter.ast.MqttUpdater;
import de.tudresden.inf.st.ros2rag.starter.data.DataConfiguration;
import de.tudresden.inf.st.ros2rag.starter.data.DataConfiguration.ActualConfiguration;
import java.io.IOException;
import java.util.Map;
import java.util.SortedMap;
/**
* Helper method dealing with config.
*
* @author rschoene - Initial contribution
*/
public class Util {
public static void setMqttHost(RootElement model, ActualConfiguration config) throws IOException {
HostAndPort hostAndPort = split(config.server);
model.MqttSetHost(hostAndPort.host, hostAndPort.port);
}
public static void setMqttHost(MqttUpdater handler, ActualConfiguration config) throws IOException {
HostAndPort hostAndPort = split(config.server);
handler.setHost(hostAndPort.host, hostAndPort.port);
}
public static void iterateLinks(HandleLink callback, ActualConfiguration config) {
for (Map.Entry<String, SortedMap<String, String>> dataRobot : config.parts.entrySet()) {
String topicPrefix = dataRobot.getKey() + "/";
for (Map.Entry<String, String> dataLink : dataRobot.getValue().entrySet()) {
String name = dataLink.getKey();
callback.handle(false, topicPrefix + name, name);
}
}
for (Map.Entry<String, SortedMap<String, String>> dataRobot : config.end_effectors.entrySet()) {
String topicPrefix = dataRobot.getKey() + "/";
for (Map.Entry<String, String> dataLink : dataRobot.getValue().entrySet()) {
String name = dataLink.getKey();
callback.handle(true, topicPrefix + name, name);
}
}
}
private static HostAndPort split(String serverString) {
HostAndPort result = new HostAndPort();
String[] serverTokens = serverString.replace("tcp://", "").split(":");
result.host = serverTokens[0];
result.port = Integer.parseInt(serverTokens[1]);
return result;
}
private static class HostAndPort {
String host;
int port;
}
@FunctionalInterface
public interface RootElement {
void MqttSetHost(String host, int port) throws IOException;
}
@FunctionalInterface
public interface HandleLink {
void handle(boolean isEndEffector, String topic, String name);
}
}
package de.tudresden.inf.st.ros2rag.starter.data; package de.tudresden.inf.st.ros2rag.starter.data;
import java.util.ArrayList; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.SortedMap;
/** /**
* Data class for initial configuration. * Data class for initial configuration.
...@@ -9,9 +11,17 @@ import java.util.List; ...@@ -9,9 +11,17 @@ import java.util.List;
* @author rschoene - Initial contribution * @author rschoene - Initial contribution
*/ */
public class DataConfiguration { public class DataConfiguration {
public List<DataJoint> joints = new ArrayList<>(); public ActualConfiguration panda_mqtt_connector;
public String robotConfigTopic; public static class ActualConfiguration {
public String dataConfigTopic; public String server = "tcp://localhost:1883";
public int exitAfterSeconds = 0; public DataTopics topics;
public String mqttHost = "localhost"; public int zone_size;
public List<String> zones;
public Map<String, SortedMap<String, String>> parts;
public Map<String, SortedMap<String, String>> end_effectors;
}
public static class DataTopics {
public String robotConfig;
public String dataConfig;
}
} }
package de.tudresden.inf.st.ros2rag.starter.data;
/**
* Data class to describe a joint.
*
* @author rschoene - Initial contribution
*/
public class DataJoint {
public String topic;
public String name;
public boolean isEndEffector = false;
}
panda_mqtt_connector:
server: "tcp://localhost:1883"
topics:
robotConfig: "robotconfig"
dataConfig: "dataconfig"
zone_size: 0.5
zones:
- "1 1"
- "-1 -1 1"
parts:
panda:
Link0: "panda::panda_link0"
Link1: "panda::panda_link1"
Link2: "panda::panda_link2"
Link3: "panda::panda_link3"
Link4: "panda::panda_link4"
Link5: "panda::panda_link5"
Link6: "panda::panda_link6"
LeftFinger: "panda::panda_leftfinger"
RightFinger: "panda::panda_rightfinger"
end_effectors:
panda:
EndEffector: "panda::panda_link7"
...@@ -19,14 +19,15 @@ buildscript { ...@@ -19,14 +19,15 @@ buildscript {
} }
dependencies { dependencies {
runtime 'org.jastadd:jastadd:2.3.4'
implementation project(':ros2rag.base') implementation project(':ros2rag.base')
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.0' runtime group: 'org.jastadd', name: 'jastadd', version: '2.3.4'
testImplementation 'org.assertj:assertj-core:3.12.1' testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.4.0'
testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.4.0'
testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.12.1'
testImplementation group: 'org.fusesource.mqtt-client', name: 'mqtt-client', version: '1.15' testImplementation group: 'org.fusesource.mqtt-client', name: 'mqtt-client', version: '1.15'
testImplementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11' testImplementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
testImplementation 'com.google.protobuf:protobuf-java:3.0.0' testImplementation group: 'com.google.protobuf', name: 'protobuf-java', version: '3.0.0'
} }
test { test {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment