Skip to content

Commit a0da77a

Browse files
committed
First draft for a working version of the code generator for ROS2 launch files
1 parent 1deda5d commit a0da77a

6 files changed

Lines changed: 351 additions & 14 deletions

File tree

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package de.fraunhofer.ipa.rossystem.generator
2+
3+
import com.google.inject.Inject
4+
import system.System
5+
6+
class CMakeListsCompiler {
7+
8+
@Inject extension GeneratorHelpers
9+
10+
11+
// def compile_CMakeLists_ROS1(RosSystem system, ComponentStack stack) '''«init_pkg()»
12+
//cmake_minimum_required(VERSION 2.8.3)
13+
//project(«IF stack===null»«system.name.toLowerCase»«ELSE»«system.name.toLowerCase»_«stack.name.toLowerCase»«ENDIF»)
14+
//
15+
//find_package(catkin REQUIRED)
16+
//
17+
//catkin_package()
18+
//
19+
//
20+
//### INSTALL ###
21+
//install(DIRECTORY launch
22+
// DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
23+
//)'''
24+
25+
def compile_CMakeLists_ROS2(System system) '''«init_pkg()»
26+
cmake_minimum_required(VERSION 3.5)
27+
projectsystem.name.toLowerCase»)
28+
29+
# Default to C++14
30+
if(NOT CMAKE_CXX_STANDARD)
31+
set(CMAKE_CXX_STANDARD 14)
32+
endif()
33+
34+
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
35+
add_compile_options(-Wall -Wextra -Wpedantic)
36+
endif()
37+
38+
find_package(ament_cmake REQUIRED)
39+
40+
### INSTALL ###
41+
install(DIRECTORY launch
42+
DESTINATION share/${PROJECT_NAME}
43+
)
44+
45+
ament_package()
46+
'''
47+
48+
49+
}
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
package de.fraunhofer.ipa.rossystem.generator
2+
3+
import java.util.ArrayList
4+
import ros.ActionClient
5+
import ros.ActionServer
6+
import ros.Parameter
7+
import ros.Publisher
8+
import ros.ServiceClient
9+
import ros.ServiceServer
10+
import ros.Subscriber
11+
import system.System
12+
import java.util.List
13+
import ros.Node
14+
import ros.impl.PackageImpl
15+
import org.eclipse.emf.ecore.EObject
16+
import java.util.Set
17+
import java.util.HashSet
18+
import ros.Dependency
19+
import ros.PackageDependency
20+
import system.Component
21+
import system.RosNode
22+
import ros.impl.AmentPackageImpl
23+
24+
class GeneratorHelpers {
25+
26+
boolean PackageSet
27+
28+
AmentPackageImpl package_impl
29+
List<CharSequence> PkgsList
30+
String Pkg
31+
RosNode node
32+
33+
def void init_pkg(){
34+
PackageSet=false
35+
}
36+
37+
def <String> getPkgsDependencies (System rossystem){
38+
PkgsList = new ArrayList()
39+
for (component: rossystem.components){
40+
init_pkg()
41+
node = component as RosNode
42+
Pkg = node.compile_pkg.toString()
43+
if (!PkgsList.contains(Pkg)){
44+
PkgsList.add(Pkg)
45+
}
46+
return PkgsList;
47+
}
48+
49+
}
50+
51+
def compile_pkg(RosNode component)
52+
'''«IF !(component.from===null)»«component.from.getPackage_node.name»«ENDIF»'''
53+
54+
// def PackageImpl get_pkg(ComponentInterface component) {
55+
// if (component.fromRosNode!==null){
56+
// return getPackage_node(component.fromRosNode)
57+
// } else if(!component.rospublisher.empty){
58+
// return getPacakge_fromObject(component.rospublisher.get(0).publisher)
59+
// } else if (!component.rossubscriber.empty){
60+
// return getPacakge_fromObject(component.rossubscriber.get(0).subscriber)
61+
// } else if (!component.rosserviceclient.empty){
62+
// return getPacakge_fromObject(component.rosserviceclient.get(0).srvclient)
63+
// } else if (!component.rosserviceserver.empty){
64+
// return getPacakge_fromObject(component.rosserviceserver.get(0).srvserver)
65+
// } else if (!component.rosactionclient.empty){
66+
// return getPacakge_fromObject(component.rosactionclient.get(0).actclient)
67+
// } else if (!component.rosactionserver.empty){
68+
// return getPacakge_fromObject(component.rosactionserver.get(0).actserver)
69+
// } else if (!component.rosparameter.empty){
70+
// return getPacakge_fromObject(component.rosparameter.get(0).parameter)
71+
// }
72+
// }
73+
//
74+
// def getPacakge_fromObject (EObject object){
75+
// package_impl = object.eContainer.eContainer.eContainer as PackageImpl;
76+
// return package_impl;
77+
// }
78+
//
79+
// def getPackage_pub(Publisher publisher){
80+
// package_impl = publisher.eContainer.eContainer.eContainer as PackageImpl;
81+
// return package_impl;
82+
// }
83+
// def getPackage_sub(Subscriber subscriber){
84+
// package_impl = subscriber.eContainer.eContainer.eContainer as PackageImpl;
85+
// return package_impl;
86+
// }
87+
// def getPackage_srvserv(ServiceServer serviceserver){
88+
// package_impl = serviceserver.eContainer.eContainer.eContainer as PackageImpl;
89+
// return package_impl;
90+
// }
91+
// def getPackage_srvcli(ServiceClient serviceclient){
92+
// package_impl = serviceclient.eContainer.eContainer.eContainer as PackageImpl;
93+
// return package_impl;
94+
// }
95+
// def getPackage_actserver(ActionServer actionserver){
96+
// package_impl = actionserver.eContainer.eContainer.eContainer as PackageImpl;
97+
// return package_impl;
98+
// }
99+
// def getPackage_actclient(ActionClient actionclient){
100+
// package_impl = actionclient.eContainer.eContainer.eContainer as PackageImpl;
101+
// return package_impl;
102+
// }
103+
// def getPackage_rosparam (Parameter param){
104+
// package_impl = param.eContainer.eContainer.eContainer as PackageImpl;
105+
// return package_impl;
106+
// }
107+
def getPackage_node (Node node){
108+
package_impl = node.eContainer.eContainer as AmentPackageImpl;
109+
return package_impl;
110+
}
111+
112+
//Launch files generators
113+
// def check_ns(ComponentInterface component){
114+
// if (component.hasNS){
115+
// return component.get_ns();
116+
// }else {
117+
// return "";
118+
// }
119+
// }
120+
// def boolean hasNS(ComponentInterface component){
121+
// if(!component.nameSpace.nullOrEmpty){
122+
// return true;
123+
// }else{
124+
// return false
125+
// }
126+
// }
127+
// def String get_ns(ComponentInterface component){
128+
// return component.nameSpace.replaceFirst("/","");
129+
// }
130+
//
131+
// def compile_pkg_type(ComponentInterface component)
132+
//'''«IF !(component.fromRosNode===null) »«component.fromRosNode.getPackageType_node»«ELSEIF !PackageSet && !component.rospublisher.empty»«FOR Rospublisher:component.rospublisher»«IF !PackageSet»«Rospublisher.publisher.getPackageType_pub()»«ENDIF»«ENDFOR»«ELSEIF !PackageSet && !component.rossubscriber.empty»«FOR Rossubscriber:component.rossubscriber»«IF !PackageSet»«Rossubscriber.subscriber.getPackageType_sub()»«ENDIF»«ENDFOR»«ELSEIF !PackageSet && !component.rosserviceserver.empty»«FOR Rosserviceserver:component.rosserviceserver»«IF !PackageSet»«Rosserviceserver.srvserver.getPackageType_srvserv()»«ENDIF»«ENDFOR»«ELSEIF !PackageSet && !component.rosserviceclient.empty»«FOR Rosserviceclient:component.rosserviceclient»«IF !PackageSet»«Rosserviceclient.srvclient.getPackageType_srvcli()»«ENDIF»«ENDFOR»«ELSEIF !PackageSet && !component.rosparameter.empty»«FOR Rosparameter:component.rosparameter»«IF !PackageSet»«Rosparameter.parameter.getPackageType_rosparam()»«ENDIF»«ENDFOR»«ELSEIF !PackageSet && !component.rosactionserver.empty»«FOR RosActionSever:component.rosactionserver»«IF !PackageSet»«RosActionSever.actserver.getPackageType_actserver()»«ENDIF»«ENDFOR»«ELSEIF !PackageSet && !component.rosactionclient.empty»«FOR RosActionClient:component.rosactionclient»«IF !PackageSet»«RosActionClient.actclient.getPackageType_actclient()»«ENDIF»«ENDFOR»«ENDIF»'''
133+
//
134+
// def getPackageType_pub(Publisher publisher){
135+
// return publisher.eContainer.eContainer.eContainer as PackageImpl;
136+
// }
137+
// def getPackageType_sub(Subscriber subscriber){
138+
// return subscriber.eContainer.eContainer.eContainer as PackageImpl;
139+
// }
140+
// def getPackageType_srvserv(ServiceServer serviceserver){
141+
// return serviceserver.eContainer.eContainer.eContainer as PackageImpl;
142+
// }
143+
// def getPackageType_srvcli(ServiceClient serviceclient){
144+
// return serviceclient.eContainer.eContainer.eContainer as PackageImpl;
145+
// }
146+
// def getPackageType_actserver(ActionServer actionserver){
147+
// return actionserver.eContainer.eContainer.eContainer as PackageImpl;
148+
// }
149+
// def getPackageType_actclient(ActionClient actionclient){
150+
// return actionclient.eContainer.eContainer.eContainer as PackageImpl;
151+
// }
152+
// def getPackageType_rosparam (Parameter param){
153+
// return param.eContainer.eContainer.eContainer as PackageImpl;
154+
// }
155+
// def getPackageType_node (Node node){
156+
// return node.eContainer.eContainer as PackageImpl;
157+
// }
158+
159+
160+
}

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

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,39 @@ package de.fraunhofer.ipa.rossystem.generator
33
import system.RosNode
44
import ros.RosPackage
55
import ros.Artifact
6-
import system.Rossystem
6+
import system.System
7+
import ros.AmentPackage
8+
import ros.impl.AmentPackageImpl
79

