ros / ros_comm

ROS communications-related packages, including core client libraries (roscpp, rospy, roslisp) and graph introspection tools (rostopic, rosnode, rosservice, rosparam).
http://wiki.ros.org/ros_comm
752 stars 911 forks source link

relay_field broken in python3 / ROS noetic #2167

Open marcelino-pensa opened 3 years ago

marcelino-pensa commented 3 years ago

I am trying to run the example for relay_field as described in this link.

Terminal 1: rosrun rospy_tutorials talker.py

Terminal 2:

rosrun topic_tools relay_field /chatter /image sensor_msgs/Image "header:
  seq: 0
  stamp: {secs: 0, nsecs: 0}
  frame_id: m.data
height: 0
width: 0
encoding: ''
is_bigendian: 0
step: 0
data: ''"

Terminal 3: rostopic echo /image

The problem arises at first in Terminal 2, with the following error:

[ERROR] [1625092139.961614]: bad callback: <bound method RelayField.callback of <__main__.RelayField object at 0x7fb62ebc1550>>
Traceback (most recent call last):
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/topics.py", line 750, in _invoke_callback
    cb(msg)
  File "relay_field", line 106, in callback
    pub_args = _eval_in_dict_impl(msg_generation, None, {'m': m})
  File "relay_field", line 40, in _eval_in_dict_impl
    res[k] = _eval_in_dict_impl(v, globals_, locals_)
  File "relay_field", line 41, in _eval_in_dict_impl
    elif (type_ is str) or (type_ is unicode):
NameError: name 'unicode' is not defined

According with this forum, this is related to an update in python3. I went ahead and replaced the check (type_ is unicode) with (type_ is bytes) in the code for relay_field, and things seem to work. However, whenever I go to terminal 3 and run rostopic echo /image, Terminal 2 starts printing the following error:

[ERROR] [1625092400.464262]: bad callback: <bound method RelayField.callback of <__main__.RelayField object at 0x7f697c585580>>
Traceback (most recent call last):
  File "/opt/ros/noetic/lib/python3/dist-packages/sensor_msgs/msg/_Image.py", line 138, in serialize
    buff.write(struct.Struct('<I%ss'%length).pack(length, _x))
struct.error: argument for 's' must be a bytes object

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/topics.py", line 882, in publish
    self.impl.publish(data)
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/topics.py", line 1066, in publish
    serialize_message(b, self.seq, message)
  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/sensor_msgs/msg/_Image.py", line 139, in serialize
    except struct.error as se: self._check_types(struct.error("%s: '%s' when writing '%s'" % (type(se), str(se), str(locals().get('_x', self)))))
  File "/opt/ros/noetic/lib/python3/dist-packages/genpy/message.py", line 385, in _check_types
    raise SerializationError(str(exc))
genpy.message.SerializationError: <class 'struct.error'>: 'argument for 's' must be a bytes object' when writing ''

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/topics.py", line 750, in _invoke_callback
    cb(msg)
  File "relay_field", line 112, in callback
    self.pub.publish(msg)
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/topics.py", line 886, in publish
    raise ROSSerializationException(str(e))
rospy.exceptions.ROSSerializationException: <class 'struct.error'>: 'argument for 's' must be a bytes object' when writing ''

I hit this dead-end, and I'm not sure on how to fix this. Any guidance or suggestions would be greatly appreciated!

RyanDMott commented 2 years ago

a year later ...

The second error appears to just be with the example. You fixed the code. I've issued a PR with that fix as you described for the first error.

In Python 2 a that field could be initialized from a string. Now that field is of types "bytes". Try replacing data: '' with data: []

The PR includes standalone launch files you can test.