欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

写自己的ROS节点使用(import)anaconda虚拟环境的包(在虚拟环境下运行)

程序员文章站 2022-05-31 11:34:03
让ROS节点script使用anaconda虚拟环境或者说在虚拟环境下运行上次留的坑结论结论1结论2在激活anaconda 虚拟环境未激活anaconda 虚拟环境自己的猜测,理解和总结没营养的试错写个学习笔记表示自己曾经爱过记录一下, 也方便回查上次留的坑教程里的脚本开头都爱来这么一下#!/usr/bin/env python说的是让ROS系统用python解释器来运行当前的脚本, 之前思考过一个问题,万一我要是用的conda虚拟环境,而且我还要import虚拟环境里的包,那么这个pyth...


写个学习笔记表示自己曾经爱过记录一下, 也方便回查, 这年头一赞难求.



2020-7-25 更新


问题

教程里的脚本开头都爱来这么一下

#!/usr/bin/env python

说的是让ROS系统用python解释器来运行当前的脚本, 之前思考过一个问题,万一我要是用的conda虚拟环境,而且我还要import虚拟环境里的包,那么这个python到底是哪个python呢?环境又是哪个环境呢?


结论

1. 第一步

虚拟环境下直接

conda activate 虚拟环境名       # 进入虚拟环境
which pip 					  # 查看使用的虚拟环境下的pip不是的话重开终端
pip install rospkg            # 你要的ros包都在里面了,下了就可以用

只要装了rospkg就一定能使用(import) ROS自带的包了,并且能调用ROS自带包里的所有东西


2. 第二步

自己写的脚本比如script.py文件第一行像下面这么写, 指定虚拟环境的python 解释器 必须是只有python2的解释器

#!/home/kuo/anaconda3/envs/虚拟环境名/bin/python

这样就既可以用虚拟环境的包,又可以用ros的工具包了,注意必须是只能是只有python2的解释器,
不然使用cvbridge的时候会出现下面的记录的报错,于是既可以用虚拟环境下的包,又可以用ros的工具包了


3. 完事

菜是原罪, 之前写错了. 我愧对之前收藏的人.
ToT



自己的理解和总结


  1. 不管是不是虚拟环境,只要安装了rospkg 就一定能找到ros的包如 rospy, std_msgs, cv_bridge

  2. script.py 文件里的第一句话就是指定文件运行的解释器:

    #!/usr/bin/env python
    

    等于这么写

    #!/usr/bin/env python3
    

    等于这么写

    #!/home/kuo/anaconda3/bin/python
    

    都是默认了使用anaconda base 环境下的python , 所以也都是在base环境下找环境里的包,
    而且base环境默认是python3, ros是不支持的,所以会出现我下面记录的报错

  3. 像下面这样写:

    #!/usr/bin/env python2
    

    就是强行在base环境下使用python2的解释器, 正常来说都能跑,既可以用base环境里的包也可以用ros的包,因为你在安装ros的官方教程的时候一般都会在这个环境下安装了rospkg

  4. 这样写:

    #!/home/kuo/anaconda3/envs/虚拟环境名/bin/python
    

    就是使用虚拟环境下的python解释器了,当然注意的是这个虚拟环境必须得是Python2的解释器
    貌似还得只有python2的解释器.


记录自己遇到的报错

在更新前, 有个老哥说他还是import不了虚拟环境的包, 于是我从新试了一下,果然不行,知道自己更新前写的搞错了,于是再试后更新:

这里记录一个最近试的时候遇到的报错,也就是上文说的python3不支持的报错

Traceback (most recent call last):
  File "/home/kuo/Desktop/catkin_ws/src/image_node/script/test_import.py", line 12, in <module>
    output_image = bridge.cv2_to_imgmsg(image, 'bgr8')
  File "/opt/ros/melodic/lib/python2.7/dist-packages/cv_bridge/core.py", line 259, in cv2_to_imgmsg
    if self.cvtype_to_name[self.encoding_to_cvtype2(encoding)] != cv_type:
  File "/opt/ros/melodic/lib/python2.7/dist-packages/cv_bridge/core.py", line 91, in encoding_to_cvtype2
    from cv_bridge.boost.cv_bridge_boost import getCvType
