Skip to content

Commit faa441b

Browse files
authored
Merge pull request #130 from ipa-nhg/Ros2CppNode
Cpp code genrators for ROS2 nodes
2 parents 42a7161 + 8dbbac9 commit faa441b

9 files changed

Lines changed: 303 additions & 26 deletions

File tree

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
cmake_minimum_required(VERSION 3.5)
2+
project(test_pkg)
3+
4+
# Default to C++14
5+
if(NOT CMAKE_CXX_STANDARD)
6+
set(CMAKE_CXX_STANDARD 14)
7+
endif()
8+
9+
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
10+
add_compile_options(-Wall -Wextra -Wpedantic)
11+
endif()
12+
13+
find_package(ament_cmake REQUIRED)
14+
find_package(Boost REQUIRED)
15+
find_package(rclcpp REQUIRED)
16+
find_package(std_srvs REQUIRED)
17+
find_package(sensor_msgs REQUIRED)
18+
19+
add_executable(test_node src/test_node.cpp)
20+
ament_target_dependencies(test_node rclcpp std_srvs sensor_msgs )
21+
22+
install(TARGETS
23+
test_node
24+
DESTINATION lib/${PROJECT_NAME})
25+
26+
ament_package()
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0"?>
2+
<?xml-model
3+
href="http://download.ros.org/schema/package_format3.xsd"
4+
schematypens="http://www.w3.org/2001/XMLSchema"?>
5+
<package format="3">
6+
<name>test_pkg</name>
7+
<version>0.0.0</version>
8+
<description>This package contains the implementation of the node test_node</description>
9+
<maintainer email="jane.doe@example.com">Jane Doe</maintainer>
10+
<author email="jane.doe@example.com">Jane Doe</author>
11+
<license>Apache 2.0</license>
12+
13+
<buildtool_depend>ament_cmake</buildtool_depend>
14+
15+
<depend>boost</depend>
16+
<depend>rclcpp</depend>
17+
<depend>std_srvs</depend>
18+
<depend>sensor_msgs</depend>
19+
20+
<test_depend>ament_lint_auto</test_depend>
21+
<test_depend>ament_lint_common</test_depend>
22+
23+
<export>
24+
<build_type>ament_cmake</build_type>
25+
</export>
26+
</package>

plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/ros2generator/test_node.cpp renamed to plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/ros2generator/test_pkg/src/test_node.cpp

File renamed without changes.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
cmake_minimum_required(VERSION 3.0.2)
2+
project(test_pkg)
3+
4+
find_package(catkin REQUIRED COMPONENTS roscpp std_srvs sensor_msgs )
5+
6+
catkin_package(
7+
CATKIN_DEPENDS roscpp std_srvs sensor_msgs
8+
)
9+
10+
### Build ###
11+
12+
include_directories(${catkin_INCLUDE_DIRS})
13+
14+
add_executable(test_node src/test_node.cpp)
15+
add_dependencies(test_node ${catkin_EXPORTED_TARGETS})
16+
target_link_libraries(test_node ${catkin_LIBRARIES})
17+
18+
### Install ###
19+
install(TARGETS test_node
20+
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
21+
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
22+
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
23+
)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0"?>
2+
<?xml-model
3+
href="http://download.ros.org/schema/package_format3.xsd"
4+
schematypens="http://www.w3.org/2001/XMLSchema"?>
5+
<package format="3">
6+
<name>test_pkg</name>
7+
<version>0.0.0</version>
8+
<description>This package contains the implementation of the node test_node</description>
9+
<maintainer email="jane.doe@example.com">Jane Doe</maintainer>
10+
<author email="jane.doe@example.com">Jane Doe</author>
11+
<license>Apache 2.0</license>
12+
13+
<buildtool_depend>catkin</buildtool_depend>
14+
15+
<depend>boost</depend>
16+
<depend>roscpp</depend>
17+
<depend>std_srvs</depend>
18+
<depend>sensor_msgs</depend>
19+
20+
</package>

plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/rosgenerator/test_node.cpp renamed to plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/rosgenerator/test_pkg/src/test_node.cpp

File renamed without changes.

plugins/de.fraunhofer.ipa.ros.xtext.tests/src/de/fraunhofer/ipa/ros/tests/RosGeneratorTest.xtend

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,20 @@ class RosGeneratorTest {
4343

4444
val resourceSet = rosTestingUtils.getMessagesResourceSet
4545
val fileContent = new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'test.ros')))
46-
4746
val model = parseHelper.parse(fileContent, resourceSet)
4847

