Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

ROS2 : Why can't I run two Python nodes (each of them in separate package) in same workspace on ROS2?

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 packages are compiled in same workspace but not when compiled individually?


Just for complete documentation I'm adding content pf pkg_two (basically same as pkg_one just renamed package name and node name in appropriate files)

Content of pkg_two: package.xml:

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/20$
<package format="2">
  <name>pkg_two</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>

setup.cfg:

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

setup.py

from setuptools import setup

package_name = 'pkg_two'

setup(
    name=package_name,
    version='0.0.0',
    packages=[],
    py_modules=[
       'src.pub_two',
    ],
    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_two = src.pub_two:main',
        ],
    },
)

and pub_two.py:

import rclpy

from std_msgs.msg import String

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

    node = rclpy.create_node('pub_two')
    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()

Thanks!

ROS2 : Why can't I run two Python nodes (each of them in separate package) in same workspace on ROS2?

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 packages are compiled in same workspace but not when compiled individually?


Just for complete documentation I'm adding content pf of pkg_two (basically same as pkg_one just renamed package name and node name in appropriate files)

Content of pkg_two: package.xml:

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/20$
<package format="2">
  <name>pkg_two</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>

setup.cfg:

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

setup.py

from setuptools import setup

package_name = 'pkg_two'

setup(
    name=package_name,
    version='0.0.0',
    packages=[],
    py_modules=[
       'src.pub_two',
    ],
    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_two = src.pub_two:main',
        ],
    },
)

and pub_two.py:

import rclpy

from std_msgs.msg import String

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

    node = rclpy.create_node('pub_two')
    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()

Thanks!

ROS2 : Why can't I run two Python nodes (each of them in separate package) in same workspace on ROS2?

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 packages are compiled in same workspace but not when compiled individually?


Just for complete documentation I'm adding content of pkg_two (basically same as pkg_one just renamed package name and node name in appropriate files)

Content of pkg_two: package.xml:

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/20$
<package format="2">
  <name>pkg_two</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>

setup.cfg:

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

setup.py

from setuptools import setup

package_name = 'pkg_two'

setup(
    name=package_name,
    version='0.0.0',
    packages=[],
    py_modules=[
       'src.pub_two',
    ],
    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_two = src.pub_two:main',
        ],
    },
)

and pub_two.py:

import rclpy

from std_msgs.msg import String

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

    node = rclpy.create_node('pub_two')
    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()

Thanks!