0
$\begingroup$

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.

/root/ros2_ws/src/tst_mapfusion_r2pp

-build

---COLCON_IGNORE

---tst_mapfusion_r2pp

----build

-----lib

------tst_mapfusion_r2pp

-------init.py

-------map_fusion.py

----colcon_build.rc

----colcon_command_prefix_setup_py.sh

----colcon_command_prefix_setup_py.sh.env

----dependencies

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

----resource

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

----tst_mapfusion_r2pp.egg-info

-----PKG-INFO

-----SOURCES.txt

-----dependency_links.txt

-----entry_points.txt

-----requires.txt

-----top_level.txt

-----zip-safe

-dependencies

--fusion

---pycache

----map_fusion.cpython-38.pyc

---map_fusion.py

--importer

---init.py

---pycache

----pgmloader.cpython-38.pyc

---pgmloader

--misc

---pycache

----mp_misc.cpython-38.py

---mp_misc.py

--opencv

---pycache

----ocvfmodule.cpython-38.pyc

---ocvfmodule.py

-install

-log

-package.xml

-resource

-setup.cfg

-setup.py

-test

-tst_mapfusion_r2pp

--init.py

--map_fusion.py

-tst_mapfusion_r2pp.egg-info

-venv


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.

$\endgroup$

1 Answer 1

0
$\begingroup$

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:

src

-tst_mapfusion_r2pp

--tst_mapfusion_r2pp

---init.py

---map_fusion.py

---fusion

----init.py

----map_fusion.py

---importer

----init.py

----pgmloader.py

etc.

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.

$\endgroup$

Your Answer

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