4948
val fsa = new InMemoryFileSystemAccess
5049
rosGenerator.doGenerate(model.eResource, fsa, new GeneratorContext)
51-
52-
Assert.assertTrue(fsa.textFiles.containsKey(CustomOutputProvider::DEFAULT_OUTPUT + "test_node.cpp"))
50+
Assert.assertTrue(fsa.textFiles.containsKey(CustomOutputProvider::DEFAULT_OUTPUT + "test_pkg/package.xml"))
51+
Assert.assertEquals(
52+
new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'rosgenerator/test_pkg/src/','test_node.cpp'))).trim,
53+
fsa.textFiles.get(CustomOutputProvider::DEFAULT_OUTPUT + "test_pkg/src/test_node.cpp").toString.trim)
54+
Assert.assertEquals(
55+
new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'rosgenerator/test_pkg/','CMakeLists.txt'))).trim,
56+
fsa.textFiles.get(CustomOutputProvider::DEFAULT_OUTPUT + "test_pkg/CMakeLists.txt").toString.trim)
5357
Assert.assertEquals(
54-
new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'rosgenerator', 'test_node.cpp'))).trim,
55-
fsa.textFiles.get(CustomOutputProvider::DEFAULT_OUTPUT + "test_node.cpp").toString.trim)
58+
new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'rosgenerator/test_pkg/','package.xml'))).trim,
59+
fsa.textFiles.get(CustomOutputProvider::DEFAULT_OUTPUT + "test_pkg/package.xml").toString.trim)
5660
}
5761

5862
@Test
@@ -63,10 +67,16 @@ class RosGeneratorTest {
6367

6468
val fsa = new InMemoryFileSystemAccess
6569
ros2Generator.doGenerate(model.eResource, fsa, new GeneratorContext)
66-
Assert.assertTrue(fsa.textFiles.containsKey(CustomOutputProvider::DEFAULT_OUTPUT + "test_node.cpp"))
70+
Assert.assertTrue(fsa.textFiles.containsKey(CustomOutputProvider::DEFAULT_OUTPUT + "test_pkg/package.xml"))
71+
Assert.assertEquals(
72+
new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'ros2generator/test_pkg/src/','test_node.cpp'))).trim,
73+
fsa.textFiles.get(CustomOutputProvider::DEFAULT_OUTPUT + "test_pkg/src/test_node.cpp").toString.trim)
74+
Assert.assertEquals(
75+
new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'ros2generator/test_pkg/','CMakeLists.txt'))).trim,
76+
fsa.textFiles.get(CustomOutputProvider::DEFAULT_OUTPUT + "test_pkg/CMakeLists.txt").toString.trim)
6777
Assert.assertEquals(
68-
new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'ros2generator', 'test_node.cpp'))).trim,
69-
fsa.textFiles.get(CustomOutputProvider::DEFAULT_OUTPUT + "test_node.cpp").toString.trim)
78+
new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'ros2generator/test_pkg/','package.xml'))).trim,
79+
fsa.textFiles.get(CustomOutputProvider::DEFAULT_OUTPUT + "test_pkg/package.xml").toString.trim)
7080
}
7181

7282
@Test

plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/Ros2CodeGenerator.xtend

Lines changed: 97 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,110 @@
11
package de.fraunhofer.ipa.roscode.generator
22

3+
import java.util.ArrayList
4+
import java.util.HashSet
5+
import java.util.List
6+
import java.util.Set
37
import org.eclipse.emf.ecore.resource.Resource
48
import org.eclipse.xtext.generator.AbstractGenerator
59
import org.eclipse.xtext.generator.IFileSystemAccess2
610
import org.eclipse.xtext.generator.IGeneratorContext
7-
import org.eclipse.xtext.generator.IOutputConfigurationProvider
8-
import org.eclipse.xtext.generator.OutputConfiguration
9-
import java.util.Set
10-
import ros.*
11-
12-
11+
import ros.Node
12+
import ros.Package
1313

