Skip to content

Commit e4f53e6

Browse files
ipa-rwuipa-nhg
authored andcommitted
Implement generator templates (Xtend) for RosSystem models to support
the new attribute ComponentStacks; the generation pipeline is consequently adapted
1 parent d222602 commit e4f53e6

7 files changed

Lines changed: 117 additions & 79 deletions

File tree

plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/CMakeListsCompiler.xtend

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@ package de.fraunhofer.ipa.rossystem.generator
22

33
import com.google.inject.Inject
44
import rossystem.RosSystem
5+
import rossystem.ComponentStack
56

67
class CMakeListsCompiler {
78

89
@Inject extension GeneratorHelpers
910

1011

11-
def compile_CMakeLists_ROS1(RosSystem system) '''«init_pkg()»
12+
def compile_CMakeLists_ROS1(RosSystem system, ComponentStack stack) '''«init_pkg()»
1213
cmake_minimum_required(VERSION 2.8.3)
13-
projectsystem.name.toLowerCase»)
14+
projectIF stack===null»«system.name.toLowerCase»«ELSE»«system.name.toLowerCase»_«stack.name.toLowerCase»«ENDIF»)
1415

1516
find_package(catkin REQUIRED)
1617

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package de.fraunhofer.ipa.rossystem.generator
2+
3+
import com.google.inject.Inject
4+
import rossystem.RosSystem
5+
import rossystem.ComponentStack
6+
7+
class DockerComposeCompiler {
8+
9+
@Inject extension GeneratorHelpers
10+
11+
def compile_toDockerCompose(RosSystem system) '''«init_pkg()»
12+
version: "3.3"
13+
networks:
14+
ros:
15+
driver: bridge
16+
17+
services:
18+
ros-master:
19+
image: ros:melodic-ros-core
20+
command: stdbuf -o L roscore
21+
networks:
22+
- ros
23+
24+
«FOR stack:system.componentStack»
25+
«" "»«system.name.toLowerCase»_«stack.name.toLowerCase»:
26+
image: "«system.name.toLowerCase»_«stack.name.toLowerCase»:latest"
27+
depends_on:
28+
- ros-master
29+
environment:
30+
- "ROS_MASTER_URI=http://ros-master:11311"
31+
- "ROS_HOSTNAME=«stack.name.toLowerCase»"
32+
networks:
33+
- ros
34+
command: stdbuf -o L roslaunch «system.name.toLowerCase»_«stack.name.toLowerCase» «stack.name.toLowerCase».launch --wait
35+
36+
«ENDFOR»
37+
38+
'''
39+
}

plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/DockerContainerCompiler.xtend

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,21 @@ package de.fraunhofer.ipa.rossystem.generator
22

33
import com.google.inject.Inject
44
import rossystem.RosSystem
5+
import rossystem.ComponentStack
56