810
class LaunchFileCompiler_ROS2 {
911

1012

11-
def compile_toROS2launch(Rossystem system) '''
13+
def compile_toROS2launch(System system) '''
1214
from launch import LaunchDescription
1315
from launch_ros.actions import Node
1416

1517
def generate_launch_description():
1618
ld = LaunchDescription()
1719

18-
«FOR component:system.components»«IF component.eClass=="RosNode"»
20+
«FOR component:system.components»
1921
«(component as RosNode).name» = Node(
20-
package="«((component as RosNode).from.eContainer.eContainer as RosPackage).name»",
22+
package="«((component as RosNode).from.eContainer.eContainer as AmentPackageImpl).name»",
2123
executable="«((component as RosNode).from.eContainer as Artifact).name»",
2224
name="«(component as RosNode).name»"
2325
)
24-
«ENDIF»
26+
2527
«ENDFOR»
2628

27-
«FOR component:system.components»«IF component.eClass=="RosNode"»
29+
«FOR component:system.components»
2830
ld.add_action(«(component as RosNode).name»)
29-
«ENDIF»
3031
«ENDFOR»
3132

3233
return ld
3334
'''
3435

3536
// def void compile_list_of_ROS2components(RosSystem system, ComponentStack stack) {
3637
// components_tmp_.clear;
37-
// Ros2components.clear;
38+
// Ros2components.clear;
3839
// if (stack === null){
3940
// components_tmp_ = system.rosComponent;
4041
// } else {
@@ -123,7 +124,7 @@ def generate_launch_description():
123124
// } else {
124125
// param_str += "{ \"" + rosParameter.parameter.name + "\" : " + get_param_value(rosParameter.value, rosParameter.parameter.name);
125126
// }
126-
// if (param_count > 1){
127+
// if (param_count > 1){
127128
// param_str +=" },\n"
128129
// } else {
129130
// param_str +=" }\n";
@@ -145,7 +146,7 @@ def generate_launch_description():
145146
// param_str += "{ \"" + name + "/" + member.getName() + "\" : " + param_val;
146147
// }
147148
// elem_count--;
148-
// if (elem_count > 0){
149+
// if (elem_count > 0){
149150
// param_str +=" },\n"
150151
// }
151152
// }
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package de.fraunhofer.ipa.rossystem.generator
2+
3+
import system.System
4+
import com.google.inject.Inject
5+
6+
class PackageXmlCompiler{
7+
8+
@Inject extension GeneratorHelpers
9+
10+
// def compile_package_xml_format2(System system) '''«init_pkg()»
11+
//<package format="2">
12+
// <name>«IF stack===null»«system.name.toLowerCase»«ELSE»«system.name.toLowerCase»_«stack.name.toLowerCase»«ENDIF»</name>
13+
// <version>0.0.1</version>
14+
// <description>This package provides launch file for operating «IF stack===null»«system.name»«ELSE»«system.name.toLowerCase»_«stack.name»«ENDIF»</description>
15+
//
16+
// <license>Apache 2.0</license>
17+
//
18+
// <url type="website">http://wiki.ros.org/</url>
19+
//
20+
//
21+
// <maintainer email="jane.doe@example.com">Jane Doe</maintainer>
22+
// <author email="jane.doe@example.com">Jane Doe</author>
23+
//
24+
// <buildtool_depend>catkin</buildtool_depend>
25+
// «FOR pkg:getPkgsDependencies(system, stack)»
26+
// <exec_depend>«pkg»</exec_depend>
27+
// «ENDFOR»
28+
// <!--test_depend>roslaunch</test_depend-->
29+
//
30+
//</package>'''
31+
32+
33+
def compile_package_xml_format3(System system) '''«init_pkg()»
34+
<?xml version="1.0"?>
35+
<?xml-model
36+
href="http://download.ros.org/schema/package_format3.xsd"
37+
schematypens="http://www.w3.org/2001/XMLSchema"?>
38+
<package format="3">
39+
<name>«system.name.toLowerCase»</name>
40+
<version>0.0.1</version>
41+
<description>This package provides launch file for operating «system.name»</description>
42+
<maintainer email="jane.doe@example.com">Jane Doe</maintainer>
43+
<author email="jane.doe@example.com">Jane Doe</author>
44+
<license>Apache 2.0</license>
45+
46+
<buildtool_depend>ament_cmake</buildtool_depend>
47+
48+
<exec_depend>ament_index_python</exec_depend>
49+
<exec_depend>launch</exec_depend>
50+
«FOR pkg:system.getPkgsDependencies»
51+
<exec_depend>«pkg»</exec_depend>
52+
«ENDFOR»
53+
54+
<!--test_depend>ament_copyright</test_depend>
55+
<test_depend>ament_flake8</test_depend>
56+
<test_depend>ament_pep257</test_depend>
57+
<test_depend>launch</test_depend>
58+
<test_depend>python3-pytest</test_depend-->
59+
60+
<export>
61+
<build_type>ament_python</build_type>
62+
</export>
63+
</package>
64+
'''
65+
66+
67+
}

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

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import org.eclipse.emf.ecore.resource.Resource
77
import org.eclipse.xtext.generator.AbstractGenerator
88
import org.eclipse.xtext.generator.IFileSystemAccess2
99
import org.eclipse.xtext.generator.IGeneratorContext
10+
import system.System
1011
import com.google.inject.Inject
11-
import system.Rossystem
1212

