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

ModuleNotFoundError after adding second Python pkg to colcon workspace

asked 2019-05-02 08:00:26 -0500

CimeROS gravatar image

updated 2019-05-02 08:18:35 -0500

gvdhoorn gravatar image

Hi.

My setup: ROS2 Crystal full version, Linux 18.04.

FIRST STEP: workspace filesystem:

testWS
..src
....pkg_one
......package.xml
......setup.cfg
......setup.py
......src
........pub_one.py
........ __init__.py

I created pkg_one with command

ros2 pkg create pkg_one

Content of package.xml:

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="2">
  <name>pkg_one</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="todo">gsc02</maintainer>
  <license>TODO: License declaration</license>

  <exec_depend>rclpy</exec_depend>
  <exec_depend>std_msgs</exec_depend>

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <export>
    <build_type>ament_python</build_type>
  </export>
</package>

content of setup.cfg:

[develop]
script-dir=$base/lib/pkg_one
[install]
install-scripts=$base/lib/pkg_one

content of setup.py

from setuptools import find_packages
from setuptools import setup

package_name = 'pkg_one'

setup(
    name=package_name,
    version='0.0.0',
    packages=[],
    py_modules=[
       'src.pub_one',
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    author='user',
    author_email="user@todo.todo",
    maintainer='user',
    maintainer_email="user@todo.todo",
    keywords=['ROS', 'ROS2'],
    classifiers=[
        'Intended Audience :: Developers',
        'License :: OSI Approved :: Apache Software License',
        'Programming Language :: Python',
        'Topic :: Software Development',
    ],
    description='TODO: Package description.',
    license='Apache License, Version 2.0',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
            'pub_one = src.pub_one:main',
        ],
    },
)

content of pub_one.py (simple publisher):

import rclpy

from std_msgs.msg import String

def main(args=None):
    rclpy.init(args=args)

    node = rclpy.create_node('pub_one')
    publisher = node.create_publisher(String, 'chatter')

    msg = String()

    def timer_callback():
        msg.data = 'Hi?'
        node.get_logger().info('Sending message: "%s"' % msg.data)
        publisher.publish(msg)

    timer_period = 0.5  # seconds
    timer = node.create_timer(timer_period, timer_callback)

    rclpy.spin(node)

    # Destroy the timer attached to the node explicitly
    # (optional - otherwise it will be done automatically
    # when the garbage collector destroys the node object)
    node.destroy_timer(timer)
    node.destroy_node()
    rclpy.shutdown()


if __name__ == '__main__':
    main()

I compile everything with:

colcon build

and after source workspace with:

source install/setup.bash && source install/local_setup.bash

When run the script with command:

ros2 run pkg_one pub_one

Everything works perfectly, but when I add the package pkg_two to the same workspace following the same procedure (just different package name and node name) and try to run the pub_one again i get the following error:

Traceback (most recent call last):
  File "/home/gsc02/testWS/install/pkg_one/lib/pkg_one/pub_one", line 11, in <module>
    load_entry_point('pkg-one==0.0.0', 'console_scripts', 'pub_one')()
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 480, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 2693, in load_entry_point
    return ep.load()
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 2324, in load
    return self.resolve()
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 2330, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
ModuleNotFoundError: No module named 'src.pub_one'

running command in the same workspace for pub_two (which is the pub node in pkg_two):

ros2 run pkg_two pub_two

works correctly. Also each individual package compiled individually in separate workspaces work as indented...

##So why does the error arise when running pub_one if both ... (more)

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2019-05-28 11:32:07 -0500

CimeROS gravatar image

updated 2019-05-29 10:12:01 -0500

I solved the problem by renaming the src folder inside packages to have separate names in each package. I renamed the one in pkg_one to be pkg_one_src

Then I changed the tag entry_points in setup.py to reflect the changes:

entry_points={
      'console_scripts': [
          'pub_one = pkg_one_src.pub_one:main',
       ],
},

Also i made some changes to packages tag:

packages=find_packages(),

to find the python packages automatically

and deleted the py_modules tag.

At the end setup.py looked like this:

from setuptools import find_packages
from setuptools import setup

package_name = 'pkg_one'

setup(
    name=package_name,
    version='0.0.0',
    packages=find_packages(),
    install_requires=['setuptools'],
    zip_safe=True,
    author='user',
    author_email="user@todo.todo",
    maintainer='user',
    maintainer_email="user@todo.todo",
    keywords=['ROS', 'ROS2'],
    classifiers=[
        'Intended Audience :: Developers',
        'License :: OSI Approved :: Apache Software License',
        'Programming Language :: Python',
        'Topic :: Software Development',
    ],
    description='TODO: Package description.',
    license='Apache License, Version 2.0',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
            'pub_one = pkg_one_src.pub_one:main',
        ],
    },
)

========================== REMARKS ========================================

" Changing your python module name to not be src makes sense. In general your module name should be your package name." - Thanks sloretz for pointing this out!

edit flag offensive delete link more

Comments

2

It looks like the end setup.py still says src.pub_one. Changing your python module name to not be src makes sense. In general your module name should be your package name. The part of the entrypoint that says pkg_one_src.pub_one:main means it will do an import like from pkg_one_src.pub_one import main. If all your packages redefine the python module src then I would expect only the last installed one to work.

sloretz gravatar image sloretz  ( 2019-05-28 12:54:04 -0500 )edit

Thanks for pointing this out, i corrected the mistake. Your expectations here are totally correct!

CimeROS gravatar image CimeROS  ( 2019-05-29 10:12:57 -0500 )edit

Question Tools

2 followers

Stats

Asked: 2019-05-02 08:00:26 -0500

Seen: 1,271 times

Last updated: May 29 '19