diff --git a/plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/ros2generator/test_pkg/CMakeLists.txt b/plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/ros2generator/test_pkg/CMakeLists.txt new file mode 100644 index 000000000..7a508095f --- /dev/null +++ b/plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/ros2generator/test_pkg/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.5) +project(test_pkg) + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +find_package(ament_cmake REQUIRED) +find_package(Boost REQUIRED) +find_package(rclcpp REQUIRED) +find_package(std_srvs REQUIRED) +find_package(sensor_msgs REQUIRED) + +add_executable(test_node src/test_node.cpp) +ament_target_dependencies(test_node rclcpp std_srvs sensor_msgs ) + +install(TARGETS + test_node + DESTINATION lib/${PROJECT_NAME}) + +ament_package() diff --git a/plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/ros2generator/test_pkg/package.xml b/plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/ros2generator/test_pkg/package.xml new file mode 100644 index 000000000..fdc193692 --- /dev/null +++ b/plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/ros2generator/test_pkg/package.xml @@ -0,0 +1,26 @@ + + + + test_pkg + 0.0.0 + This package contains the implementation of the node test_node + Jane Doe + Jane Doe + Apache 2.0 + + ament_cmake + + boost + rclcpp + std_srvs + sensor_msgs + + ament_lint_auto + ament_lint_common + + + ament_cmake + + diff --git a/plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/ros2generator/test_node.cpp b/plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/ros2generator/test_pkg/src/test_node.cpp similarity index 100% rename from plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/ros2generator/test_node.cpp rename to plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/ros2generator/test_pkg/src/test_node.cpp diff --git a/plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/rosgenerator/test_pkg/CMakeLists.txt b/plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/rosgenerator/test_pkg/CMakeLists.txt new file mode 100644 index 000000000..b9de24ae5 --- /dev/null +++ b/plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/rosgenerator/test_pkg/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.0.2) +project(test_pkg) + +find_package(catkin REQUIRED COMPONENTS roscpp std_srvs sensor_msgs ) + +catkin_package( + CATKIN_DEPENDS roscpp std_srvs sensor_msgs +) + +### Build ### + +include_directories(${catkin_INCLUDE_DIRS}) + +add_executable(test_node src/test_node.cpp) +add_dependencies(test_node ${catkin_EXPORTED_TARGETS}) +target_link_libraries(test_node ${catkin_LIBRARIES}) + +### Install ### +install(TARGETS test_node + ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +) diff --git a/plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/rosgenerator/test_pkg/package.xml b/plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/rosgenerator/test_pkg/package.xml new file mode 100644 index 000000000..a548026ca --- /dev/null +++ b/plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/rosgenerator/test_pkg/package.xml @@ -0,0 +1,20 @@ + + + + test_pkg + 0.0.0 + This package contains the implementation of the node test_node + Jane Doe + Jane Doe + Apache 2.0 + + catkin + + boost + roscpp + std_srvs + sensor_msgs + + diff --git a/plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/rosgenerator/test_node.cpp b/plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/rosgenerator/test_pkg/src/test_node.cpp similarity index 100% rename from plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/rosgenerator/test_node.cpp rename to plugins/de.fraunhofer.ipa.ros.xtext.tests/resources/rosgenerator/test_pkg/src/test_node.cpp diff --git a/plugins/de.fraunhofer.ipa.ros.xtext.tests/src/de/fraunhofer/ipa/ros/tests/RosGeneratorTest.xtend b/plugins/de.fraunhofer.ipa.ros.xtext.tests/src/de/fraunhofer/ipa/ros/tests/RosGeneratorTest.xtend index cfa7a4f23..202323be3 100644 --- a/plugins/de.fraunhofer.ipa.ros.xtext.tests/src/de/fraunhofer/ipa/ros/tests/RosGeneratorTest.xtend +++ b/plugins/de.fraunhofer.ipa.ros.xtext.tests/src/de/fraunhofer/ipa/ros/tests/RosGeneratorTest.xtend @@ -43,16 +43,20 @@ class RosGeneratorTest { val resourceSet = rosTestingUtils.getMessagesResourceSet val fileContent = new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'test.ros'))) - val model = parseHelper.parse(fileContent, resourceSet) val fsa = new InMemoryFileSystemAccess rosGenerator.doGenerate(model.eResource, fsa, new GeneratorContext) - - Assert.assertTrue(fsa.textFiles.containsKey(CustomOutputProvider::DEFAULT_OUTPUT + "test_node.cpp")) + Assert.assertTrue(fsa.textFiles.containsKey(CustomOutputProvider::DEFAULT_OUTPUT + "test_pkg/package.xml")) + Assert.assertEquals( + new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'rosgenerator/test_pkg/src/','test_node.cpp'))).trim, + fsa.textFiles.get(CustomOutputProvider::DEFAULT_OUTPUT + "test_pkg/src/test_node.cpp").toString.trim) + Assert.assertEquals( + new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'rosgenerator/test_pkg/','CMakeLists.txt'))).trim, + fsa.textFiles.get(CustomOutputProvider::DEFAULT_OUTPUT + "test_pkg/CMakeLists.txt").toString.trim) Assert.assertEquals( - new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'rosgenerator', 'test_node.cpp'))).trim, - fsa.textFiles.get(CustomOutputProvider::DEFAULT_OUTPUT + "test_node.cpp").toString.trim) + new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'rosgenerator/test_pkg/','package.xml'))).trim, + fsa.textFiles.get(CustomOutputProvider::DEFAULT_OUTPUT + "test_pkg/package.xml").toString.trim) } @Test @@ -63,10 +67,16 @@ class RosGeneratorTest { val fsa = new InMemoryFileSystemAccess ros2Generator.doGenerate(model.eResource, fsa, new GeneratorContext) - Assert.assertTrue(fsa.textFiles.containsKey(CustomOutputProvider::DEFAULT_OUTPUT + "test_node.cpp")) + Assert.assertTrue(fsa.textFiles.containsKey(CustomOutputProvider::DEFAULT_OUTPUT + "test_pkg/package.xml")) + Assert.assertEquals( + new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'ros2generator/test_pkg/src/','test_node.cpp'))).trim, + fsa.textFiles.get(CustomOutputProvider::DEFAULT_OUTPUT + "test_pkg/src/test_node.cpp").toString.trim) + Assert.assertEquals( + new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'ros2generator/test_pkg/','CMakeLists.txt'))).trim, + fsa.textFiles.get(CustomOutputProvider::DEFAULT_OUTPUT + "test_pkg/CMakeLists.txt").toString.trim) Assert.assertEquals( - new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'ros2generator', 'test_node.cpp'))).trim, - fsa.textFiles.get(CustomOutputProvider::DEFAULT_OUTPUT + "test_node.cpp").toString.trim) + new String(Files.readAllBytes(Paths.get(RESOURCES_BASE_DIR, 'ros2generator/test_pkg/','package.xml'))).trim, + fsa.textFiles.get(CustomOutputProvider::DEFAULT_OUTPUT + "test_pkg/package.xml").toString.trim) } @Test diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/Ros2CodeGenerator.xtend b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/Ros2CodeGenerator.xtend index 23db18105..d1e615aaf 100644 --- a/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/Ros2CodeGenerator.xtend +++ b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/Ros2CodeGenerator.xtend @@ -1,15 +1,15 @@ package de.fraunhofer.ipa.roscode.generator +import java.util.ArrayList +import java.util.HashSet +import java.util.List +import java.util.Set import org.eclipse.emf.ecore.resource.Resource import org.eclipse.xtext.generator.AbstractGenerator import org.eclipse.xtext.generator.IFileSystemAccess2 import org.eclipse.xtext.generator.IGeneratorContext -import org.eclipse.xtext.generator.IOutputConfigurationProvider -import org.eclipse.xtext.generator.OutputConfiguration -import java.util.Set -import ros.* - - +import ros.Node +import ros.Package /** * Generates code from your model files on save. @@ -17,22 +17,94 @@ import ros.* * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation */ class Ros2CodeGenerator extends AbstractGenerator { - String resourcepath String import_msgs int char_i + Node node + List PkgsList + Set set + override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) { resourcepath = resource.URI.toString(); if (! resourcepath.contains("/ros-input")) { - for (node : resource.allContents.toIterable.filter(Node)){ - fsa.generateFile(node.getName()+".cpp",node.compile) + for (pkg : resource.allContents.toIterable.filter(Package)){ + fsa.generateFile(pkg.getName().toLowerCase+"/package.xml",pkg.compile_package_xml) + fsa.generateFile(pkg.getName().toLowerCase+"/CMakeLists.txt",pkg.compile_CMakeLists) + for (art : pkg.artifact){ + node = art.node + fsa.generateFile(pkg.getName().toLowerCase+"/src/"+node.name+".cpp",node.compile_node) + + } + } } } - } -def compile(Node node) ''' + +def compile_package_xml(Package pkg)''' + + + + «pkg.name» + 0.0.0 + This package contains the implementation of the node «pkg.artifact.get(0).node.name» + Jane Doe + Jane Doe + Apache 2.0 + + ament_cmake + + boost + rclcpp + «FOR depend_pkg:pkg.getPkgDependencies» + «depend_pkg» + «ENDFOR» + + ament_lint_auto + ament_lint_common + + + ament_cmake + + +''' + +def compile_CMakeLists(Package pkg)''' +cmake_minimum_required(VERSION 3.5) +project(«pkg.name») + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +find_package(ament_cmake REQUIRED) +find_package(Boost REQUIRED) +find_package(rclcpp REQUIRED) + «FOR depend_pkg:pkg.getPkgDependencies» +find_package(«depend_pkg» REQUIRED) + «ENDFOR» + +«FOR art:pkg.artifact» +add_executable(«art.name» src/«art.node.name».cpp) +ament_target_dependencies(«art.name» rclcpp «FOR depend_pkg:pkg.getPkgDependencies»«depend_pkg» «ENDFOR») + +install(TARGETS + «art.name» + DESTINATION lib/${PROJECT_NAME}) +«ENDFOR» + +ament_package() +''' + +def compile_node(Node node) ''' #include #include #include @@ -149,6 +221,20 @@ int main(int argc, char * argv[]) } ''' + def List getPkgDependencies(Package pkg){ + set=new HashSet() + PkgsList = new ArrayList() + for (art:pkg.artifact){ + node=art.node + for (pub:node.publisher){set.add(pub.message.package.name)} + for (sub:node.subscriber){set.add(sub.message.package.name)} + for (srvserver:node.serviceserver){set.add(srvserver.service.package.name)} + for (srvclient:node.serviceclient){set.add(srvclient.service.package.name)} + } + PkgsList.addAll(set) + return PkgsList + } + def String check_message_include(String message_name){ import_msgs = message_name.toFirstLower; for (char_i =0; char_i < import_msgs.length; char_i++ ){ diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/RosCodeGenerator.xtend b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/RosCodeGenerator.xtend index 448543f8a..8f12e54d3 100644 --- a/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/RosCodeGenerator.xtend +++ b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/RosCodeGenerator.xtend @@ -1,13 +1,21 @@ package de.fraunhofer.ipa.roscode.generator +import java.util.ArrayList +import java.util.HashSet +import java.util.List +import java.util.Set import org.eclipse.emf.ecore.resource.Resource import org.eclipse.xtext.generator.AbstractGenerator import org.eclipse.xtext.generator.IFileSystemAccess2 import org.eclipse.xtext.generator.IGeneratorContext +import ros.Node +import ros.Package import org.eclipse.xtext.generator.IOutputConfigurationProvider import org.eclipse.xtext.generator.OutputConfiguration -import java.util.Set -import ros.* +import ros.Publisher +import ros.Subscriber +import ros.ServiceServer +import ros.ServiceClient class CustomOutputProvider implements IOutputConfigurationProvider { public final static String DEFAULT_OUTPUT = "DEFAULT_OUTPUT" @@ -34,17 +42,79 @@ class RosCodeGenerator extends AbstractGenerator { String resourcepath + Node node + List PkgsList + Set set + override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) { resourcepath = resource.URI.toString(); if (! resourcepath.contains("/ros-input")) { - for (node : resource.allContents.toIterable.filter(Node)){ - fsa.generateFile(node.getName()+".cpp",node.compile) + for (pkg : resource.allContents.toIterable.filter(Package)){ + fsa.generateFile(pkg.getName().toLowerCase+"/package.xml",pkg.compile_package_xml) + fsa.generateFile(pkg.getName().toLowerCase+"/CMakeLists.txt",pkg.compile_CMakeLists) + for (art : pkg.artifact){ + node = art.node + fsa.generateFile(pkg.getName().toLowerCase+"/src/"+node.name+".cpp",node.compile_node) + + } + } } - } } -def compile(Node node) ''' +def compile_package_xml(Package pkg)''' + + + + «pkg.name» + 0.0.0 + This package contains the implementation of the node «pkg.artifact.get(0).node.name» + Jane Doe + Jane Doe + Apache 2.0 + + catkin + + boost + roscpp + «FOR depend_pkg:pkg.getPkgDependencies» + «depend_pkg» + «ENDFOR» + + +''' + +def compile_CMakeLists(Package pkg)''' +cmake_minimum_required(VERSION 3.0.2) +project(«pkg.name») + +find_package(catkin REQUIRED COMPONENTS roscpp «FOR depend_pkg:pkg.getPkgDependencies»«depend_pkg» «ENDFOR») + +catkin_package( + CATKIN_DEPENDS roscpp «FOR depend_pkg:pkg.getPkgDependencies»«depend_pkg» «ENDFOR» +) + +### Build ### + +include_directories(${catkin_INCLUDE_DIRS}) + +«FOR art:pkg.artifact» +add_executable(«art.name» src/«art.node.name».cpp) +add_dependencies(«art.name» ${catkin_EXPORTED_TARGETS}) +target_link_libraries(«art.name» ${catkin_LIBRARIES}) + +«ENDFOR» +### Install ### +install(TARGETS «FOR art:pkg.artifact»«art.name»«ENDFOR» + ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +) +''' + +def compile_node(Node node) ''' #include «FOR pub : node.publisher» #include <«pub.message.package.name»/«pub.message.name».h> @@ -102,4 +172,20 @@ def compile(ServiceServer srvserver) def compile(ServiceClient srvclient) ''' ros::ServiceClient «srvclient.name» = n.serviceClient<«srvclient.service.package.name»::«srvclient.service.name»>("«srvclient.name»");''' -} + + def List getPkgDependencies(Package pkg){ + set=new HashSet() + PkgsList = new ArrayList() + for (art:pkg.artifact){ + node=art.node + for (pub:node.publisher){set.add(pub.message.package.name)} + for (sub:node.subscriber){set.add(sub.message.package.name)} + for (srvserver:node.serviceserver){set.add(srvserver.service.package.name)} + for (srvclient:node.serviceclient){set.add(srvclient.service.package.name)} + } + PkgsList.addAll(set) + return PkgsList + } + + } +