ImportError: dynamic module does not define module export function (PyInit_cv_bridge_boost)

原因:

虚拟环境用了python3的环境, 弄成python2.7的就好了








--------------------------------------------------------------------------

后面是更新前的, 写错了,不用看,愧对那个第一个给我博客赞的人, 这里留着只是做个记录


结论

先说自己试出来的结论, 后面没必要看,就是记录自己的各种试错,别浪费时间

结论1
在激活anaconda 虚拟环境

conda activate 虚拟环境名

的情况下, 节点script .py文件第一行这么写:

#!/usr/bin/env python2

既可以调用(import)虚拟环境下的包如: cv2, torch, numpy
也可以调用ROS系统里自带集成的工具包 如 rospy, std_msgs, cv_bridge
所以这种情况下该装啥包装啥包,直接用就对了,四方通行
但是注意前提是你虚拟环境里没有python2的解释器


结论2

在激活anaconda 虚拟环境

conda activate 虚拟环境名

的情况下, 节点script .py文件第一行这么写:

#!/usr/bin/env python

等于这么写

#!/usr/bin/env python3

也等于这么写

#!/home/kuo/anaconda3/envs/虚拟环境/bin/python

结果都是找的到虚拟环境的包, 找不到ROS自带的包


未激活anaconda 虚拟环境

conda deactivate

的情况下, 节点script .py文件第一行这么写:

#!/usr/bin/env python

等于

#!/usr/bin/env python2

结果都是找的到ROS自带的包和 anaconda base 环境下的包,找不到虚拟环境下的包


自己的猜测,理解和总结

  1. 激活什么环境, 就能用什么环境的包

  2. 只要用了python2的解释器, ROS自带的包就能找到

  3. 自己猜测的原因和过程:

    因为ros只支持python2, 所以激活了虚拟环境它当然在虚拟环境下找
    而 conda 虚拟环境下(因为你一般都只装个python 3), 于是

    #!/usr/bin/env python
    

    自动就默认成python3,于是等于

    #!/usr/bin/env python3
    

    其实也是等于直接运行虚拟环境的python3解释器bin运行文件

    #!/home/kuo/anaconda3/envs/虚拟环境/bin/python
    

    而由于ROS就是不支持python3的解释器调用, 于是python3的解释器
    找不到ROS自带的工具包

    但是如果你硬是在虚拟环境下写成这样

    #!/usr/bin/env python2
    

    强制用python2的解释器,由于它在你虚拟环境下找不到(因为你一般都只会在虚拟环境下装个python3), 那么它(anaconda)就会允许你跳出虚拟环境,从系统环境里去找,调用系统环境下的python2环境(名义上貌似也被anaconda归在base环境的名下),而这个环境里就有你安装的ros系统时的系统自带ROS基础包, 进而你又可以用虚拟环境里的包, 又能用上ros,但python解释器依旧只能是系统环境下的python2,也不违背ROS只支持python2的道理

    1. 没激活虚拟环境的情况下,一般来说,安装anaconda的时候,它自动会在你的base环境里既安装了python2(我估计是直接冠名系统默认了), 也安装了python3(我估计也是直接强行冠名系统默认了)于是
    #!/usr/bin/env python
    

    ROS自己会找到base环境下的自己只支持的python2,于是就默认等于

    #!/usr/bin/env python2
    

    于是能使用base环境的包,和ROS包.

    1. 如果在虚拟环境中既安装了python3的解释器又安装了python2的解释器, 那么当你激活虚拟环境,程序默认从虚拟环境中找python2解释器,而这个环境下根本没有安装ROS因为你的ROS按照官网的教程安装的话, 是安装在base环境下的,故而依旧会找不到rospy. 除非你在虚拟环境中直接安装了ros.

    这些结论呢都是自己试出来的, 自己也菜,不懂原理源码,所以不一定对. 就当抛砖引玉吧.



