【已解决】ImportError: dynamic module does not define module export function (PyInit__tf2)

【ros问题记录】

问题描述

ImportError: dynamic module does not define module export function (PyInit__tf2)

Traceback (most recent call last):
  File "/home/mandy/ross/racecar_ws/src/Map_construction-Navigation_simulation/racecar_gazebo/scripts/XL_controller_cmd.py", line 18, in <module>
    import tf
  File "/opt/ros/melodic/lib/python2.7/dist-packages/tf/__init__.py", line 30, in <module>
    from tf2_ros import TransformException as Exception, ConnectivityException, LookupException, ExtrapolationException
  File "/opt/ros/melodic/lib/python2.7/dist-packages/tf2_ros/__init__.py", line 38, in <module>
    from tf2_py import *
  File "/opt/ros/melodic/lib/python2.7/dist-packages/tf2_py/__init__.py", line 38, in <module>
    from ._tf2 import *
ImportError: dynamic module does not define module export function (PyInit__tf2)

方法一主要参考:但貌似这博主是官网照抄的,这里根据实际情况进行修改

方法一是整个ros工作空间都在python3下编译工作

更新:我发现这个方法一点都不好用,因为ros melodic本来就是基于python2.7设计的,换到python3运行bug太多了,比如xacro:include会出现下面的问题。ArgException 是一个 Python 异常,xacro可能是一个基于 Python 的工具,所以我思考了许久觉得这个错误可能是因为python版本不兼容,而我也不会把底层源码改到兼容……所以还是老老实实用python2.7吧……


问题分析

所以回到最初,理清楚问题是什么,
参考1,方法一参考的博主的参考
参考2,ROS Melodic 中使用 Python3 和 tf2 实现位姿的坐标变换

在ros工作空间里找到引用的出问题的包(比如tf_ros)模块的python源码, print一下看看引入的模块来自哪个位置,如图可以看到我这引用的是来自python2.7的,

from tf2_ros import *
print("tf2_ros module path:", tf2_ros.__file__)

print输出

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

方法二:更改python脚本的shebang行

那为什么会出现ImportError: dynamic module does not define module export function (PyInit__tf2) 的问题?

  1. 首先排除没有安装这个包,没安就sudo apt-get install一下
sudo apt-get install ros-melodic-tf2-ros ros-melodic-tf2-geometry-msgs
  1. 然后,确保你引用的这个包的python文件的Shebang行#! *****写对了,是你想要python解释器,如过你是想要默认的python2.7的解释器就写第一条,如果是想要python3的解释器就写第二条,如此类推(不确定解释器路径的就which一下)
#! /usr/bin/python

#! /home/mandy/anaconda3/envs/py36sarl/bin/python

总结:针对本身就安装在python2下的tf包,python源文件直接shebang行用#! /usr/bin/python就可以,不用其他乱七八糟的操作,非常简单

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

方法三参考2,重装 tf2_py使能在python3下使用

根据参考2中的描述,总结了一下自己的操作

  1. 把geometry2从github上下到catkin_ws/src下,我这里因为是操作过方法一,用wstool管理geometry2包。但单纯git
    clone应该也没问题,我感觉这个方法和wstool、rosdep没啥关系…?
# 使用wstool管理geometry2包
wstool init
wstool set -y src/geometry2 --git https://github.com/ros/geometry2 -v 0.6.5
wstool up
rosdep install --from-paths src --ignore-src -y -r
  1. 在 catkin_ws/src/geometry2/tf2_py/ 下的CMakeLists.txt里,在project(tf2_py)后添加三行set,PYTHON_EXECUTABLE、PYTHON_INCLUDE_DIR、PYTHON_LIBRARY参数的获取方法可以往下翻到方法一
    在这里插入图片描述
project(tf2_py)

set(PYTHON_EXECUTABLE /home/mandy/anaconda3/envs/py36sarl/bin/python)
set(PYTHON_INCLUDE_DIR /home/mandy/anaconda3/envs/py36sarl/include/python3.9)
set(PYTHON_LIBRARY /home/mandy/anaconda3/envs/py36sarl/lib/libpython3.9.so)

  1. cd 到catkin_ws文件夹下, catkin build, 然后source devel/setup.bash (注:不用catkin_make了,其实我不懂这个区别在哪里)