67
class DockerContainerCompiler {
78

89
@Inject extension GeneratorHelpers
910

10-
def compile_toDockerContainer(RosSystem system) '''«init_pkg()»
11+
def compile_toDockerContainer(RosSystem system, ComponentStack stack) '''«init_pkg()»
1112
# syntax=docker/dockerfile:experimental
1213
ARG SUFFIX=
1314
ARG PREFIX=
1415
FROM ros:melodic-ros-core as base
1516
FROM ${PREFIX}builder${SUFFIX} as builder
1617

1718
FROM base as build
18-
COPY . /root/ws/src/«system.name.toLowerCase»/
19+
COPY . /root/ws/src/«IF stack===null»«system.name.toLowerCase»«ELSE»«system.name.toLowerCase»_«stack.name.toLowerCase»«ENDIF»/
1920
RUN --mount=type=bind,from=builder,target=/builder \
2021
apt-get update -qq && \
2122
/builder/workspace.bash build_workspace /root/ws && \
@@ -47,7 +48,7 @@ RUN --mount=type=bind,from=builder,target=/builder --mount=type=bind,target=/roo
4748
COPY --from=install /opt/ros/$ROS_DISTRO /opt/ros/$ROS_DISTRO
4849
4950
FROM deploy as launch
50-
CMD ["roslaunch", "«system.name»", "«system.name».launch"]
51+
«IF stack===null»CMD ["roslaunch", "«system.name»", "«system.name».launch"]«ELSE»CMD ["roslaunch", "«system.name.toLowerCase»_«stack.name.toLowerCase»", "«stack.name.toLowerCase».launch"]«ENDIF»
5152
'''
5253
5354
}

plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/GeneratorHelpers.xtend

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import rossystem.RosSystem
1313
import java.util.List
1414
import ros.Node
1515
import ros.impl.PackageImpl
16+
import rossystem.ComponentStack
1617

1718
class GeneratorHelpers {
1819

@@ -21,14 +22,30 @@ class GeneratorHelpers {
2122
PackageImpl package_impl
2223
List<CharSequence> PkgsList
2324
String Pkg
25+
List<ComponentInterface> ComponentsList
2426

2527
def void init_pkg(){
2628
PackageSet=false
2729
}
30+
31+
def <String> getPkgsDependencies (RosSystem rossystem, ComponentStack stack){
32+
if (stack===null){
33+
return getPkgsDependencies(rossystem)
34+
} else {
35+
return getPkgsDependencies(stack)
36+
}
37+
}
2838

29-
def <String> getPkgsDependencies(RosSystem rossystem){
39+
def <String> getPkgsDependencies(Object subsystem){
3040
PkgsList = new ArrayList()
31-
for (component:rossystem.rosComponent){
41+
ComponentsList = new ArrayList<ComponentInterface>();
42+
43+
if (subsystem.class.toString.contains("RosSystemImpl")){
44+
ComponentsList = (subsystem as RosSystem).rosComponent
45+
} else if (subsystem.class.toString.contains("ComponentStackImpl")) {
46+
ComponentsList = (subsystem as ComponentStack).rosComponent
47+
}
48+
for (component:ComponentsList){
3249
init_pkg()
3350
Pkg = component.compile_pkg.toString()
3451
if (!PkgsList.contains(Pkg)){

plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/LaunchFileCompiler_ROS1.xtend

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import componentInterface.RosServiceClient
1818
import componentInterface.RosActionClient
1919
import rossystem.ActionConnection
2020
import componentInterface.RosActionServer
21+
import rossystem.ComponentStack
2122

2223
class LaunchFileCompiler_ROS1 {
2324
@Inject extension GeneratorHelpers
@@ -29,13 +30,16 @@ class LaunchFileCompiler_ROS1 {
2930
String tab_tmp=""
3031
List<Integer> sizes_list = new ArrayList<Integer>();
3132
List<EObject> param_list = new ArrayList<EObject>();
33+
List<ComponentInterface> components = new ArrayList<ComponentInterface>();
34+
3235

3336
int i=0;
3437
int k=0;
3538

36-
def compile_toROS1launch(RosSystem system) '''«init_comp()»
39+
def compile_toROS1launch(RosSystem system, ComponentStack stack) '''«init_comp()»
3740
<?xml version="1.0"?>
3841
<launch>
42+
«IF stack===null»
3943
«FOR ROSParameter:system.parameter»
4044
«IF ROSParameter.type.toString.contains("ParameterStructType")»
4145
<rosparam>
@@ -56,41 +60,11 @@ class LaunchFileCompiler_ROS1 {
5660
«ELSE»
5761
<param name="«ROSParameter.name»" value="«compile_param_value(ROSParameter.value)»"/>
5862
«ENDIF»
59-
«ENDFOR»
60-
««« «FOR component:system.rosComponent»
61-
««« «FOR rosPublisher:component.rospublisher»
62-
««« «IF component.hasNS»«IF !rosPublisher.name.equals(compile_topic_name(rosPublisher.publisher,component.get_ns()))»
63-
««« <remap from=«compile_topic_name(rosPublisher.publisher,component.get_ns())» to=«rosPublisher.name» />
64-
««« «ENDIF»«ENDIF»
65-
««« «ENDFOR»
66-
««« «FOR rosSubscriber:component.rossubscriber»
67-
««« «IF component.hasNS»«IF !rosSubscriber.name.equals(compile_topic_name(rosSubscriber.subscriber,component.get_ns()))»
68-
««« <remap from=«compile_topic_name(rosSubscriber.subscriber,component.get_ns())» to=«rosSubscriber.name» />
69-
««« «ENDIF»«ENDIF»
70-
««« «ENDFOR»
71-
««« «FOR rosServiceServer:component.rosserviceserver»
72-
««« «IF component.hasNS»«IF !rosServiceServer.name.equals(compile_service_name(rosServiceServer.srvserver,component.get_ns()))»
73-
««« <remap from=«compile_service_name(rosServiceServer.srvserver,component.get_ns())» to=«rosServiceServer.name» />
74-
««« «ENDIF»«ENDIF»
75-
««« «ENDFOR»
76-
««« «FOR rosServiceClient:component.rosserviceclient»
77-
««« «IF component.hasNS»«IF !rosServiceClient.name.equals(compile_service_name(rosServiceClient.srvclient,component.get_ns()))»
78-
««« <remap from=«compile_service_name(rosServiceClient.srvclient,component.get_ns())» to=«rosServiceClient.name» />
79-
««« «ENDIF»«ENDIF»
80-
««« «ENDFOR»
81-
««« «FOR rosActionServer:component.rosactionserver»
82-
««« «IF component.hasNS»«IF !rosActionServer.name.equals(compile_action_name(rosActionServer.actserver,component.get_ns()))»
83-
««« <remap from=«compile_action_name(rosActionServer.actserver,component.get_ns())» to=«rosActionServer.name» />
84-
««« «ENDIF»«ENDIF»
85-
««« «ENDFOR»
86-
««« «FOR rosActionClient:component.rosactionclient»
87-
««« «IF component.hasNS»«IF !rosActionClient.name.equals(compile_action_name(rosActionClient.actclient,component.get_ns()))»
88-
««« <remap from=«compile_action_name(rosActionClient.actclient,component.get_ns())» to=«rosActionClient.name» />
89-
««« «ENDIF»«ENDIF»
90-
««« «ENDFOR»
91-
««« «ENDFOR»
63+
«ENDFOR»«ELSE»«FOR qa:stack.qualityAttribute»
64+
<param name="«qa.name»" value="«compile_param_value(qa.value)»"/>
65+
«ENDFOR»«ENDIF»
9266

93-
«FOR component:system.rosComponent»
67+
«FOR component:compile_list_of_components(system,stack)»
9468
<node pkg="«component.compile_pkg»«init_pkg»" type="«component.compile_art»«init_comp()»" name="«component.name»"«IF component.hasNS» ns="«component.get_ns»"«ENDIF» cwd="node" respawn="false" output="screen">«init_comp()»«init_pkg»
9569
«FOR rosPublisher:component.rospublisher»
9670
«remapping_function_pub(rosPublisher, component.hasNS, inTopicFromConnection(rosPublisher, system.topicConnections),component.check_ns)»
@@ -128,6 +102,16 @@ class LaunchFileCompiler_ROS1 {
128102
</launch>
129103
'''
130104

105+
def List<ComponentInterface> compile_list_of_components(RosSystem system, ComponentStack stack) {
106+
components=null;
107+
if (stack === null){
108+
components = system.rosComponent;
109+
} else {
110+
components = stack.rosComponent;
111+
}
112+
return components;
113+
}
114+
131115
// TOPICS REMAP
132116
def String remapping_function_pub(RosPublisher rosPublisher, boolean HasNS, String inConnection, String NS) {
133117
if(inConnection!==null){

plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/PackageXmlCompiler.xtend

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,21 @@ package de.fraunhofer.ipa.rossystem.generator
22

33
import rossystem.RosSystem
44
import com.google.inject.Inject
5+
import rossystem.ComponentStack
6+
import java.util.List
7+
import java.util.ArrayList
58

69
class PackageXmlCompiler{
710

811
@Inject extension GeneratorHelpers
12+
List<CharSequence> depends_list
913

1014

11-
def compile_package_xml_format2(RosSystem system) '''«init_pkg()»
15+
def compile_package_xml_format2(RosSystem system,ComponentStack stack) '''«init_pkg()»
1216
<package format="2">
13-
<name>«system.name.toLowerCase»</name>
17+
<name>«IF stack===null»«system.name.toLowerCase»«ELSE»«system.name.toLowerCase»_«stack.name.toLowerCase»«ENDIF»</name>
1418
<version>0.0.1</version>
15-
<description>This package provides launch file for operating «system.name»</description>
19+
<description>This package provides launch file for operating «IF stack===null»«system.name»«ELSE»«system.name.toLowerCase»_«stack.name»«ENDIF»</description>
1620

1721
<license>Apache 2.0</license>
1822

@@ -22,15 +26,15 @@ class PackageXmlCompiler{
2226
<maintainer email="jane.doe@example.com">Jane Doe</maintainer>
2327
<author email="jane.doe@example.com">Jane Doe</author>
2428

25-
2629
<buildtool_depend>catkin</buildtool_depend>
27-
«FOR pkg:system.getPkgsDependencies»
30+
«FOR pkg:getPkgsDependencies(system, stack)»
2831
<exec_depend>«pkg»</exec_depend>
2932
«ENDFOR»
3033
<!--test_depend>roslaunch</test_depend-->
3134

3235
</package>'''
3336

37+
3438
def compile_package_xml_format3(RosSystem system) '''«init_pkg()»
3539
<?xml version="1.0"?>
3640
<?xml-model

plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/RosSystemGenerator.xtend

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ class RosSystemGenerator extends AbstractGenerator {
4646
@Inject extension LaunchFileCompiler_ROS1
4747
@Inject extension LaunchFileCompiler_ROS2
4848
@Inject extension SetupPyCompile
49+
@Inject extension DockerComposeCompiler
4950
@Inject extension DockerContainerCompiler
50-
5151
//@Inject extension InstallScriptCompiler
5252

5353

@@ -60,41 +60,33 @@ class RosSystemGenerator extends AbstractGenerator {
6060
// }
6161

6262

63-
// ROS1 package
64-
for (system : resource.allContents.toIterable.filter(RosSystem)){
65-
fsa.generateFile(system.getName().toLowerCase+"/launch/"+system.getName()+".launch",system.compile_toROS1launch.toString().replace("\t"," "))
66-
}
67-
for (system : resource.allContents.toIterable.filter(RosSystem)){
68-
fsa.generateFile(system.getName().toLowerCase+"/package.xml",system.compile_package_xml_format2)
69-
}
63+
// ROS1 package with docker composition for component Stacks
7064
for (system : resource.allContents.toIterable.filter(RosSystem)){
71-
fsa.generateFile(system.getName().toLowerCase+"/CMakeLists.txt",system.compile_CMakeLists_ROS1)
72-
}
73-
for (system : resource.allContents.toIterable.filter(RosSystem)){
74-
fsa.generateFile(system.getName().toLowerCase+"/Dockerfile",system.compile_toDockerContainer)
75-
}
65+
if (system.componentStack.size==0){
66+
fsa.generateFile(system.getName().toLowerCase+"/package.xml",compile_package_xml_format2(system, null))
67+
fsa.generateFile(system.getName().toLowerCase+"/CMakeLists.txt",compile_CMakeLists_ROS1(system, null))
68+
fsa.generateFile(system.getName().toLowerCase+"/launch/"+system.getName()+".launch",compile_toROS1launch(system, null).toString().replace("\t"," "))
69+
fsa.generateFile(system.getName().toLowerCase+"/Dockerfile",compile_toDockerContainer(system, null))
70+
} else {
71+
for (stack : system.componentStack){
72+
fsa.generateFile(String.join("/", system.getName().toLowerCase, system.name.toLowerCase+'_'+stack.name.toLowerCase, "package.xml"),compile_package_xml_format2(system, stack))
73+
fsa.generateFile(String.join("/", system.getName().toLowerCase, system.name.toLowerCase+'_'+stack.name.toLowerCase, "CMakeLists.txt"),compile_CMakeLists_ROS1(system, stack))
74+
fsa.generateFile(String.join("/", system.getName().toLowerCase, system.name.toLowerCase+'_'+stack.name.toLowerCase, "launch", stack.getName()+".launch"), compile_toROS1launch(system, stack).toString().replace("\t"," "))
75+
fsa.generateFile(String.join("/", system.getName().toLowerCase, system.name.toLowerCase+'_'+stack.name.toLowerCase, "Dockerfile"),compile_toDockerContainer(system, stack))
76+
}
77+
fsa.generateFile(String.join("/", system.getName().toLowerCase, "docker-compose.yml"),compile_toDockerCompose(system))
78+
}
79+
}
7680

7781
//ROS2 package
7882
for (system : resource.allContents.toIterable.filter(RosSystem)){
79-
fsa.generateFile(system.getName().toLowerCase+"_ros2/launch/"+system.getName()+".launch.py",system.compile_toROS2launch.toString().replace("\t"," "))
80-
}
81-
for (system : resource.allContents.toIterable.filter(RosSystem)){
82-
fsa.generateFile(system.getName().toLowerCase+"_ros2/package.xml",system.compile_package_xml_format3)
83-
}
84-
for (system : resource.allContents.toIterable.filter(RosSystem)){
85-
fsa.generateFile(system.getName().toLowerCase+"_ros2/setup.py",system.compile_setup_py)
86-
}
87-
for (system : resource.allContents.toIterable.filter(RosSystem)){
88-
fsa.generateFile(system.getName().toLowerCase+"_ros2/resource/" + system.getName().toLowerCase, "")
89-
}
90-
for (system : resource.allContents.toIterable.filter(RosSystem)){
91-
fsa.generateFile(system.getName().toLowerCase+"_ros2/" + system.getName().toLowerCase + "/__init__.py", "")
92-
}
93-
// for (system : resource.allContents.toIterable.filter(RosSystem)){
94-
// fsa.generateFile(system.getName().toLowerCase+"_ros2/CMakeLists.txt",system.compile_CMakeLists_ROS2)
95-
// }
96-
97-
83+
fsa.generateFile(system.getName().toLowerCase+"_ros2/launch/"+system.getName()+".launch.py",system.compile_toROS2launch.toString().replace("\t"," "))
84+
fsa.generateFile(system.getName().toLowerCase+"_ros2/package.xml",system.compile_package_xml_format3)
85+
fsa.generateFile(system.getName().toLowerCase+"_ros2/setup.py",system.compile_setup_py)
86+
fsa.generateFile(system.getName().toLowerCase+"_ros2/resource/" + system.getName().toLowerCase, "")
87+
fsa.generateFile(system.getName().toLowerCase+"_ros2/" + system.getName().toLowerCase + "/__init__.py", "")
88+
fsa.generateFile(system.getName().toLowerCase+"_ros2/CMakeLists.txt",system.compile_CMakeLists_ROS2)
89+
}
9890
}
9991
}
10092

0 commit comments

Comments
 (0)