ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
5

Including a Python module in a ROS2 package

asked 2020-12-15 13:21:32 -0500

edesta gravatar image

Hey you all I have been scratching at my head for a solid day trying to figure out why this is proving to be such a problem.

So i have a python ROs2 package. Inside my package i have a node trying to reference a submodule i have included. It keeps saying there is no module in package. I have tried to look at the setup.py file and still have had no luck trying to add it as part of the path.

Project Folder

    A [package] 

         A 

            nodeFile.py 

            Submodule 

                 file-that-i-am-trying-to-call.py

.....

Sos. I havent added anything unique to the setup.py or the package.xml from a typical basic node setup so its pretty blank in terms of that.

Any help would be awesome thank you so much!!

edit retag flag offensive close merge delete

Comments

What is the path you use for importing that submodule? Do you have an __init__.py?

nnmm gravatar image nnmm  ( 2020-12-16 05:42:47 -0500 )edit

to import it i said from Submodule.file_that-i-am-trying-to-call.py and yes it has an __init__.py

An interesting thing that happens is when i remove the submodule folder and pull the file in by itself, i can import it like: .file-that-i-am-trying-to-call.py

edesta gravatar image edesta  ( 2020-12-16 07:25:20 -0500 )edit
1

You shouldn't use dashes in module names, and you shouldn't need the .py extension when importing. I think theoretically it should be import A.Submodule.file_that_i_am_trying_to_call (i.e. with the package name in front). If that doesn't work, please provide a minimal example to reproduce the error.

nnmm gravatar image nnmm  ( 2020-12-16 07:32:20 -0500 )edit

Hi, So this is for the example i used dashes for the actual implementation i will give you the set of steps to recreate.

I made a python ros2 package just using the customary build instructions I then made a node that includes a submodule for a dstar algorithm implementation.

so the folder (called dstar) contains dstar_algorithm.py and some of its own helper files.

I mispoke when i added a .py at the end of the include it does not have one.

So in my node class, all it does, is it prints hello -- i literally am just testing the ability to pull in different python modules into ros2.

My colcon build passes which is what i expect, but on the run of the node file, it fails on the line that is including the dstar_algorithm .

i import it like from dstar.dstar_algorithm import *

I have also tried: from ...(more)

edesta gravatar image edesta  ( 2020-12-16 11:56:49 -0500 )edit

Have you been able to find a solution? Thanks

veilkrand gravatar image veilkrand  ( 2021-03-03 23:37:10 -0500 )edit

3 Answers

Sort by » oldest newest most voted
10

answered 2021-05-29 12:13:38 -0500

nagda9 gravatar image

updated 2021-07-21 08:43:07 -0500

I think this question is also related so I recommend to check it out first: https://answers.ros.org/question/3198...

When ROS2 builds the src files with colcon, it puts the python files into workspace/install/lib/python3.8/site-packages/<package_name>. This folder is considered as the root of python packages in the given ROS 2 package.

If you can find the python files there, then you can use the following import statement: import .<file_name>. Note the . at the start of the import. You don't have to edit nothing else.

If you want to put the imported files into submodules, then you have to achieve that they show up in the workspace/install/lib/python3.8/site-packages/<package_name>/<submodule_name> folder. This can be done by replacing the packages argument in the setup.py file to the following: packages=["<package_name>", "<packages_name>/<submodule_name>"]. This way the import statement is import .<submodule_name>.<file_name>.

Example file structure to import with submodule:

workspace
|-> ...
|-> src
      |-> mypackage
             |-> mypackage
                    |-> submodules
                           |->__init__.py
                           |-> imported.py
                    |-> __init__.py
                    |-> main.py
             |-> resource
                    |-> ...
             |-> test
                    |-> ...
             |-> package.xml
             |-> setup.cfg
             |-> setup.py

setup.py:

from setuptools import setup

package_name = 'mypackage'
submodules = "mypackage/submodules"

setup(
    name=package_name,
    version='0.0.0',
    packages=[package_name, submodules],
    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    maintainer='TODO',
    maintainer_email='TODO@email.com',
    description='TODO: Package description',
    license='TODO: License declaration',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
            'main = mypackage.main:main',
        ],
    },
)

main.py:

from .submodules.imported import function


def main():
    function()


if __name__ == '__main__':
    main()

imported.py:

def function():
    print("hello world")
edit flag offensive delete link more

Comments

thank you so much. It works well.

engro39 gravatar image engro39  ( 2021-09-15 09:33:28 -0500 )edit
1

with dot. I can run as pkg, but cannot run directly from vscode, (without dot I can) is there a way to do both?

xzkeee gravatar image xzkeee  ( 2022-04-04 08:41:12 -0500 )edit

I have the same problem, i can either run my nodes with a launch file, or directly from vscode but both of them are not working at the same time, i allways get an import related error e.g. module not found.

Bogdan gravatar image Bogdan  ( 2022-06-24 06:01:47 -0500 )edit
1

Well, I think ROS 2 is still a bit quirky/clumsy in this regard. It was designed to be used in the "ROS" way: you have to build the workspace first, then you can run your program with the ros2 run command. As far as I know, it is not really compatible with "just running files". The build system is not allowing it to see the submodules in the usual way. I agree this is a disadvantage as it slows down development and makes things more complicated, but for now, this is the cost of the necessary build tool due to platform independentness. To correct this issue, either colcon should be changed, or ROS 2 should use a different build tool or build method.

nagda9 gravatar image nagda9  ( 2022-07-09 16:59:32 -0500 )edit
1

answered 2020-12-17 09:45:12 -0500

nnmm gravatar image

updated 2020-12-17 10:15:14 -0500

Best start from the template ROS gives you:

ros2 pkg create --build-type ament_python --node-name dstar_node --library-name dstar_algorithm dstar

That gives you

dstar
├── dstar
│   ├── dstar_algorithm
│   │   └── __init__.py
│   ├── dstar_node.py
│   └── __init__.py
├── package.xml
├── resource
│   └── dstar
├── setup.cfg
├── setup.py
└── test
    ├── test_copyright.py
    ├── test_flake8.py
    └── test_pep257.py

You can then put a file, e.g. impl.py, with the implementation inside the dstar_algorithm directory and import it with from dstar.dstar_algorithm.impl import *.

Or you can replace the dstar_algorithm directory by a file dstar_algorithm.py that has the implementation and import with from dstar.dstar_algorithm import *.

edit flag offensive delete link more

Comments

1

--library-name parameter only creates and additional module folder. It doesn't fix any import/build issue

veilkrand gravatar image veilkrand  ( 2021-03-03 23:36:45 -0500 )edit

This does not solve the problem.

nagda9 gravatar image nagda9  ( 2021-05-29 12:08:14 -0500 )edit
0

answered 2022-09-18 04:15:27 -0500

omers gravatar image

Taken from here: https://answers.ros.org/question/3497...

Instead of having to manually add your subfolders to setup.py, you can:

from setuptools import setup, find_packages

package_name = 'bar30'

setup(
    name=package_name,
    version='0.0.1',
    packages=find_packages(exclude=['test']),
edit flag offensive delete link more

Question Tools

3 followers

Stats

Asked: 2020-12-15 13:19:26 -0500

Seen: 15,128 times

Last updated: Sep 18 '22