$ rm -rf build devel  
$ catkin build

然后顺利的话,就能在devel/lib/python3/dist-packages/下看到生成了 Python3 可运行的功能包

$ ls devel/lib/python3/dist-packages/
tf2_py  tf2_ros
$ source devel/setup.bash
  1. 修改catkin_ws下的引用到这个模块的python脚本的shebang行,选择你前面cmakelist里修改使用的python解释器。以及将包所在的路径插入到 sys.path,确保 Python 优先从这个路径搜索模块
#! /home/mandy/anaconda3/envs/py36sarl/bin/python
import sys
# print(sys.path)
sys.path.insert(0, '/home/mandy/ross/racecar_ws/devel/lib/python3/dist-packages')
from tf2_ros import *
print("tf2_ros module path:", tf2_ros.__file__)

这个时候print出来的包路径就能看到是来自我们前面编译的python3路径在这里插入图片描述

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

曾经写下的方法一,作为记录就不删了

运行环境:

:conda管理的虚拟环境,python=3.9,这里做的主要是设置一个使用python3.9虚拟环境的ros工作空间

# 进入虚拟环境
conda activate py36sarl #虽然我的名字叫36但确实是39
# 安装必要的python3模块
sudo apt update
sudo apt install python3-catkin-pkg-modules python3-rospkg-modules python3-empy 

cd ~/ross/catkin_ws  # 进入自己的catkin workspace
# 初始化工作空间让ros识别到
catkin_make
source devel/setup.bash

# 使用wstool管理geometry2包
wstool init
wstool set -y src/geometry2 --git https://github.com/ros/geometry2 -v 0.6.5
wstool up
rosdep install --from-paths src --ignore-src -y -r

# 使用Python 3编译工作空间,通过设置DPYTHON_xxxxx参数
catkin_make --cmake-args \
            -DCMAKE_BUILD_TYPE=Release \
            -DPYTHON_EXECUTABLE=/home/mandy/anaconda3/envs/py36sarl/bin/python  \
            -DPYTHON_INCLUDE_DIR=/home/mandy/anaconda3/envs/py36sarl/include/python3.9 \
            -DPYTHON_LIBRARY=/home/mandy/anaconda3/envs/py36sarl/lib/libpython3.9.so

参数解释:

:-DPYTHON_EXECUTABLE:
设置为虚拟环境中的Python可执行文件路径,确保CMake在编译过程中使用虚拟环境中的Python解释器。
:-DPYTHON_INCLUDE_DIR:
设置为虚拟环境中的Python头文件目录,确保CMake在编译过程中包含正确的Python头文件。
:-DPYTHON_LIBRARY:
设置为虚拟环境中的Python库文件路径,确保CMake在链接过程中使用正确的Python库。

可以通过以下命令寻找自己的环境的这些参数:

$  which python
/home/mandy/anaconda3/envs/py36sarl/bin/python
$ python -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())"
/home/mandy/anaconda3/envs/py36sarl/include/python3.9
$ python -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))"
/home/mandy/anaconda3/envs/py36sarl/lib
$ ls /home/mandy/anaconda3/envs/py36sarl/lib | grep libpython
libpython3.9.so
libpython3.9.so.1.0
libpython3.so

如果需要,修改roslaunch脚本:

roslaunch脚本的shebang行写的还是支持默认的2.7的解释器,所以需要修改为使用python3

sudo gedit  /opt/ros/melodic/bin/roslaunch

将第一行改成;

#!/usr/bin/env python3

通过这些设置可以使ROS工作空间与Python 3.9环境完全兼容,避免了与系统默认的Python版本(通常是Python 2.7)相关的兼容性问题。

最后catkin_make的过程中可能会遇到缺包或者包不兼容的情况,pip install 到兼容的版本就是了

也或许可以通过类似的方式来确保你是在最初始的python2.7中工作的?

我也不懂,欢迎大佬多多指教
-------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值