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

Importing python files/functions from the same directory (as simple as it sounds!)

asked 2023-01-27 11:04:37 -0500

none gravatar image

updated 2023-01-29 08:49:25 -0500

Hello everyone,

I've managed to run in an incredible issue that me and my friend just are not able to solve. Luckily, we managed to replicate the issue in the example talker.py and listener.py. My issue is that I cannot seem to import any function from another python file, even when these files are located in the same folder as the talker.py file.

Here is the code (you just need talker.py for this):

#!/usr/bin/env python

import rospy
from sum import Sum
from std_msgs.msg import String

def talker():
    pub = rospy.Publisher('chatter', String, queue_size=10)
    print(Sum(1,2))
    rospy.init_node('talker', anonymous=True)
    rate = rospy.Rate(10) # 10hz
    while not rospy.is_shutdown():
        hello_str = "hello world %s" % rospy.get_time()
        rospy.loginfo(hello_str)
        pub.publish(hello_str)
        rate.sleep()

if __name__ == '__main__':
    try:
        talker()
    except rospy.ROSInterruptException:
        pass

the sum.py:

#!/usr/bin/env python

def Sum(a,b):
     return a + b

And what I have added to the CMakeLists.txt file:

catkin_install_python(PROGRAMS
  scripts/talker.py scripts/listener.py scripts/sum.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

after doing catkin_make, source devel/setup.bash, and rosrun test talker.py I get the output:

Traceback (most recent call last):
  File "/home/-/catkin_ws/devel/lib/test/talker.py", line 15, in <module>
    exec(compile(fh.read(), python_script, 'exec'), context)
  File "/home/-/catkin_ws/src/test/scripts/talker.py", line 40, in <module>
    from sum import Sum
ImportError: cannot import name 'Sum' from 'sum' (/home/-/catkin_ws/devel/lib/test/sum.py)

where test is the name that I gave the package. Things I have tried (to no avail):

  • add import rospy to the sum.py file
  • use catkin build test instead of catkin_make
  • use the setup.py file
  • use a blank __init__.py file

I'm quite frankly at a loss on what to do. It seems like such a fundamental thing to do, that I'm afraid I'm missing something extremely obvious. However, after a lot of search engine work, it seems that no one has such as simple problem before (most of what I find relates to importing functions/files/modules from different packages etc.)

Any help or hints would be really appreciated!

Cheers!

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
0

answered 2023-01-31 03:54:30 -0500

none gravatar image

I appreciate Mike's help. Hopefully, this answer can help someone that stumbles upon the same importing issue.

I'm not quite sure what the underlying problem is, yet allow me to show the structure that removes the error:

CMakeLists.xtx:

cmake_minimum_required(VERSION 3.0.2)
project(test_package)

## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
  message_generation
  rospy
  std_msgs
)

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES test
#  CATKIN_DEPENDS rospy std_msgs message_runtime
#  DEPENDS system_lib
)

## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

## Mark executable scripts (Python etc.) for installation
## in contrast to setup.py, you can choose the destination
catkin_install_python(PROGRAMS
  src/talker.py 
  src/listener.py #src/test_package/sum.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

package.xml

<?xml version="1.0"?>
<package format="2">
  <name>test_package</name>
  <version>0.0.0</version>
  <description>The test package</description>

  <maintainer email="anon@todo.todo">anon</maintainer>

  <license>TODO</license>

  <buildtool_depend>catkin</buildtool_depend>

  <build_depend>message_generation</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>

  <build_export_depend>rospy</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>

  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>

  <export>

  </export>
</package>

setup.py

## ! DO NOT MANUALLY INVOKE THIS setup.py, USE CATKIN INSTEAD
from distutils.core import setup
from catkin_pkg.python_setup import generate_distutils_setup
# fetch values from package.xml
setup_args = generate_distutils_setup(
packages=['test_package'],
package_dir={'': 'src'},
)
setup(**setup_args)

talker.py

#!/usr/bin/env python

import rospy
from test_package.sum import Sum
from std_msgs.msg import String

def talker():
    pub = rospy.Publisher('chatter', String, queue_size=10)
    print(Sum(1,2))
    rospy.init_node('talker', anonymous=True)
    rate = rospy.Rate(10) # 10hz
    while not rospy.is_shutdown():
        hello_str = "hello world %s" % rospy.get_time()
        rospy.loginfo(hello_str)
        pub.publish(hello_str)
        rate.sleep()

if __name__ == '__main__':
    try:
        talker()
    except rospy.ROSInterruptException:
        pass

And most importantly, the file structure:

catkin_ws/src/test_package
    /src
        /test_package
            __init__.py
            sum.py
        talker.py
        listener.py
    CmakeLists.txt
    package.xml
    setup.py

where I build with catkin build, then source devel/setup.bash and rosrun test_package talker.py after running an instance of roscore. Given the location of the __init__.py and the setup.py file, I suspect something went wrong there initially.

edit flag offensive delete link more
0

answered 2023-01-28 09:13:14 -0500

Mike Scheutzow gravatar image

updated 2023-01-29 13:07:08 -0500

  • In python3, for a ros node consisting of multiple .py files, it looks like there are two approaches you can take:

    Path 1. No python module. Do NOT use catkin_install_python in the CMakeLists.txt, and set the executable bit on your main .py file. Importing another python file from the same directory will work. The downside of this simple approach is that the ros package can not be installed to /opt/ros/, but it's fine for development purposes.

    Path 2. Use a python module. Put your .py files in a python module, add a setup.py to top-level to install the python module, and use catkin_install_python() and catkin_python_setup() in CMakeLists.txt. Your imports must be changed to use the dot-prefix notation (e.g. from .sum import Sum)

  • Do not put a __init__.py in your ros package's scripts/ directory. roslaunch and rosrun do not expect to find a python package there.

  • You should not mix the output of catkin_make and catkin build - they are incompatible. You must use one or the other, and fully remove the directories catkin_ws/build/ and catkin_ws/devel/ if you switch between them.

  • You are asking for trouble using a ros or python package name of "test". It's theoretically legal, but the probability of an undesired name collision is very high.

edit flag offensive delete link more

Comments

Hi Mike, I understand that catkin_make and catkin build are incompatible, and I have definitely removed the build and devel folders between building, yet the issue remains. If I do catkin_make from scratch, I still get the error you highlighted (and similarly for a clean catkin build, so I'm not sure how to approach this.

none gravatar image none  ( 2023-01-29 08:25:49 -0500 )edit

I updated my answer.

Mike Scheutzow gravatar image Mike Scheutzow  ( 2023-01-29 09:16:28 -0500 )edit

Thanks Mike!

  1. in devel/lib/test/ it does indeed show all three files + an empty cmake.lock file. If I remove sum.py from the CMakeLists catkin_install_python statement, the respective linker file disappears, yet the error remains... Intuitively, it might have to do with relevant imports that have now disappeared (I'm more amazed by it not working when I do add sum.py to the CMake file.
  2. Done! yet unfortunately still the same issue.

Regarding 1., it does feel to me that it would have to work without the sum.py as it would require me to, in the future, include every possible python file to the catkin_install_python which would get very messy

none gravatar image none  ( 2023-01-29 09:31:30 -0500 )edit

Question Tools

2 followers

Stats

Asked: 2023-01-27 10:59:54 -0500

Seen: 4,731 times

Last updated: Jan 31 '23