1414
/**
1515
* Generates code from your model files on save.
1616
*
1717
* See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation
1818
*/
1919
class Ros2CodeGenerator extends AbstractGenerator {
20-
2120

2221
String resourcepath
2322
String import_msgs
2423
int char_i
24+
Node node
25+
List<String> PkgsList
26+
Set<String> set
27+
2528

2629
override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
2730
resourcepath = resource.URI.toString();
2831
if (! resourcepath.contains("/ros-input")) {
29-
for (node : resource.allContents.toIterable.filter(Node)){
30-
fsa.generateFile(node.getName()+".cpp",node.compile)
32+
for (pkg : resource.allContents.toIterable.filter(Package)){
33+
fsa.generateFile(pkg.getName().toLowerCase+"/package.xml",pkg.compile_package_xml)
34+
fsa.generateFile(pkg.getName().toLowerCase+"/CMakeLists.txt",pkg.compile_CMakeLists)
35+
for (art : pkg.artifact){
36+
node = art.node
37+
fsa.generateFile(pkg.getName().toLowerCase+"/src/"+node.name+".cpp",node.compile_node)
38+
39+
}
40+
}
3141
}
3242
}
33-
}
3443

35-
def compile(Node node) '''
44+
45+
def compile_package_xml(Package pkg)'''
46+
<?xml version="1.0"?>
47+
<?xml-model
48+
href="http://download.ros.org/schema/package_format3.xsd"
49+
schematypens="http://www.w3.org/2001/XMLSchema"?>
50+
<package format="3">
51+
<name>«pkg.name»</name>
52+
<version>0.0.0</version>
53+
<description>This package contains the implementation of the node «pkg.artifact.get(0).node.name»</description>
54+
<maintainer email="jane.doe@example.com">Jane Doe</maintainer>
55+
<author email="jane.doe@example.com">Jane Doe</author>
56+
<license>Apache 2.0</license>
57+
58+
<buildtool_depend>ament_cmake</buildtool_depend>
59+
60+
<depend>boost</depend>
61+
<depend>rclcpp</depend>
62+
«FOR depend_pkg:pkg.getPkgDependencies»
63+
<depend>«depend_pkg»</depend>
64+
«ENDFOR»
65+
66+
<test_depend>ament_lint_auto</test_depend>
67+
<test_depend>ament_lint_common</test_depend>
68+
69+
<export>
70+
<build_type>ament_cmake</build_type>
71+
</export>
72+
</package>
73+
'''
74+
75+
def compile_CMakeLists(Package pkg)'''
76+
cmake_minimum_required(VERSION 3.5)
77+
projectpkg.name»)
78+
79+
# Default to C++14
80+
if(NOT CMAKE_CXX_STANDARD)
81+
set(CMAKE_CXX_STANDARD 14)
82+
endif()
83+
84+
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
85+
add_compile_options(-Wall -Wextra -Wpedantic)
86+
endif()
87+
88+
find_package(ament_cmake REQUIRED)
89+
find_package(Boost REQUIRED)
90+
find_package(rclcpp REQUIRED)
91+
«FOR depend_pkg:pkg.getPkgDependencies»
92+
find_packagedepend_pkg» REQUIRED)
93+
«ENDFOR»
94+
95+
«FOR art:pkg.artifact»
96+
add_executableart.name» srcart.node.name».cpp)
97+
ament_target_dependenciesart.name» rclcpp «FOR depend_pkg:pkg.getPkgDependencies»«depend_pkg» «ENDFOR»)
98+
99+
install(TARGETS
100+
«art.name»
101+
DESTINATION lib/${PROJECT_NAME})
102+
«ENDFOR»
103+
104+
ament_package()
105+
'''
106+
107+
def compile_node(Node node) '''
36108
#include <chrono>
37109
#include <cstdio>
38110
#include <memory>
@@ -149,6 +221,20 @@ int main(int argc, char * argv[])
149221
}
150222
'''
151223
224+
def List<String> getPkgDependencies(Package pkg){
225+
set=new HashSet<String>()
226+
PkgsList = new ArrayList()
227+
for (art:pkg.artifact){
228+
node=art.node
229+
for (pub:node.publisher){set.add(pub.message.package.name)}
230+
for (sub:node.subscriber){set.add(sub.message.package.name)}
231+
for (srvserver:node.serviceserver){set.add(srvserver.service.package.name)}
232+
for (srvclient:node.serviceclient){set.add(srvclient.service.package.name)}
233+
}
234+
PkgsList.addAll(set)
235+
return PkgsList
236+
}
237+
152238
def String check_message_include(String message_name){
153239
import_msgs = message_name.toFirstLower;
154240
for (char_i =0; char_i < import_msgs.length; char_i++ ){

0 commit comments

Comments
 (0)