没营养的试错

因为自己是个菜鸟,不太了解原理,所以就自己慢慢试,要是有清楚的朋友麻烦告知了
于是把脚本改成这样, 可以吗?

#!/home/kuo/anaconda3/envs/torch/bin python

这里torch是我的虚拟环境名,上面就是虚拟环境中python 2进制文件(执行文件)位置
于是运行一波出现报错

/home/kuo/anaconda3/envs/torch/bin: bad interpreter: Permission denied

写自己的ROS节点使用(import)anaconda虚拟环境的包(在虚拟环境下运行)
查了一波后发现得这么写

#!/home/kuo/anaconda3/envs/torch/bin/python

再次运行一波,看看结果,出现报错, 但是报错的东西不一样了~
报错如下:

rosrun image_node image_talker.py 
Traceback (most recent call last):
  File "/home/kuo/Desktop/catkin_ws/src/image_node/script/image_talker.py", line 9, in <module>
    import rospy
  File "/opt/ros/melodic/lib/python2.7/dist-packages/rospy/__init__.py", line 49, in <module>
    from .client import spin, myargv, init_node, \
  File "/opt/ros/melodic/lib/python2.7/dist-packages/rospy/client.py", line 52, in <module>
    import roslib
  File "/opt/ros/melodic/lib/python2.7/dist-packages/roslib/__init__.py", line 50, in <module>
    from roslib.launcher import load_manifest  # noqa: F401
  File "/opt/ros/melodic/lib/python2.7/dist-packages/roslib/launcher.py", line 42, in <module>
    import rospkg
ModuleNotFoundError: No module named 'rospkg'

先看看我的script文件:


# 这里是要使用的虚拟环境下的包
import time 
import numpy as np 
import cv2
import glob
import matplotlib.pyplot as plt

#这里是要使用的ROS系统自带的基础工具包
import rospy
from std_msgs.msg import Header
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError

#这里是自己定义的程序包里的库
from image_node.msg import mask_image, mask2_image

写自己的ROS节点使用(import)anaconda虚拟环境的包(在虚拟环境下运行)
这里表示没有找到ros的一些包,说名anaconda下我的torch 虚拟环境没找到ROS, 但是torch虚拟环境
下的包找到了…

接着试:
这次不激活虚拟环境,且把第一行弄成官方教程里的样子

#!/usr/bin/env python

直接错的离谱:

rosrun image_node image_talker.py 
import-im6.q16: not authorized `time' @ error/constitute.c/WriteImage/1037.
import-im6.q16: not authorized `np' @ error/constitute.c/WriteImage/1037.
import-im6.q16: not authorized `cv2' @ error/constitute.c/WriteImage/1037.
import-im6.q16: not authorized `glob' @ error/constitute.c/WriteImage/1037.
import-im6.q16: not authorized `plt' @ error/constitute.c/WriteImage/1037.
import-im6.q16: not authorized `rospy' @ error/constitute.c/WriteImage/1037.
from: can't read /var/mail/std_msgs.msg
from: can't read /var/mail/sensor_msgs.msg
from: can't read /var/mail/cv_bridge
from: can't read /var/mail/image_node.msg
/home/kuo/Desktop/catkin_ws/src/image_node/script/image_talker.py: line 23: syntax error near unexpected token `('
/home/kuo/Desktop/catkin_ws/src/image_node/script/image_talker.py: line 23: `def set_params():'

写自己的ROS节点使用(import)anaconda虚拟环境的包(在虚拟环境下运行)
表示没找到虚拟环境里的包并且错乱了得重新打开一个终端
激活虚拟环境呢?
结果和上面一样
写自己的ROS节点使用(import)anaconda虚拟环境的包(在虚拟环境下运行)
再试激活虚拟环境下
考虑到ROS只支持python3, 那我硬来个python2如何?

#!/usr/bin/env python2

WOC 编译通过, 可以使用虚拟环境下的包,和ros本身的基础工具包ToT

本文地址:https://blog.csdn.net/GungnirsPledge/article/details/107237370