From 1deda5d24dec7851a5e9b76ae4dce0ae1b6e802a Mon Sep 17 00:00:00 2001 From: ipa-nhg Date: Thu, 10 Aug 2023 12:26:51 +0200 Subject: [PATCH 1/2] Created sklethon for the launch file generator for ROS2 --- .../generator/LaunchFileCompiler_ROS2.xtend | 183 ++++++++++++++++++ .../generator/RosSystemGenerator.xtend | 13 +- 2 files changed, 190 insertions(+), 6 deletions(-) create mode 100644 plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/LaunchFileCompiler_ROS2.xtend diff --git a/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/LaunchFileCompiler_ROS2.xtend b/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/LaunchFileCompiler_ROS2.xtend new file mode 100644 index 000000000..72438463a --- /dev/null +++ b/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/LaunchFileCompiler_ROS2.xtend @@ -0,0 +1,183 @@ +package de.fraunhofer.ipa.rossystem.generator + +import system.RosNode +import ros.RosPackage +import ros.Artifact +import system.Rossystem + +class LaunchFileCompiler_ROS2 { + + + def compile_toROS2launch(Rossystem system) ''' +from launch import LaunchDescription +from launch_ros.actions import Node + +def generate_launch_description(): + ld = LaunchDescription() + + «FOR component:system.components»«IF component.eClass=="RosNode"» + «(component as RosNode).name» = Node( + package="«((component as RosNode).from.eContainer.eContainer as RosPackage).name»", + executable="«((component as RosNode).from.eContainer as Artifact).name»", + name="«(component as RosNode).name»" + ) + «ENDIF» + «ENDFOR» + + «FOR component:system.components»«IF component.eClass=="RosNode"» + ld.add_action(«(component as RosNode).name») + «ENDIF» + «ENDFOR» + + return ld + ''' + +// def void compile_list_of_ROS2components(RosSystem system, ComponentStack stack) { +// components_tmp_.clear; +// Ros2components.clear; +// if (stack === null){ +// components_tmp_ = system.rosComponent; +// } else { +// components_tmp_ = stack.rosComponent; +// } +// for(ComponentInterface component:components_tmp_){ +// if (component.compile_pkg_type.toString.contains("AmentPackage")){ +// Ros2components.add(component); +// } +// } +// } +// +// def check_ns(ComponentInterface component){ +// if (component.hasNS){ +// return component.get_ns(); +// }else { +// return ""; +// } +// } +// +// def List InterfaceDef(String name, String type){ +// ListInterfaceDef = new ArrayList() +// ListInterfaceDef.add(name.replace("/","_")) +// ListInterfaceDef.add(name) +// ListInterfaceDef.add(type) +// return ListInterfaceDef +// } +// +// def boolean hasNS(ComponentInterface component){ +// if(!component.nameSpace.nullOrEmpty){ +// return true; +// }else{ +// return false +// } +// } +// def String get_ns(ComponentInterface component){ +// return component.nameSpace.replaceFirst("/",""); +// } +// +// def String compile_remappings_str(ComponentInterface component) { +// var remap_str = ""; +// val NS = component.check_ns(); +// for (rosPublisher : component.rospublisher) { +// if (!((prefix(NS)+rosPublisher.name).equals(compile_topic_name(rosPublisher.publisher, NS)))) { +// remap_str += "\t(\"" + rosPublisher.publisher.name + "\", \"" + rosPublisher.name + "\"),\n"; +// } +// } +// for (rosSubscriber : component.rossubscriber) { +// if (!((prefix(NS)+rosSubscriber.name).equals(compile_topic_name(rosSubscriber.subscriber, NS)))) { +// remap_str += "\t(\"" + rosSubscriber.subscriber.name + "\", \"" + rosSubscriber.name + "\"),\n"; +// } +// } +// for (rosServiceServer : component.rosserviceserver) { +// if (!((prefix(NS)+rosServiceServer.name).equals(compile_service_name(rosServiceServer.srvserver, NS)))) { +// remap_str += "\t(\"" + rosServiceServer.srvserver.name + "\", \"" + rosServiceServer.name + "\"),\n"; +// } +// } +// for (rosServiceClient : component.rosserviceclient) { +// if (!((prefix(NS)+rosServiceClient.name).equals(compile_service_name(rosServiceClient.srvclient, NS)))) { +// remap_str += "\t(\"" + rosServiceClient.srvclient.name + "\", \"" + rosServiceClient.name + "\"),\n"; +// } +// } +// for (rosActionServer : component.rosactionserver) { +// if (!((prefix(NS)+rosActionServer.name).equals(compile_action_name(rosActionServer.actserver, NS)))) { +// remap_str += "\t(\"" + rosActionServer.actserver.name + "\", \"" + rosActionServer.name + "\"),\n"; +// } +// } +// for (rosActionClient : component.rosactionclient) { +// if (!((prefix(NS)+rosActionClient.name).equals(compile_action_name(rosActionClient.actclient, NS)))) { +// remap_str += "\t(\"" + rosActionClient.actclient.name + "\", \"" + rosActionClient.name + "\"),\n"; +// } +// } +// if (!remap_str.empty) { +// remap_str = ",\nremappings=[\n" + remap_str.substring(0,remap_str.length-2) + "]\n"; +// } +// return remap_str; +// } +// +// def String compile_parameters_str(EList rosParameters) { +// param_count = rosParameters.length; +// var param_str = ""; +// for (rosParameter : rosParameters) { +// val param_count=param_count--; +// if (rosParameter.parameter.type instanceof ParameterStructTypeImpl) { +// param_str += compile_struct_str(rosParameter.value, rosParameter.parameter.name); +// } else { +// param_str += "{ \"" + rosParameter.parameter.name + "\" : " + get_param_value(rosParameter.value, rosParameter.parameter.name); +// } +// if (param_count > 1){ +// param_str +=" },\n" +// } else { +// param_str +=" }\n"; +// } +// } +// return param_str; +// } +// +// def String compile_struct_str(ParameterValue value, String name) { +// var param_str = ""; +// var elem_count = (value as ParameterSequenceImpl).eContents.length; +// +// for (elem : ((value as ParameterSequenceImpl).eContents)) { +// var member = ((elem as ParameterStructImpl).eContents.get(0) as ParameterStructMemberImpl); +// val param_val = get_param_value(member.getValue(), name + "/" + member.getName()); +// if (param_val.startsWith("{")) { +// param_str += param_val; +// } else { +// param_str += "{ \"" + name + "/" + member.getName() + "\" : " + param_val; +// } +// elem_count--; +// if (elem_count > 0){ +// param_str +=" },\n" +// } +// } +// return param_str; +// } +// +// def String get_param_value(ParameterValue value, String name) { +// var param_val = ""; +// if (value instanceof ParameterStringImpl) { +// param_val = "\"" + (value as ParameterStringImpl).getValue() + "\""; +// } else if (value instanceof ParameterIntegerImpl) { +// param_val = (value as ParameterIntegerImpl).getValue().toString; +// } else if (value instanceof ParameterDoubleImpl) { +// param_val = (value as ParameterDoubleImpl).getValue().toString; +// } else if (value instanceof ParameterBooleanImpl) { +// param_val = (value as ParameterBooleanImpl).isValue().toString; +// } else if (value instanceof ParameterSequenceImpl) { +// var elem_count = (value as ParameterSequenceImpl).eContents.length; +// if ((value as ParameterSequenceImpl).eContents.get(0) instanceof ParameterStructImpl) { +// param_val = compile_struct_str(value, name); +// } else { +// param_val += "["; +// for (elem : (value as ParameterSequenceImpl).eContents) { +// param_val += get_param_value(elem as ParameterValue, name); +// elem_count--; +// if (elem_count > 0){ +// param_val +=", " +// } +// } +// param_val += "]"; +// } +// } +// return param_val; +// } +} diff --git a/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/RosSystemGenerator.xtend b/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/RosSystemGenerator.xtend index 560446d93..83bf567ce 100644 --- a/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/RosSystemGenerator.xtend +++ b/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/RosSystemGenerator.xtend @@ -7,6 +7,8 @@ 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 com.google.inject.Inject +import system.Rossystem /** * Generates code from your model files on save. @@ -14,12 +16,11 @@ import org.eclipse.xtext.generator.IGeneratorContext * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation */ class RosSystemGenerator extends AbstractGenerator { - + @Inject extension LaunchFileCompiler_ROS2 + override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) { -// fsa.generateFile('greetings.txt', 'People to greet: ' + -// resource.allContents -// .filter(Greeting) -// .map[name] -// .join(', ')) + for (system : resource.allContents.toIterable.filter(Rossystem)){ + fsa.generateFile(system.getName().toLowerCase+"_ros2/launch/"+system.getName()+".launch.py",compile_toROS2launch(system).toString().replace("\t"," ")) } } +} From a0da77a4bd4f66bebc21cf6e2e4dd0975d5fc305 Mon Sep 17 00:00:00 2001 From: ipa-nhg Date: Tue, 19 Sep 2023 10:56:40 +0200 Subject: [PATCH 2/2] First draft for a working version of the code generator for ROS2 launch files --- .../generator/CMakeListsCompiler.xtend | 49 ++++++ .../generator/GeneratorHelpers.xtend | 160 ++++++++++++++++++ .../generator/LaunchFileCompiler_ROS2.xtend | 21 +-- .../generator/PackageXmlCompiler.xtend | 67 ++++++++ .../generator/RosSystemGenerator.xtend | 34 +++- .../rossystem/generator/SetupPyCompiler.xtend | 34 ++++ 6 files changed, 351 insertions(+), 14 deletions(-) create mode 100644 plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/CMakeListsCompiler.xtend create mode 100644 plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/GeneratorHelpers.xtend create mode 100644 plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/PackageXmlCompiler.xtend create mode 100644 plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/SetupPyCompiler.xtend diff --git a/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/CMakeListsCompiler.xtend b/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/CMakeListsCompiler.xtend new file mode 100644 index 000000000..44acac9be --- /dev/null +++ b/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/CMakeListsCompiler.xtend @@ -0,0 +1,49 @@ +package de.fraunhofer.ipa.rossystem.generator + +import com.google.inject.Inject +import system.System + +class CMakeListsCompiler { + + @Inject extension GeneratorHelpers + + +// def compile_CMakeLists_ROS1(RosSystem system, ComponentStack stack) '''«init_pkg()» +//cmake_minimum_required(VERSION 2.8.3) +//project(«IF stack===null»«system.name.toLowerCase»«ELSE»«system.name.toLowerCase»_«stack.name.toLowerCase»«ENDIF») +// +//find_package(catkin REQUIRED) +// +//catkin_package() +// +// +//### INSTALL ### +//install(DIRECTORY launch +// DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} +//)''' + + def compile_CMakeLists_ROS2(System system) '''«init_pkg()» +cmake_minimum_required(VERSION 3.5) +project(«system.name.toLowerCase») + +# 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) + +### INSTALL ### +install(DIRECTORY launch + DESTINATION share/${PROJECT_NAME} +) + +ament_package() +''' + + +} \ No newline at end of file diff --git a/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/GeneratorHelpers.xtend b/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/GeneratorHelpers.xtend new file mode 100644 index 000000000..37f5a4f5b --- /dev/null +++ b/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/GeneratorHelpers.xtend @@ -0,0 +1,160 @@ +package de.fraunhofer.ipa.rossystem.generator + +import java.util.ArrayList +import ros.ActionClient +import ros.ActionServer +import ros.Parameter +import ros.Publisher +import ros.ServiceClient +import ros.ServiceServer +import ros.Subscriber +import system.System +import java.util.List +import ros.Node +import ros.impl.PackageImpl +import org.eclipse.emf.ecore.EObject +import java.util.Set +import java.util.HashSet +import ros.Dependency +import ros.PackageDependency +import system.Component +import system.RosNode +import ros.impl.AmentPackageImpl + +class GeneratorHelpers { + + boolean PackageSet + + AmentPackageImpl package_impl + List PkgsList + String Pkg + RosNode node + + def void init_pkg(){ + PackageSet=false + } + + def getPkgsDependencies (System rossystem){ + PkgsList = new ArrayList() + for (component: rossystem.components){ + init_pkg() + node = component as RosNode + Pkg = node.compile_pkg.toString() + if (!PkgsList.contains(Pkg)){ + PkgsList.add(Pkg) + } + return PkgsList; + } + + } + + def compile_pkg(RosNode component) +'''«IF !(component.from===null)»«component.from.getPackage_node.name»«ENDIF»''' + +// def PackageImpl get_pkg(ComponentInterface component) { +// if (component.fromRosNode!==null){ +// return getPackage_node(component.fromRosNode) +// } else if(!component.rospublisher.empty){ +// return getPacakge_fromObject(component.rospublisher.get(0).publisher) +// } else if (!component.rossubscriber.empty){ +// return getPacakge_fromObject(component.rossubscriber.get(0).subscriber) +// } else if (!component.rosserviceclient.empty){ +// return getPacakge_fromObject(component.rosserviceclient.get(0).srvclient) +// } else if (!component.rosserviceserver.empty){ +// return getPacakge_fromObject(component.rosserviceserver.get(0).srvserver) +// } else if (!component.rosactionclient.empty){ +// return getPacakge_fromObject(component.rosactionclient.get(0).actclient) +// } else if (!component.rosactionserver.empty){ +// return getPacakge_fromObject(component.rosactionserver.get(0).actserver) +// } else if (!component.rosparameter.empty){ +// return getPacakge_fromObject(component.rosparameter.get(0).parameter) +// } +// } +// +// def getPacakge_fromObject (EObject object){ +// package_impl = object.eContainer.eContainer.eContainer as PackageImpl; +// return package_impl; +// } +// +// def getPackage_pub(Publisher publisher){ +// package_impl = publisher.eContainer.eContainer.eContainer as PackageImpl; +// return package_impl; +// } +// def getPackage_sub(Subscriber subscriber){ +// package_impl = subscriber.eContainer.eContainer.eContainer as PackageImpl; +// return package_impl; +// } +// def getPackage_srvserv(ServiceServer serviceserver){ +// package_impl = serviceserver.eContainer.eContainer.eContainer as PackageImpl; +// return package_impl; +// } +// def getPackage_srvcli(ServiceClient serviceclient){ +// package_impl = serviceclient.eContainer.eContainer.eContainer as PackageImpl; +// return package_impl; +// } +// def getPackage_actserver(ActionServer actionserver){ +// package_impl = actionserver.eContainer.eContainer.eContainer as PackageImpl; +// return package_impl; +// } +// def getPackage_actclient(ActionClient actionclient){ +// package_impl = actionclient.eContainer.eContainer.eContainer as PackageImpl; +// return package_impl; +// } +// def getPackage_rosparam (Parameter param){ +// package_impl = param.eContainer.eContainer.eContainer as PackageImpl; +// return package_impl; +// } + def getPackage_node (Node node){ + package_impl = node.eContainer.eContainer as AmentPackageImpl; + return package_impl; + } + + //Launch files generators +// def check_ns(ComponentInterface component){ +// if (component.hasNS){ +// return component.get_ns(); +// }else { +// return ""; +// } +// } +// def boolean hasNS(ComponentInterface component){ +// if(!component.nameSpace.nullOrEmpty){ +// return true; +// }else{ +// return false +// } +// } +// def String get_ns(ComponentInterface component){ +// return component.nameSpace.replaceFirst("/",""); +// } +// +// def compile_pkg_type(ComponentInterface component) +//'''«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»''' +// +// def getPackageType_pub(Publisher publisher){ +// return publisher.eContainer.eContainer.eContainer as PackageImpl; +// } +// def getPackageType_sub(Subscriber subscriber){ +// return subscriber.eContainer.eContainer.eContainer as PackageImpl; +// } +// def getPackageType_srvserv(ServiceServer serviceserver){ +// return serviceserver.eContainer.eContainer.eContainer as PackageImpl; +// } +// def getPackageType_srvcli(ServiceClient serviceclient){ +// return serviceclient.eContainer.eContainer.eContainer as PackageImpl; +// } +// def getPackageType_actserver(ActionServer actionserver){ +// return actionserver.eContainer.eContainer.eContainer as PackageImpl; +// } +// def getPackageType_actclient(ActionClient actionclient){ +// return actionclient.eContainer.eContainer.eContainer as PackageImpl; +// } +// def getPackageType_rosparam (Parameter param){ +// return param.eContainer.eContainer.eContainer as PackageImpl; +// } +// def getPackageType_node (Node node){ +// return node.eContainer.eContainer as PackageImpl; +// } + + +} diff --git a/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/LaunchFileCompiler_ROS2.xtend b/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/LaunchFileCompiler_ROS2.xtend index 72438463a..a57d5a56d 100644 --- a/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/LaunchFileCompiler_ROS2.xtend +++ b/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/LaunchFileCompiler_ROS2.xtend @@ -3,30 +3,31 @@ package de.fraunhofer.ipa.rossystem.generator import system.RosNode import ros.RosPackage import ros.Artifact -import system.Rossystem +import system.System +import ros.AmentPackage +import ros.impl.AmentPackageImpl class LaunchFileCompiler_ROS2 { - def compile_toROS2launch(Rossystem system) ''' + def compile_toROS2launch(System system) ''' from launch import LaunchDescription from launch_ros.actions import Node def generate_launch_description(): ld = LaunchDescription() - «FOR component:system.components»«IF component.eClass=="RosNode"» + «FOR component:system.components» «(component as RosNode).name» = Node( - package="«((component as RosNode).from.eContainer.eContainer as RosPackage).name»", + package="«((component as RosNode).from.eContainer.eContainer as AmentPackageImpl).name»", executable="«((component as RosNode).from.eContainer as Artifact).name»", name="«(component as RosNode).name»" ) - «ENDIF» + «ENDFOR» - «FOR component:system.components»«IF component.eClass=="RosNode"» + «FOR component:system.components» ld.add_action(«(component as RosNode).name») - «ENDIF» «ENDFOR» return ld @@ -34,7 +35,7 @@ def generate_launch_description(): // def void compile_list_of_ROS2components(RosSystem system, ComponentStack stack) { // components_tmp_.clear; -// Ros2components.clear; +// Ros2components.clear; // if (stack === null){ // components_tmp_ = system.rosComponent; // } else { @@ -123,7 +124,7 @@ def generate_launch_description(): // } else { // param_str += "{ \"" + rosParameter.parameter.name + "\" : " + get_param_value(rosParameter.value, rosParameter.parameter.name); // } -// if (param_count > 1){ +// if (param_count > 1){ // param_str +=" },\n" // } else { // param_str +=" }\n"; @@ -145,7 +146,7 @@ def generate_launch_description(): // param_str += "{ \"" + name + "/" + member.getName() + "\" : " + param_val; // } // elem_count--; -// if (elem_count > 0){ +// if (elem_count > 0){ // param_str +=" },\n" // } // } diff --git a/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/PackageXmlCompiler.xtend b/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/PackageXmlCompiler.xtend new file mode 100644 index 000000000..46be8ec03 --- /dev/null +++ b/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/PackageXmlCompiler.xtend @@ -0,0 +1,67 @@ +package de.fraunhofer.ipa.rossystem.generator + +import system.System +import com.google.inject.Inject + +class PackageXmlCompiler{ + + @Inject extension GeneratorHelpers + +// def compile_package_xml_format2(System system) '''«init_pkg()» +// +// «IF stack===null»«system.name.toLowerCase»«ELSE»«system.name.toLowerCase»_«stack.name.toLowerCase»«ENDIF» +// 0.0.1 +// This package provides launch file for operating «IF stack===null»«system.name»«ELSE»«system.name.toLowerCase»_«stack.name»«ENDIF» +// +// Apache 2.0 +// +// http://wiki.ros.org/ +// +// +// Jane Doe +// Jane Doe +// +// catkin +// «FOR pkg:getPkgsDependencies(system, stack)» +// «pkg» +// «ENDFOR» +// +// +//''' + + + def compile_package_xml_format3(System system) '''«init_pkg()» + + + + «system.name.toLowerCase» + 0.0.1 + This package provides launch file for operating «system.name» + Jane Doe + Jane Doe + Apache 2.0 + + ament_cmake + + ament_index_python + launch + «FOR pkg:system.getPkgsDependencies» + «pkg» + «ENDFOR» + + + + + ament_python + + + ''' + + + } diff --git a/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/RosSystemGenerator.xtend b/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/RosSystemGenerator.xtend index 83bf567ce..239b0b867 100644 --- a/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/RosSystemGenerator.xtend +++ b/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/RosSystemGenerator.xtend @@ -7,8 +7,8 @@ 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 system.System import com.google.inject.Inject -import system.Rossystem /** * Generates code from your model files on save. @@ -17,10 +17,36 @@ import system.Rossystem */ class RosSystemGenerator extends AbstractGenerator { @Inject extension LaunchFileCompiler_ROS2 - + @Inject extension SetupPyCompiler + @Inject extension PackageXmlCompiler + @Inject extension CMakeListsCompiler + override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) { - for (system : resource.allContents.toIterable.filter(Rossystem)){ - fsa.generateFile(system.getName().toLowerCase+"_ros2/launch/"+system.getName()+".launch.py",compile_toROS2launch(system).toString().replace("\t"," ")) + for (system : resource.allContents.toIterable.filter(System)){ + fsa.generateFile( + system.getName().toLowerCase+"_ros2/launch/"+system.getName()+".launch.py", + compile_toROS2launch(system).toString().replace("\t"," ") + ) + fsa.generateFile( + system.getName().toLowerCase+"_ros2/package.xml", + compile_package_xml_format3(system) + ) + fsa.generateFile( + system.getName().toLowerCase+"_ros2/CMakeLists.txt", + compile_CMakeLists_ROS2(system) + ) + fsa.generateFile( + system.getName().toLowerCase+"_ros2/setup.py", + compile_setup_py(system) + ) + fsa.generateFile( + system.getName().toLowerCase+"_ros2/resource/" + system.getName().toLowerCase, + "" + ) + fsa.generateFile( + system.getName().toLowerCase+"_ros2/" + system.getName().toLowerCase + "/__init__.py", + "" + ) } } } diff --git a/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/SetupPyCompiler.xtend b/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/SetupPyCompiler.xtend new file mode 100644 index 000000000..c3e523818 --- /dev/null +++ b/plugins/de.fraunhofer.ipa.rossystem.xtext/src/de/fraunhofer/ipa/rossystem/generator/SetupPyCompiler.xtend @@ -0,0 +1,34 @@ +package de.fraunhofer.ipa.rossystem.generator + +import system.System +import com.google.inject.Inject + +class SetupPyCompiler{ + + @Inject extension GeneratorHelpers + + + def compile_setup_py(System system) '''«init_pkg()» +import os +from glob import glob +from setuptools import setup + +PACKAGE_NAME = '«system.name.toLowerCase»' + +setup( + name=PACKAGE_NAME, + version='0.0.1', + packages=[PACKAGE_NAME], + data_files=[ + # Install marker file in the package index + ('share/ament_index/resource_index/packages', + ['resource/' + PACKAGE_NAME]), + # Include our package.xml file + (os.path.join('share', PACKAGE_NAME), ['package.xml']), + # Include all launch files. + (os.path.join('share', PACKAGE_NAME, 'launch'), glob(os.path.join('launch', '*.launch.py'))) + ], + install_requires=['setuptools'], + zip_safe=True +)''' + }