Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
monticore
EmbeddedMontiArc
generators
EMAM2Middleware
Commits
de3f01f5
Commit
de3f01f5
authored
Feb 14, 2018
by
Alexander David Hellwig
Browse files
Added DistributedTargetGenerator.java + test
parent
2babad19
Changes
7
Hide whitespace changes
Inline
Side-by-side
pom.xml
View file @
de3f01f5
...
...
@@ -87,6 +87,11 @@
<version>
0.0.1c-SNAPSHOT
</version>
</dependency>
<dependency>
<groupId>
de.monticore.lang.monticar
</groupId>
<artifactId>
embedded-montiarc-math-rosmsg-generator
</artifactId>
<version>
0.0.1-SNAPSHOT
</version>
</dependency>
<dependency>
<groupId>
com.esotericsoftware.yamlbeans
</groupId>
...
...
src/main/java/de/monticore/lang/monticar/generator/master/DistributedTargetGenerator.java
0 → 100644
View file @
de3f01f5
package
de.monticore.lang.monticar.generator.master
;
import
de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ConnectorSymbol
;
import
de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ExpandedComponentInstanceSymbol
;
import
de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.PortSymbol
;
import
de.monticore.lang.embeddedmontiarc.tagging.MiddlewareSymbol
;
import
de.monticore.lang.embeddedmontiarc.tagging.RosConnectionSymbol
;
import
de.monticore.lang.monticar.generator.roscpp.helper.TagHelper
;
import
de.monticore.lang.monticar.generator.rosmsg.RosMsg
;
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.*
;
public
class
DistributedTargetGenerator
extends
CMakeMasterGenerator
{
private
RosMsgImpl
rosMsgImpl
;
public
DistributedTargetGenerator
(
String
generationTargetPath
)
{
setGenerationTargetPath
(
generationTargetPath
);
rosMsgImpl
=
new
RosMsgImpl
(
"rosmsg"
);
//this.add(rosMsgImpl,"rosmsg/");
}
@Override
public
List
<
File
>
generate
(
ExpandedComponentInstanceSymbol
componentInstanceSymbol
,
TaggingResolver
taggingResolver
)
throws
IOException
{
Map
<
PortSymbol
,
RosConnectionSymbol
>
resolvedTags
=
TagHelper
.
resolveTags
(
taggingResolver
,
componentInstanceSymbol
);
Map
<
ExpandedComponentInstanceSymbol
,
GeneratorImpl
>
generatorMap
=
new
HashMap
<>();
fixComponentInstance
(
componentInstanceSymbol
);
Collection
<
ExpandedComponentInstanceSymbol
>
subComps
=
getSubComponentInstances
(
componentInstanceSymbol
);
//TODO: cluster non mw subcomps together with mw subcomps
boolean
allSubsMwOnly
=
subComps
.
stream
()
.
flatMap
(
comp
->
comp
.
getPorts
().
stream
())
.
allMatch
(
p
->
p
.
getMiddlewareSymbol
().
isPresent
());
if
(
allSubsMwOnly
)
{
subComps
.
forEach
(
comp
->
generatorMap
.
put
(
comp
,
createFullGenerator
(
comp
.
getFullName
().
replace
(
"."
,
"_"
)))
);
}
else
{
generatorMap
.
put
(
componentInstanceSymbol
,
createFullGenerator
(
componentInstanceSymbol
.
getFullName
().
replace
(
"."
,
"_"
)));
}
List
<
File
>
files
=
new
ArrayList
<>();
CMakeMasterGenerator
cmakeListsGenerator
=
new
CMakeMasterGenerator
();
cmakeListsGenerator
.
setGenerationTargetPath
(
generationTargetPath
);
for
(
ExpandedComponentInstanceSymbol
comp
:
generatorMap
.
keySet
())
{
files
.
addAll
(
generatorMap
.
get
(
comp
).
generate
(
comp
,
taggingResolver
));
//add empty generator to cmakeListsGenerator so that CMakeLists.txt will be generated
cmakeListsGenerator
.
add
(
new
GeneratorImpl
()
{
},
comp
.
getFullName
().
replace
(
"."
,
"_"
));
}
files
.
addAll
(
cmakeListsGenerator
.
generate
(
componentInstanceSymbol
,
taggingResolver
));
return
files
;
}
private
GeneratorImpl
createFullGenerator
(
String
subdir
)
{
MiddlewareMasterGenerator
res
=
new
MiddlewareMasterGenerator
();
res
.
setGenerationTargetPath
(
generationTargetPath
+
(
subdir
.
endsWith
(
"/"
)
?
subdir
:
subdir
+
"/"
));
this
.
getGeneratorImpls
().
forEach
(
gen
->
res
.
add
(
gen
,
this
.
getImplSubfolder
(
gen
)));
return
res
;
}
private
void
fixComponentInstance
(
ExpandedComponentInstanceSymbol
componentInstanceSymbol
)
{
fixRosTopics
(
componentInstanceSymbol
);
}
private
void
fixRosTopics
(
ExpandedComponentInstanceSymbol
componentInstanceSymbol
)
{
componentInstanceSymbol
.
getConnectors
().
stream
()
.
filter
(
connectorSymbol
->
connectorSymbol
.
getSourcePort
().
isRosPort
()
&&
connectorSymbol
.
getTargetPort
().
isRosPort
())
.
forEach
(
connectorSymbol
->
{
if
(
Objects
.
equals
(
connectorSymbol
.
getSourcePort
().
getComponentInstance
().
orElse
(
null
),
componentInstanceSymbol
))
{
//In port of supercomp
inferRosConnectionIfPossible
(
connectorSymbol
.
getSourcePort
(),
connectorSymbol
.
getTargetPort
());
}
else
if
(
Objects
.
equals
(
connectorSymbol
.
getTargetPort
().
getComponentInstance
().
orElse
(
null
),
componentInstanceSymbol
))
{
//out port of supercomp
inferRosConnectionIfPossible
(
connectorSymbol
.
getTargetPort
(),
connectorSymbol
.
getSourcePort
());
}
else
{
//In between subcomps
generateRosConnectionIfPossible
(
connectorSymbol
);
}
});
}
private
void
generateRosConnectionIfPossible
(
ConnectorSymbol
connectorSymbol
)
{
MiddlewareSymbol
sourceTag
=
connectorSymbol
.
getSourcePort
().
getMiddlewareSymbol
().
orElse
(
null
);
MiddlewareSymbol
targetTag
=
connectorSymbol
.
getTargetPort
().
getMiddlewareSymbol
().
orElse
(
null
);
if
(
sourceTag
==
null
||
targetTag
==
null
||
!
sourceTag
.
isKindOf
(
RosConnectionSymbol
.
KIND
)
||
!
targetTag
.
isKindOf
(
RosConnectionSymbol
.
KIND
))
{
Log
.
debug
(
"Both sourcePort and targetPort need to have a RosConnectionSymbol"
,
"RosConnectionSymbol"
);
return
;
}
RosConnectionSymbol
rosConnectionA
=
(
RosConnectionSymbol
)
sourceTag
;
RosConnectionSymbol
rosConnectionB
=
(
RosConnectionSymbol
)
targetTag
;
RosConnectionSymbol
emptyRosConnection
=
new
RosConnectionSymbol
();
if
(!
rosConnectionA
.
equals
(
emptyRosConnection
)
||
!
rosConnectionB
.
equals
(
emptyRosConnection
))
{
Log
.
debug
(
"Will not override rosConnections that are not empty!"
,
"RosConnectionSymbol"
);
return
;
}
//target port name is unique: each in port can only have one connection!
String
topicName
=
connectorSymbol
.
getTargetPort
().
getFullName
().
replace
(
"."
,
"_"
);
RosMsg
rosTypeA
=
rosMsgImpl
.
getRosType
(
connectorSymbol
.
getTargetPort
().
getTypeReference
());
RosMsg
rosTypeB
=
rosMsgImpl
.
getRosType
(
connectorSymbol
.
getSourcePort
().
getTypeReference
());
if
(!
rosTypeA
.
equals
(
rosTypeB
))
{
Log
.
error
(
"topicType mismatch! "
+
connectorSymbol
.
getSourcePort
().
getFullName
()
+
" has "
+
rosTypeB
+
" and "
+
connectorSymbol
.
getTargetPort
().
getFullName
()
+
" has "
+
rosTypeA
);
return
;
}
rosMsgImpl
.
addRosTypeToGenerate
(
connectorSymbol
.
getTargetPort
().
getTypeReference
());
if
(
rosTypeA
.
getFields
().
size
()
==
1
)
{
connectorSymbol
.
getSourcePort
().
setMiddlewareSymbol
(
new
RosConnectionSymbol
(
topicName
,
rosTypeB
.
getName
(),
rosTypeB
.
getFields
().
get
(
0
).
getName
()));
connectorSymbol
.
getTargetPort
().
setMiddlewareSymbol
(
new
RosConnectionSymbol
(
topicName
,
rosTypeA
.
getName
(),
rosTypeA
.
getFields
().
get
(
0
).
getName
()));
}
else
{
connectorSymbol
.
getSourcePort
().
setMiddlewareSymbol
(
new
RosConnectionSymbol
(
topicName
,
rosTypeB
.
getName
()));
connectorSymbol
.
getTargetPort
().
setMiddlewareSymbol
(
new
RosConnectionSymbol
(
topicName
,
rosTypeA
.
getName
()));
}
}
private
void
inferRosConnectionIfPossible
(
PortSymbol
sourcePort
,
PortSymbol
targetPort
)
{
MiddlewareSymbol
sourceTag
=
sourcePort
.
getMiddlewareSymbol
().
orElse
(
null
);
MiddlewareSymbol
targetTag
=
targetPort
.
getMiddlewareSymbol
().
orElse
(
null
);
if
(
sourceTag
==
null
||
targetTag
==
null
||
!
sourceTag
.
isKindOf
(
RosConnectionSymbol
.
KIND
)
||
!
targetTag
.
isKindOf
(
RosConnectionSymbol
.
KIND
))
{
Log
.
debug
(
"Both sourcePort and targetPort need to have a RosConnectionSymbol"
,
"RosConnectionSymbol"
);
return
;
}
RosConnectionSymbol
sourceRosConnection
=
(
RosConnectionSymbol
)
sourceTag
;
RosConnectionSymbol
targetRosConnection
=
(
RosConnectionSymbol
)
targetTag
;
if
(
sourceRosConnection
.
getTopicName
().
isPresent
()
&&
!
targetRosConnection
.
getTopicName
().
isPresent
())
targetRosConnection
.
setTopicName
(
sourceRosConnection
.
getTopicName
().
get
());
if
(
sourceRosConnection
.
getTopicType
().
isPresent
()
&&
!
targetRosConnection
.
getTopicType
().
isPresent
())
targetRosConnection
.
setTopicType
(
sourceRosConnection
.
getTopicType
().
get
());
if
(
sourceRosConnection
.
getMsgField
().
isPresent
()
&&
!
targetRosConnection
.
getMsgField
().
isPresent
())
targetRosConnection
.
setMsgField
(
sourceRosConnection
.
getMsgField
().
get
());
}
private
Collection
<
ExpandedComponentInstanceSymbol
>
getSubComponentInstances
(
ExpandedComponentInstanceSymbol
componentInstanceSymbol
)
{
//TODO: check which subcomponents are mw only
//TODO: (build clusters?)
return
componentInstanceSymbol
.
getSubComponents
();
}
}
src/main/java/de/monticore/lang/monticar/generator/master/RosCppImpl.java
View file @
de3f01f5
...
...
@@ -2,7 +2,6 @@ package de.monticore.lang.monticar.generator.master;
import
de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ExpandedComponentInstanceSymbol
;
import
de.monticore.lang.monticar.generator.roscpp.GeneratorRosCpp
;
import
de.monticore.lang.monticar.generator.roscpp.helper.TagHelper
;
import
de.monticore.lang.tagging._symboltable.TaggingResolver
;
import
java.io.File
;
...
...
@@ -17,7 +16,7 @@ public class RosCppImpl implements GeneratorImpl {
GeneratorRosCpp
generatorRosCpp
=
new
GeneratorRosCpp
();
generatorRosCpp
.
setGenerateCMake
(
true
);
generatorRosCpp
.
setGenerationTargetPath
(
generationTargetPath
);
return
TagHelper
.
generate
(
generatorRosCpp
,
taggingResolver
,
componentInstanceSymbol
);
return
generatorRosCpp
.
generateFiles
(
componentInstanceSymbol
,
taggingResolver
);
}
@Override
...
...
src/main/java/de/monticore/lang/monticar/generator/master/RosMsgImpl.java
0 → 100644
View file @
de3f01f5
package
de.monticore.lang.monticar.generator.master
;
import
de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ExpandedComponentInstanceSymbol
;
import
de.monticore.lang.monticar.generator.rosmsg.GeneratorRosMsg
;
import
de.monticore.lang.monticar.generator.rosmsg.RosMsg
;
import
de.monticore.lang.monticar.ts.MCTypeSymbol
;
import
de.monticore.lang.monticar.ts.references.MCTypeReference
;
import
de.monticore.lang.tagging._symboltable.TaggingResolver
;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.List
;
public
class
RosMsgImpl
implements
GeneratorImpl
{
private
GeneratorRosMsg
generatorRosMsg
;
private
List
<
MCTypeReference
<?
extends
MCTypeSymbol
>>
rosTypesToGenerate
=
new
ArrayList
<>();
private
String
packageName
;
public
RosMsgImpl
(
String
packageName
)
{
this
.
packageName
=
packageName
;
generatorRosMsg
=
new
GeneratorRosMsg
();
}
@Override
public
List
<
File
>
generate
(
ExpandedComponentInstanceSymbol
componentInstanceSymbol
,
TaggingResolver
taggingResolver
)
throws
IOException
{
List
<
File
>
files
=
new
ArrayList
<>();
for
(
MCTypeReference
<?
extends
MCTypeSymbol
>
type
:
rosTypesToGenerate
)
{
files
.
addAll
(
generatorRosMsg
.
generate
(
type
));
}
return
files
;
}
@Override
public
void
setGenerationTargetPath
(
String
path
)
{
generatorRosMsg
.
setTarget
(
path
,
packageName
);
}
public
void
addRosTypeToGenerate
(
MCTypeReference
<?
extends
MCTypeSymbol
>
typeReference
)
{
rosTypesToGenerate
.
add
(
typeReference
);
}
public
RosMsg
getRosType
(
MCTypeReference
<?
extends
MCTypeSymbol
>
typeReference
)
{
return
generatorRosMsg
.
getRosType
(
typeReference
);
}
}
src/test/java/de/monticore/lang/monticar/generator/master/GenerationTest.java
View file @
de3f01f5
...
...
@@ -2,7 +2,9 @@ package de.monticore.lang.monticar.generator.master;
import
de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ExpandedComponentInstanceSymbol
;
import
de.monticore.lang.embeddedmontiarc.tagging.RosToEmamTagSchema
;
import
de.monticore.lang.monticar.generator.roscpp.helper.TagHelper
;
import
de.monticore.lang.tagging._symboltable.TaggingResolver
;
import
org.junit.Before
;
import
org.junit.Test
;
import
java.io.IOException
;
...
...
@@ -11,6 +13,11 @@ import static org.junit.Assert.assertNotNull;
public
class
GenerationTest
extends
AbstractSymtabTest
{
@Before
public
void
initTest
()
{
TagHelper
.
reset
();
}
@Test
public
void
testBasicGeneration
()
throws
IOException
{
TaggingResolver
taggingResolver
=
createSymTabAndTaggingResolver
(
"src/test/resources/"
);
...
...
@@ -18,6 +25,7 @@ public class GenerationTest extends AbstractSymtabTest {
ExpandedComponentInstanceSymbol
componentInstanceSymbol
=
taggingResolver
.<
ExpandedComponentInstanceSymbol
>
resolve
(
"tests.a.compA"
,
ExpandedComponentInstanceSymbol
.
KIND
).
orElse
(
null
);
assertNotNull
(
componentInstanceSymbol
);
TagHelper
.
resolveTags
(
taggingResolver
,
componentInstanceSymbol
);
MasterGenerator
masterGenerator
=
new
MasterGenerator
();
masterGenerator
.
setGenerationTargetPath
(
"./target/generated-sources/basicGeneration/"
);
...
...
@@ -34,6 +42,7 @@ public class GenerationTest extends AbstractSymtabTest {
ExpandedComponentInstanceSymbol
componentInstanceSymbol
=
taggingResolver
.<
ExpandedComponentInstanceSymbol
>
resolve
(
"tests.a.compA"
,
ExpandedComponentInstanceSymbol
.
KIND
).
orElse
(
null
);
assertNotNull
(
componentInstanceSymbol
);
TagHelper
.
resolveTags
(
taggingResolver
,
componentInstanceSymbol
);
MasterGenerator
masterGenerator
=
new
CMakeMasterGenerator
();
masterGenerator
.
setGenerationTargetPath
(
"./target/generated-sources/CMakeGeneration/"
);
...
...
@@ -50,6 +59,7 @@ public class GenerationTest extends AbstractSymtabTest {
ExpandedComponentInstanceSymbol
componentInstanceSymbol
=
taggingResolver
.<
ExpandedComponentInstanceSymbol
>
resolve
(
"tests.a.addComp"
,
ExpandedComponentInstanceSymbol
.
KIND
).
orElse
(
null
);
assertNotNull
(
componentInstanceSymbol
);
TagHelper
.
resolveTags
(
taggingResolver
,
componentInstanceSymbol
);
MasterGenerator
masterGenerator
=
new
MiddlewareMasterGenerator
();
masterGenerator
.
setGenerationTargetPath
(
"./target/generated-sources/middlewareMasterGenerator/src/"
);
...
...
@@ -58,7 +68,23 @@ public class GenerationTest extends AbstractSymtabTest {
masterGenerator
.
add
(
new
DummyMiddlewareGenerator
(),
"dummy"
);
masterGenerator
.
generate
(
componentInstanceSymbol
,
taggingResolver
);
}
@Test
public
void
testDistributedTargetGenerator
()
throws
IOException
{
TaggingResolver
taggingResolver
=
createSymTabAndTaggingResolver
(
"src/test/resources/"
);
RosToEmamTagSchema
.
registerTagTypes
(
taggingResolver
);
ExpandedComponentInstanceSymbol
componentInstanceSymbol
=
taggingResolver
.<
ExpandedComponentInstanceSymbol
>
resolve
(
"tests.dist.distComp"
,
ExpandedComponentInstanceSymbol
.
KIND
).
orElse
(
null
);
assertNotNull
(
componentInstanceSymbol
);
TagHelper
.
resolveTags
(
taggingResolver
,
componentInstanceSymbol
);
MasterGenerator
masterGenerator
=
new
DistributedTargetGenerator
(
"./target/generated-sources/distributed/src/"
);
masterGenerator
.
add
(
new
CPPImpl
(),
"cpp"
);
masterGenerator
.
add
(
new
RosCppImpl
(),
"roscpp"
);
masterGenerator
.
generate
(
componentInstanceSymbol
,
taggingResolver
);
}
}
src/test/resources/tests/dist/DistComp.emam
0 → 100644
View file @
de3f01f5
package
tests
.
dist
;
component
DistComp
{
component
SubComp1
{
ports
out
Q
out1
,
out
Q
out2
;
}
component
SubComp2
{
ports
in
Q
in1
,
in
Q
in2
;
}
instance
SubComp1
sub1
;
instance
SubComp2
sub2
;
connect
sub1
.
out1
->
sub2
.
in1
;
connect
sub1
.
out2
->
sub2
.
in2
;
}
\ No newline at end of file
src/test/resources/tests/dist/SimpleDist.tag
0 → 100644
View file @
de3f01f5
package
tests
.
dist
;
conforms
to
de
.
monticore
.
lang
.
monticar
.
generator
.
roscpp
.
RosToEmamTagSchema
;
tags
SimpleDist
{
tag
distComp
.
sub1
.
out1
with
RosConnection
=
{
topic
=
(
topicIn1
,
std_msgs
/
Float64
),
msgField
=
data
};
tag
distComp
.
sub1
.
out2
with
RosConnection
=
{
topic
=
(
topicIn2
,
std_msgs
/
Float64
),
msgField
=
data
};
tag
distComp
.
sub2
.
in1
with
RosConnection
=
{
topic
=
(
topicIn1
,
std_msgs
/
Float64
),
msgField
=
data
};
tag
distComp
.
sub2
.
in2
with
RosConnection
=
{
topic
=
(
topicIn2
,
std_msgs
/
Float64
),
msgField
=
data
};
}
\ No newline at end of file
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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