Rosanswers logo

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 setup.py 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

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

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







































Originally posted by NotARobot on ROS Answers with karma: 109 on 2021-02-04

Post score: 1

Original comments

Comment by phillipov on 2021-02-05:
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.

Comment by jdlangs on 2021-02-08:
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 setup.py. This doesn't work?

Comment by NotARobot on 2021-02-08:
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?

Comment by jdlangs on 2021-02-08:
colcon build is not doing anything more than invoking setuptools to install everything into the install/ directory, the same way calling python setup.py 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.

Comment by jdlangs on 2021-02-08:
In case you haven't seen it, you can understand how setup.py and the packages keyword work here: https://docs.python.org/3/distutils/setupscript.html One thing that often trips people up is remembering a python package is only defined when an __init__.py file is present.


1 Answer 1


Rosanswers logo

Solved. Thanks to jdlangs and phillipov. With regard to the setup.py 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.

Originally posted by NotARobot with karma: 109 on 2021-02-09

This answer was ACCEPTED on the original site

Post score: 1

Original comments

Comment by jdlangs on 2021-02-09:
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.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.