From 7e50ea2876a9644354e842de2bdd155aa0a5ece2 Mon Sep 17 00:00:00 2001 From: Emerson Knapp Date: Fri, 17 May 2019 13:47:46 -0700 Subject: [PATCH 1/3] Add convenience name translations for use by commandline utilities etc. Signed-off-by: Emerson Knapp --- rclpy/rclpy/qos.py | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/rclpy/rclpy/qos.py b/rclpy/rclpy/qos.py index 3d33ae201..cd9f7dd42 100644 --- a/rclpy/rclpy/qos.py +++ b/rclpy/rclpy/qos.py @@ -308,3 +308,65 @@ def __init__(self, qos_profile: QoSProfile, profile_name: str): 'qos_profile_parameter_events') qos_profile_action_status_default = _rclpy_action.rclpy_action_get_rmw_qos_profile( 'rcl_action_qos_profile_status_default') + + +class QoSNameTranslations: + """ + Convenience namespace to provide String->Type translations for string-configured utilities. + + For example, the ros2topic command line tool uses these maps for its options. + """ + + HistoryPolicy = { + None: None, # Allow default of None + 'system_default': + QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT, + 'keep_last': + QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_KEEP_LAST, + 'keep_all': + QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_KEEP_ALL, + } + ReliabilityPolicy = { + None: None, # Allow default of None + 'system_default': + QoSReliabilityPolicy.RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT, + 'reliable': + QoSReliabilityPolicy.RMW_QOS_POLICY_RELIABILITY_RELIABLE, + 'best_effort': + QoSReliabilityPolicy.RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT, + } + DurabilityPolicy = { + None: None, # Allow default of None + 'system_default': + QoSDurabilityPolicy.RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT, + 'transient_local': + QoSDurabilityPolicy.RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL, + 'volatile': + QoSDurabilityPolicy.RMW_QOS_POLICY_DURABILITY_VOLATILE, + } + LivelinessPolicy = { + None: None, # Allow default of None + 'system_default': + QoSLivelinessPolicy.RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT, + 'automatic': + QoSLivelinessPolicy.RMW_QOS_POLICY_LIVELINESS_AUTOMATIC, + 'manual_by_node': + QoSLivelinessPolicy.RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_NODE, + 'manual_by_topic': + QoSLivelinessPolicy.RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC, + } + PresetProfiles = { + None: qos_profile_system_default, # Allow default of None + 'system_default': + qos_profile_system_default, + 'sensor_data': + qos_profile_sensor_data, + 'services_default': + qos_profile_services_default, + 'parameters': + qos_profile_parameters, + 'parameter_events': + qos_profile_parameter_events, + 'action_status_default': + qos_profile_action_status_default, + } From 9d8920675ce562b0d86b8dc53b8b341d1d185a2e Mon Sep 17 00:00:00 2001 From: Emerson Knapp Date: Mon, 20 May 2019 14:36:05 -0700 Subject: [PATCH 2/3] Get the friendly names closer to the definitions, using enum semantics Signed-off-by: Emerson Knapp --- rclpy/rclpy/qos.py | 101 +++++++++++++++-------------------------- rclpy/test/test_qos.py | 16 +++++++ 2 files changed, 53 insertions(+), 64 deletions(-) diff --git a/rclpy/rclpy/qos.py b/rclpy/rclpy/qos.py index cd9f7dd42..4f3577854 100644 --- a/rclpy/rclpy/qos.py +++ b/rclpy/rclpy/qos.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from enum import Enum from enum import IntEnum import warnings @@ -228,7 +229,19 @@ def __eq__(self, other): for slot in self.__slots__) -class QoSHistoryPolicy(IntEnum): +class QoSPolicyEnum(IntEnum): + """ + Base for QoS Policy enumerations. + + Provides helper function to filter keys for utilities. + """ + + @classmethod + def short_keys(cls): + return [k for k in cls.__members__.keys() if not k.startswith('RMW')] + + +class QoSHistoryPolicy(QoSPolicyEnum): """ Enum for QoS History settings. @@ -236,11 +249,14 @@ class QoSHistoryPolicy(IntEnum): """ RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT = 0 + system_default = RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT RMW_QOS_POLICY_HISTORY_KEEP_LAST = 1 + keep_last = RMW_QOS_POLICY_HISTORY_KEEP_LAST RMW_QOS_POLICY_HISTORY_KEEP_ALL = 2 + keep_all = RMW_QOS_POLICY_HISTORY_KEEP_ALL -class QoSReliabilityPolicy(IntEnum): +class QoSReliabilityPolicy(QoSPolicyEnum): """ Enum for QoS Reliability settings. @@ -248,11 +264,14 @@ class QoSReliabilityPolicy(IntEnum): """ RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT = 0 + system_default = RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT RMW_QOS_POLICY_RELIABILITY_RELIABLE = 1 + reliable = RMW_QOS_POLICY_RELIABILITY_RELIABLE RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT = 2 + best_effort = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT -class QoSDurabilityPolicy(IntEnum): +class QoSDurabilityPolicy(QoSPolicyEnum): """ Enum for QoS Durability settings. @@ -260,11 +279,14 @@ class QoSDurabilityPolicy(IntEnum): """ RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT = 0 + system_default = RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL = 1 + transient_local = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL RMW_QOS_POLICY_DURABILITY_VOLATILE = 2 + volatile = RMW_QOS_POLICY_DURABILITY_VOLATILE -class QoSLivelinessPolicy(IntEnum): +class QoSLivelinessPolicy(QoSPolicyEnum): """ Enum for QoS Liveliness settings. @@ -272,9 +294,13 @@ class QoSLivelinessPolicy(IntEnum): """ RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT = 0 + system_default = RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT RMW_QOS_POLICY_LIVELINESS_AUTOMATIC = 1 + automatic = RMW_QOS_POLICY_LIVELINESS_AUTOMATIC RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_NODE = 2 + manual_by_node = RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_NODE RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC = 3 + manual_by_topic = RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC class DeprecatedQoSProfile(QoSProfile): @@ -310,63 +336,10 @@ def __init__(self, qos_profile: QoSProfile, profile_name: str): 'rcl_action_qos_profile_status_default') -class QoSNameTranslations: - """ - Convenience namespace to provide String->Type translations for string-configured utilities. - - For example, the ros2topic command line tool uses these maps for its options. - """ - - HistoryPolicy = { - None: None, # Allow default of None - 'system_default': - QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT, - 'keep_last': - QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_KEEP_LAST, - 'keep_all': - QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_KEEP_ALL, - } - ReliabilityPolicy = { - None: None, # Allow default of None - 'system_default': - QoSReliabilityPolicy.RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT, - 'reliable': - QoSReliabilityPolicy.RMW_QOS_POLICY_RELIABILITY_RELIABLE, - 'best_effort': - QoSReliabilityPolicy.RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT, - } - DurabilityPolicy = { - None: None, # Allow default of None - 'system_default': - QoSDurabilityPolicy.RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT, - 'transient_local': - QoSDurabilityPolicy.RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL, - 'volatile': - QoSDurabilityPolicy.RMW_QOS_POLICY_DURABILITY_VOLATILE, - } - LivelinessPolicy = { - None: None, # Allow default of None - 'system_default': - QoSLivelinessPolicy.RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT, - 'automatic': - QoSLivelinessPolicy.RMW_QOS_POLICY_LIVELINESS_AUTOMATIC, - 'manual_by_node': - QoSLivelinessPolicy.RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_NODE, - 'manual_by_topic': - QoSLivelinessPolicy.RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC, - } - PresetProfiles = { - None: qos_profile_system_default, # Allow default of None - 'system_default': - qos_profile_system_default, - 'sensor_data': - qos_profile_sensor_data, - 'services_default': - qos_profile_services_default, - 'parameters': - qos_profile_parameters, - 'parameter_events': - qos_profile_parameter_events, - 'action_status_default': - qos_profile_action_status_default, - } +class QoSPresetProfiles(Enum): + system_default = qos_profile_system_default + sensor_data = qos_profile_sensor_data + services_default = qos_profile_services_default + parameters = qos_profile_parameters + parameter_events = qos_profile_parameter_events + action_status_default = qos_profile_action_status_default diff --git a/rclpy/test/test_qos.py b/rclpy/test/test_qos.py index 589ee8b9c..ada962d8a 100644 --- a/rclpy/test/test_qos.py +++ b/rclpy/test/test_qos.py @@ -17,9 +17,11 @@ from rclpy.duration import Duration from rclpy.impl.implementation_singleton import rclpy_implementation as _rclpy +from rclpy.qos import qos_profile_system_default from rclpy.qos import QoSDurabilityPolicy from rclpy.qos import QoSHistoryPolicy from rclpy.qos import QoSLivelinessPolicy +from rclpy.qos import QoSPresetProfiles from rclpy.qos import QoSProfile from rclpy.qos import QoSReliabilityPolicy @@ -120,3 +122,17 @@ def test_deprecation_warnings(self): # No deprecation if only depth QoSProfile(depth=1) assert len(w) == 0, str(w[-1].message) + + def test_policy_short_names(self): + # Full test on History to show the mechanism works + assert QoSHistoryPolicy.short_keys() == ['system_default', 'keep_last', 'keep_all'] + assert ( + QoSHistoryPolicy['system_default'] == + QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT) + assert QoSHistoryPolicy['keep_all'] == QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_KEEP_ALL + assert QoSHistoryPolicy['keep_last'] == QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_KEEP_LAST + + def test_preset_profiles(self): + # Make sure the Enum does what we expect + assert QoSPresetProfiles.system_default.value == qos_profile_system_default + assert QoSPresetProfiles['system_default'] == QoSPresetProfiles.system_default From 9353c7a9a075f79806f77b86702d06053fc0766f Mon Sep 17 00:00:00 2001 From: Emerson Knapp Date: Mon, 20 May 2019 16:02:12 -0700 Subject: [PATCH 3/3] All uppercase enum values Signed-off-by: Emerson Knapp --- rclpy/rclpy/qos.py | 60 ++++++++++++++++++++++++++++-------------- rclpy/test/test_qos.py | 18 ++++++++----- 2 files changed, 52 insertions(+), 26 deletions(-) diff --git a/rclpy/rclpy/qos.py b/rclpy/rclpy/qos.py index 4f3577854..6f3d13caf 100644 --- a/rclpy/rclpy/qos.py +++ b/rclpy/rclpy/qos.py @@ -238,7 +238,13 @@ class QoSPolicyEnum(IntEnum): @classmethod def short_keys(cls): - return [k for k in cls.__members__.keys() if not k.startswith('RMW')] + """Return a list of shortened typing-friendly enum values.""" + return [k.lower() for k in cls.__members__.keys() if not k.startswith('RMW')] + + @classmethod + def get_from_short_key(cls, name): + """Retrieve a policy type from a short name, case-insensitive.""" + return cls[name.upper()].value class QoSHistoryPolicy(QoSPolicyEnum): @@ -249,11 +255,11 @@ class QoSHistoryPolicy(QoSPolicyEnum): """ RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT = 0 - system_default = RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT + SYSTEM_DEFAULT = RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT RMW_QOS_POLICY_HISTORY_KEEP_LAST = 1 - keep_last = RMW_QOS_POLICY_HISTORY_KEEP_LAST + KEEP_LAST = RMW_QOS_POLICY_HISTORY_KEEP_LAST RMW_QOS_POLICY_HISTORY_KEEP_ALL = 2 - keep_all = RMW_QOS_POLICY_HISTORY_KEEP_ALL + KEEP_ALL = RMW_QOS_POLICY_HISTORY_KEEP_ALL class QoSReliabilityPolicy(QoSPolicyEnum): @@ -264,11 +270,11 @@ class QoSReliabilityPolicy(QoSPolicyEnum): """ RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT = 0 - system_default = RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT + SYSTEM_DEFAULT = RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT RMW_QOS_POLICY_RELIABILITY_RELIABLE = 1 - reliable = RMW_QOS_POLICY_RELIABILITY_RELIABLE + RELIABLE = RMW_QOS_POLICY_RELIABILITY_RELIABLE RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT = 2 - best_effort = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT + BEST_EFFORT = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT class QoSDurabilityPolicy(QoSPolicyEnum): @@ -279,11 +285,11 @@ class QoSDurabilityPolicy(QoSPolicyEnum): """ RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT = 0 - system_default = RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT + SYSTEM_DEFAULT = RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL = 1 - transient_local = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL + TRANSIENT_LOCAL = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL RMW_QOS_POLICY_DURABILITY_VOLATILE = 2 - volatile = RMW_QOS_POLICY_DURABILITY_VOLATILE + VOLATILE = RMW_QOS_POLICY_DURABILITY_VOLATILE class QoSLivelinessPolicy(QoSPolicyEnum): @@ -294,13 +300,13 @@ class QoSLivelinessPolicy(QoSPolicyEnum): """ RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT = 0 - system_default = RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT + SYSTEM_DEFAULT = RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT RMW_QOS_POLICY_LIVELINESS_AUTOMATIC = 1 - automatic = RMW_QOS_POLICY_LIVELINESS_AUTOMATIC + AUTOMATIC = RMW_QOS_POLICY_LIVELINESS_AUTOMATIC RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_NODE = 2 - manual_by_node = RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_NODE + MANUAL_BY_NODE = RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_NODE RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC = 3 - manual_by_topic = RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC + MANUAL_BY_TOPIC = RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC class DeprecatedQoSProfile(QoSProfile): @@ -337,9 +343,23 @@ def __init__(self, qos_profile: QoSProfile, profile_name: str): class QoSPresetProfiles(Enum): - system_default = qos_profile_system_default - sensor_data = qos_profile_sensor_data - services_default = qos_profile_services_default - parameters = qos_profile_parameters - parameter_events = qos_profile_parameter_events - action_status_default = qos_profile_action_status_default + SYSTEM_DEFAULT = qos_profile_system_default + SENSOR_DATA = qos_profile_sensor_data + SERVICES_DEFAULT = qos_profile_services_default + PARAMETERS = qos_profile_parameters + PARAMETER_EVENTS = qos_profile_parameter_events + ACTION_STATUS_DEFAULT = qos_profile_action_status_default + + """Noted that the following are duplicated from QoSPolicyEnum. + + Our supported version of Python3 (3.5) doesn't have a fix that allows mixins on Enum. + """ + @classmethod + def short_keys(cls): + """Return a list of shortened typing-friendly enum values.""" + return [k.lower() for k in cls.__members__.keys() if not k.startswith('RMW')] + + @classmethod + def get_from_short_key(cls, name): + """Retrieve a policy type from a short name, case-insensitive.""" + return cls[name.upper()].value diff --git a/rclpy/test/test_qos.py b/rclpy/test/test_qos.py index ada962d8a..4693f78f4 100644 --- a/rclpy/test/test_qos.py +++ b/rclpy/test/test_qos.py @@ -127,12 +127,18 @@ def test_policy_short_names(self): # Full test on History to show the mechanism works assert QoSHistoryPolicy.short_keys() == ['system_default', 'keep_last', 'keep_all'] assert ( - QoSHistoryPolicy['system_default'] == - QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT) - assert QoSHistoryPolicy['keep_all'] == QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_KEEP_ALL - assert QoSHistoryPolicy['keep_last'] == QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_KEEP_LAST + QoSHistoryPolicy.get_from_short_key('system_default') == + QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT.value) + assert ( + QoSHistoryPolicy.get_from_short_key('KEEP_ALL') == + QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_KEEP_ALL.value) + assert ( + QoSHistoryPolicy.get_from_short_key('KEEP_last') == + QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_KEEP_LAST.value) def test_preset_profiles(self): # Make sure the Enum does what we expect - assert QoSPresetProfiles.system_default.value == qos_profile_system_default - assert QoSPresetProfiles['system_default'] == QoSPresetProfiles.system_default + assert QoSPresetProfiles.SYSTEM_DEFAULT.value == qos_profile_system_default + assert ( + QoSPresetProfiles.SYSTEM_DEFAULT.value == + QoSPresetProfiles.get_from_short_key('system_default'))