1313
/**
1414
* Generates code from your model files on save.
@@ -17,10 +17,36 @@ import system.Rossystem
1717
*/
1818
class RosSystemGenerator extends AbstractGenerator {
1919
@Inject extension LaunchFileCompiler_ROS2
20-
20+
@Inject extension SetupPyCompiler
21+
@Inject extension PackageXmlCompiler
22+
@Inject extension CMakeListsCompiler
23+
2124
override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
22-
for (system : resource.allContents.toIterable.filter(Rossystem)){
23-
fsa.generateFile(system.getName().toLowerCase+"_ros2/launch/"+system.getName()+".launch.py",compile_toROS2launch(system).toString().replace("\t"," "))
25+
for (system : resource.allContents.toIterable.filter(System)){
26+
fsa.generateFile(
27+
system.getName().toLowerCase+"_ros2/launch/"+system.getName()+".launch.py",
28+
compile_toROS2launch(system).toString().replace("\t"," ")
29+
)
30+
fsa.generateFile(
31+
system.getName().toLowerCase+"_ros2/package.xml",
32+
compile_package_xml_format3(system)
33+
)
34+
fsa.generateFile(
35+
system.getName().toLowerCase+"_ros2/CMakeLists.txt",
36+
compile_CMakeLists_ROS2(system)
37+
)
38+
fsa.generateFile(
39+
system.getName().toLowerCase+"_ros2/setup.py",
40+
compile_setup_py(system)
41+
)
42+
fsa.generateFile(
43+
system.getName().toLowerCase+"_ros2/resource/" + system.getName().toLowerCase,
44+
""
45+
)
46+
fsa.generateFile(
47+
system.getName().toLowerCase+"_ros2/" + system.getName().toLowerCase + "/__init__.py",
48+
""
49+
)
2450
}
2551
}
2652
}

0 commit comments

Comments
 (0)