简体   繁体   English

从 ROS 中的同一目录导入 python 个文件/函数(听起来很简单!)

[英]Importing python files/functions from the same directory in ROS (as simple as it sounds!)

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.幸运的是,我们设法在示例 talker.py 和 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.我的问题是我似乎无法从另一个 python 文件导入任何 function,即使这些文件与 talker.py 文件位于同一文件夹中。

Here is the code (you just need talker.py for this):这是代码(为此你只需要 talker.py):

#!/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:总和.py:

#!/usr/bin/env python

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

And what I have added to the CMakeLists.txt file:以及我添加到 CMakeLists.txt 文件中的内容:

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:在执行 catkin_make、source devel/setup.bash 和 rosrun test talker.py 之后,我得到了 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 (not the smartest name, but it doesn't conflict right now).其中 test 是我给 package 起的名字(不是最聪明的名字,但现在不冲突)。 Things I have tried (to no avail):我尝试过的事情(无济于事):

  1. add import rospy to the sum.py file将 import rospy 添加到 sum.py 文件
  2. use catkin build test instead of catkin_make使用 catkin 构建测试而不是 catkin_make
  3. use the setup.py file使用 setup.py 文件
  4. use a blank init .py file (per another answer on StackOverflow)使用空白的init .py 文件(根据 StackOverflow 上的另一个答案)

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 had 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!任何帮助或提示将不胜感激!

The source directory of your package should be added to PYTHONPATH list. package 的源目录应该添加到PYTHONPATH列表中。

The best way to do this is described here in the ROS documentation. ROS 文档中描述执行此操作的最佳方法。 Create setup.py file in the root directory of the package containing delisted src directory:在 package 根目录下创建setup.py文件,包含下架的src目录:

setup_args = generate_distutils_setup(
    packages=['package'],
    package_dir={'': 'src'},
)

Then use catkin_python_setup() function in CMakeLists.txt to list your src directory in the PYTHONPATH for the sourced workspace.然后在CMakeLists.txt中使用catkin_python_setup() function 在源工作区的PYTHONPATH中列出您的src目录。

I appreciate Andrei and John's help.我感谢 Andrei 和 John 的帮助。 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 : 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 .我使用 catkin build 进行catkin build ,然后在运行 roscore 实例后获取source devel/setup.bashrosrun test_package talker.py roscore Given the location of the __init__.py and the setup.py file, I suspect something went wrong there initially.鉴于__init__.pysetup.py文件的位置,我怀疑最初那里出了问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM