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 {
baseRuntimeClasspath project (':ros2rag.base')
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.dataformat', name: 'jackson-dataformat-yaml', version: "${jackson_version}"
implementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
compile 'com.google.protobuf:protobuf-java:3.0.0'
compile group: 'org.fusesource.mqtt-client', name: 'mqtt-client', version: '1.15'
implementation group: 'com.google.protobuf', name: 'protobuf-java', version: '3.0.0'
implementation group: 'org.fusesource.mqtt-client', name: 'mqtt-client', version: '1.15'
jastadd2 "org.jastadd:jastadd:2.3.4"
}
......
aspect Computation {
syn boolean RobotArm.isInSafetyZone() {
System.out.println("isInSafetyZone()");
for (Joint joint : getJointList()) {
if (model().getZoneModel().isInSafetyZone(joint.getCurrentPosition())) {
for (Link link : getLinkList()) {
if (model().getZoneModel().isInSafetyZone(link.getCurrentPosition())) {
return true;
}
}
......
......@@ -2,11 +2,11 @@
* Version 2020-05-28
*/
// --- update definitions ---
read Joint.CurrentPosition using ParseLinkState, LinkStateToIntPosition ;
read Link.CurrentPosition using ParseLinkState, LinkStateToIntPosition ;
write RobotArm.AppropriateSpeed using CreateSpeedMessage, SerializeRobotConfig ;
// --- dependency definitions ---
RobotArm.AppropriateSpeed canDependOn Joint.CurrentPosition as dependency1 ;
RobotArm.AppropriateSpeed canDependOn Link.CurrentPosition as dependency1 ;
// --- mapping definitions ---
ParseLinkState maps byte[] bytes to panda.Linkstate.PandaLinkState {:
......
......@@ -2,7 +2,7 @@ aspect Navigation {
inh Model RobotArm.model();
eq Model.getRobotArm().model() = this;
inh RobotArm Joint.containingRobotArm();
eq RobotArm.getJoint().containingRobotArm() = this;
inh RobotArm Link.containingRobotArm();
eq RobotArm.getLink().containingRobotArm() = this;
eq RobotArm.getEndEffector().containingRobotArm() = this;
}
......@@ -4,10 +4,10 @@ ZoneModel ::= SafetyZone:Zone* ;
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> ;
package de.tudresden.inf.st.ros2rag.starter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import config.Dataconfig;
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.DataJoint;
import de.tudresden.inf.st.ros2rag.starter.data.DataConfiguration.ActualConfiguration;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.IOException;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
......@@ -25,26 +28,26 @@ public class StarterMain {
private Model model;
public void run(String[] args) throws IOException, InterruptedException {
File configFile = new File(args[0]);
final int[][] safetyZoneCoordinates = {
{1, 1, 0},
{-1, -1, 1}
};
File configFile = new File(args.length == 0 ? "./src/main/resources/config.yaml" : args[0]);
// --- No configuration below this line ---
ObjectMapper mapper = new ObjectMapper();
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
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.MqttSetHost(config.mqttHost);
Util.setMqttHost(model::MqttSetHost, config);
ZoneModel zoneModel = new ZoneModel();
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(
IntPosition.of(coordinate[0], coordinate[1], coordinate[2])));
}
......@@ -55,24 +58,23 @@ public class StarterMain {
RobotArm robotArm = new RobotArm();
model.setRobotArm(robotArm);
for (DataJoint dataJoint : config.joints) {
final Joint jointOrEndEffector;
if (dataJoint.isEndEffector) {
Util.iterateLinks((isEndEffector, topic, name) -> {
Link link;
if (isEndEffector) {
EndEffector endEffector = new EndEffector();
robotArm.setEndEffector(endEffector);
jointOrEndEffector = endEffector;
link = endEffector;
} else {
Joint joint = new Joint();
robotArm.addJoint(joint);
jointOrEndEffector = joint;
link = new Link();
robotArm.addLink(link);
}
jointOrEndEffector.setName(dataJoint.name);
jointOrEndEffector.setCurrentPosition(makePosition(0, 0, 0));
robotArm.addDependency1(jointOrEndEffector);
jointOrEndEffector.connectCurrentPosition(dataJoint.topic);
}
link.setName(name);
link.setCurrentPosition(makePosition(0, 0, 0));
link.containingRobotArm().addDependency1(link);
link.connectCurrentPosition(topic);
}, config);
robotArm.connectAppropriateSpeed(config.robotConfigTopic, true);
robotArm.connectAppropriateSpeed(config.topics.robotConfig, true);
logStatus("Start", robotArm);
CountDownLatch exitCondition = new CountDownLatch(1);
......@@ -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.");
mainHandler = new MqttUpdater("mainHandler");
mainHandler.setHost(config.mqttHost);
Util.setMqttHost(mainHandler, config);
mainHandler.waitUntilReady(2, TimeUnit.SECONDS);
mainHandler.newConnection("exit", bytes -> exitCondition.countDown());
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));
......@@ -110,7 +112,7 @@ public class StarterMain {
StringBuilder sb = new StringBuilder(prefix).append("\n")
.append("robotArm.isInSafetyZone: ").append(robotArm.isInSafetyZone())
.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("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;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
/**
* Data class for initial configuration.
......@@ -9,9 +11,17 @@ import java.util.List;
* @author rschoene - Initial contribution
*/
public class DataConfiguration {
public List<DataJoint> joints = new ArrayList<>();
public String robotConfigTopic;
public String dataConfigTopic;
public int exitAfterSeconds = 0;
public String mqttHost = "localhost";
public ActualConfiguration panda_mqtt_connector;
public static class ActualConfiguration {
public String server = "tcp://localhost:1883";
public DataTopics topics;
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 {
}
dependencies {
runtime 'org.jastadd:jastadd:2.3.4'
implementation project(':ros2rag.base')
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.0'
testImplementation 'org.assertj:assertj-core:3.12.1'
runtime group: 'org.jastadd', name: 'jastadd', version: '2.3.4'
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: '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 {
......
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