I have to send binary String messages via the ROS message bus. That worked out perfectly with Python 2.7 and ROS Melodic, but fails with ROS Noetic. Here's some example code (of course I don't just want to send 'test' as binary data):
import rospy
from std_msgs.msg import String
rospy.init_node('test_pub')
pub = rospy.Publisher('bin', String, queue_size=10)
while not rospy.is_shutdown():
msg = String()
msg.data = b'test'
pub.publish(msg)
rospy.sleep(1.)
With Noetic that fails as soon as someone subscribes to the topic. The reason is that ROS tries to encode the data of String messages via .encode(utf-8)
once it detects Python 3, which will of course fail for bytes
.
Here's the error:
File "/opt/ros/noetic/lib/python3/dist-packages/rospy/msg.py", line 152, in serialize_message
msg.serialize(b)
File "/opt/ros/noetic/lib/python3/dist-packages/std_msgs/msg/_String.py", line 56, in serialize
_x = _x.encode('utf-8')
AttributeError: 'bytes' object has no attribute 'encode'
And the problematic passage in the String messages source:
def serialize(self, buff):
"""
serialize message into buffer
:param buff: buffer, ``StringIO``
"""
try:
_x = self.data
length = len(_x)
if python3 or type(_x) == unicode:
_x = _x.encode('utf-8')
Is there some way to work around that without modifying/destroying the binary data itself? Decoding the binary data first so that ROS can encode it again unfortunately does modify it.
And yes, I know that there exist the messages Byte
/ MultiByteArray
, but therefore I would need to convert the binary data to/from an Integer array on all ends, which would add massive overhead and break compatibility with ROS Melodic clients and rosbags.
Originally posted by gm88 on ROS Answers with karma: 13 on 2021-03-22
Post score: 0