ros2cli
ros2cli copied to clipboard
Cannot/don't know how to publish message with `byte[]` field
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/
-
Float32
andFloat32MultiArray
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}}"
@iuhilnehc-ynos @ivanpauno any thoughts?
@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
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.
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.
any progress??