ROS中在一个功能包中导入另一个功能包的python模块

2023-05-16

目录

 

1. 引言

2. 创建一个功能包

3. 安装功能包到ROS环境

3.1 编辑CMakeLists.txt

3.2 编辑setup.py

3.3 安装到ROS环境

4. 模块导入

4.1 创建验证功能包

4.2 编译工作空间

4.3 运行ros节点

5. 总结

6. 参考文献


1. 引言

在使用python编写ROS的功能包时总是会有一些公用python模块存在。相较于公用模块被到处拷贝,一种更优雅的方式应该是将公用模块提取为一个功能包,其他模块直接引用这个功能包即可。这种复用的思想在编程过程中十分重要。但是实际操作中经常会遇到ImportError: No module named ***等的错误,这篇文章将介绍一个ROS功能包中的python模块如何导入并使用另一个ROS功能包的python模块。

如果你是ROS初学者,我还是建议你先去看一下初学者教程:ROS Tutorials。本文会按照以下顺序介绍

  1. 创建一个功能包并在功能包下创建一个模块
  2. 安装功能包到ROS环境
  3. 在另一个功能包中导入并使用前面创建的模块

2. 创建一个功能包

创建一个catkin_ws的命名空间,并进行以下操作

cd catkin_ws/src
catkin_create_pkg py_pkg_1 rospy
cd py_pkg_1
touch setup.py
mkdir -p src/py_pkg_1
cd src/py_pkg_1
touch __init__.py
touch common.py

以上操作创建一个名为py_pkg_1的ROS功能包,在py_pkg_1功能包的根目录创建一个setup.py文件用于python模块的安装,在src目录下创建一个名为py_pkg_1的python包,其中有一个名为common的模块(这里请注意区分一下ROS功能包和python包以及python模块这几个概念,关于python包和模块的介绍可以参考这篇文章)。

在common.py模块中添加以下代码

#!/usr/bin/python
# -*- coding:utf-8 -*-

import rospy

def say_hello_world():
    rospy.loginfo('Hello world!')

这个模块很简单,定义了一个名为say_hello_world的函数。__init__.py文件用于告诉python这个py_pkg_1目录是一个python包,这里__init__.py中可以什么都不写,如果你希望外部模块可以使用from py_pkg_1 import *这个语法导入你的python包,需要在__init__.py文件中定义以下变量

__all__=['common']

3. 安装功能包到ROS环境

3.1 编辑CMakeLists.txt

安装功能包到ROS环境分为两个步骤,其一是要修改py_pkg_1功能包的CMakeList.txt文件,文件内容如下

cmake_minimum_required(VERSION 3.0.2)
project(py_pkg_1)

find_package(catkin REQUIRED COMPONENTS
  rospy
)

catkin_python_setup()

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES py_pkg_1
#  CATKIN_DEPENDS rospy
#  DEPENDS system_lib
)

include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

其实就是将功能包创建时生成的默认文件中catkin_python_setup()取消注释而已。这一行是告诉catkin编译工具这里面有python的包要安装,这样catkin在编译时就会在这个功能包的根目录下自动寻找setup.py文件并执行了。

3.2 编辑setup.py

setup.py文件用于将python包安装到ROS环境,这个setup.py经过了catkin的一层封装变得更为简洁了,其实它的底层调用的是python的distutils包实现安装的。关于使用distutils进行python包的安装及发布可以参考这篇文章。语法上这两者是很相似的。setup.py文件的内容如下

from distutils.core import setup
from catkin_pkg.python_setup import generate_distutils_setup

d = generate_distutils_setup(
    packages=['py_pkg_1'],
    package_dir={'': 'src'}
)

setup(**d)
  • packages代表你想要安装的python包
  • package_dir描述的是python包的存放路径,这个必须得写否则你的python包只能放在setup.py的同级目录
  • setup(**d)其实就是调用distutils包的setup模块

3.3 安装到ROS环境

所谓安装到ROS环境其实就是编译catkin_ws这个工作空间。

cd catkin_ws
catkin_make

4. 模块导入

4.1 创建验证功能包

为了验证模块安装是否成功,需要额外创建一个名为py_pkg_2的ROS功能包并导入py_pkg_1中的common模块。进行以下操作

cd catkin_ws/src
catkin_create_pkg py_pkg_2 rospy
cd py_pkg_2
mkdir -p src/py_pkg_2
cd src/py_pkg_2
touch test.py

test.py文件内容如下

#!/usr/bin/env python

import rospy

from py_pkg_1 import common

if __name__=='__main__':
    rospy.init_node('test_node')
    common.say_hello_world()

这个test.py定义了一个ROS节点,导入了py_pkg_1中的common模块并调用模块的say_hello_world函数。

4.2 编译工作空间

定位到catkin_ws工作空间根目录并编译

cd catkin_ws
catkin_make

4.3 运行ros节点

在一个单独的窗口中启动roscore,打开一个新的窗口,执行以下指令

cd catkin_ws
source devel/setup.bash
rosrun py_pkg_2 test.py

此时你会发现模块调用成功,窗口中打印信息类似于

[INFO] [1609229996.409039]: Hello world!

5. 总结

这篇文章主要介绍了在ROS功能包中怎么安装python包并在其他ROS功能包中导入已经安装的python包,相关代码已上传至github:https://github.com/hitgavin/rosws/tree/master/src/python_pkg_import,感兴趣可以参考一下。

6. 参考文献

[1]. https://roboticsbackend.com/ros-import-python-module-from-another-package/

[2]. https://blog.csdn.net/fireflychh/article/details/80162981

[3]. https://blog.csdn.net/weixin_38256474/article/details/81228492

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS中在一个功能包中导入另一个功能包的python模块 的相关文章

随机推荐