红联Linux门户
Linux帮助

ROS运行python脚本报错ImportError: No module named srv

发布时间:2016-07-31 09:33:37来源:linux网站作者:六个九十度
最近又写了个ROS(robot operating system)包,格式照抄之前的包,结构如下:
haipeng@wang:~/catkin_ws/src$ tree net_man/
net_man/
├── CMakeLists.txt
├── package.xml
├── scripts
│   └── net_man.py
├── src
└── srv
├── ConnectWifi.srv
└── Switch2AP.srv
3 directories, 5 files
 
其中net_man.py内容如下
#!/usr/bin/env python  
# -*- coding:utf-8 -*-  
import sys  
import roslib  
import rospy  
from net_man.srv import *  
def switch_to_ap(req):  
print 'AP doudou created'  
print 'please connect the AP and visit http://192.168.0.1/ to enter you wifi password'  
return True  
def connect_user_wifi(req):  
ssid = req.ssid.decode('utf-8')  
password = req.password  
print 'agent of internet : ' + ssid  
return True  
if __name__ == "__main__":  
rospy.init_node('NetMan')  
#init switch to AP mode service  
s1 = rospy.Service('/netman_switch_to_ap', Switch2AP, switch_to_ap)  
#init connect user wifi service  
s2 = rospy.Service('/netman_connect_user_wifi', ConnectWifi, connect_user_wifi)  
rospy.spin()  
 
编译顺利通过,但运行报错
Traceback (most recent call last):
File "net_man.py", line 6, in <module>
from net_man.srv import *
File "/home/haipeng/catkin_ws/src/net_man/scripts/net_man.py", line 6, in <module>
from net_man.srv import *
ImportError: No module named srv
奇怪!我明明有srv目录啊,而且
devel/lib/python2.7/dist-packages/net_man/srv/__init__.py
文件也存在啊?
 
排除过以下错误:
1、检查package.xml和CMakeList.txt文件,没有问题
2、运行被照抄的包,一切OK
3、运行roswtf命令检查ROS环境,发现ros cache db有问题,用rosdep处理OK后,现象依旧
4、尝试在其他包里执行from net_man.srv import *语句,没问题。又尝试在net_man.py里执行导入其他包的srv,也成功。
到这里我不禁怀疑起名称冲突问题了,将net_man.py改成net_man2.py(改之前记得删除.pyc文件,否则你运行net_man2.py时python调用的还是net_man.py!)后,问题消失!
原来python导入一个模块时,会先对模块名按点号分段(xxx.yyy.zzz),每一段都先从当前目录找起,如果最终在目录A找到,则从A的子目录Aa  Ab  Ac等找第二段,找不到则报错,找到则继续,直到最后一段也找到
所以,我的代码里
from net_man.srv import *
当python找第一段net_man时,先从当前目录找起,然后刚好找到了(net_man.py与net_man目录重名!),于是接着找第二段srv,net_man.py里并没有srv,于是出错退出
 
感悟:
1、如果python的包导入代码能加入回溯功能就好了,比如第二段查找进入死胡同,则在sys.path里查找下一个匹配项,再试,直到第一段的所有适配项都走入死胡同时,再报错
2、其实只要注意将包名、模块名、函数名区分开,就能避免大部分import问题。
 
本文永久更新地址:http://www.linuxdiyf.com/linux/22864.html