From 2381bf474aa70323752b9f66cb5bbe93a5b0f99c Mon Sep 17 00:00:00 2001 From: Loy van Beek Date: Mon, 7 Nov 2022 00:19:40 +0100 Subject: [PATCH] Apply automatic mapping rules in case only package+message mapping exists (#382) * Fix message mapping by removing early return so other rules can still be applied In determine_field_mapping, there was an early return inside a loop over all mapping rules. IF there we any mapping rules but they don't specify field mappings, the early return made the function return without creating mappings automatically. For a particular message type, ROS 1's uuid_msgs/UniqueID vs ROS 2's unique_identifier_msgs/UUID, the message definition is exacly the same but type name is not. The only mapping fule defined in for unique_identifier_msgs/UUID is that it maps to uuid_msgs/UniqueID, but no field mappings are needed because the definitions are the same. But, then we hit the early return (because the for-loop is ran without any rule applying to the message at hand and thus not `continue`-ing in a code branch handling a rule) and return without applying the normal automatic field mapping generation rules. By removing the early return, the other rules are applied and the mapping rules for handling the exact same message defintions are applied Signed-off-by: Loy van Beek * Account for fields mapped by rules when checking for missed fields The code after the early return mentioned in the previous commit assumed all fields would match by name, which was of course true. But not anymore, so the missing check now only fails when the missing fields are also not already accounted for via a mapping Signed-off-by: Loy van Beek * Fix flake8 violations Signed-off-by: Loy van Beek Signed-off-by: Loy van Beek --- ros1_bridge/__init__.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ros1_bridge/__init__.py b/ros1_bridge/__init__.py index 98e509e5..756ef3f8 100644 --- a/ros1_bridge/__init__.py +++ b/ros1_bridge/__init__.py @@ -785,11 +785,11 @@ def determine_field_mapping(ros1_msg, ros2_msg, mapping_rules, msg_idx): file=sys.stderr) continue mapping.add_field_pair(ros1_selected_fields, ros2_selected_fields) - return mapping # apply name based mapping of fields ros1_field_missing_in_ros2 = False + ros1_fields_not_mapped = [] for ros1_field in ros1_spec.parsed_fields(): for ros2_member in ros2_spec.structure.members: if ros1_field.name.lower() == ros2_member.name: @@ -797,9 +797,15 @@ def determine_field_mapping(ros1_msg, ros2_msg, mapping_rules, msg_idx): update_ros1_field_information(ros1_field, ros1_msg.package_name) mapping.add_field_pair(ros1_field, ros2_member) break - else: + + ros1_fields_mapped_to_a_ros2_member = [field[0].name + for field + in mapping.fields_1_to_2.keys()] + if ros1_field.name not in ros1_fields_mapped_to_a_ros2_member: # this allows fields to exist in ROS 1 but not in ROS 2 - ros1_field_missing_in_ros2 = True + ros1_fields_not_mapped += [ros1_field] + + ros1_field_missing_in_ros2 = any(ros1_fields_not_mapped) if ros1_field_missing_in_ros2: # if some fields exist in ROS 1 but not in ROS 2