Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NOT FOR MERGE] Add uint8 field when ROS 2 message definition is empty. #34

Closed

Conversation

achim-k
Copy link
Contributor

@achim-k achim-k commented May 29, 2023

Public-Facing Changes

  • Add uint8 field when ROS 2 message definition is empty

Description

Since IDL does not allow empty structs, ROS adds an extra uint8 field in case the message definition does not contain any fields (e.g. std_msgs/Empty). See https://github.com/ros2/rosidl/blob/e3b71ece/rosidl_adapter/rosidl_adapter/resource/struct.idl.em#L101

This patch mirrors this behavior.

Motivation:

Consider the following message definition empty_test_msgs/msg/EmptyAndInt32:

std_msgs/Empty empty
int32 int_val

When publishing this type on a topic

ros2 topic pub /empty_and_int32 empty_test_msgs/msg/EmptyAndInt32 int_32_field:\ 2\ 

Studio does not parse the message correctly, as it considers the empty field to have a size of 0.

This patch will fix foxglove/ros-foxglove-bridge#229

Since IDL structs can't be empty, ROS adds a uint8 field in case the
message definition is empty (e.g. std_msgs/Empty):
See https://github.com/ros2/rosidl/blob/e3b71ece/rosidl_adapter/rosidl_adapter/resource/struct.idl.em#L101

This patch mirros this behavior.
// Since IDL structs can't be empty, ROS adds a uint8 field in case the
// message definition is empty (e.g. std_msgs/Empty):
// https://github.com/ros2/rosidl/blob/e3b71ece/rosidl_adapter/rosidl_adapter/resource/struct.idl.em#L101
if (lines.length === 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a serialization time concern rather than something that would be in the MessageDefinition itself (which is more of an app description for the message fields). Is it possible to make this a rosmsg2-serialization thing rather than a message definition builder thing?

Copy link
Contributor Author

@achim-k achim-k May 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing that in rosmsg2-serialization is definitely a possibility. However, since the IDL definition contains that extra member, I find it more correct to modify the MessageDefinition to be consistent with IDL parsing and how the field is displayed in Studio (e.g. RawMessage / Publish panels).

Content of Empty.idl:

// generated from rosidl_adapter/resource/msg.idl.em
// with input from std_msgs/msg/Empty.msg
// generated code does not contain a copyright notice


module std_msgs {
  module msg {
    struct Empty {
      uint8 structure_needs_at_least_one_member;
    };
  };
};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens in ROS tooling when working with these empty messages? Does ros topic echo show the field? Or are they special-casing the std_msgs/Empty (or even all empty messages?).

In practice empty messages are rare so this is an edge case with limited risk and impact but figuring out what the expectations are for a ROS user and following those seems defensible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens in ROS tooling when working with these empty messages? Does ros topic echo show the field? Or are they special-casing the std_msgs/Empty (or even all empty messages?).

The python based ros2cli tools do not show the padding member anymore (since ros2/rosidl_python#73). And indeed, this applies for all empty message definitions, also empty service requests such as of std_srvs/Trigger (cfr. foxglove/ros-foxglove-bridge#229)

I have now implemented this in foxglove/rosmsg2-serialization#16, to avoid that the padding member is being shown.

achim-k added a commit to achim-k/rosmsg2-serialization that referenced this pull request Jun 5, 2023
In case a message definition definition is empty, ROS 2 adds a
`uint8 structure_needs_at_least_one_member` field when converting to
IDL, to satisfy the requirement from IDL of not being empty.
See also
https://design.ros2.org/articles/legacy_interface_definition.html

This patch inserts or skips that extra member when serializing or
deserializing respectively.

Replaces foxglove/rosmsg#34, to avoid that the
`structure_needs_at_least_one_member` is being displayed.
@achim-k achim-k changed the title Add uint8 field when ROS 2 message definition is empty. [NOT FOR MERGE] Add uint8 field when ROS 2 message definition is empty. Jun 5, 2023
@achim-k
Copy link
Contributor Author

achim-k commented Jun 7, 2023

Superseded by foxglove/rosmsg2-serialization#16

@achim-k achim-k closed this Jun 7, 2023
jtbandes pushed a commit to foxglove/rosmsg2-serialization that referenced this pull request Jun 7, 2023
### Public-Facing Changes

Fix serde of empty message definition

### Description
In case a message definition definition is empty, ROS 2 adds a `uint8 structure_needs_at_least_one_member` field when converting to IDL, to satisfy the requirement from IDL of not being empty. See also
https://design.ros2.org/articles/legacy_interface_definition.html

This patch inserts or skips that extra member when serializing or deserializing respectively.

Replaces foxglove/rosmsg#34, to avoid that the `structure_needs_at_least_one_member` is being displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Trigger service call failed to desirialize
2 participants