galou / python_bindings_tutorial

Files for the Python bindings tutorial for ROS
The Unlicense
7 stars 2 forks source link

Compatibility Python3 #2

Open sebaleme opened 2 years ago

sebaleme commented 2 years ago

Hi,

we could use your tutorial to create python 2.7 bindings, but it is quite harder to use python3 libs. StringsIO has changed, and strings are automatically formatted to unicode now, which is a problem. Is there any solution for this yet?

galou commented 2 years ago

I don't need to create any ROS binding for Python right now so I'd welcome any help to port the tutorial to Python3.

I don't understand what is difficult with StringIO, it's just at a different place. Can you give some details about the issue with unicode strings in Python3?

YinpeiDai commented 11 months ago

Change _add_two_ints_wrapper_py.py as follows

from io import BytesIO

import rospy
from std_msgs.msg import Int64

from python_bindings_tutorial._add_two_ints_wrapper_cpp import AddTwoIntsWrapper

class AddTwoInts(object):
    def __init__(self):
        self._add_two_ints = AddTwoIntsWrapper()

    def _to_cpp(self, msg: Int64):
        """Return a serialized string from a ROS message

        Parameters
        ----------
        - msg: a ROS message instance.
        """
        buf = BytesIO()
        msg.serialize(buf)
        return buf.getvalue()

    def _from_cpp(self, str_msg, cls):
        """Return a ROS message from a serialized string

        Parameters
        ----------
        - str_msg: str, serialized message
        - cls: ROS message class, e.g. sensor_msgs.msg.LaserScan.
        """
        msg = cls()
        return msg.deserialize(str_msg)

    def add(self, a, b):
        """Add two std_mgs/Int64 messages

        Return a std_msgs/Int64 instance.

        Parameters
        ----------
        - a: a std_msgs/Int64 instance.
        - b: a std_msgs/Int64 instance.
        """
        if not isinstance(a, Int64):
            rospy.ROSException('Argument 1 is not a std_msgs/Int64')
        if not isinstance(b, Int64):
            rospy.ROSException('Argument 2 is not a std_msgs/Int64')
        str_a = self._to_cpp(a)
        str_b = self._to_cpp(b)
        str_sum = self._add_two_ints.add(str_a, str_b)
        # encode the string into bytes
        str_sum = str_sum.encode('utf-8')
        return self._from_cpp(str_sum, Int64)
galou commented 11 months ago

@YinpeiDai is your change compatible with Python2, so that I wouldn't need to create a Python3 branch?

daleigehhh commented 2 months ago

@galou Hi, I think you need to create a Python3 branch, because there are some differences between Python2 and Python3 when using boost bind. I am not familiar with serialization and BytesIO and StringIO in python. I followed the tutorial on Ubuntu20.04 ROS noetic with Python 3.8. I got a error in Python: python3_bindgins_error And fortunately I see the upper comment, it seems like I should use ByteIO instead of StringIO in Python3