🕒 3 min read

Wanted to compile ROS packages with Python 3 on ROS Melodic, only realizing that catkin_make only compiles Python 2 scripts instead after a while? No worries! In this tutorial, we’ll be looking exactly into that.

Background

This tutorial is tested on Jetson Nano with JetPack 4.3 L4T 32.4.2 (Ubuntu 18.04) with ROS Melodic & custom Open CV 4.3.0 installation.

As I was writing a ROS package that utililses the Sensor Image transport and OpenCV4, everything was going well from building to compilation of the code. The issue arrises when I started to run the node itself, which gives the following error:

Assertion failed (tlsSlots.size() > slotIdx) in releaseSlot

Searching online, I found out that others had a similar issue when there are 2 conflicting versions of OpenCV being used.

Therefore, I tried compiling the open_vision package (noetic-branch) within the catkin workspace itself and modifying the CMakeLists.txt accordingly, thinking it would work. However, some error arises again:

In file included from /usr/include/python2.7/numpy/ndarrayobject.h:27:0,
from /home/jnano/catkin_ws/src/vision_opencv/cv_bridge/src/module.hpp:26,
from /home/jnano/catkin_ws/src/vision_opencv/cv_bridge/src/module.cpp:35:
/home/jnano/catkin_ws/src/vision_opencv/cv_bridge/src/module.hpp: In function ‘void* do_numpy_import()’:
/usr/include/python2.7/numpy/__multiarray_api.h:1537:144: error: return-statement with no value, in function returning ‘void*’ [-fpermissive]
#define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return NUMPY_IMPORT_ARRAY_RETVAL; } }
^
/usr/include/python2.7/numpy/__multiarray_api.h:1537:144: note: in definition of macro ‘import_array’
#define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return NUMPY_IMPORT_ARRAY_RETVAL; } }
^~~~~~

And then it dawned on me: the fact I was trying to compile the package with Python 2 instead of 3. However, if I wanted to stick to compiling the melodic branch with OpenCV 4, another arises as the melodic branch is based on OpenCV 3.

Melodic branch

Since ROS does not support Python 3 by default, we would have to compile cv_bridge via another method if want to use OpenCV 4 with Python 3.

Fun fact: ROS2 supports Python 3 by default.

Furthermore, as the support of Python 2.7 ended last year (December 2019), it is recommended to discontinue the use of Python 2.7 as it would not be updated anymore and move on to Python 3.

Therefore, this tutorial would be covering how to compile a Python 3 ROS package with ROS Melodic, specifically cv_bridge. With that, let’s get started!

Dependencies

We’ll first download the python build tools:

$ sudo apt-get install python3-pip python-catkin-tools python3-dev python3-numpy
$ sudo pip3 install rospkg catkin_pkg

Workspace

Next, create a separate workspace to compile the bridge_cv ROS package. We would be naming the directory cvbridge_build_ws.

$ mkdir -p ~/cvbridge_build_ws/src
$ cd ~/cvbridge_build_ws/src

After the workspace has been setup, we’ll clone the open_vision repository into ~/cvbridge_build_ws/src:

$ git clone -b noetic https://github.com/ros-perception/vision_opencv.git

We would be downloading the noetic branch instead of the melodic branch as it supports for both OpenCV 4 and Python 3.If you try compiling immediately, you would get this error:

Can't find boost37

Therefore, we need to make a slight change to the cv_bridge CMakeLists.txt file before proceeding as Ubuntu 18.04 is not be able to recognise python37 by default.
Open CMakeLists.txt with you favorite text editor and make the following modification at Line 11, changing:

find_package(Boost REQUIRED python37)

to

find_package(Boost REQUIRED python3)

Save and exit the text editor.

Compilation

After the dependencies and workspace have been setup, we would proceed to configure the workspace for compilation:

Configuring catkin

$ cd ~/cvbridge_build_ws
$ catkin config -DPYTHON_EXECUTABLE=/usr/bin/python3 -DPYTHON_INCLUDE_DIR=/usr/include/python3.6m -DPYTHON_LIBRARY=/usr/lib/aarch64-linux-gnu/libpython3.6m.so
$ catkin config --install

Note: Change the python path accordingly, you could check out the location via Python 3.

Finding python3 path

$ python3
>>> import sys
>>> print(sys.executable) #Print python3 executable path
>>> print(sys.path) #Print python3 library path

To find where the include files are:

$ python3-config --includes

After the configuration is completed, build the package:

$ catkin build cv_bridge

To use the package, you could source it via:

$ source install/setup.bash --extend

And Viola! You have “compiled” the cv_bridge package via Python 3.

You could add it to .bashrc if you use the ROS package frequently.

References

  • https://wiki.ros.org/UsingPython3
  • https://medium.com/@beta_b0t/how-to-setup-ros-with-python-3-44a69ca36674
  • https://answers.ros.org/question/350904/cv_bridge-throws-boost-import-error-in-python-3-and-ros-melodic/
  • https://stackoverflow.com/questions/49221565/unable-to-use-cv-bridge-with-ros-kinetic-and-python3
  • https://stackoverflow.com/questions/35071192/how-to-find-out-where-the-python-include-directory-is
  • https://stackoverflow.com/questions/6767283/find-where-python-is-installed-if-it-isnt-default-dir#6767329

16 Replies to “Compiling ROS cv_bridge with Python 3

    1. Hi, have you configured and build the workspace before sourcing `setup.bash`? The setup script would only be available after building the workspace.

        1. Hi, we are building only the cv_bridge package, hence catkin build is used.

          In general, catkin build could be used from any directory in the workspace and can be used to compile a specific set of packages, with more flexibility in terms of package compilation. Whereas for catkin_make, it only works in the top level directory of the workspace and compiles all the packages in the workspace. The packages would also be compiled in parallel, which makes the whole compilation time shorter.

  1. Really thank you for the wonderful instructions. By the way, i am trying to do this in ubuntu 16.04 and i know that 16.04 uses python3.5 instead of 3.6. Would it be okay just by changing all the 3.6 to 3.5 in the commands?

  2. Hello, I got an error
    “TypeError: signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object”
    when i “$ catkin build cv_bridge” I have tried some solution but still the same.

    i’m using Jetson Xavier JP4.4, python3.6 and ROS Melodic

  3. Hi, after building and sourcing, ROS cannot find the other package i was working on, located in another catkin workspace.
    Was i supposed to do all these steps in that workspace?

  4. This article was incredibly helpful. Thanks a lot!

    I just wanted to add that if you are using Ubuntu the DPYTHON_LIBRARY flag should begin with
    /usr/lib/x86_64-linux-gnu/…

    no big deal but hopefully that helps someone
    happy coding

  5. I want to thank you for this amazing post. My comrade and I went insane solving this problem. Now it works like a charm. May Odin bless your soul.

Leave a Reply

Your email address will not be published. Required fields are marked *