Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
monticore
EmbeddedMontiArc
generators
EMAM2Middleware
Commits
696525ee
Commit
696525ee
authored
Jan 29, 2019
by
Alexander David Hellwig
Browse files
Added rclcpp/ros2 generator impl + basic tests
parent
488147f8
Pipeline
#101058
passed with stages
in 8 minutes and 18 seconds
Changes
8
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/main/java/de/monticore/lang/monticar/generator/middleware/DistributedTargetGeneratorCli.java
View file @
696525ee
...
...
@@ -5,16 +5,11 @@ import com.google.gson.stream.JsonReader;
import
de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol
;
import
de.monticore.lang.embeddedmontiarc.tagging.middleware.ros.RosToEmamTagSchema
;
import
de.monticore.lang.monticar.emadl.generator.EMADLAbstractSymtab
;
import
de.monticore.lang.monticar.emadl.generator.EMADLGeneratorCli
;
import
de.monticore.lang.monticar.generator.middleware.impls.CPPGenImpl
;
import
de.monticore.lang.monticar.generator.middleware.impls.EMADLGeneratorImpl
;
import
de.monticore.lang.monticar.generator.middleware.impls.ODVGenImpl
;
import
de.monticore.lang.monticar.generator.middleware.impls.RosCppGenImpl
;
import
de.monticore.lang.monticar.generator.middleware.impls.*
;
import
de.monticore.lang.monticar.generator.order.simulator.AbstractSymtab
;
import
de.monticore.lang.monticar.generator.roscpp.helper.TagHelper
;
import
de.monticore.lang.tagging._symboltable.TaggingResolver
;
import
de.se_rwth.commons.logging.Log
;
import
org.apache.commons.cli.*
;
import
java.io.FileNotFoundException
;
import
java.io.FileReader
;
...
...
@@ -24,7 +19,6 @@ import java.nio.file.Paths;
import
java.util.Arrays
;
import
java.util.HashSet
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
public
final
class
DistributedTargetGeneratorCli
{
...
...
@@ -48,6 +42,9 @@ public final class DistributedTargetGeneratorCli {
public
static
final
String
GENERATOR_EMADL
=
"emadlcpp"
;
public
static
final
String
GENERATOR_ROSCPP
=
"roscpp"
;
public
static
final
String
GENERATOR_ODV
=
"odv"
;
//ros2cpp is an alias for rclcpp
public
static
final
String
GENERATOR_RCLCPP
=
"rclcpp"
;
public
static
final
String
GENERATOR_ROS2CPP
=
"ros2cpp"
;
private
DistributedTargetGeneratorCli
()
{}
...
...
@@ -85,6 +82,8 @@ public final class DistributedTargetGeneratorCli {
res
.
add
(
GENERATOR_EMADL
);
res
.
add
(
GENERATOR_ROSCPP
);
res
.
add
(
GENERATOR_ODV
);
res
.
add
(
GENERATOR_ROS2CPP
);
res
.
add
(
GENERATOR_RCLCPP
);
return
res
;
}
...
...
@@ -95,7 +94,8 @@ public final class DistributedTargetGeneratorCli {
}
String
fullModelsDirPath
=
expandHomeDir
(
cliParameters
.
getModelsDir
());
if
(
cliParameters
.
getGenerators
().
size
()
==
0
){
Set
<
String
>
generators
=
cliParameters
.
getGenerators
();
if
(
generators
.
size
()
==
0
){
Log
.
error
(
"0x6178E: No generator was specified!"
);
return
;
}
...
...
@@ -106,7 +106,7 @@ public final class DistributedTargetGeneratorCli {
}
TaggingResolver
taggingResolver
;
if
(
cliParameters
.
getG
enerators
()
.
contains
(
GENERATOR_EMADL
))
{
if
(
g
enerators
.
contains
(
GENERATOR_EMADL
))
{
taggingResolver
=
EMADLAbstractSymtab
.
createSymTabAndTaggingResolver
(
fullModelsDirPath
);
}
else
{
...
...
@@ -118,9 +118,13 @@ public final class DistributedTargetGeneratorCli {
Set
<
String
>
validGenNames
=
getGeneratorNames
();
cliParameters
.
getG
enerators
()
.
forEach
(
genName
->
{
g
enerators
.
forEach
(
genName
->
{
if
(
validGenNames
.
contains
(
genName
))
{
Log
.
warn
(
"Using generator "
+
genName
);
if
(
genName
.
equals
(
GENERATOR_ROS2CPP
))
{
Log
.
warn
(
"Using generator "
+
GENERATOR_RCLCPP
+
" since "
+
genName
+
" is an alias!"
);
}
else
{
Log
.
warn
(
"Using generator "
+
genName
);
}
}
else
{
Log
.
error
(
"0xE28B6: Not a valid generator Name:"
+
genName
+
"."
);
return
;
...
...
@@ -134,11 +138,11 @@ public final class DistributedTargetGeneratorCli {
return
;
}
if
(
cliParameters
.
getG
enerators
()
.
contains
(
GENERATOR_CPP
))
{
if
(
g
enerators
.
contains
(
GENERATOR_CPP
))
{
generator
.
add
(
new
CPPGenImpl
(),
"cpp"
);
}
if
(
cliParameters
.
getG
enerators
()
.
contains
(
GENERATOR_EMADL
))
{
if
(
g
enerators
.
contains
(
GENERATOR_EMADL
))
{
if
(
cliParameters
.
getEmadlBackend
()
!=
null
&&
!
cliParameters
.
getEmadlBackend
().
equals
(
""
))
{
generator
.
add
(
new
EMADLGeneratorImpl
(
fullModelsDirPath
,
cliParameters
.
getEmadlBackend
()),
"cpp"
);
}
else
{
...
...
@@ -147,13 +151,19 @@ public final class DistributedTargetGeneratorCli {
}
}
if
(
cliParameters
.
getG
enerators
()
.
contains
(
GENERATOR_ROSCPP
))
{
if
(
g
enerators
.
contains
(
GENERATOR_ROSCPP
))
{
generator
.
add
(
new
RosCppGenImpl
(),
"roscpp"
);
RosToEmamTagSchema
.
registerTagTypes
(
taggingResolver
);
TagHelper
.
resolveTags
(
taggingResolver
,
componentInstanceSymbol
);
}
if
(
cliParameters
.
getGenerators
().
contains
(
GENERATOR_ODV
))
{
if
(
generators
.
contains
(
GENERATOR_RCLCPP
)
||
generators
.
contains
(
GENERATOR_ROS2CPP
))
{
generator
.
add
(
new
RclCppGenImpl
(),
"rclcpp"
);
RosToEmamTagSchema
.
registerTagTypes
(
taggingResolver
);
TagHelper
.
resolveTags
(
taggingResolver
,
componentInstanceSymbol
);
}
if
(
generators
.
contains
(
GENERATOR_ODV
))
{
generator
.
add
(
new
ODVGenImpl
(),
"odv"
);
}
...
...
src/main/java/de/monticore/lang/monticar/generator/middleware/impls/RclCppGenImpl.java
0 → 100644
View file @
696525ee
package
de.monticore.lang.monticar.generator.middleware.impls
;
import
de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol
;
import
de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAPortInstanceSymbol
;
import
de.monticore.lang.monticar.generator.roscpp.GeneratorRosCpp
;
import
de.monticore.lang.tagging._symboltable.TaggingResolver
;
import
de.se_rwth.commons.logging.Log
;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.List
;
public
class
RclCppGenImpl
implements
GeneratorImpl
{
private
String
generationTargetPath
;
private
GeneratorRosCpp
generatorRosCpp
;
public
RclCppGenImpl
(){
generatorRosCpp
=
new
GeneratorRosCpp
();
generatorRosCpp
.
setGenerateCMake
(
true
);
generatorRosCpp
.
setRos2Mode
(
true
);
}
public
void
setGeneratorRosCpp
(
GeneratorRosCpp
generatorRosCpp
)
{
this
.
generatorRosCpp
=
generatorRosCpp
;
}
@Override
public
List
<
File
>
generate
(
EMAComponentInstanceSymbol
componentInstanceSymbol
,
TaggingResolver
taggingResolver
)
throws
IOException
{
generatorRosCpp
.
setGenerationTargetPath
(
generationTargetPath
);
return
generatorRosCpp
.
generateFiles
(
componentInstanceSymbol
,
taggingResolver
);
}
@Override
public
void
setGenerationTargetPath
(
String
path
)
{
this
.
generationTargetPath
=
path
;
}
@Override
public
boolean
willAccept
(
EMAComponentInstanceSymbol
componentInstanceSymbol
)
{
boolean
result
=
componentInstanceSymbol
.
getPortInstanceList
().
stream
().
anyMatch
(
EMAPortInstanceSymbol:
:
isRosPort
);
if
(!
result
){
Log
.
warn
(
"Generator rclcpp: No ROS Ports found! Ignoring component "
+
componentInstanceSymbol
.
getName
());
}
return
result
;
}
}
src/main/java/de/monticore/lang/monticar/generator/middleware/impls/RosCppGenImpl.java
View file @
696525ee
...
...
@@ -10,7 +10,6 @@ import java.io.File;
import
java.io.IOException
;
import
java.util.List
;
//TODO: make GeneratorRosCpp implement GeneratorImpl
public
class
RosCppGenImpl
implements
GeneratorImpl
{
private
String
generationTargetPath
;
private
GeneratorRosCpp
generatorRosCpp
;
...
...
src/test/java/de/monticore/lang/monticar/generator/middleware/CliTest.java
View file @
696525ee
...
...
@@ -286,4 +286,57 @@ public class CliTest {
private
boolean
logContains
(
String
errorCode
)
{
return
LogConfig
.
getFindings
().
stream
().
map
(
Finding:
:
getMsg
).
anyMatch
(
msg
->
msg
.
contains
(
errorCode
));
}
@Test
public
void
testRclcppGenerator
(){
String
targetDir
=
"target/cliTest/AllGenerators/"
;
String
json
=
buildParameterJson
(
VALID_MODELS_DIR_OPTION
,
VALID_ROOT_MODEL_OPTION
,
Arrays
.
asList
(
"cpp"
,
"rclcpp"
),
targetDir
);
DistributedTargetGeneratorCli
.
main
(
new
String
[]{
"-r"
,
json
});
String
[]
positiveFileNames
=
{
"CMakeLists.txt"
,
"tests_a_addComp/cpp/tests_a_addComp.h"
,
"tests_a_addComp/cpp/CMakeLists.txt"
,
"tests_a_addComp/coordinator/CMakeLists.txt"
,
"tests_a_addComp/coordinator/Coordinator_tests_a_addComp.cpp"
,
"tests_a_addComp/rclcpp/RosAdapter_tests_a_addComp.h"
,
"tests_a_addComp/rclcpp/CMakeLists.txt"
,
};
for
(
String
positiveFileName
:
positiveFileNames
)
{
assertTrue
(
Files
.
exists
(
Paths
.
get
(
targetDir
+
positiveFileName
)));
}
}
@Test
public
void
testRos2cppGenerator
(){
String
targetDir
=
"target/cliTest/AllGenerators/"
;
String
json
=
buildParameterJson
(
VALID_MODELS_DIR_OPTION
,
VALID_ROOT_MODEL_OPTION
,
Arrays
.
asList
(
"cpp"
,
"ros2cpp"
),
targetDir
);
DistributedTargetGeneratorCli
.
main
(
new
String
[]{
"-r"
,
json
});
String
[]
positiveFileNames
=
{
"CMakeLists.txt"
,
"tests_a_addComp/cpp/tests_a_addComp.h"
,
"tests_a_addComp/cpp/CMakeLists.txt"
,
"tests_a_addComp/coordinator/CMakeLists.txt"
,
"tests_a_addComp/coordinator/Coordinator_tests_a_addComp.cpp"
,
"tests_a_addComp/rclcpp/RosAdapter_tests_a_addComp.h"
,
"tests_a_addComp/rclcpp/CMakeLists.txt"
,
};
for
(
String
positiveFileName
:
positiveFileNames
)
{
assertTrue
(
Files
.
exists
(
Paths
.
get
(
targetDir
+
positiveFileName
)));
}
}
}
src/test/java/de/monticore/lang/monticar/generator/middleware/GenerationTest.java
View file @
696525ee
...
...
@@ -2,6 +2,7 @@ package de.monticore.lang.monticar.generator.middleware;
import
de.monticore.lang.embeddedmontiarc.embeddedmontiarc._ast.ASTComponent
;
import
de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.cncModel.EMAComponentSymbol
;
import
de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.cncModel.EMAPortSymbol
;
import
de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol
;
import
de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAPortInstanceSymbol
;
import
de.monticore.lang.embeddedmontiarc.embeddedmontiarcmath.cocos.EmbeddedMontiArcMathCoCos
;
...
...
@@ -19,6 +20,7 @@ import org.junit.Test;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
import
static
junit
.
framework
.
TestCase
.
assertTrue
;
...
...
@@ -335,4 +337,20 @@ public class GenerationTest extends AbstractSymtabTest {
assertFalse
(
filenames
.
stream
().
anyMatch
(
fn
->
fn
.
endsWith
(
"rosMsg/CMakeLists.txt"
)));
}
@Test
public
void
testRos2Generation
()
throws
IOException
{
TaggingResolver
taggingResolver
=
createSymTabAndTaggingResolver
(
TEST_PATH
);
EMAComponentInstanceSymbol
componentInstanceSymbol
=
taggingResolver
.<
EMAComponentInstanceSymbol
>
resolve
(
"tests.aRos2.addComp"
,
EMAComponentInstanceSymbol
.
KIND
).
orElse
(
null
);
RosToEmamTagSchema
.
registerTagTypes
(
taggingResolver
);
assertNotNull
(
componentInstanceSymbol
);
TagHelper
.
resolveTags
(
taggingResolver
,
componentInstanceSymbol
);
DistributedTargetGenerator
distributedTargetGenerator
=
new
DistributedTargetGenerator
();
distributedTargetGenerator
.
setGenerationTargetPath
(
"./target/generated-sources-ros2/addComp/src"
);
distributedTargetGenerator
.
add
(
new
CPPGenImpl
(),
"cpp"
);
distributedTargetGenerator
.
add
(
new
RclCppGenImpl
(),
"rclcpp"
);
List
<
File
>
files
=
distributedTargetGenerator
.
generate
(
componentInstanceSymbol
,
taggingResolver
);
}
}
src/test/resources/results/CMakeCppOnly/src/cpp/HelperA.h
deleted
100644 → 0
View file @
488147f8
#ifndef HELPERA_H
#define HELPERA_H
#include <iostream>
#include "armadillo.h"
#include <stdarg.h>
#include <initializer_list>
#include <fstream>
using
namespace
arma
;
#ifndef _FILESTRING_CONVERSION___A
#define _FILESTRING_CONVERSION___A
#include "armadillo.h"
using
namespace
arma
;
void
toFileString
(
std
::
ofstream
&
myfile
,
mat
A
){
myfile
<<
"["
;
for
(
int
i
=
0
;
i
<
A
.
n_rows
;
i
++
){
for
(
int
j
=
0
;
j
<
A
.
n_cols
;
j
++
){
myfile
<<
A
(
i
,
j
);
if
(
j
+
1
<
A
.
n_cols
){
myfile
<<
", "
;
}
}
if
(
i
+
1
<
A
.
n_rows
){
myfile
<<
";"
;
}
}
myfile
<<
"]"
;
}
void
toFileString
(
std
::
ofstream
&
myfile
,
double
A
){
myfile
<<
A
;
}
void
toFileString
(
std
::
ofstream
&
myfile
,
float
A
){
myfile
<<
A
;
}
void
toFileString
(
std
::
ofstream
&
myfile
,
int
A
){
myfile
<<
A
;
}
void
toFileString
(
std
::
ofstream
&
myfile
,
bool
A
){
myfile
<<
A
;
}
bool
Is_close
(
mat
&
X
,
mat
&
Y
,
double
tol
)
{
// abs returns a mat type then max checks columns and returns a row_vec
// max used again will return the biggest element in the row_vec
bool
close
(
false
);
if
(
arma
::
max
(
arma
::
max
(
arma
::
abs
(
X
-
Y
)))
<
tol
)
{
close
=
true
;
}
return
close
;
}
void
rangeValueCheck
(
double
A
,
double
lower
,
double
upper
){
REQUIRE
(
A
>=
lower
);
REQUIRE
(
A
<=
upper
);
}
void
rangeValueCheck
(
int
A
,
double
lower
,
double
upper
){
REQUIRE
(
A
>=
lower
);
REQUIRE
(
A
<=
upper
);
}
void
rangeValueCheck
(
mat
&
A
,
mat
&
lower
,
mat
&
upper
){
REQUIRE
(
Is_close
(
A
,
lower
,
0.0001
));
REQUIRE
(
Is_close
(
A
,
upper
,
0.0001
));
}
#endif
class
HelperA
{
public:
static
mat
getEigenVectors
(
mat
A
){
vec
eigenValues
;
mat
eigenVectors
;
eig_sym
(
eigenValues
,
eigenVectors
,
A
);
return
eigenVectors
;
}
static
vec
getEigenValues
(
mat
A
){
vec
eigenValues
;
mat
eigenVectors
;
eig_sym
(
eigenValues
,
eigenVectors
,
A
);
return
eigenValues
;
}
static
mat
getKMeansClusters
(
mat
A
,
int
k
){
mat
clusters
;
kmeans
(
clusters
,
A
.
t
(),
k
,
random_subset
,
20
,
true
);
/*printf("cluster centroid calculation done\n");
std::ofstream myfile;
myfile.open("data after cluster.txt");
myfile << A;
myfile.close();
std::ofstream myfile2;
myfile2.open("cluster centroids.txt");
myfile2 << clusters;
myfile2.close();*/
mat
indexedData
=
getKMeansClustersIndexData
(
A
.
t
(),
clusters
);
/*std::ofstream myfile3;
myfile3.open("data after index.txt");
myfile3 << indexedData;
myfile3.close();
*/
return
indexedData
;
}
static
mat
getKMeansClustersIndexData
(
mat
A
,
mat
centroids
){
mat
result
=
mat
(
A
.
n_cols
,
1
);
for
(
int
i
=
0
;
i
<
A
.
n_cols
;
++
i
){
result
(
i
,
0
)
=
getIndexForClusterCentroids
(
A
,
i
,
centroids
);
}
return
result
;
}
static
int
getIndexForClusterCentroids
(
mat
A
,
int
colIndex
,
mat
centroids
){
int
index
=
1
;
double
lowestDistance
=
getEuclideanDistance
(
A
,
colIndex
,
centroids
,
0
);
for
(
int
i
=
1
;
i
<
centroids
.
n_cols
;
++
i
){
double
curDistance
=
getEuclideanDistance
(
A
,
colIndex
,
centroids
,
i
);
if
(
curDistance
<
lowestDistance
){
lowestDistance
=
curDistance
;
index
=
i
+
1
;
}
}
return
index
;
}
static
double
getEuclideanDistance
(
mat
A
,
int
colIndexA
,
mat
B
,
int
colIndexB
){
double
distance
=
0
;
for
(
int
i
=
0
;
i
<
A
.
n_rows
;
++
i
){
double
elementA
=
A
(
i
,
colIndexA
);
double
elementB
=
B
(
i
,
colIndexB
);
double
diff
=
elementA
-
elementB
;
distance
+=
diff
*
diff
;
}
return
sqrt
(
distance
);
}
static
mat
getSqrtMat
(
mat
A
){
cx_mat
result
=
sqrtmat
(
A
);
return
real
(
result
);
}
static
mat
getSqrtMatDiag
(
mat
A
){
for
(
int
i
=
0
;
i
<
A
.
n_rows
;
++
i
){
double
curVal
=
A
(
i
,
i
);
A
(
i
,
i
)
=
sqrt
(
curVal
);
}
return
A
;
}
static
mat
invertDiagMatrix
(
mat
A
){
for
(
int
i
=
0
;
i
<
A
.
n_rows
;
++
i
){
double
curVal
=
A
(
i
,
i
);
A
(
i
,
i
)
=
1
/
curVal
;
}
return
A
;
}
};
#endif
src/test/resources/tests/aRos2/Add.tag
0 → 100644
View file @
696525ee
package
tests
.
aRos2
;
conforms
to
de
.
monticore
.
lang
.
monticar
.
generator
.
roscpp
.
RosToEmamTagSchema
;
tags
Add
{
tag
addComp
.
in1
with
RosConnection
=
{
topic
=
(/
clock
,
std_msgs
/
msg
/
Float64
),
msgField
=
data
};
tag
addComp
.
out1
with
RosConnection
=
{
topic
=
(/
echo
,
std_msgs
/
msg
/
Float64
),
msgField
=
data
};
}
src/test/resources/tests/aRos2/AddComp.emam
0 → 100644
View file @
696525ee
package
tests
.
aRos2
;
component
AddComp
{
ports
in
Q
in1
,
in
Q
in2
,
out
Q
out1
;
implementation
Math
{
out1
=
in1
+
in2
;
}
}
\ No newline at end of file
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment