diff --git a/plugins/de.fraunhofer.ipa.ros.feature/feature.xml b/plugins/de.fraunhofer.ipa.ros.feature/feature.xml
index 8d90d570..ba0aafbe 100644
--- a/plugins/de.fraunhofer.ipa.ros.feature/feature.xml
+++ b/plugins/de.fraunhofer.ipa.ros.feature/feature.xml
@@ -197,4 +197,11 @@ POSSIBILITY OF SUCH DAMAGE.
version="3.0.0.qualifier"
unpack="false"/>
+
+
diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/.classpath b/plugins/de.fraunhofer.ipa.roscode.generator/.classpath
new file mode 100644
index 00000000..45427fef
--- /dev/null
+++ b/plugins/de.fraunhofer.ipa.roscode.generator/.classpath
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/.project b/plugins/de.fraunhofer.ipa.roscode.generator/.project
new file mode 100644
index 00000000..87835c34
--- /dev/null
+++ b/plugins/de.fraunhofer.ipa.roscode.generator/.project
@@ -0,0 +1,34 @@
+
+
+ de.fraunhofer.ipa.roscode.generator
+
+
+
+
+
+ org.eclipse.xtext.ui.shared.xtextBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.xtext.ui.shared.xtextNature
+ org.eclipse.jdt.core.javanature
+ org.eclipse.pde.PluginNature
+
+
diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/.settings/org.eclipse.core.resources.prefs b/plugins/de.fraunhofer.ipa.roscode.generator/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 00000000..99f26c02
--- /dev/null
+++ b/plugins/de.fraunhofer.ipa.roscode.generator/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/.settings/org.eclipse.jdt.core.prefs b/plugins/de.fraunhofer.ipa.roscode.generator/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..49cf78d8
--- /dev/null
+++ b/plugins/de.fraunhofer.ipa.roscode.generator/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=19
+org.eclipse.jdt.core.compiler.compliance=19
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=19
diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/META-INF/MANIFEST.MF b/plugins/de.fraunhofer.ipa.roscode.generator/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..f5b6b455
--- /dev/null
+++ b/plugins/de.fraunhofer.ipa.roscode.generator/META-INF/MANIFEST.MF
@@ -0,0 +1,24 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: de.fraunhofer.ipa.roscode.generator;singleton:=true
+Bundle-Version: 3.0.0.qualifier
+Bundle-Vendor: %providerName
+Export-Package: de.fraunhofer.ipa.roscode.generator
+Bundle-RequiredExecutionEnvironment: JavaSE-19
+Import-Package: javax.inject;version="1.0.0",
+ org.eclipse.ui.handlers,
+ org.eclipse.xtext.ui.resource
+Bundle-ActivationPolicy: lazy
+Bundle-Activator: de.fraunhofer.ipa.roscode.generator.Activator
+Require-Bundle: org.eclipse.xtext.builder,
+ org.eclipse.xtext.ui,
+ de.fraunhofer.ipa.ros2.xtext;bundle-version="3.0.0",
+ de.fraunhofer.ipa.ros2.xtext.ide;bundle-version="3.0.0",
+ de.fraunhofer.ipa.ros2.xtext.ui;bundle-version="3.0.0",
+ de.fraunhofer.ipa.ros.xtext;bundle-version="3.0.0",
+ de.fraunhofer.ipa.ros.xtext.ide;bundle-version="3.0.0",
+ de.fraunhofer.ipa.ros.xtext.ui;bundle-version="3.0.0",
+ de.fraunhofer.ipa.ros;bundle-version="3.0.0",
+ de.fraunhofer.ipa.ros.edit;bundle-version="3.0.0",
+ de.fraunhofer.ipa.ros.editor;bundle-version="3.0.0"
diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/build.properties b/plugins/de.fraunhofer.ipa.roscode.generator/build.properties
new file mode 100644
index 00000000..41a2e90a
--- /dev/null
+++ b/plugins/de.fraunhofer.ipa.roscode.generator/build.properties
@@ -0,0 +1,17 @@
+source.. = src/,\
+ xtend-gen/
+bin.includes = .,\
+ META-INF/,\
+ plugin.xml
+bin.excludes = **/*.mwe2,\
+ **/*.xtend
+additional.bundles = org.eclipse.xtext.xbase,\
+ org.eclipse.xtext.common.types,\
+ org.eclipse.xtext.xtext.generator,\
+ org.eclipse.emf.codegen.ecore,\
+ org.eclipse.emf.mwe.utils,\
+ org.eclipse.emf.mwe2.lib,\
+ org.objectweb.asm,\
+ org.apache.commons.logging,\
+ org.apache.log4j,\
+ com.ibm.icu
\ No newline at end of file
diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/plugin.xml b/plugins/de.fraunhofer.ipa.roscode.generator/plugin.xml
new file mode 100644
index 00000000..90ab3c4e
--- /dev/null
+++ b/plugins/de.fraunhofer.ipa.roscode.generator/plugin.xml
@@ -0,0 +1,144 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/pom.xml b/plugins/de.fraunhofer.ipa.roscode.generator/pom.xml
new file mode 100644
index 00000000..bf60bf56
--- /dev/null
+++ b/plugins/de.fraunhofer.ipa.roscode.generator/pom.xml
@@ -0,0 +1,31 @@
+
+ 4.0.0
+
+ de.fraunhofer.ipa.ros
+ de.fraunhofer.ipa.ros.parent
+ 2.0.0-SNAPSHOT
+ ../de.fraunhofer.ipa.ros.parent/pom.xml
+
+ de.fraunhofer.ipa.roscode.generator
+ eclipse-plugin
+
+
+
+
+ org.eclipse.xtend
+ xtend-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-clean-plugin
+
+
+ xtend-gen-clean
+ clean
+
+
+
+
+
+
diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/Activator.java b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/Activator.java
new file mode 100644
index 00000000..d50e613d
--- /dev/null
+++ b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/Activator.java
@@ -0,0 +1,7 @@
+package de.fraunhofer.ipa.roscode.generator;
+
+import de.fraunhofer.ipa.ros2.xtext.ui.internal.XtextActivator;
+
+public class Activator extends XtextActivator {
+
+}
diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/GenerationHandler.java b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/GenerationHandler.java
new file mode 100644
index 00000000..db86d9aa
--- /dev/null
+++ b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/GenerationHandler.java
@@ -0,0 +1,82 @@
+package de.fraunhofer.ipa.roscode.generator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.xtext.builder.EclipseResourceFileSystemAccess2;
+import org.eclipse.xtext.generator.GeneratorContext;
+import org.eclipse.xtext.generator.IOutputConfigurationProvider;
+import org.eclipse.xtext.generator.OutputConfiguration;
+import org.eclipse.xtext.resource.IResourceDescriptions;
+import org.eclipse.xtext.ui.resource.IResourceSetProvider;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+import de.fraunhofer.ipa.roscode.generator.RosCodeGenerator;;
+
+public class GenerationHandler extends AbstractHandler implements IHandler {
+
+ @Inject
+ private Provider fileAccessProvider;
+
+ @Inject
+ IResourceDescriptions resourceDescriptions;
+
+ @Inject
+ IResourceSetProvider resourceSetProvider;
+
+ static Map getOutputConfigurationsAsMap(IOutputConfigurationProvider provider) {
+ Map outputs = new HashMap();
+ for(OutputConfiguration c: provider.getOutputConfigurations()) {
+ outputs.put(c.getName(), c);
+ }
+ return outputs;
+ }
+
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+ Object firstElement = structuredSelection.getFirstElement();
+ if (firstElement instanceof IFile) {
+ IFile file = (IFile) firstElement;
+ IProject project = file.getProject();
+
+ final EclipseResourceFileSystemAccess2 fsa = fileAccessProvider.get();
+ fsa.setProject(project);
+ fsa.setOutputConfigurations(getOutputConfigurationsAsMap(new CustomOutputProvider()));
+ fsa.setMonitor(new NullProgressMonitor());
+
+ URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true);
+ ResourceSet rs = resourceSetProvider.get(project);
+ Resource r = rs.getResource(uri, true);
+
+ RosCodeGenerator generator = new RosCodeGenerator();
+ generator.doGenerate(r, fsa, new GeneratorContext());
+
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+ }
diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/GenerationRos2CppHandler.java b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/GenerationRos2CppHandler.java
new file mode 100644
index 00000000..658695dd
--- /dev/null
+++ b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/GenerationRos2CppHandler.java
@@ -0,0 +1,82 @@
+package de.fraunhofer.ipa.roscode.generator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.xtext.builder.EclipseResourceFileSystemAccess2;
+import org.eclipse.xtext.generator.GeneratorContext;
+import org.eclipse.xtext.generator.IOutputConfigurationProvider;
+import org.eclipse.xtext.generator.OutputConfiguration;
+import org.eclipse.xtext.resource.IResourceDescriptions;
+import org.eclipse.xtext.ui.resource.IResourceSetProvider;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+import de.fraunhofer.ipa.roscode.generator.RosCodeGenerator;;
+
+public class GenerationRos2CppHandler extends AbstractHandler implements IHandler {
+
+ @Inject
+ private Provider fileAccessProvider;
+
+ @Inject
+ IResourceDescriptions resourceDescriptions;
+
+ @Inject
+ IResourceSetProvider resourceSetProvider;
+
+ static Map getOutputConfigurationsAsMap(IOutputConfigurationProvider provider) {
+ Map outputs = new HashMap();
+ for(OutputConfiguration c: provider.getOutputConfigurations()) {
+ outputs.put(c.getName(), c);
+ }
+ return outputs;
+ }
+
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+ Object firstElement = structuredSelection.getFirstElement();
+ if (firstElement instanceof IFile) {
+ IFile file = (IFile) firstElement;
+ IProject project = file.getProject();
+
+ final EclipseResourceFileSystemAccess2 fsa = fileAccessProvider.get();
+ fsa.setProject(project);
+ fsa.setOutputConfigurations(getOutputConfigurationsAsMap(new CustomOutputProvider()));
+ fsa.setMonitor(new NullProgressMonitor());
+
+ URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true);
+ ResourceSet rs = resourceSetProvider.get(project);
+ Resource r = rs.getResource(uri, true);
+
+ Ros2CppCodeGenerator generator = new Ros2CppCodeGenerator();
+ generator.doGenerate(r, fsa, new GeneratorContext());
+
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+ }
\ No newline at end of file
diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/GenerationRos2PythonHandler.java b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/GenerationRos2PythonHandler.java
new file mode 100644
index 00000000..af69301c
--- /dev/null
+++ b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/GenerationRos2PythonHandler.java
@@ -0,0 +1,82 @@
+package de.fraunhofer.ipa.roscode.generator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.xtext.builder.EclipseResourceFileSystemAccess2;
+import org.eclipse.xtext.generator.GeneratorContext;
+import org.eclipse.xtext.generator.IOutputConfigurationProvider;
+import org.eclipse.xtext.generator.OutputConfiguration;
+import org.eclipse.xtext.resource.IResourceDescriptions;
+import org.eclipse.xtext.ui.resource.IResourceSetProvider;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+import de.fraunhofer.ipa.roscode.generator.RosCodeGenerator;;
+
+public class GenerationRos2PythonHandler extends AbstractHandler implements IHandler {
+
+ @Inject
+ private Provider fileAccessProvider;
+
+ @Inject
+ IResourceDescriptions resourceDescriptions;
+
+ @Inject
+ IResourceSetProvider resourceSetProvider;
+
+ static Map getOutputConfigurationsAsMap(IOutputConfigurationProvider provider) {
+ Map outputs = new HashMap();
+ for(OutputConfiguration c: provider.getOutputConfigurations()) {
+ outputs.put(c.getName(), c);
+ }
+ return outputs;
+ }
+
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+ Object firstElement = structuredSelection.getFirstElement();
+ if (firstElement instanceof IFile) {
+ IFile file = (IFile) firstElement;
+ IProject project = file.getProject();
+
+ final EclipseResourceFileSystemAccess2 fsa = fileAccessProvider.get();
+ fsa.setProject(project);
+ fsa.setOutputConfigurations(getOutputConfigurationsAsMap(new CustomOutputProvider()));
+ fsa.setMonitor(new NullProgressMonitor());
+
+ URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true);
+ ResourceSet rs = resourceSetProvider.get(project);
+ Resource r = rs.getResource(uri, true);
+
+ Ros2PythonCodeGenerator generator = new Ros2PythonCodeGenerator();
+ generator.doGenerate(r, fsa, new GeneratorContext());
+
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+ }
\ No newline at end of file
diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/ParameterGeneratorHelpers.xtend b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/ParameterGeneratorHelpers.xtend
new file mode 100644
index 00000000..77c75ac1
--- /dev/null
+++ b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/ParameterGeneratorHelpers.xtend
@@ -0,0 +1,95 @@
+package de.fraunhofer.ipa.roscode.generator
+
+import ros.impl.ParameterStringTypeImpl
+import ros.impl.ParameterStringImpl
+import ros.impl.ParameterIntegerTypeImpl
+import ros.impl.ParameterIntegerImpl
+import ros.impl.ParameterDoubleTypeImpl
+import ros.impl.ParameterDoubleImpl
+import ros.impl.ParameterBooleanTypeImpl
+import ros.impl.ParameterBooleanImpl
+import ros.impl.ParameterBase64TypeImpl
+import ros.impl.ParameterBase64Impl
+import ros.impl.ParameterListTypeImpl
+import org.eclipse.emf.common.util.EList
+import ros.ParameterType
+import ros.impl.ParameterStructTypeImpl
+import ros.impl.ParameterArrayTypeImpl
+
+abstract class ParameterGeneratorHelpers {
+
+ def String get_param_declaration_str(String param_type, String param_name, String delim, Boolean has_value)
+
+ def Boolean is_array(EList list) {
+ var t = list.get(0).class
+ for (type : list) {
+ if (!(type.class == t)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ def Pair compile_struct(ParameterStructTypeImpl struct, String name) {
+ var struct_str = "";
+ var struct_type_str = "";
+ for (elem : struct.getParameterstructypetmember()) {
+ if (elem.getType() instanceof ParameterStructTypeImpl) {
+ var elem_pair = compile_struct(elem.getType() as ParameterStructTypeImpl, name + "." + elem.getName());
+ struct_str += elem_pair.getKey();
+ struct_type_str += elem_pair.getValue();
+ } else {
+ var param_pair = get_param_type(elem.getType());
+ var elem_name = name + "." + elem.getName();
+ struct_str += get_param_declaration_str(param_pair.getKey(), elem_name, ".", (param_pair.getValue != ""));
+
+ struct_type_str += param_pair.getKey() + " " + elem_name.replace(".", "_") + "_;\n";
+ }
+ }
+ return new Pair(struct_str, struct_type_str);
+ }
+
+ def Pair get_param_type(ParameterType type) {
+ var has_value = type.eContents.length > 0;
+ var param_val = ""
+ if (type instanceof ParameterStringTypeImpl) {
+ if (has_value) {
+ param_val = ", \"" + (type.eContents.get(0) as ParameterStringImpl).getValue() + "\"";
+ }
+ return new Pair("std::string", param_val);
+ } else if (type instanceof ParameterIntegerTypeImpl) {
+ if (has_value) {
+ param_val = ", " + (type.eContents.get(0) as ParameterIntegerImpl).getValue();
+ }
+ return new Pair("int", param_val);
+ } else if (type instanceof ParameterDoubleTypeImpl) {
+ if (has_value) {
+ param_val = ", " + (type.eContents.get(0) as ParameterDoubleImpl).getValue();
+ }
+ return new Pair("double", param_val);
+ } else if (type instanceof ParameterBooleanTypeImpl) {
+ if (has_value) {
+ param_val = ", " + (type.eContents.get(0) as ParameterBooleanImpl).isValue();
+ }
+ return new Pair("bool", param_val);
+ /*} else if (type instanceof ParameterBase64TypeImpl) {
+ if (has_value) {
+ param_val = ", " + (type.eContents.get(0) as ParameterBase64Impl).getValue();
+ }
+ return new Pair("uint64_t", param_val); // not sure about this*/
+ } else if (type instanceof ParameterListTypeImpl) {
+ var list = (type as ParameterListTypeImpl).getSequence();
+ if (!list.is_array()) {
+ return new Pair("", "");
+ }
+ var list_type = get_param_type(list.get(0));
+ return new Pair("std::vector<" + list_type.getKey() + ">", "");
+ } else if (type instanceof ParameterArrayTypeImpl) {
+ var array = type as ParameterArrayTypeImpl;
+ return new Pair("std::vector<" + get_param_type(array.getType()).getKey() + ">", "");
+ }
+
+ return new Pair("", "");
+ }
+
+}
diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/Ros2CppCodeGenerator.xtend b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/Ros2CppCodeGenerator.xtend
new file mode 100644
index 00000000..5d5e626c
--- /dev/null
+++ b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/Ros2CppCodeGenerator.xtend
@@ -0,0 +1,291 @@
+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.Package
+import ros.impl.ParameterStructTypeImpl
+import ros.Node
+
+/**
+ * Generates code from your model files on save.
+ *
+ * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation
+ */
+class Ros2CppCodeGenerator extends AbstractGenerator {
+
+ String resourcepath
+ String import_msgs
+ int char_i
+ Node node
+ List PkgsList
+ Set set
+ ParameterGeneratorHelpers parameter_helper = new ParameterGeneratorHelpers() {
+
+ override get_param_declaration_str(String param_type, String param_name, String delim, Boolean has_value) {
+ var struct_str = "";
+ struct_str += "this->declare_parameter";
+ if (has_value) {
+ struct_str += "<" + param_type + ">";
+ }
+ struct_str += "(\"" + param_name + "\");\n";
+ struct_str += "this->get_parameter(\"" + param_name + "\", " + param_name.replace(delim, "_") + "_);\n\n";
+
+ return struct_str;
+ }
+
+ };
+
+ override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
+ resourcepath = resource.URI.toString();
+ if (! resourcepath.contains("/ros-input")) {
+ 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_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
+#include
+#include
+
+#include "rclcpp/rclcpp.hpp"
+#include "rcutils/cmdline_parser.h"
+ «FOR pub : node.publisher»
+#include <«pub.message.package.name»/msg/«check_message_include(pub.message.name)».hpp>
+ «ENDFOR»
+ «FOR sub : node.subscriber»
+#include <«sub.message.package.name»/msg/«check_message_include(sub.message.name)».hpp>
+ «ENDFOR»
+ «FOR srvserver : node.serviceserver»
+#include <«srvserver.service.package.name»/srv/«check_message_include(srvserver.service.name)».hpp>
+ «ENDFOR»
+ «FOR srvclient : node.serviceclient»
+#include <«srvclient.service.package.name»/srv/«check_message_include(srvclient.service.name)».hpp>
+ «ENDFOR»
+
+using namespace std::chrono_literals;
+using std::placeholders::_1;
+using std::placeholders::_2;
+using std::placeholders::_3;
+
+void print_usage()
+{
+ printf("Usage for «node.name» app:\n");
+ printf("..... \n");
+ printf("..... \n");
+ printf("..... \n");
+}
+
+class «node.name» : public rclcpp::Node {
+ public:
+ «node.name»() : Node("«node.name»") {
+ «FOR param : node.parameter»
+ «IF (param.type instanceof ParameterStructTypeImpl)»
+ «parameter_helper.compile_struct(param.type as ParameterStructTypeImpl, param.name).getKey()»
+ «ELSE»
+«var param_pair = parameter_helper.get_param_type(param.type)»
+ «IF !(param_pair.getKey().empty)»
+ this->declare_parameter«IF !param_pair.getValue().empty»<«param_pair.getKey()»>«ENDIF»("«param.name»"«param_pair.getValue()»);
+ this->get_parameter("«param.name»", «param.name»_);
+ «ENDIF»
+ «ENDIF»
+ «ENDFOR»
+ «FOR pub : node.publisher»
+ «check_name(pub.name)»_ = this->create_publisher<«pub.message.package.name»::msg::«pub.message.name»>("«pub.name»",10);
+ «ENDFOR»
+ «FOR sub : node.subscriber»
+ «check_name(sub.name)»_ = this->create_subscription<«sub.message.package.name»::msg::«sub.message.name»>("«sub.name»", 10, std::bind(&«node.name»::«check_name(sub.name)»_callback, this, _1));
+ «ENDFOR»
+ «FOR client : node.serviceclient»
+ «check_name(client.name)»_ = this->create_client<«client.service.package.name»::srv::«client.service.name»>("«client.name»");
+ «ENDFOR»
+ «FOR service : node.serviceserver»
+ «check_name(service.name)»_ = this->create_service<«service.service.package.name»::srv::«service.service.name»>("«service.name»", std::bind(&«node.name»::«check_name(service.name)»_handle, this, _1, _2, _3));
+ «ENDFOR»
+
+ «IF node.publisher.length > 0»
+ timer_ = this->create_wall_timer(500ms, std::bind(&«node.name»::timer_callback, this));
+ «ENDIF»
+
+ «FOR client : node.serviceclient»
+ // Service client
+ while (!«check_name(client.name)»_->wait_for_service(std::chrono::seconds(10))){
+ RCLCPP_ERROR(this->get_logger(), "Client interrupted while waiting for service '%s' to appear.", "«client.name»");
+ }
+ auto request = std::make_shared<«client.service.package.name»::srv::«client.service.name»::Request>();
+ // request-> ... = ....;
+ auto result_future = «check_name(client.name)»_->async_send_request(request);
+ auto result = result_future.get();
+ RCLCPP_INFO(this->get_logger(), "Service called, service: '%s'", "«client.name»");
+ «ENDFOR»
+ }
+
+ private:
+ «FOR param : node.parameter»
+ «IF (param.type instanceof ParameterStructTypeImpl)»
+ «parameter_helper.compile_struct(param.type as ParameterStructTypeImpl, param.name).getValue()»
+ «ELSE»
+ «var param_pair = parameter_helper.get_param_type(param.type)»
+ «IF !(param_pair.getKey().empty)»
+ «param_pair.getKey()» «param.name»_;
+ «ENDIF»
+ «ENDIF»
+ «ENDFOR»
+
+ «FOR sub : node.subscriber»
+ // Subscriber callback
+ void «check_name(sub.name)»_callback(const «sub.message.package.name»::msg::«sub.message.name»::SharedPtr msg) const {
+ RCLCPP_INFO(this->get_logger(), "«sub.name» topic got a message", msg);
+ }
+
+ rclcpp::Subscription<«sub.message.package.name»::msg::«sub.message.name»>::SharedPtr «check_name(sub.name)»_ ;
+ «ENDFOR»
+ «FOR pub : node.publisher»
+ rclcpp::Publisher<«pub.message.package.name»::msg::«pub.message.name»>::SharedPtr «check_name(pub.name)»_;
+ «ENDFOR»
+ «IF node.publisher.length > 0»
+ // Timer Callback
+ void timer_callback(){
+ «FOR pub : node.publisher»
+ auto «check_name(pub.name)»_msg = «pub.message.package.name»::msg::«pub.message.name»();
+ //«check_name(pub.name)»_msg = ...
+ «check_name(pub.name)»_->publish(«check_name(pub.name)»_msg);
+ RCLCPP_INFO(this->get_logger(), "«pub.name» publisher active");
+ «ENDFOR»
+ }
+ rclcpp::TimerBase::SharedPtr timer_;
+ «ENDIF»
+
+ «FOR client : node.serviceclient»rclcpp::Client<«client.service.package.name»::srv::«client.service.name»>::SharedPtr «check_name(client.name)»_;
+ «ENDFOR»
+
+ «FOR service : node.serviceserver»
+ // Service Handler
+ void «check_name(service.name)»_handle( const std::shared_ptr request_header,
+ const std::shared_ptr<«service.service.package.name»::srv::«service.service.name»::Request> request_,
+ const std::shared_ptr<«service.service.package.name»::srv::«service.service.name»::Response> response_){
+ (void)request_header;
+ (void)request_;
+ (void)response_;
+ RCLCPP_INFO( this->get_logger(), "trigger service '%s'","«service.name»");
+ }
+ rclcpp::Service<«service.service.package.name»::srv::«service.service.name»>::SharedPtr «check_name(service.name)»_;
+ «ENDFOR»
+};
+
+int main(int argc, char * argv[])
+{
+ rclcpp::init(argc, argv);
+ rclcpp::spin(std::make_shared<«node.name»>());
+ rclcpp::shutdown();
+ return 0;
+}
+ '''
+
+ 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++ ){
+ if (Character.isUpperCase(import_msgs.charAt(char_i))){
+ import_msgs = import_msgs.substring(0,char_i)+"_"+Character.toLowerCase(import_msgs.charAt(char_i))+import_msgs.substring(char_i+1);
+ }
+ }
+ return import_msgs;
+ }
+
+ def String check_name(String interface_name){
+ return interface_name.replace("/","");
+ }
+
+}
diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/Ros2PythonCodeGenerator.xtend b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/Ros2PythonCodeGenerator.xtend
new file mode 100644
index 00000000..c933dbf1
--- /dev/null
+++ b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/Ros2PythonCodeGenerator.xtend
@@ -0,0 +1,189 @@
+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.Package
+import ros.impl.ParameterStructTypeImpl
+import ros.Node
+
+/**
+ * Generates code from your model files on save.
+ *
+ * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation
+ */
+class Ros2PythonCodeGenerator extends AbstractGenerator {
+
+ String resourcepath
+ String import_msgs
+ int char_i
+ Node node
+ List PkgsList
+ Set set
+ ParameterGeneratorHelpers parameter_helper = new ParameterGeneratorHelpers() {
+
+ override get_param_declaration_str(String param_type, String param_name, String delim, Boolean has_value) {
+ var struct_str = "";
+ struct_str += "this->declare_parameter";
+ if (has_value) {
+ struct_str += "<" + param_type + ">";
+ }
+ struct_str += "(\"" + param_name + "\");\n";
+ struct_str += "this->get_parameter(\"" + param_name + "\", " + param_name.replace(delim, "_") + "_);\n\n";
+
+ return struct_str;
+ }
+
+ };
+
+ override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
+ resourcepath = resource.URI.toString();
+ if (! resourcepath.contains("/ros-input")) {
+ for (pkg : resource.allContents.toIterable.filter(Package)){
+ fsa.generateFile(pkg.getName().toLowerCase+"/package.xml",pkg.compile_package_xml)
+ fsa.generateFile(pkg.getName().toLowerCase+"/"+pkg.getName().toLowerCase+"/__init__.py","")
+ fsa.generateFile(pkg.getName().toLowerCase+"/resource/"+pkg.getName().toLowerCase,"")
+ fsa.generateFile(pkg.getName().toLowerCase+"/setup.cfg",pkg.compile_setup_cfg)
+ fsa.generateFile(pkg.getName().toLowerCase+"/setup.py",pkg.compile_setup_py)
+
+
+ for (art : pkg.artifact){
+ node = art.node
+ fsa.generateFile(pkg.getName().toLowerCase+"/"+pkg.getName().toLowerCase+"/"+node.name+".py",node.compile_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»
+ Name
+ Name
+ Apache 2.0
+
+ ament_cmake
+
+ boost
+ rclpy
+ «FOR depend_pkg:pkg.getPkgDependencies»
+ «depend_pkg»
+ «ENDFOR»
+
+ ament_lint_auto
+ ament_lint_common
+
+
+ ament_cmake
+
+
+'''
+
+def compile_setup_cfg(Package pkg)'''
+[develop]
+script-dir=$base/lib/«pkg.getName().toLowerCase»
+[install]
+install-scripts=$base/lib/«pkg.getName().toLowerCase»
+'''
+
+def compile_setup_py(Package pkg)'''
+from setuptools import setup
+
+package_name = '«pkg.getName().toLowerCase»'
+
+setup(
+ name=package_name,
+ version='0.0.0',
+ packages=[package_name],
+ data_files=[
+ ('share/ament_index/resource_index/packages',
+ ['resource/' + package_name]),
+ ('share/' + package_name, ['package.xml']),
+ ],
+ install_requires=['setuptools'],
+ zip_safe=True,
+ maintainer='Name',
+ maintainer_email='your@email.com',
+ description='TODO: Package description',
+ license='TODO: License declaration',
+ tests_require=['pytest'],
+ entry_points={
+ 'console_scripts': [
+ ],
+ },
+)
+'''
+
+def compile_node(Node node) '''
+import rclpy
+from rclpy.node import Node
+
+ «FOR pub : node.publisher»
+from «pub.message.package.name».msg import «check_message_include(pub.message.name)»
+ «ENDFOR»
+ «FOR sub : node.subscriber»
+from «sub.message.package.name».msg import «check_message_include(sub.message.name)»
+ «ENDFOR»
+ «FOR srvserver : node.serviceserver»
+from «srvserver.service.package.name».srv import «check_message_include(srvserver.service.name)»
+ «ENDFOR»
+ «FOR srvclient : node.serviceclient»
+from «srvclient.service.package.name».srv import «check_message_include(srvclient.service.name)»
+ «ENDFOR»
+
+
+class «node.name»(Node):
+ def __init__(self):
+ super().__init__("«node.name»")
+ self.get_logger().info("This node just says 'Hello'")
+def main(args=None):
+ rclpy.init(args=args)
+ node = «node.name»()
+ rclpy.spin(node)
+ node.destroy_node()
+ rclpy.shutdown()
+if __name__ == "__main__":
+ main()
+ '''
+
+ def List getPkgDependencies(Package pkg){
+ set=new HashSet()
+ PkgsList = new ArrayList()
+ for (art:pkg.artifact){
+ node=art.node
+ for (pub:node.publisher){ if (pub.message.package !== null) set.add(pub.message.package.name)}
+ for (sub:node.subscriber){ if (sub.message.package !== null) set.add(sub.message.package.name)}
+ for (srvserver:node.serviceserver){if (srvserver.service.package !== null) set.add(srvserver.service.package.name)}
+ for (srvclient:node.serviceclient){if (srvclient.service.package !== null) 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++ ){
+ if (Character.isUpperCase(import_msgs.charAt(char_i))){
+ import_msgs = import_msgs.substring(0,char_i)+"_"+Character.toLowerCase(import_msgs.charAt(char_i))+import_msgs.substring(char_i+1);
+ }
+ }
+ return import_msgs;
+ }
+
+ def String check_name(String interface_name){
+ return interface_name.replace("/","");
+ }
+
+}
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
new file mode 100644
index 00000000..93751f77
--- /dev/null
+++ b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/RosCodeGenerator.xtend
@@ -0,0 +1,211 @@
+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 ros.Node
+import ros.Package
+import ros.Publisher
+import ros.ServiceClient
+import ros.ServiceServer
+import ros.Subscriber
+import ros.impl.ParameterStructTypeImpl
+
+class CustomOutputProvider implements IOutputConfigurationProvider {
+ public final static String DEFAULT_OUTPUT = "DEFAULT_OUTPUT"
+
+
+ override Set getOutputConfigurations() {
+ var OutputConfiguration default_config = new OutputConfiguration(DEFAULT_OUTPUT)
+ default_config.setDescription("DEFAULT_OUTPUT");
+ default_config.setOutputDirectory("./src-gen/");
+ default_config.setOverrideExistingResources(true);
+ default_config.setCreateOutputDirectory(true);
+ default_config.setCleanUpDerivedResources(true);
+ default_config.setSetDerivedProperty(true);
+ return newHashSet(default_config)
+ }
+}
+
+/**
+ * Generates code from your model files on save.
+ *
+ * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation
+ */
+class RosCodeGenerator extends AbstractGenerator {
+
+
+ String resourcepath
+ Node node
+ List PkgsList
+ Set set
+ ParameterGeneratorHelpers parameter_helper = new ParameterGeneratorHelpers() {
+
+ override get_param_declaration_str(String param_type, String param_name, String delim, Boolean has_value) {
+ var struct_str = "";
+ struct_str += param_type + " " + param_name.replace(delim, "_") + "_;\n";
+ struct_str += "n.param(\"" + param_name.replace(delim, "/") + "\", " + param_name.replace(delim, "_") + "_);\n\n";
+
+ return struct_str;
+ }
+
+ };
+
+ override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
+ resourcepath = resource.URI.toString();
+ if (! resourcepath.contains("/ros-input")) {
+ 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_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>
+ «ENDFOR»
+ «FOR sub : node.subscriber»
+#include <«sub.message.package.name»/«sub.message.name».h>
+ «ENDFOR»
+ «FOR srvserver : node.serviceserver»
+#include <«srvserver.service.package.name»/«srvserver.service.name».h>
+ «ENDFOR»
+ «FOR srvclient : node.serviceclient»
+#include <«srvclient.service.package.name»/«srvclient.service.name».h>
+ «ENDFOR»
+
+ «FOR srvserver : node.serviceserver»
+bool «srvserver.name»_cb («srvserver.service.package.name»::«srvserver.service.name»::Request &req, «srvserver.service.package.name»::«srvserver.service.name»::Response &res){
+ return true;
+}
+ «ENDFOR»
+ «FOR sub : node.subscriber»
+void «sub.name»_cb (const «sub.message.package.name»::«sub.message.name» msg){}
+ «ENDFOR»
+
+
+int main(int argc, char **argv)
+{
+ ros::init(argc, argv, "«node.name»");
+ ros::NodeHandle n;
+ «FOR param : node.parameter»
+ «IF (param.type instanceof ParameterStructTypeImpl)»
+ «parameter_helper.compile_struct(param.type as ParameterStructTypeImpl, param.name).getKey()»
+ «ELSE»
+ «var param_pair = parameter_helper.get_param_type(param.type)»
+ «IF !(param_pair.getKey().empty)»
+ «param_pair.getKey()» «param.name»_;
+ n.param«IF!(param_pair.getValue().empty)»<«param_pair.getKey()»>«ENDIF»("«param.name»", «param.name»_«param_pair.getValue()»);
+ «ENDIF»
+ «ENDIF»
+«ENDFOR»
+«FOR pub : node.publisher»
+«pub.compile»
+«ENDFOR»
+«FOR sub : node.subscriber»
+«sub.compile»
+«ENDFOR»
+«FOR srvserver : node.serviceserver»
+«srvserver.compile»
+«ENDFOR»
+«FOR srvclient : node.serviceclient»
+«srvclient.compile»
+«ENDFOR»
+
+ ros::spin();
+
+ return 0;
+}
+ '''
+
+def compile(Publisher pub)
+''' ros::Publisher «pub.name»_pub = n.advertise<«pub.message.package.name»::«pub.message.name»>("«pub.name»", 10);'''
+def compile(Subscriber sub)
+''' ros::Subscriber «sub.name» = n.subscribe("«sub.name»", 10, «sub.name»_cb);'''
+def compile(ServiceServer srvserver)
+''' ros::ServiceServer «srvserver.name» = n.advertiseService("«srvserver.name»", «srvserver.name»_cb);'''
+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
+ }
+
+}
diff --git a/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/RosCodeGeneratorExecutableExtensionFactory.java b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/RosCodeGeneratorExecutableExtensionFactory.java
new file mode 100644
index 00000000..66bc4a47
--- /dev/null
+++ b/plugins/de.fraunhofer.ipa.roscode.generator/src/de/fraunhofer/ipa/roscode/generator/RosCodeGeneratorExecutableExtensionFactory.java
@@ -0,0 +1,19 @@
+package de.fraunhofer.ipa.roscode.generator;
+
+import org.eclipse.xtext.ui.guice.AbstractGuiceAwareExecutableExtensionFactory;
+import org.osgi.framework.Bundle;
+
+import com.google.inject.Injector;
+
+public class RosCodeGeneratorExecutableExtensionFactory extends AbstractGuiceAwareExecutableExtensionFactory {
+
+ @Override
+ protected Bundle getBundle() {
+ return Activator.getInstance().getBundle();
+ }
+
+ @Override
+ protected Injector getInjector() {
+ return Activator.getInstance().getInjector(Activator.DE_FRAUNHOFER_IPA_ROS2_ROS2);
+ }
+ }