如何在ROS中调用anaconda虚拟环境,以及如何将一个python工程封装为一个ROS包并rosrun执行。

该文章已生成可运行项目,

目录

一、如何在ROS中调用anaconda虚拟环境

1、先上结论:

注意事项:

2、举例验证

二、如何将一个python工程封装为一个ROS包并rosrun执行

举例演示


前言:

        我的python代码一般都在pycharm上直接右键运行的,因为pycharm可以集成我的conda虚拟环境。但前段时间需要将我写的python工程“打包”为一个ROS包,并丢到工作空间中和其他部分的代码进行通讯。好假如现在我把整个python工程放到我新创建的一个ros包里,然后我去rosrun这个python工程的入口.py文件(就是平时在pycharm当中右键运行所处在的那份.py文件),就会发现一个大问题:pycharm上能运行是因为它已经帮你集成了你想要的conda虚拟环境,那ROS它在rosrun你的函数时,怎么能知道你的conda虚拟环境呢?这说明我们必须通过某种方式告诉ROS我所期望的编译器在哪里。

        也是看网上资料较多较杂,故做个总结。

一、如何在ROS中调用anaconda虚拟环境

1、先上结论:

比如说我指定的conda虚拟环境叫做test_condaros,并且我要运行的文件为:

rosrun test_condaros_pkg main.py

那么我就在这个main.py的第一行加上

#!<path-to-your-conda-env>/bin/python3

这是shebang行,专门用来告诉ROS,当它读到这行注释时,那么接下来的代码都要用shebang行指定的python编译器来运行。其中,

#!

这是必须要有的,后面接不接空格都没关系。然后,

<path-to-your-conda-env>/bin/python3

表示你要指定的python编译器的绝对路径。比如说我创建了一个conda虚拟环境,叫做test_condaros,那么它的python编译器在我的Ubuntu系统里的绝对路径为:

/home/czl/anaconda3/envs/test_condaros/bin/python3,其中czl是我的用户名,至于是python还是python3就要视自己情况而定了。

完整的shebang行长这样:

#! /home/czl/anaconda3/envs/test_condaros/bin/python3

注意事项:

如果希望自己写的shebang行能够正常生效,那么Cmakelistts中的catkin_install_python要保持注释

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

若按照ROS官方的教程“如何写一个发布订阅者节点(python)”cn/ROS/Tutorials/WritingPublisherSubscriber(python) - ROS Wiki

里面会有一步:

如果你在shebang行指定了编译器的同时,还将这个catkin_install_python取消注释,那么catkin_build后这一行catkin_install_python指令便会将你写的shebang行覆盖掉,并调用ROS默认的python编译器。

详细问题可以参考shebang is ignored by rosrun - Robotics Stack Exchange

在这篇博客里,楼主问了“shebang行被rosrun无视了”这个问题,下面有人解答了:

就是说这个catkin_install_python指令会重写你的shebang行。

2、举例验证

下面创建一个简单的ros包来验证上面的结论。

catkin_create_pkg test_condaros_pkg rospy std_msgs

在scripts文件下创建main.py,并添加:

import sys
print(sys.executable)  # 来验证能否正确调用test_condaros虚拟环境

用来打印出执行这个文件用的编译器是哪个。

然后我创建一个新的conda虚拟环境:

conda create -n test_condaros python=3.8

并在main.py开头添加shibang行:

#! /home/czl/anaconda3/envs/test_condaros/bin/python3

好测试程序完成,长这样:

#! /home/czl/anaconda3/envs/test_condaros/bin/python3

import sys
print(sys.executable)  # 来验证能否正确调用test_condaros虚拟环境

下面开始rosrun来看看使用的编译器是是什么(rosrun前记得给python文件赋予可执行权限)。 

①:若按照ROS官方教程来取消注释catkin_install_python指令,rosrun的结果为:

可明显我的shebang行被覆盖掉了。

②:注释catkin_install_python指令,再rosrun(需要在工作空间先catkin clean后,再执行

catkin build,再rosrun):

成功!

PS:我还遇到了一个很神奇的bug,如果是自己在Ubuntu上新建工程写shebang行是没有任何问题的,但是这个移植过来的工程就会说我的shebang行有问题,解决办法如下:
若出现报错:

home/czl/anaconda3/envs/trace_detect/bin/python^M:解释器错误: 没有那个文件或目录


则需要在终端出运行如下代码:

sed -i 's/\r$//' /home/czl/catkin_ws/src/test_trace_detect_pkg/scripts/trace_detect_node.py

原因:错误信息中的 ^M 表示在文件中检测到了 Windows 风格的换行符(Carriage Return, CR),这可能是因为文件在 Windows 系统上被编辑过,然后被复制到了 Linux 系统上。Linux 系统期望的是 Unix 风格的换行符,所以需要自己手动去修改

二、如何将一个python工程封装为一个ROS包并rosrun执行

举例演示

我原先有一个python工程,里面主要是一个faster-rcnn的深度学习模型,以及一些open3d之类的其他图像处理代码,大致结构长这样:

总之就是,所有代码都在faster_rcnn文件夹里面了,并且,入口文件main_2D3D.py在faster_rcnn目录下面。

现在我创建一个ros包:trace_detect_pkg,并在其中的scripts文件中,将faster_rcnn里的所有文件全部复制到里面(方便起见,确保入口文件在scripts目录下就行)。

同时,这个main_2D3D.py将不再作为我的入口文件了,我新建了一个trace_detect_node.py作为我的这个trace_detect_pkg的入口文件(作为一个用于通讯的节点python文件,并在里面调用main_2D3D.py),方便管理,也保证用于ROS通讯部分的代码不会污染原先的代码。

好,现在已经将整个python工程搬到ros包里了,接下来就是要做4件事:

1、告诉ROS,当执行

rosrun trace_detect_pkg trace_detect_node.py

时,要用哪个编译器。这个简单,只需要在入口文件trace_detect_node.py的第一行加上sheshang行:

#! /home/czl/anaconda3/envs/trace_detect/bin/python

2、确保ROS能够根据程序里写的各种 相对路径 来查找文件。

同样,也是在入口文件trace_detect_node.py里加上:

import os
script_dir = os.path.dirname(os.path.realpath(__file__))
os.chdir(script_dir)

这段代码的作用是将Python脚本的当前工作目录切换到该脚本文件所在的目录。

例子:假如我现在要运行这个main_2D3D.py(里面包含了许多相对于这个main_2D3D.py而言的路径,比如 ../tmpl.ply)我是在终端直接跑czl@czl-virtual-machine:~$ rosrun test_trace_detect_pkg trace_detect_node.py 这个节点的,那么此时运行的路径就在你的主目录/home/czl下,那么遇到这些相对路径../tmpl.ply,肯定是找不到的。

3、赋予入口文件执行权限

chmod +x trace_detect_node.py

4、至于Cmakelists与package.xml,如果你只是想rosrun这个python工程而不进行任何ros通讯的话,那么只需要一个rospy就搞定了,不需要c++那么复杂。

## 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
  rospy
)

好,此时catkin_build一下,没问题就可以rosrun了。 

本文章已经生成可运行项目
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值