ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

Python2 and Python3 interoperability

asked 2021-04-24 15:53:49 -0500

rosnoob123 gravatar image

Currently, we have a node that utilizes a learned torch model to publish some topic. However, torch requires python3 and our ros melodic python version is 2.7. Due to our simulator, python 2.7 is required for melodic. What are some ways to address this python3 vs python2 compatibility error? For reference, we are using ubuntu 18.04 with ros melodic.

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
1

answered 2021-04-25 05:52:19 -0500

gvdhoorn gravatar image

updated 2021-04-25 05:53:41 -0500

I believe catkin_virtualenv can run Python 3 venvs in a Python 2 environment, fully integrated as a "regular" ROS package.

Alternatively: use rospypi/simple instead of the regular rospy. That's fully Melodic and Python 3 compatible.

edit flag offensive delete link more

Comments

1

@gvdhoorn Your comment deserves a separate post so I made it an answer :)

130s gravatar image 130s  ( 2021-04-25 06:28:32 -0500 )edit
0

answered 2021-04-25 05:35:51 -0500

130s gravatar image

updated 2021-04-25 06:28:01 -0500

I'm no expert in py2-py3 (I'm only recently struggling in production system dev). That said, I think of a few ways. If OPT-1 works then that might be preferrable as it might be extendable at lower cost.

OPT-1. Call Python2 module/executable from Python3 code. I don't know if there's officially supported Pythonic way to do this.

I think finding Python interpreter with specific version like 2.7 like this stackoverflow.com#q27863832 should work (I haven't tried). Code copied from the link:

import execnet

def call_python_version(Version, Module, Function, ArgumentList):
    gw      = execnet.makegateway("popen//python=python%s" % Version)
    channel = gw.remote_exec("""
        from %s import %s as the_function
        channel.send(the_function(*channel.receive()))
    """ % (Module, Function))
    channel.send(ArgumentList)
    return channel.receive()

OPT-2. Separately run Py2 executables/modules and Py3. ROS being distributed system (wiki.ros.org/ROS/Introduction) allows each node/process to communicate over the network, meaning they can be started separately. So divide the processes that need to run in Py2 and Py3. A challenge is when you're currently using roslaunch to start all processes by batch. I thought of separating a .launch file into a launch for Py2 and a .launch for Py3. However, roslaunch starts with the Python version default on your environment, and AFAICT there's no good way to start roslaunch with a Python version that is not default on your environment (related #q340390). In this case, I'd try (I haven't tried. Also for readability, I set Py2 is default on your environment):

  • From all-in-one .launch file, move Py3 portion out. Make Py3 portion executable without relying on ROS toolset (roslaunch/rosrun etc.)
  • Start .launch file, and maybe wait for a second or so (to wait for ROS Master to be available by the roslaunch) separately start Py3 portion.
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2021-04-24 15:53:49 -0500

Seen: 1,043 times

Last updated: Apr 25 '21