From b30fd0d65330e93858de6e21d2b340c5742d0821 Mon Sep 17 00:00:00 2001 From: Thomas Moulard Date: Fri, 20 Dec 2019 11:21:49 -0800 Subject: [PATCH] Fix plotting of values containers in an array Before this commit, attempting to plot a value in an array would trigger the following exception: Traceback (most recent call last): File "/opt/ros/eloquent/lib/python3.6/site-packages/rqt_plot/plot_widget.py", line 259, in on_topic_edit_textChanged plottable, message = is_plottable(self._node, topic_name) File "/opt/ros/eloquent/lib/python3.6/site-packages/rqt_plot/plot_widget.py", line 154, in is_plottable fields, message = get_plot_fields(node, topic_name) File "/opt/ros/eloquent/lib/python3.6/site-packages/rqt_plot/plot_widget.py", line 137, in get_plot_fields for slot, slot_type in field_class.get_fields_and_field_types().items(): AttributeError: 'NoneType' object has no attribute 'get_fields_and_field_types' Line 129 in plot_widget.py: field_class = message_helpers.get_message_class(slot_type) ...would be executed with slot_type set to 'sequence' which returns a None value. field_class is set to None and the call to get_fields_and_field_types is then failing. This pull request adds an extra layer of logic before calling get_message_class to ensure that, if the type is an array, we extract the inner array type instead of attempting to run get_message_class on the DDS sequence type directly. Signed-off-by: Thomas Moulard --- src/rqt_plot/plot_widget.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/rqt_plot/plot_widget.py b/src/rqt_plot/plot_widget.py index 98f4319..ff85bdd 100644 --- a/src/rqt_plot/plot_widget.py +++ b/src/rqt_plot/plot_widget.py @@ -31,6 +31,7 @@ # POSSIBILITY OF SUCH DAMAGE. import os +import re import time from ament_index_python.resources import get_resource @@ -114,6 +115,14 @@ def get_plot_fields(node, topic_name): slot_type, slot_is_array, array_size = _parse_type(slot_type) is_array = slot_is_array and field_index is None + # If the field is an array, we need to update slot_type to extract + # the inner type, e.g. sequence -> foo_msgs/Foo + # See https://design.ros2.org/articles/mapping_dds_types.html + if is_array: + sequence_inner_type_regexp = re.match('sequence<(.*)>', slot_type) + if sequence_inner_type_regexp: + slot_type = sequence_inner_type_regexp.groupdict()['slot_type'] + if topic_helpers.is_primitive_type(slot_type): field_class = topic_helpers.get_type_class(slot_type) else: