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模块 的相关文章

  • 使用 psycopg2 在 python 中执行查询时出现“编程错误:语法错误位于或附近”

    我正在运行 Python v 2 7 和 psycopg2 v 2 5 我有一个 postgresql 数据库函数 它将 SQL 查询作为文本字段返回 我使用以下代码来调用该函数并从文本字段中提取查询 cur2 execute SELECT
  • 没有名为 crypto.cipher 的模块

    我现在正在尝试加密一段时间 我最近得到了这个基于 python 的密码器 名为PythonCrypter https github com jbertman PythonCrypter 我对 Python 相当陌生 当我尝试通过终端打开 C
  • Python 中的 Lanczos 插值与 2D 图像

    我尝试重新缩放 2D 图像 灰度 图像大小为 256x256 所需输出为 224x224 像素值范围从 0 到 1300 我尝试了两种使用 Lanczos 插值来重新调整它们的方法 首先使用PIL图像 import numpy as np
  • Django 管理员在模型编辑时间歇性返回 404

    我们使用 Django Admin 来维护导出到我们的一些站点的一些数据 有时 当单击标准更改列表视图来获取模型编辑表单而不是路由到正确的页面时 我们会得到 Django 404 页面 模板 它是偶尔发生的 我们可以通过重新加载三次来重现它
  • 将 saxon 与 python 结合使用

    我需要使用 python 处理 XSLT 目前我正在使用仅支持 XSLT 1 的 lxml 现在我需要处理 XSLT 2 有没有办法将 saxon XSLT 处理器与 python 一起使用 有两种可能的方法 设置一个 HTTP 服务 接受
  • 为 Anaconda Python 安装 psycopg2

    我有 Anaconda Python 3 4 但是每当我运行旧代码时 我都会通过输入 source activate python2 切换到 Anaconda Python 2 7 我的问题是我为 Anaconda Python 3 4 安
  • 如何替换 pandas 数据框列中的重音符号

    我有一个数据框dataSwiss其中包含瑞士城市的信息 我想用普通字母替换带有重音符号的字母 这就是我正在做的 dataSwiss Municipality dataSwiss Municipality str encode utf 8 d
  • python 相当于 R 中的 get() (= 使用字符串检索符号的值)

    在 R 中 get s 函数检索名称存储在字符变量 向量 中的符号的值s e g X lt 10 r lt XVI s lt substr r 1 1 X get s 10 取罗马数字的第一个符号r并将其转换为其等效整数 尽管花了一些时间翻
  • 如何从网页中嵌入的 Tableau 图表中抓取工具提示值

    我试图弄清楚是否有一种方法以及如何使用 python 从网页中的 Tableau 嵌入图形中抓取工具提示值 以下是当用户将鼠标悬停在条形上时带有工具提示的图表示例 我从要从中抓取的原始网页中获取了此网址 https covid19 colo
  • 测试 python Counter 是否包含在另一个 Counter 中

    如何测试是否是pythonCounter https docs python org 2 library collections html collections Counter is 包含在另一个中使用以下定义 柜台a包含在计数器中b当且
  • Python pickle:腌制对象不等于源对象

    我认为这是预期的行为 但想检查一下 也许找出原因 因为我所做的研究结果是空白 我有一个函数可以提取数据 创建自定义类的新实例 然后将其附加到列表中 该类仅包含变量 然后 我使用协议 2 作为二进制文件将该列表腌制到文件中 稍后我重新运行脚本
  • OpenCV 无法从 MacBook Pro iSight 捕获

    几天后 我无法再从 opencv 应用程序内部打开我的 iSight 相机 cap cv2 VideoCapture 0 返回 并且cap isOpened 回报true 然而 cap grab 刚刚返回false 有任何想法吗 示例代码
  • IO 密集型任务中的 Python 多线程

    建议仅在 IO 密集型任务中使用 Python 多线程 因为 Python 有一个全局解释器锁 GIL 只允许一个线程持有 Python 解释器的控制权 然而 多线程对于 IO 密集型操作有意义吗 https stackoverflow c
  • 无法在 Python 3 中导入 cProfile

    我试图将 cProfile 模块导入 Python 3 3 0 但出现以下错误 Traceback most recent call last File
  • Pandas:merge_asof() 对多行求和/不重复

    我正在处理两个数据集 每个数据集具有不同的关联日期 我想合并它们 但因为日期不完全匹配 我相信merge asof 是最好的方法 然而 有两件事发生merge asof 不理想的 数字重复 数字丢失 以下代码是一个示例 df a pd Da
  • 将图像分割成多个网格

    我使用下面的代码将图像分割成网格的 20 个相等的部分 import cv2 im cv2 imread apple jpg im cv2 resize im 1000 500 imgwidth im shape 0 imgheight i
  • 对年龄列进行分组/分类

    我有一个数据框说df有一个柱子 Ages gt gt gt df Age 0 22 1 38 2 26 3 35 4 35 5 1 6 54 我想对这个年龄段进行分组并创建一个像这样的新专栏 If age gt 0 age lt 2 the
  • 有没有办法检测正在运行的代码是否正在上下文管理器内执行?

    正如标题所述 有没有办法做到这样的事情 def call back if called inside context print running in context else print called outside context 这将
  • Python:如何将列表列表的元素转换为无向图?

    我有一个程序 可以检索 PubMed 出版物列表 并希望构建一个共同作者图 这意味着对于每篇文章 我想将每个作者 如果尚未存在 添加为顶点 并添加无向边 或增加每个合著者之间的权重 我设法编写了第一个程序 该程序检索每个出版物的作者列表 并
  • 如何将输入读取为数字?

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 Why are x and y下面的代码中使用字符串而不是整数 注意 在Python 2

随机推荐