Bug 582095 - [Robotics] Several small issues
1. Python: if no chrono literal postfix is found, pass unmodified value
(modified python ComponentTransformations)
2. Port handlers: use varName function to escape some potentially problematic names in new function that is created when connecting an activity port
(modified CreateFunctionsCommand)
3. Take all communication objects into account (modified InteractionUtils)
4. In an action, loop over feedback attributes instead of twice over response (modified CreateMessage)
5. Add escapeUnderscore function to RosHelpers and use it for filename calculations
For consistency: Move CamlCase function into RosHelpers, since rather specific for ROS)
Change-Id: I3eeaf7c8507f4b971662bcd46eb586ec2cad82fb
Signed-off-by: aradermache <ansgar.radermacher@cea.fr>
diff --git a/plugins/codegen/org.eclipse.papyrus.robotics.codegen.common/src/org/eclipse/papyrus/robotics/codegen/common/utils/Helpers.java b/plugins/codegen/org.eclipse.papyrus.robotics.codegen.common/src/org/eclipse/papyrus/robotics/codegen/common/utils/Helpers.java
index e34a561..625dc0a 100644
--- a/plugins/codegen/org.eclipse.papyrus.robotics.codegen.common/src/org/eclipse/papyrus/robotics/codegen/common/utils/Helpers.java
+++ b/plugins/codegen/org.eclipse.papyrus.robotics.codegen.common/src/org/eclipse/papyrus/robotics/codegen/common/utils/Helpers.java
@@ -93,37 +93,4 @@
Ptr ptr = StereotypeUtil.applyApp(typedElement, Ptr.class);
ptr.setDeclaration("::SharedPtr"); //$NON-NLS-1$
}
-
- /**
- * Return a small_caps string (for file names) in which CamlCase is prefixed with "_"
- * e.g. ServiceType is transformed into service_type. The "_" is added to upper case
- * characters following previous alphabetic or digit characters. I.e. it is not added
- * after special characters including in particular the FileSeparator.
- * This function is not only used by ROS, but also by protobuf
- *
- * @param str
- * a string
- * @return the transformed string
- */
- public static String escapeCamlCase(String str) {
- String out = ""; //$NON-NLS-1$
- boolean previousLC = false;
- boolean previousUC = false;
- int i = 1;
- for (char c : str.toCharArray()) {
- // underscore prefix also depends on next character
- boolean nextLC = i < str.length() ?
- Character.isLowerCase(str.charAt(i++)) :
- false;
- if (Character.isUpperCase(c)) {
- if (previousLC || (previousUC && nextLC)) {
- out += "_"; //$NON-NLS-1$
- }
- }
- previousLC = Character.isLowerCase(c);
- previousUC = Character.isUpperCase(c);
- out += Character.toLowerCase(c);
- }
- return out;
- }
}
diff --git a/plugins/customization/org.eclipse.papyrus.robotics.core/src/org/eclipse/papyrus/robotics/core/commands/CreateFunctionsCommand.java b/plugins/customization/org.eclipse.papyrus.robotics.core/src/org/eclipse/papyrus/robotics/core/commands/CreateFunctionsCommand.java
index 490276c..5db9eb8 100644
--- a/plugins/customization/org.eclipse.papyrus.robotics.core/src/org/eclipse/papyrus/robotics/core/commands/CreateFunctionsCommand.java
+++ b/plugins/customization/org.eclipse.papyrus.robotics.core/src/org/eclipse/papyrus/robotics/core/commands/CreateFunctionsCommand.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2020 CEA LIST
+ * Copyright (c) 2023 CEA LIST
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -9,7 +9,8 @@
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
- * Ansgar Radermacher - initial API and implementation
+ * Ansgar Radermacher - initial API and implementation
+ * Ansgar Radermacher - Bug 582095
*
*****************************************************************************/
@@ -17,6 +18,7 @@
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.util.TransactionUtil;
+import org.eclipse.papyrus.designer.infra.base.StringUtils;
import org.eclipse.papyrus.robotics.core.utils.FunctionUtils;
import org.eclipse.papyrus.robotics.core.utils.InteractionUtils;
import org.eclipse.papyrus.robotics.profile.robotics.commpattern.CommunicationPattern;
@@ -90,7 +92,8 @@
protected void setName(Property fctAttr, String postFix) {
Type function = fctAttr.getType();
- function.setName(componentPortUml.getName() + "_" + postFix); //$NON-NLS-1$
+ // use varName to assure that created function name is compatible with most programming languages
+ function.setName(StringUtils.varName(componentPortUml.getName()) + "_" + postFix); //$NON-NLS-1$
}
protected void createFunction(String postFix) {
diff --git a/plugins/customization/org.eclipse.papyrus.robotics.core/src/org/eclipse/papyrus/robotics/core/utils/InteractionUtils.java b/plugins/customization/org.eclipse.papyrus.robotics.core/src/org/eclipse/papyrus/robotics/core/utils/InteractionUtils.java
index 819b94d..b127948 100644
--- a/plugins/customization/org.eclipse.papyrus.robotics.core/src/org/eclipse/papyrus/robotics/core/utils/InteractionUtils.java
+++ b/plugins/customization/org.eclipse.papyrus.robotics.core/src/org/eclipse/papyrus/robotics/core/utils/InteractionUtils.java
@@ -110,7 +110,7 @@
}
/**
- * Get the communication object from a template binding (first template parameter)
+ * Get the communication object from a template binding (all parameter substitutions)
*
* @param tb
* a template binding
@@ -119,8 +119,8 @@
public static List<Type> getCommObjects(TemplateBinding tb) {
List<Type> commObjects = new ArrayList<Type>();
if (tb != null) {
- if (tb.getParameterSubstitutions().size() > 0) {
- ParameterableElement pe = tb.getParameterSubstitutions().get(0).getActual();
+ for (TemplateParameterSubstitution tps : tb.getParameterSubstitutions()) {
+ ParameterableElement pe = tps.getActual();
if (pe instanceof Type) {
commObjects.add((Type) pe);
}
diff --git a/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/message/CreateMessage.xtend b/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/message/CreateMessage.xtend
index a5f6d98..71b83f6 100644
--- a/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/message/CreateMessage.xtend
+++ b/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/message/CreateMessage.xtend
@@ -102,7 +102,7 @@
«ENDFOR»
---
# attributes of feedback «feedback.qualifiedName»
- «FOR attribute : response.getAllAttributes»
+ «FOR attribute : feedback.getAllAttributes»
«attribute.createAttributeMsg»
«ENDFOR»
'''
diff --git a/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/message/CreateMsgPackage.xtend b/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/message/CreateMsgPackage.xtend
index bc68d75..442df89 100644
--- a/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/message/CreateMsgPackage.xtend
+++ b/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/message/CreateMsgPackage.xtend
@@ -30,6 +30,7 @@
import org.eclipse.uml2.uml.TemplateBinding
import static extension org.eclipse.papyrus.robotics.codegen.common.utils.PackageTools.pkgName
+import static extension org.eclipse.papyrus.robotics.ros2.codegen.common.utils.RosHelpers.escapeUnderscore
import static extension org.eclipse.papyrus.robotics.core.utils.InteractionUtils.*
import static extension org.eclipse.papyrus.robotics.ros2.codegen.common.utils.MessageUtils.*
@@ -118,14 +119,14 @@
// messages covers push and send (and enumerations)
for (msg : srcPkg.messages) {
- cm.generateFile(fileAccess, msg.name, MessageUtils.MESSAGE, cm.createDtOrEnumMsg(msg))
+ cm.generateFile(fileAccess, msg.name.escapeUnderscore, MessageUtils.MESSAGE, cm.createDtOrEnumMsg(msg))
}
for (sd : srcPkg.queries) {
// request and reply data types are found in communication package
val tb = sd.templateBinding
val req = MessageUtils.getRequest(tb)
val res = MessageUtils.getResponse(tb)
- cm.generateFile(fileAccess, sd.nameWoPrefix, MessageUtils.SERVICE, cm.createServiceMsg(req as DataType, res as DataType))
+ cm.generateFile(fileAccess, sd.nameWoPrefix.escapeUnderscore, MessageUtils.SERVICE, cm.createServiceMsg(req as DataType, res as DataType))
}
for (sd : srcPkg.actions) {
// request and reply data types are found in communication package
@@ -133,7 +134,7 @@
val goal = MessageUtils.getGoal(tb)
val res = MessageUtils.getResponse(tb)
val feedback = MessageUtils.getFeedback(tb)
- cm.generateFile(fileAccess, sd.nameWoPrefix, MessageUtils.ACTION, cm.createActionMsg(goal as DataType, res as DataType, feedback as DataType))
+ cm.generateFile(fileAccess, sd.nameWoPrefix.escapeUnderscore, MessageUtils.ACTION, cm.createActionMsg(goal as DataType, res as DataType, feedback as DataType))
}
try {
fileAccess.cleanUntouched(project.getFolder(MessageUtils.MESSAGE), new NullProgressMonitor);
diff --git a/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/utils/MessageUtils.xtend b/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/utils/MessageUtils.xtend
index 476ebb1..958f2b9 100644
--- a/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/utils/MessageUtils.xtend
+++ b/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/utils/MessageUtils.xtend
@@ -51,7 +51,8 @@
import org.eclipse.uml2.uml.Type
import static extension org.eclipse.papyrus.robotics.codegen.common.utils.ComponentUtils.isRegistered
-import static extension org.eclipse.papyrus.robotics.codegen.common.utils.Helpers.escapeCamlCase
+import static extension org.eclipse.papyrus.robotics.ros2.codegen.common.utils.RosHelpers.escapeCamlCase
+import static extension org.eclipse.papyrus.robotics.ros2.codegen.common.utils.RosHelpers.escapeUnderscore
import static extension org.eclipse.papyrus.robotics.core.utils.InteractionUtils.*
class MessageUtils {
@@ -197,7 +198,7 @@
val msgFileNames = new UniqueEList<String>
for (msg : msgPackage.messages) {
- msgFileNames.add(msg.name + ".msg")
+ msgFileNames.add(msg.name.escapeUnderscore + ".msg")
}
return msgFileNames
}
@@ -206,7 +207,7 @@
val srvFileNames = new UniqueEList<String>
for (sd : msgPackage.queries) {
// use name of service definition, typically consisting of a query and a request
- srvFileNames.add(sd.nameWoPrefix + ".srv")
+ srvFileNames.add(sd.nameWoPrefix.escapeUnderscore + ".srv")
}
return srvFileNames
}
@@ -215,7 +216,7 @@
val actFileNames = new UniqueEList<String>
for (sd : msgPackage.actions) {
// use name of service definition, typically consisting of a query and a request
- actFileNames.add(sd.nameWoPrefix + ".action")
+ actFileNames.add(sd.nameWoPrefix.escapeUnderscore + ".action")
}
return actFileNames
}
diff --git a/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/utils/RosHelpers.java b/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/utils/RosHelpers.java
index d955757..6283c1a 100644
--- a/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/utils/RosHelpers.java
+++ b/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/utils/RosHelpers.java
@@ -15,6 +15,7 @@
package org.eclipse.papyrus.robotics.ros2.codegen.common.utils;
import org.eclipse.emf.common.util.URI;
+import org.eclipse.papyrus.designer.infra.base.StringConstants;
import org.eclipse.papyrus.designer.languages.cpp.profile.C_Cpp.External;
import org.eclipse.papyrus.designer.languages.cpp.profile.C_Cpp.Ptr;
import org.eclipse.papyrus.robotics.codegen.common.utils.Helpers;
@@ -82,4 +83,47 @@
Ptr ptr = StereotypeUtil.applyApp(typedElement, Ptr.class);
ptr.setDeclaration("::SharedPtr"); //$NON-NLS-1$
}
+
+ /**
+ * Return a small_caps string (for file names) in which CamlCase is prefixed with "_"
+ * e.g. ServiceType is transformed into service_type. The "_" is added to upper case
+ * characters following previous alphabetic or digit characters. I.e. it is not added
+ * after special characters including in particular the FileSeparator.
+ * This function is not only used by ROS, but also by protobuf
+ *
+ * @param str
+ * a string
+ * @return the transformed string
+ */
+ public static String escapeCamlCase(String str) {
+ String out = StringConstants.EMPTY;
+ boolean previousLC = false;
+ boolean previousUC = false;
+ int i = 1;
+ for (char c : str.toCharArray()) {
+ // underscore prefix also depends on next character
+ boolean nextLC = i < str.length() ? Character.isLowerCase(str.charAt(i++)) : false;
+ if (Character.isUpperCase(c)) {
+ if (previousLC || (previousUC && nextLC)) {
+ out += StringConstants.UNDERSCORE;
+ }
+ }
+ previousLC = Character.isLowerCase(c);
+ previousUC = Character.isUpperCase(c);
+ out += Character.toLowerCase(c);
+ }
+ return out;
+ }
+
+ /**
+ * Simple implementation of avoiding underscores by just removing them (for service definition filenames)
+ *
+ * @param str
+ * a string
+ * @return the string without underscore
+ */
+ public static String escapeUnderscore(String str) {
+ return str.replaceAll(StringConstants.UNDERSCORE, StringConstants.SPACE);
+ }
+
}
diff --git a/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/utils/SkillUtils.xtend b/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/utils/SkillUtils.xtend
index a75b5f3..5df19e0 100644
--- a/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/utils/SkillUtils.xtend
+++ b/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.common/src/org/eclipse/papyrus/robotics/ros2/codegen/common/utils/SkillUtils.xtend
@@ -27,7 +27,7 @@
import org.eclipse.uml2.uml.util.UMLUtil
import static extension org.eclipse.papyrus.robotics.core.utils.InteractionUtils.*
-import static extension org.eclipse.papyrus.robotics.codegen.common.utils.Helpers.escapeCamlCase
+import static extension org.eclipse.papyrus.robotics.ros2.codegen.common.utils.RosHelpers.escapeCamlCase
import static extension org.eclipse.papyrus.robotics.codegen.common.utils.PackageTools.pkgName
import static extension org.eclipse.papyrus.robotics.ros2.codegen.common.utils.MessageUtils.*
import org.eclipse.uml2.uml.Namespace
diff --git a/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.python/src/org/eclipse/papyrus/robotics/ros2/codegen/python/component/ComponentTransformations.xtend b/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.python/src/org/eclipse/papyrus/robotics/ros2/codegen/python/component/ComponentTransformations.xtend
index fec1a2f..a89ece1 100644
--- a/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.python/src/org/eclipse/papyrus/robotics/ros2/codegen/python/component/ComponentTransformations.xtend
+++ b/plugins/ros2/org.eclipse.papyrus.robotics.ros2.codegen.python/src/org/eclipse/papyrus/robotics/ros2/codegen/python/component/ComponentTransformations.xtend
@@ -96,14 +96,20 @@
}
/**
- *
+ * Convert a method that uses a unit in seconds or milliseconds to a number
+ * passed to the Python call (unlike in C++, there are no ChronoLiterals)
*/
def static convertPeriod(String period) {
if (period.contains("ms")) {
val floatPeriod = Float.parseFloat(period.replace("ms", "")) / 1000
return floatPeriod.toString
- } else if (period.contains("s"))
+ } else if (period.contains("s")) {
return period.replace("s", "")
+ }
+ else {
+ // return unmodified period
+ return period;
+ }
}
/**