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

最近又写了个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
    from net_man.srv import *
  File "/home/haipeng/catkin_ws/src/net_man/scripts/net_man.py", line 6, in
    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问题

你可能感兴趣的:(机器人)