Commit 7ae180ad authored by Alexander David Hellwig's avatar Alexander David Hellwig
Browse files

Merge branch 'adapted-ros-cpp-generator-for-path-arrays-2' into 'master'

Adapted ros cpp generator for path arrays; update versions and expected code

See merge request !15
parents ba3b2114 fe816f21
Pipeline #186255 passed with stages
in 2 minutes and 33 seconds
......@@ -10,7 +10,7 @@
<groupId>de.monticore.lang.monticar</groupId>
<artifactId>embedded-montiarc-math-roscpp-generator</artifactId>
<version>0.1.6-SNAPSHOT</version>
<version>0.1.7-SNAPSHOT</version>
<!-- == PROJECT DEPENDENCIES ============================================= -->
......@@ -18,7 +18,7 @@
<!-- .. SE-Libraries .................................................. -->
<se-commons.version>1.7.7</se-commons.version>
<Embedded-MontiArc-Math.version>0.1.7-SNAPSHOT</Embedded-MontiArc-Math.version>
<Embedded-MontiArc-Math.version>0.1.13-SNAPSHOT</Embedded-MontiArc-Math.version>
<Embedded-montiarc-math-rosmsg-generator.version>0.1.3-SNAPSHOT</Embedded-montiarc-math-rosmsg-generator.version>
<!-- .. Libraries .................................................. -->
......@@ -31,7 +31,7 @@
<compiler.plugin>3.3</compiler.plugin>
<source.plugin>2.4</source.plugin>
<shade.plugin>2.4.3</shade.plugin>
<jacoco.plugin>0.8.1</jacoco.plugin>
<jacoco.plugin>0.8.3</jacoco.plugin>
<!-- Classifiers -->
<grammars.classifier>grammars</grammars.classifier>
......
......@@ -19,42 +19,13 @@ public class SetStructPortInstruction{
private SetStructPortInstruction() {
}
public static String getInstruction(EMAPortSymbol port, RosMsg rosMsg, String fieldPrefix) {
public static String getStructInstruction(EMAPortSymbol port, RosMsg rosMsg, String fieldPrefix) {
String inst;
if (rosMsg.getName().startsWith("std_msgs/")) {
if (rosMsg.getName().endsWith("MultiArray")) {
ASTCommonMatrixType matrixType = (ASTCommonMatrixType) ((MCASTTypeSymbol) port.getTypeReference().getReferencedSymbol()).getAstType();
List<String> dimSizes = IndexHelper.getDimSizesOfMatrixType(matrixType);
inst = "";
inst += "int counter = 0;\n";
String indexString = "";
for (int i = 0; i < dimSizes.size(); i++) {
String curInd = "i" + i;
indexString += (i == 0 ? "" : ", ") + curInd;
inst += "for(int " + curInd + " = 0; " + curInd + " < " + dimSizes.get(i) + "; " + curInd + "++){\n";
}
inst += "(component->" + NameHelper.getPortNameTargetLanguage(port) + ")(" + indexString + ") = msg->" + fieldPrefix + "data[counter]";
//TODO: check type not name
if (rosMsg.getName().equals("std_msgs/ByteMultiArray")) {
//is a bool msg
inst += " != 0";
}
inst += ";\n";
inst += "counter++;\n";
for (int i = 0; i < dimSizes.size(); i++) {
inst += "}\n";
}
} else {
inst = NameHelper.getAllFieldNames(rosMsg).stream()
.map(field -> "component->" + NameHelper.getPortNameTargetLanguage(port) + " = msg->" + fieldPrefix + field + ";")
.sorted()
.collect(Collectors.joining("\n"));
}
} else {
StructSymbol structSymbol = (StructSymbol) port.getTypeReference().getReferencedSymbol();
......@@ -94,4 +65,74 @@ public class SetStructPortInstruction{
return inst;
}
public static String getMatrixInstruction(EMAPortSymbol port, RosMsg rosMsg, String fieldPrefix){
String inst;
ASTCommonMatrixType matrixType = (ASTCommonMatrixType) ((MCASTTypeSymbol) port.getTypeReference().getReferencedSymbol()).getAstType();
List<String> dimSizes = IndexHelper.getDimSizesOfMatrixType(matrixType);
inst = "";
inst += "int counter = 0;\n";
String indexString = "";
for (int i = 0; i < dimSizes.size(); i++) {
String curInd = "i" + i;
indexString += (i == 0 ? "" : ", ") + curInd;
inst += "for(int " + curInd + " = 0; " + curInd + " < " + dimSizes.get(i) + "; " + curInd + "++){\n";
}
String upperBound;
String lowerBound;
if (!fieldPrefix.isEmpty() && fieldPrefix.contains(":")){
String split[] = fieldPrefix.split(":", 2);
boolean boundExists = !split[0].replaceAll("[^0-9]", "").isEmpty();
lowerBound = boundExists ? split[0].replaceAll("[^0-9]", "") : "0";
boundExists = !split[1].replaceAll("[^0-9]", "").isEmpty();
upperBound = boundExists ? split[1].replaceAll("[^0-9]", "") : dimSizes.get(dimSizes.size()-1)+"-1";
} else {
lowerBound = "0";
upperBound = dimSizes.get(dimSizes.size()-1)+"-1";
}
if(!upperBound.equals("")){
// if (Integer.parseInt(lowerBound) > Integer.parseInt(upperBound)) { If
// Log.error(" ArrayBoundsHandler: lowerBound > upperBound!");
// }
inst += "if(" + lowerBound + " <= counter && counter <= " + upperBound + "){\n";
}
String tmp;
if (fieldPrefix.isEmpty()){
tmp = "(component->" + NameHelper.getPortNameTargetLanguage(port) + ")(" + indexString + ") = msg->" + fieldPrefix + "data[counter]";
} else {
tmp = "(component->" + NameHelper.getPortNameTargetLanguage(port) + ")(" + indexString + "-" + lowerBound + ") = msg->" + fieldPrefix.replaceAll("[0-9]", "").replace(":","counter");
tmp = tmp.substring(0,tmp.length()-1);
}
inst += tmp;
//TODO: check type not name
if (rosMsg.getName().equals("std_msgs/ByteMultiArray")) {
//is a bool msg
inst += " != 0";
}
inst += ";\n";
if(!upperBound.equals("")){
inst += "}\n";
inst += "else if(" + lowerBound + " > counter){\n";
inst += "(component->" + NameHelper.getPortNameTargetLanguage(port) + ")(" + indexString + "+" + upperBound + "-" + lowerBound + "+1" +") = 0" + ";\n";
inst += "}\n";
inst += "else{\n";
inst += "(component->" + NameHelper.getPortNameTargetLanguage(port) + ")(" + indexString + ") = 0" + ";\n";
inst += "}\n";
}
inst += "counter++;\n";
for (int i = 0; i < dimSizes.size(); i++) {
inst += "}\n";
}
return inst;
}
}
......@@ -61,6 +61,10 @@ public abstract class RosInterface {
public abstract String getRos2SetStructInstruction();
public abstract String getRosSetMatrixInstruction();
public abstract String getRos2SetMatrixInstruction();
public String getTopicType() {
return getRosConnectionSymbol().getTopicType().get();
}
......@@ -81,4 +85,13 @@ public abstract class RosInterface {
return port.getTypeReference().getReferencedSymbol() instanceof StructSymbol;
}
public boolean isMatrixInterface(){
if(!port.getTypeReference().existsReferencedSymbol()){
return false;
}
return port.getTypeReference().toString().equals("CommonMatrixType");
}
}
......@@ -33,12 +33,28 @@ public class RosPublisher extends RosInterface {
@Override
public String getRosSetStructInstruction() {
String fieldPrefix = this.rosConnectionSymbol.getMsgField().map(msgfield -> msgfield + ".").orElse("");
//return SetStructMsgInstruction.getStructInstruction(getPort(), getRosMsg(), fieldPrefix);
return SetStructMsgInstruction.getInstruction(getPort(), getRosMsg(), fieldPrefix);
}
@Override
public String getRosSetMatrixInstruction() {
String fieldPrefix = this.rosConnectionSymbol.getMsgField().map(msgfield -> msgfield + ".").orElse("");
//return SetStructMsgInstruction.getMatrixInstruction(getPort(), getRosMsg(), fieldPrefix);
return SetStructMsgInstruction.getInstruction(getPort(), getRosMsg(), fieldPrefix);
}
@Override
public String getRos2SetStructInstruction() {
String fieldPrefix = this.rosConnectionSymbol.getMsgField().map(msgfield -> msgfield + ".").orElse("");
return SetStructMsgInstruction.getInstruction(getPort(), getRos2Msg(),fieldPrefix);
//return SetStructMsgInstruction.getStructInstruction(getPort(), getRos2Msg(),fieldPrefix);
return SetStructMsgInstruction.getInstruction(getPort(), getRosMsg(), fieldPrefix);
}
@Override
public String getRos2SetMatrixInstruction() {
String fieldPrefix = this.rosConnectionSymbol.getMsgField().map(msgfield -> msgfield + ".").orElse("");
//return SetStructMsgInstruction.getMatrixInstruction(getPort(), getRos2Msg(),fieldPrefix);
return SetStructMsgInstruction.getInstruction(getPort(), getRosMsg(), fieldPrefix);
}
}
......@@ -33,12 +33,24 @@ public class RosSubscriber extends RosInterface {
@Override
public String getRosSetStructInstruction() {
String fieldPrefix = this.rosConnectionSymbol.getMsgField().map(msgfield -> msgfield + ".").orElse("");
return SetStructPortInstruction.getInstruction(getPort(), getRosMsg(), fieldPrefix);
return SetStructPortInstruction.getStructInstruction(getPort(), getRosMsg(), fieldPrefix);
}
@Override
public String getRosSetMatrixInstruction() {
String fieldPrefix = this.rosConnectionSymbol.getMsgField().map(msgfield -> msgfield + ".").orElse("");
return SetStructPortInstruction.getMatrixInstruction(getPort(), getRosMsg(), fieldPrefix);
}
@Override
public String getRos2SetStructInstruction() {
String fieldPrefix = this.rosConnectionSymbol.getMsgField().map(msgfield -> msgfield + ".").orElse("");
return SetStructPortInstruction.getInstruction(getPort(), getRos2Msg(), fieldPrefix);
return SetStructPortInstruction.getStructInstruction(getPort(), getRos2Msg(),fieldPrefix);
}
@Override
public String getRos2SetMatrixInstruction() {
String fieldPrefix = this.rosConnectionSymbol.getMsgField().map(msgfield -> msgfield + ".").orElse("");
return SetStructPortInstruction.getMatrixInstruction(getPort(), getRos2Msg(),fieldPrefix);
}
}
......@@ -39,10 +39,17 @@ ros::Publisher ${name};
<#macro callback sub>
void ${sub.getMethodName()}(const ${sub.getTypeNameInTargetLanguage()}::ConstPtr& msg){
<#if !sub.isStructInterface() && sub.getRosConnectionSymbol().getMsgField().isPresent()>
<#if !sub.isStructInterface() && !sub.isMatrixInterface() && sub.getRosConnectionSymbol().getMsgField().isPresent()>
component->${sub.getPortNameInTargetLanguage()} = msg->${sub.getRosConnectionSymbol().getMsgField().get()};
<#else>
${sub.getRosSetStructInstruction()}
<#-- ${sub.getRosSetStructInstruction()} -->
<#if sub.isMatrixInterface()>
${sub.getRosSetMatrixInstruction()}
<#else>
${sub.getRosSetStructInstruction()}
</#if>
</#if>
}
</#macro>
......
......@@ -198,6 +198,25 @@ public class TaggingTest extends AbstractSymtabTest {
testFilesAreEqual(files, "matrixTypesComp/", generationTargetPath);
}
@Test
public void testArrayHandlingComp() throws IOException {
TaggingResolver symtab = createSymTabAndTaggingResolver("src/test/resources");
RosToEmamTagSchema.registerTagTypes(symtab);
GeneratorRosCpp generatorRosCpp = new GeneratorRosCpp();
String generationTargetPath = "./target/generated-sources-roscpp/arrayHandlingComp/";
generatorRosCpp.setGenerationTargetPath(generationTargetPath);
EMAComponentInstanceSymbol component = symtab.<EMAComponentInstanceSymbol>resolve("tests.structs.arrayHandlingComp", EMAComponentInstanceSymbol.KIND).orElse(null);
assertNotNull(component);
Map<EMAPortSymbol, RosConnectionSymbol> tags = TagHelper.resolveTags(symtab, component);
List<File> files = TagHelper.resolveAndGenerate(generatorRosCpp, symtab, component);
testFilesAreEqual(files, "arrayHandlingComp/", generationTargetPath);
}
@Test
public void testMissingTopicName() throws IOException {
Log.enableFailQuick(false);
......
/* (c) https://github.com/MontiCore/monticore */
#pragma once
#include "IAdapter_tests_structs_arrayHandlingComp.h"
#include "tests_structs_arrayHandlingComp.h"
#include <ros/ros.h>
#include <nav_msgs/Path.h>
#include <std_msgs/ByteMultiArray.h>
#include <std_msgs/Float64MultiArray.h>
#include <std_msgs/Int32MultiArray.h>
class RosAdapter_tests_structs_arrayHandlingComp: public IAdapter_tests_structs_arrayHandlingComp{
tests_structs_arrayHandlingComp* component;
ros::Subscriber _name1Subscriber;
ros::Subscriber _name2Subscriber;
ros::Subscriber _name3Subscriber;
ros::Subscriber _name4Subscriber;
ros::Publisher _name5Publisher;
ros::Publisher _name6Publisher;
public:
RosAdapter_tests_structs_arrayHandlingComp(){
}
void init(tests_structs_arrayHandlingComp* comp){
this->component = comp;
char* tmp = strdup("");
int i = 0;
ros::init(i, &tmp, "RosAdapter_tests_structs_arrayHandlingComp_node");
ros::NodeHandle node_handle = ros::NodeHandle();
_name1Subscriber = node_handle.subscribe("/name1", 5, &RosAdapter_tests_structs_arrayHandlingComp::_name1Callback, this, ros::TransportHints().tcpNoDelay());
_name2Subscriber = node_handle.subscribe("/name2", 5, &RosAdapter_tests_structs_arrayHandlingComp::_name2Callback, this, ros::TransportHints().tcpNoDelay());
_name3Subscriber = node_handle.subscribe("/name3", 5, &RosAdapter_tests_structs_arrayHandlingComp::_name3Callback, this, ros::TransportHints().tcpNoDelay());
_name4Subscriber = node_handle.subscribe("/name4", 5, &RosAdapter_tests_structs_arrayHandlingComp::_name4Callback, this, ros::TransportHints().tcpNoDelay());
_name5Publisher = node_handle.advertise<std_msgs::ByteMultiArray>("/name5",5);
_name6Publisher = node_handle.advertise<std_msgs::Int32MultiArray>("/name6",5);
ros::spin();
}
void _name1Callback(const std_msgs::Float64MultiArray::ConstPtr& msg){
int counter = 0;
for(int i0 = 0; i0 < 3; i0++){
for(int i1 = 0; i1 < 1; i1++){
if(0 <= counter && counter <= 1-1){
(component->in1)(i0, i1-0) = msg->data[counter];
}
else if(0 > counter){
(component->in1)(i0, i1+1-1-0+1) = 0;
}
else{
(component->in1)(i0, i1) = 0;
}
counter++;
}
}
}
void _name2Callback(const std_msgs::ByteMultiArray::ConstPtr& msg){
int counter = 0;
for(int i0 = 0; i0 < 4; i0++){
for(int i1 = 0; i1 < 4; i1++){
if(0 <= counter && counter <= 4-1){
(component->in2)(i0, i1) = msg->data[counter] != 0;
}
else if(0 > counter){
(component->in2)(i0, i1+4-1-0+1) = 0;
}
else{
(component->in2)(i0, i1) = 0;
}
counter++;
}
}
}
void _name3Callback(const nav_msgs::Path::ConstPtr& msg){
int counter = 0;
for(int i0 = 0; i0 < 1; i0++){
for(int i1 = 0; i1 < 10; i1++){
if(0 <= counter && counter <= 10-1){
(component->in3)(i0, i1-0) = msg->poses[counter].pose.orientation.x;
}
else if(0 > counter){
(component->in3)(i0, i1+10-1-0+1) = 0;
}
else{
(component->in3)(i0, i1) = 0;
}
counter++;
}
}
}
void _name4Callback(const nav_msgs::Path::ConstPtr& msg){
int counter = 0;
for(int i0 = 0; i0 < 1; i0++){
for(int i1 = 0; i1 < 7; i1++){
if(2 <= counter && counter <= 6){
(component->in4)(i0, i1-2) = msg->poses[counter].pose.orientation.x;
}
else if(2 > counter){
(component->in4)(i0, i1+6-2+1) = 0;
}
else{
(component->in4)(i0, i1) = 0;
}
counter++;
}
}
}
void publish_name5Publisher(){
std_msgs::ByteMultiArray tmpMsg;
tmpMsg.data.resize(2 * 3);
int counter = 0;
for(int i0 = 0; i0 < 2; i0++){
for(int i1 = 0; i1 < 3; i1++){
tmpMsg.data[counter] = (component->out1)(i0, i1) ? 1 : 0;
counter++;
}
}
_name5Publisher.publish(tmpMsg);
}
void publish_name6Publisher(){
std_msgs::Int32MultiArray tmpMsg;
tmpMsg.data.resize(2 * 4);
int counter = 0;
for(int i0 = 0; i0 < 2; i0++){
for(int i1 = 0; i1 < 4; i1++){
tmpMsg.data[counter] = (component->out2)(i0, i1);
counter++;
}
}
_name6Publisher.publish(tmpMsg);
}
void tick(){
publish_name5Publisher();
publish_name6Publisher();
}
};
......@@ -16,7 +16,7 @@ class RosAdapter_test_basicGenericInstance_basicGeneric: public IAdapter_test_ba
RosAdapter_test_basicGenericInstance_basicGeneric(){
}
void init(test_basicGenericInstance_basicGeneric* comp){
this->component = comp;
char* tmp = strdup("");
......@@ -30,17 +30,28 @@ class RosAdapter_test_basicGenericInstance_basicGeneric: public IAdapter_test_ba
ros::spin();
}
void _name1Callback(const std_msgs::Float64MultiArray::ConstPtr& msg){
int counter = 0;
for(int i0 = 0; i0 < n; i0++){
for(int i1 = 0; i1 < n; i1++){
(component->mat1)(i0, i1) = msg->data[counter];
counter++;
}
}
}
void _name1Callback(const std_msgs::Float64MultiArray::ConstPtr& msg){
int counter = 0;
for(int i0 = 0; i0 < n; i0++){
for(int i1 = 0; i1 < n; i1++){
if(0 <= counter && counter <= n-1){
(component->mat1)(i0, i1) = msg->data[counter];
}
else if(0 > counter){
(component->mat1)(i0, i1+n-1-0+1) = 0;
}
else{
(component->mat1)(i0, i1) = 0;
}
counter++;
}
}
}
void publish_name1Publisher(){
std_msgs::Float64MultiArray tmpMsg;
tmpMsg.data.resize(n * n);
......
......@@ -6,7 +6,9 @@
#include <std_msgs/ByteMultiArray.h>
#include <std_msgs/Float64MultiArray.h>
#include <std_msgs/Int32MultiArray.h>
class RosAdapter_tests_structs_matrixTypesComp: public IAdapter_tests_structs_matrixTypesComp{
tests_structs_matrixTypesComp* component;
ros::Subscriber _name1Subscriber;
ros::Subscriber _name2Subscriber;
......@@ -24,34 +26,56 @@ class RosAdapter_tests_structs_matrixTypesComp: public IAdapter_tests_structs_ma
int i = 0;
ros::init(i, &tmp, "RosAdapter_tests_structs_matrixTypesComp_node");
ros::NodeHandle node_handle = ros::NodeHandle();
_name1Subscriber = node_handle.subscribe("/name1", 5, &RosAdapter_tests_structs_matrixTypesComp::_name1Callback, this, ros::TransportHints().tcpNoDelay());
_name2Subscriber = node_handle.subscribe("/name2", 5, &RosAdapter_tests_structs_matrixTypesComp::_name2Callback, this, ros::TransportHints().tcpNoDelay());
_name3Publisher = node_handle.advertise<std_msgs::ByteMultiArray>("/name3",5);
_name4Publisher = node_handle.advertise<std_msgs::Int32MultiArray>("/name4",5);
ros::spin();
}
void _name1Callback(const std_msgs::Float64MultiArray::ConstPtr& msg){
int counter = 0;
for(int i0 = 0; i0 < 3; i0++){
for(int i1 = 0; i1 < 1; i1++){
(component->in1)(i0, i1) = msg->data[counter];
counter++;
}
}
}
void _name2Callback(const std_msgs::ByteMultiArray::ConstPtr& msg){
int counter = 0;
for(int i0 = 0; i0 < 4; i0++){
for(int i1 = 0; i1 < 4; i1++){
(component->in2)(i0, i1) = msg->data[counter] != 0;
counter++;
}
}
}
void _name1Callback(const std_msgs::Float64MultiArray::ConstPtr& msg){
int counter = 0;
for(int i0 = 0; i0 < 3; i0++){
for(int i1 = 0; i1 < 1; i1++){
if(0 <= counter && counter <= 1-1){
(component->in1)(i0, i1) = msg->data[counter];
}
else if(0 > counter){
(component->in1)(i0, i1+1-1-0+1) = 0;
}
else{
(component->in1)(i0, i1) = 0;
}
counter++;
}
}
}
void _name2Callback(const std_msgs::ByteMultiArray::ConstPtr& msg){
int counter = 0;