🕒 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

6 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.

Leave a Reply

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