Ask Your Question

Using Python3 modules in ROS2 packages

asked 2021-02-04 11:29:48 -0600

NotARobot gravatar image

updated 2021-02-09 05:17:13 -0600

I developed Python3 modules with code independent from ROS. Now I want to use them in a ROS2 package, more specifically I want to import them in a ROS2 node. The node listens to a ROS topic and should use my Python modules to work with the data provided by the topic.

However I couldn't find any information on how to achieve this. At first I tried to plug my modules next to the node, but when I tried to run the node after colcon build it was unable to import the modules, because colcon build runs the script in the install directory. So I modified the data_files in with

data_files=[ ('share/ament_index/resource_index/packages', ['resource/' + package_name]), ('share/' + package_name, ['package.xml']), (os.path.join('share', package_name, 'dependencies'), glob('dependencies/*')) ],

and put my modules in the dependencies directory. Now I am unable to build the package, due to a colcon error

Starting >>> tst_mapfusion_r2pp

--- stderr: tst_mapfusion_r2pp error: cant't copy 'dependencies/fusion':

doesn't exist or not a regular file

--- Failed <<< tst_mapfusion_r2pp [0.45s, exited with code 1]

Summary: 0 packages finished [0.74s]

1 package failed: tst_mapfusion_r2pp

1 package had stderr output: tst_mapfusion_r2pp

Whereas the dependencies directory contains the sub-directories for my modules, one of them being fusion.

Where do I have to put my own python modules in order to use them inside the ROS2 package? Is it possible without shenanigans like fiddling with $PYTHONPATH?

Edit: The tree is a bit extensive and I'm not allowed to upload files or pictures (new user -.- ). So please be patient with me.










-----fusion -> /root/ros2_ws/src/tst_mapfusion_r2pp/dependencies/fusion

-----importer -> /root/ros2_ws/src/tst_mapfusion_r2pp/dependencies/importer

-----misc -> /root/ros2_ws/src/tst_mapfusion_r2pp/dependencies/misc

-----opencv -> /root/ros2_ws/src/tst_mapfusion_r2pp/dependencies/opencv

----package.xml -> /root/ros2_ws/src/tst_mapfusion_r2pp/package.xml


-----tst_mapfusion_r2pp -> /root/ros2_ws/src/tst_mapfusion_r2pp/resource/tst_mapfusion_r2pp

----setup.cfg -> /root/ros2_ws/src/tst_mapfusion_r2pp/setup.cfg -> /root/ros2_ws/src/tst_mapfusion_r2pp/

----tst_mapfusion_r2pp -> /root/ros2_ws/src/tst_mapfusion_r3pp/tst_mapfusion_r2pp































edit retag flag offensive close merge delete


For clarity, could you please run tree ~/location_of_workspace/src/tst_mapfusion_r2pp and update your question with the output? It should print a tree-like structure of all the files and directories.

phillipov gravatar image phillipov  ( 2021-02-05 13:35:46 -0600 )edit

My understanding is that the data_files option is only supposed to be used for extra stuff your code needs, not code itself. I would expect you would be fine just inserting your extra modules alongside the ROS-specific stuff that gets installed by the packages term in This doesn't work?

jdlangs gravatar image jdlangs  ( 2021-02-08 09:57:31 -0600 )edit

I suspect, it's for ROS-packages. I've tried to add my dependencies here, but I got: error: package directory 'dependencies' does not exist.

From my limited understanding, when writing a ROS2 node with Python; colcon build will copy the ROS code in the install folder, specified by setup.cfg and, for a lack of a better term, 'register' it for ROS2 to be found as run-able. So isn't it possible to tell colcon to copy my files in the proper directory when building?

NotARobot gravatar image NotARobot  ( 2021-02-08 10:28:39 -0600 )edit

colcon build is not doing anything more than invoking setuptools to install everything into the install/ directory, the same way calling python install would. The stuff listed under the packages keywords are simply the python packages that will be placed under install/, which most likely should include these extra modules you mention.

jdlangs gravatar image jdlangs  ( 2021-02-08 14:16:36 -0600 )edit

In case you haven't seen it, you can understand how and the packageskeyword work here: One thing that often trips people up is remembering a python package is only defined when an file is present.

jdlangs gravatar image jdlangs  ( 2021-02-08 14:22:53 -0600 )edit

1 Answer

Sort by ยป oldest newest most voted

answered 2021-02-09 05:17:28 -0600

NotARobot gravatar image

Solved. Thanks to jdlangs and phillipov. With regard to the documentation I packed my modules in packages parallel to the node like that:







Furthermore, as jdlangs suggested I edited setup.pys packages section: packages[package_name, '{}'.fusion.(package_name), '{}'.importer(package_name)] and so on for all my modules.

Additionally the import statements in my ROS2 node had to be edited from import fusion.map_fusion as fusion to from .fusion import map_fusion as fusion

Unfortunately deeper dependencies like my misc package which is needed by my ocvfmodule require an import a level deeper, like from ..misc import mp_misc.

Thank you very much for answering my question, even if it turns out to be more of a general python question.

edit flag offensive delete link more


I believe it should also be possible to put your fusion package at the same level as tst_mapfusion_r2pp and have it installed as a separate top-level package. Then your original import statements would work.

jdlangs gravatar image jdlangs  ( 2021-02-09 10:55:25 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools



Asked: 2021-02-04 11:29:48 -0600

Seen: 462 times

Last updated: Feb 09