ros2cli icon indicating copy to clipboard operation
ros2cli copied to clipboard

Cannot/don't know how to publish message with `byte[]` field

Open cadmus-to opened this issue 2 years ago • 6 comments

Bug report

Required Info:

  • Operating System:
    • Ubuntu 20.04
  • Installation type:
    • binaries
  • Version or commit hash:
    • ros2cli 0.13.4
  • DDS implementation:
    • rmw_cyclonedds_cpp: 0.22.5
  • Client library (if applicable):
    • N/A

Steps to reproduce issue

Trying to ros2 topic pub a std_msgs/msg/ByteMultiArray message. I have tried:

bash ros2 topic pub -1 /whatever std_msgs/msg/ByteMultiArray "{data: [{3}, {4}]}"

and

bash ros2 topic pub -1 /whatever std_msgs/msg/ByteMultiArray "{data: [0x03, 0x04]}" 

Expected behavior

Successful publishing.

Actual behavior

Error response:

Failed to populate field: The 'data' field must be a set or sequence and each value of type 'bytes'

Additional information

  • Related ROS Answer: https://answers.ros.org/question/406242/how-is-a-std_msgsmsgbytemultiarray-message-published-via-cli/

cadmus-to avatar Sep 12 '22 08:09 cadmus-to

  • Float32 and Float32MultiArray

    This works w/o any error.

root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Float32 "data: 3.0"
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Float32 "{data: 3.0}"

root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Float32MultiArray "data: [3.0, 4.0]"
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Float32MultiArray "{data: [3.0, 4.0]}"
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Float32MultiArray "{data: {3.0, 4.0}}"
  • std_msgs/msg/Byte

    This works w/o any error.

root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "data: [3]"
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "{data: [3]}"
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "data: [0x03]"
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "{data: [0x03]}"
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "data: {3}"
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "{data: {3}}"
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "data: {0x03}"
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "{data: {0x03}}"
  • std_msgs/msg/ByteMultiArray

    Any of them does not work.

root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/ByteMultiArray "{data: [3]}"
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/ByteMultiArray "{data: [3,4]}"
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/ByteMultiArray "{data: [0x03]}"
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/ByteMultiArray "{data: [0x03,0x04]}"
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/ByteMultiArray "{data: [0x03],[0x04]}"
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/ByteMultiArray "{data: {0x03}}"
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/ByteMultiArray "{data: {0x03,0x04}}"
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/ByteMultiArray "{data: {0x03},{0x04}}"

fujitatomoya avatar Sep 12 '22 22:09 fujitatomoya

@iuhilnehc-ynos @ivanpauno any thoughts?

fujitatomoya avatar Sep 12 '22 22:09 fujitatomoya

@fujitatomoya

The generated message for python in build/std_msgs/ament_cmake_python/std_msgs/std_msgs/msg/_byte_multi_array.py:158 only checking a type bytes seems not enough.

            assert \
                ((isinstance(value, Sequence) or
                  isinstance(value, Set) or
                  isinstance(value, UserList)) and
                 not isinstance(value, str) and
                 not isinstance(value, UserString) and
                 all(isinstance(v, bytes) for v in value) and
                 True), \
                "The 'data' field must be a set or sequence and each value of type 'bytes'"
        self._data = value

The type could be int if using ros2 topic pub -1 /whatever std_msgs/msg/ByteMultiArray "{data: [3]}".

I am afraid that we should update the above source code with

            assert \
                ((isinstance(value, Sequence) or
                  isinstance(value, Set) or
                  isinstance(value, UserList)) and
                 not isinstance(value, str) and
                 not isinstance(value, UserString) and
                 all((isinstance(v, bytes) or isinstance(v, int)) for v in value) and
                 True), \
                "The 'data' field must be a set or sequence and each value of type 'bytes'"
        if any(isinstance(v, int) for v in value):
            self._data = bytearray(value)
        else:
            self._data = value

NOTE: It means that we need to update https://github.com/ros2/rosidl_python/blob/52e099efef21366ff651385da865e305228d24ec/rosidl_generator_py/resource/_msg.py.em

iuhilnehc-ynos avatar Sep 13 '22 06:09 iuhilnehc-ynos

root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "data: {3}" root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "{data: {3}}" root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "data: {0x03}" root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "{data: {0x03}}"

It's strange that those are valid, they shouldn't IMO.

root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "data: [3]" root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "{data: [3]}" root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "data: [0x03]" root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "{data: [0x03]}"

Those seem fine, does

ros2 topic pub -1 /whatever std_msgs/msg/Byte "!!binary 'Aw=='"

work?

root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/ByteMultiArray "{data: [3]}" root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/ByteMultiArray "{data: [3,4]}" root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/ByteMultiArray "{data: [0x03]}" root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/ByteMultiArray "{data: [0x03,0x04]}" root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/ByteMultiArray "{data: [0x03],[0x04]}"

These should work as well. Does

ros2 topic pub -1 /whatever std_msgs/msg/Byte "!!binary 'AwQ='"

work?

I am afraid that we should update the above source code with

I'm not sure about that fix, but if you could propose a PR with it that would be a great start.

ivanpauno avatar Sep 13 '22 19:09 ivanpauno

root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "\!\!binary 'Aw=='"
The passed value needs to be a dictionary in YAML format
root@tomoyafujita:~/ros2_ws/colcon_ws# ros2 topic pub -1 /whatever std_msgs/msg/Byte "\!\!binary 'AwQ='"
The passed value needs to be a dictionary in YAML format

both do not work.

fujitatomoya avatar Sep 13 '22 19:09 fujitatomoya

any progress??

rty813 avatar Oct 26 '23 09:10 rty813