Commit 7d6a79a5 authored by René Schöne's avatar René Schöne
Browse files

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

parents 88a3b283 0fa7f92a
......@@ -21,7 +21,7 @@ test:
image: openjdk:8
stage: test
script:
- ./gradlew test
- ./gradlew allTests
artifacts:
reports:
junit: ros2rag.tests/build/test-results/test/TEST-*.xml
FROM ubuntu:bionic
ENV DEBIAN_FRONTEND noninteractive
ENV HOME /home/user
RUN useradd --create-home --home-dir $HOME user \
&& chmod -R u+rwx $HOME \
&& chown -R user:user $HOME
RUN apt-get update -y \
&& apt-get upgrade -y \
&& apt-get install -y --no-install-recommends openjdk-8-jdk \
&& apt-get clean
COPY --chown=user:user . /ros2rag/
USER user
WORKDIR /ros2rag
RUN ./gradlew --no-daemon installDist
ENTRYPOINT /bin/bash -c "./ros2rag.starter/build/install/ros2rag.starter/bin/ros2rag.starter ./ros2rag.starter/src/main/resources/config.json"
......@@ -141,16 +141,23 @@ aspect AspectGeneration {
sb.append(ind(indent + 1)).append(preemptiveReturnStatement()).append("\n");
sb.append(ind(indent)).append("}\n");
if (!getAlwaysApply()) {
sb.append(ind(indent)).append("if (").append(preemptiveExpectedValue());
if (getToken().isPrimitiveType()) {
sb.append(" == ").append(inputVariableName);
} else if (effectiveMappings().get(effectiveMappings().size() - 1).isDefaultMappingDefinition()) {
sb.append(" != null && ").append(preemptiveExpectedValue()).append(".equals(")
.append(inputVariableName).append(")");
MappingDefinition lastMapping = effectiveMappings().get(effectiveMappings().size() - 1);
sb.append(ind(indent)).append("if (");
if (lastMapping.getToType().isArray()) {
sb.append("java.util.Arrays.equals(").append(preemptiveExpectedValue())
.append(", ").append(inputVariableName).append(")");
} else {
sb.append(" != null ? ").append(preemptiveExpectedValue()).append(".equals(")
.append(inputVariableName).append(")").append(" : ")
.append(inputVariableName).append(" == null");
sb.append(preemptiveExpectedValue());
if (getToken().isPrimitiveType() && lastMapping.getToType().isPrimitiveType()) {
sb.append(" == ").append(inputVariableName);
} else if (lastMapping.isDefaultMappingDefinition()) {
sb.append(" != null && ").append(preemptiveExpectedValue()).append(".equals(")
.append(inputVariableName).append(")");
} else {
sb.append(" != null ? ").append(preemptiveExpectedValue()).append(".equals(")
.append(inputVariableName).append(")").append(" : ")
.append(inputVariableName).append(" == null");
}
}
sb.append(") { ").append(preemptiveReturnStatement()).append(" }\n");
}
......
......@@ -151,6 +151,12 @@ aspect Mappings {
default: return false;
}
}
syn boolean MappingDefinitionType.isPrimitiveType() = false;
eq JavaMappingDefinitionType.isPrimitiveType() = getType().isPrimitiveType();
// --- isArray ---
syn boolean MappingDefinitionType.isArray() = false;
eq JavaArrayMappingDefinitionType.isArray() = true;
// --- suitableDefaultMapping ---
syn DefaultMappingDefinition UpdateDefinition.suitableDefaultMapping();
......
......@@ -231,8 +231,16 @@ public class MqttUpdater {
}
public void publish(String topic, byte[] bytes) {
publish(topic, bytes, false);
}
public void publish(String topic, byte[] bytes, boolean retain) {
publish(topic, bytes, this.qos, retain);
}
public void publish(String topic, byte[] bytes, org.fusesource.mqtt.client.QoS qos, boolean retain) {
connection.getDispatchQueue().execute(() -> {
connection.publish(topic, bytes, qos, false, new org.fusesource.mqtt.client.Callback<Void>() {
connection.publish(topic, bytes, qos, retain, new org.fusesource.mqtt.client.Callback<Void>() {
@Override
public void onSuccess(Void value) {
logger.debug("Published some bytes to {}", topic);
......
......@@ -7,6 +7,7 @@ import config.Robotconfig.RobotConfig;
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.DataJoint;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import panda.Linkstate.PandaLinkState;
......@@ -19,6 +20,7 @@ import java.util.concurrent.TimeUnit;
public class Main {
private static final Logger logger = LogManager.getLogger(Main.class);
private String topicPattern;
public static void main(String[] args) throws Exception {
Main main = new Main();
......@@ -32,6 +34,7 @@ public class Main {
private void run(DataConfiguration config) throws IOException, InterruptedException {
final CountDownLatch finish = new CountDownLatch(1);
int topicMaxLength = 0;
MqttUpdater receiver = new MqttUpdater("receiver stub");
receiver.setHost(config.mqttHost);
receiver.waitUntilReady(2, TimeUnit.SECONDS);
......@@ -39,7 +42,9 @@ public class Main {
receiver.newConnection(config.dataConfigTopic, this::printDataConfig);
for (DataJoint joint : config.joints) {
receiver.newConnection(joint.topic, this::printPandaLinkState);
topicMaxLength = Math.max(topicMaxLength, joint.topic.length());
}
this.topicPattern = "%" + topicMaxLength + "s";
receiver.newConnection("components", bytes -> {
String message = new String(bytes);
......@@ -70,8 +75,10 @@ public class Main {
PandaLinkState.Orientation tmpOrientation = pls.getOrient();
PandaLinkState.TwistLinear tmpTwistLinear = pls.getTl();
PandaLinkState.TwistAngular tmpTwistAngular = pls.getTa();
logger.info("{}: pos({},{},{}), orient({},{},{},{})," +
" twist-linear({},{},{}), twist-angular({},{},{})",
// panda::panda_link0: pos(-3.0621333E-8,-1.5197388E-8,3.3411725E-5), orient(0.0,0.0,0.0,0.0), twist-linear(0.0,0.0,0.0), twist-angular(0.0,0.0,0.0)
logger.printf(Level.INFO,topicPattern + ": pos(% .5f,% .5f,% .5f), ori(%.1f,%.1f,%.1f,%.1f)," +
" twL(%.1f,%.1f,%.1f), twA(%.1f,%.1f,%.1f)",
pls.getName(),
tmpPosition.getPositionX(),
tmpPosition.getPositionY(),
......
......@@ -6,7 +6,7 @@
</Console>
</Appenders>
<Loggers>
<Root level="debug">
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
......
......@@ -7,34 +7,21 @@ import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) throws Exception {
final String topic;
final byte[] message;
if (args.length < 1) {
topic = "robot/joint1";
} else {
topic = args[0];
}
if (args.length < 2) {
Linkstate.PandaLinkState pls = Linkstate.PandaLinkState.newBuilder()
.setName("Joint1")
.setPos(Linkstate.PandaLinkState.Position.newBuilder()
.setPositionX(0.5f)
.setPositionY(0.5f)
.setPositionZ(0.5f)
.build())
.setOrient(Linkstate.PandaLinkState.Orientation.newBuilder()
.setOrientationX(0)
.setOrientationY(0)
.setOrientationZ(0)
.setOrientationW(0)
.build())
.build();
message = pls.toByteArray();
} else {
message = args[1].getBytes();
// assume 4 arguments
if (args.length < 4) {
System.err.println("Sends a new position, expected arguments: topic x y z");
return;
}
final String topic = args[0];
Linkstate.PandaLinkState pls = Linkstate.PandaLinkState.newBuilder()
.setName(args[0])
.setPos(Linkstate.PandaLinkState.Position.newBuilder()
.setPositionX(Float.parseFloat(args[1]))
.setPositionY(Float.parseFloat(args[2]))
.setPositionZ(Float.parseFloat(args[3]))
.build())
.build();
final byte[] message = pls.toByteArray();
MqttUpdater sender = new MqttUpdater("sender stub").dontSendWelcomeMessage();
sender.setHost("localhost", 1883);
......
aspect Computation {
syn boolean RobotArm.isInSafetyZone() {
System.out.println("isInSafetyZone()");
for (Joint joint : getJointList()) {
if (model().getZoneModel().isInSafetyZone(joint.getCurrentPosition())) {
return true;
......@@ -10,15 +11,10 @@ aspect Computation {
cache ZoneModel.isInSafetyZone(IntPosition pos);
syn boolean ZoneModel.isInSafetyZone(IntPosition pos) {
System.out.println("isInSafetyZone(" + pos + ")");
for (Zone sz : getSafetyZoneList()) {
for (Coordinate coordinate : sz.getCoordinateList()) {
IntPosition inside = coordinate.getPosition();
if (inside.getX() <= pos.getX() &&
inside.getY() <= pos.getY() &&
inside.getZ() <= pos.getZ() &&
pos.getX() <= inside.getX() + getSize().getX() &&
pos.getY() <= inside.getY() + getSize().getY() &&
pos.getZ() <= inside.getZ() + getSize().getZ()) {
if (coordinate.getPosition().equals(pos)) {
return true;
}
}
......
......@@ -10,20 +10,23 @@ RobotArm.AppropriateSpeed canDependOn Joint.CurrentPosition as dependency1 ;
// --- mapping definitions ---
ParseLinkState maps byte[] bytes to panda.Linkstate.PandaLinkState {:
// System.out.println("ParseLinkState");
return panda.Linkstate.PandaLinkState.parseFrom(bytes);
:}
SerializeRobotConfig maps config.Robotconfig.RobotConfig rc to byte[] {:
// System.out.println("SerializeRobotConfig");
return rc.toByteArray();
:}
LinkStateToIntPosition maps panda.Linkstate.PandaLinkState pls to IntPosition {:
// System.out.println("LinkStateToIntPosition");
panda.Linkstate.PandaLinkState.Position p = pls.getPos();
{ int i = 0; }
return IntPosition.of((int) p.getPositionX(), (int) p.getPositionY(), (int) p.getPositionZ());
return IntPosition.of((int) (Math.round(p.getPositionX() * 2)), (int) (Math.round(p.getPositionY() * 2)), (int) (Math.round(p.getPositionZ() * 2 + 0.5)));
:}
CreateSpeedMessage maps double speed to config.Robotconfig.RobotConfig {:
// System.out.println("CreateSpeedMessage");
return config.Robotconfig.RobotConfig.newBuilder()
.setSpeed(speed)
.setLoopTrajectory(true)
......
Model ::= RobotArm ZoneModel ;
ZoneModel ::= <Size:IntPosition> SafetyZone:Zone* ;
ZoneModel ::= SafetyZone:Zone* ;
Zone ::= Coordinate* ;
......
......@@ -28,9 +28,8 @@ public class StarterMain {
File configFile = new File(args[0]);
final int[][] safetyZoneCoordinates = {
{0, 0, 0},
{-1, 0, 0},
{1, 0, 0}
{1, 1, 0},
{-1, -1, 1}
};
// --- No configuration below this line ---
......@@ -43,7 +42,6 @@ public class StarterMain {
model.MqttSetHost(config.mqttHost);
ZoneModel zoneModel = new ZoneModel();
zoneModel.setSize(makePosition(1, 1, 1));
Zone safetyZone = new Zone();
for (int[] coordinate : safetyZoneCoordinates) {
......@@ -103,9 +101,9 @@ public class StarterMain {
.setEnableOrientation(false)
.setEnableTwistAngular(false)
.setEnableTwistLinear(false)
.setPublishRate(1000)
.setPublishRate(100)
.build();
mainHandler.publish(dataConfigTopic, dataConfig.toByteArray());
mainHandler.publish(dataConfigTopic, dataConfig.toByteArray(), true);
}
private void logStatus(String prefix, RobotArm robotArm) {
......
{
"joints": [
{"name": "Joint0", "topic": "panda_link_0"},
{"name": "Joint1", "topic": "panda_link_1"},
{"name": "Joint2", "topic": "panda_link_2"},
{"name": "Joint3", "topic": "panda_link_3"},
{"name": "Joint4", "topic": "panda_link_4"},
{"name": "Joint5", "topic": "panda_link_5"},
{"name": "Joint6", "topic": "panda_link_6"},
{"name": "EndEffector", "topic": "panda_link_7", "isEndEffector": true},
{"name": "LeftFinger", "topic": "panda_link_8"},
{"name": "RightFinger", "topic": "panda_link_9"}
{"name": "Joint0", "topic": "panda::panda_link0"},
{"name": "Joint1", "topic": "panda::panda_link1"},
{"name": "Joint2", "topic": "panda::panda_link2"},
{"name": "Joint3", "topic": "panda::panda_link3"},
{"name": "Joint4", "topic": "panda::panda_link4"},
{"name": "Joint5", "topic": "panda::panda_link5"},
{"name": "Joint6", "topic": "panda::panda_link6"},
{"name": "EndEffector", "topic": "panda::panda_link7", "isEndEffector": true},
{"name": "LeftFinger", "topic": "panda::panda_leftfinger"},
{"name": "RightFinger", "topic": "panda::panda_rightfinger"}
],
"robotConfigTopic": "robotconfig",
"dataConfigTopic": "dataconfig"
......
......@@ -30,11 +30,22 @@ dependencies {
}
test {
useJUnitPlatform()
useJUnitPlatform {
excludeTags 'mqtt'
}
maxHeapSize = '1G'
}
task allTests(type: Test, dependsOn: testClasses) {
description = 'Run every test'
group = 'verification'
useJUnitPlatform {
includeTags 'mqtt'
}
}
relastTest {
compilerLocation = '../libs/relast.jar'
}
......@@ -82,7 +93,7 @@ task compileExampleTest(type: RelastTest) {
'src/test/02-after-ros2rag/example/ROS2RAG.jadd'
}
test.dependsOn compileExampleTest
testClasses.dependsOn compileExampleTest
compileExampleTest.dependsOn preprocessExampleTest
// --- Test: default-only-read ---
......@@ -112,7 +123,7 @@ task compileDefaultOnlyReadTest(type: RelastTest) {
'src/test/02-after-ros2rag/defaultOnlyRead/ROS2RAG.jadd'
}
test.dependsOn compileDefaultOnlyReadTest
testClasses.dependsOn compileDefaultOnlyReadTest
compileDefaultOnlyReadTest.dependsOn preprocessDefaultOnlyReadTest
// --- Test: default-only-write ---
......@@ -143,7 +154,7 @@ task compileDefaultOnlyWriteTest(type: RelastTest) {
'src/test/02-after-ros2rag/defaultOnlyWrite/ROS2RAG.jadd'
}
test.dependsOn compileDefaultOnlyWriteTest
testClasses.dependsOn compileDefaultOnlyWriteTest
compileDefaultOnlyWriteTest.dependsOn preprocessDefaultOnlyWriteTest
// --- Test: read1write2 ---
......@@ -174,7 +185,7 @@ task compileRead1Write2Test(type: RelastTest) {
'src/test/02-after-ros2rag/read1write2/ROS2RAG.jadd'
}
test.dependsOn compileRead1Write2Test
testClasses.dependsOn compileRead1Write2Test
compileRead1Write2Test.dependsOn preprocessRead1Write2Test
// --- Test: read2write1 ---
......@@ -205,7 +216,7 @@ task compileRead2Write1Test(type: RelastTest) {
'src/test/02-after-ros2rag/read2write1/ROS2RAG.jadd'
}
test.dependsOn compileRead2Write1Test
testClasses.dependsOn compileRead2Write1Test
compileRead2Write1Test.dependsOn preprocessRead2Write1Test
clean {
......
aspect GrammarTypes {
public class TestCounter {
public static TestCounter INSTANCE = new TestCounter();
public int numberParseLinkState = 0;
public int numberSerializeRobotConfig = 0;
public int numberLinkStateToIntPosition = 0;
public int numberCreateSpeedMessage = 0;
public int numberInSafetyZone = 0;
public static void reset() {
TestCounter.INSTANCE = new TestCounter();
}
}
public class IntPosition {
private final int x, y, z;
......@@ -53,6 +65,7 @@ aspect GrammarTypes {
eq RobotArm.getEndEffector().containingRobotArm() = this;
syn boolean RobotArm.isInSafetyZone() {
TestCounter.INSTANCE.numberInSafetyZone += 1;
for (Joint joint : getJointList()) {
if (model().getZoneModel().isInSafetyZone(joint.getCurrentPosition())) {
return true;
......
......@@ -4,7 +4,7 @@ ZoneModel ::= <Size:IntPosition> SafetyZone:Zone* ;
Zone ::= Coordinate* ;
RobotArm ::= Joint* EndEffector <AttributeTestSource:int> /<AppropriateSpeed:double>/ ;
RobotArm ::= Joint* EndEffector /<AppropriateSpeed:double>/ ;
Joint ::= <Name:String> <CurrentPosition:IntPosition> ;
......
......@@ -5,24 +5,26 @@ write RobotArm.AppropriateSpeed using CreateSpeedMessage, SerializeRobotConfig ;
// --- dependency definitions ---
RobotArm.AppropriateSpeed canDependOn Joint.CurrentPosition as dependency1 ;
RobotArm.AppropriateSpeed canDependOn RobotArm.AttributeTestSource as dependency2 ;
// --- mapping definitions ---
ParseLinkState maps byte[] bytes to panda.Linkstate.PandaLinkState {:
TestCounter.INSTANCE.numberParseLinkState += 1;
return panda.Linkstate.PandaLinkState.parseFrom(bytes);
:}
SerializeRobotConfig maps config.Robotconfig.RobotConfig rc to byte[] {:
TestCounter.INSTANCE.numberSerializeRobotConfig += 1;
return rc.toByteArray();
:}
LinkStateToIntPosition maps panda.Linkstate.PandaLinkState pls to IntPosition {:
TestCounter.INSTANCE.numberLinkStateToIntPosition += 1;
panda.Linkstate.PandaLinkState.Position p = pls.getPos();
{ int i = 0; }
return IntPosition.of((int) p.getPositionX(), (int) p.getPositionY(), (int) p.getPositionZ());
return IntPosition.of((int) (10 * p.getPositionX()), (int) (10 * p.getPositionY()), (int) (10 * p.getPositionZ()));
:}
CreateSpeedMessage maps double speed to config.Robotconfig.RobotConfig {:
TestCounter.INSTANCE.numberCreateSpeedMessage += 1;
return config.Robotconfig.RobotConfig.newBuilder()
.setSpeed(speed)
.build();
......
......@@ -2,6 +2,7 @@ package org.jastadd.ros2rag.tests;
import defaultOnlyRead.ast.MqttUpdater;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Tag;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
......@@ -11,6 +12,7 @@ import java.util.concurrent.TimeUnit;
*
* @author rschoene - Initial contribution
*/
@Tag("mqtt")
public abstract class AbstractMqttTest {
static boolean checkDone = false;
static Boolean checkResult;
......
......@@ -106,7 +106,7 @@ public class DefaultOnlyReadTest extends AbstractMqttTest {
sender.publish(TOPIC_BOXED_DOUBLE, ByteBuffer.allocate(8).putDouble(expectedDoubleValue).array());
sender.publish(TOPIC_BOXED_CHARACTER, ByteBuffer.allocate(2).putChar(expectedCharValue).array());
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
assertEquals(expectedIntValue, integers.getIntValue());
assertEquals(expectedShortValue, integers.getShortValue());
......
......@@ -67,21 +67,21 @@ public class DefaultOnlyWriteTest extends AbstractMqttTest {
setupReceiverAndConnect(true);
// check initial value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(1, 1, 1.1, 'a', "ab");
// set new value
setData("2", "2.2", "cd");
// check new value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(2, 2, 2.2, 'c', "cd");
// set new value
setData("3", "3.2", "ee");
// check new value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(3, 3, 3.2, 'e', "ee");
}
......@@ -92,21 +92,21 @@ public class DefaultOnlyWriteTest extends AbstractMqttTest {
setupReceiverAndConnect(false);
// check initial value (will be default values)
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(0, null, null, null, null);
// set new value
setData("2", "2.2", "cd");
// check new value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(1, 2, 2.2, 'c', "cd");
// set new value
setData("3", "3.2", "ee");
// check new value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(2, 3, 3.2, 'e', "ee");
}
......
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