开发者

Python file location conventions and Import errors

开发者 https://www.devze.com 2023-03-12 15:49 出处:网络
I\'m new to Python and I simply don\'t know how to handle this specific problem: I\'m trying to run an executable (named ros_M5e.py) that\'s located in the directory /opt/ros/diamondback/stacks/hrl/hr

I'm new to Python and I simply don't know how to handle this specific problem: I'm trying to run an executable (named ros_M5e.py) that's located in the directory /opt/ros/diamondback/stacks/hrl/hrl_rfid/src/hrl_rfid/ros_M5e.py (annoyingly long filepath, I know, but necessary). However, within the ros_M5e.py file there is a call to another file that is further up the file path: from hrl.hrl_rfid.msg import RFIDread. The directory msg indeed is located at /opt/ros/diamondback/stacks/hrl/hrl_rfid/ and it does indeed contain the file RFIDread. However, whenever I try to execute ros_M5e.py I get this error:

Traceback (most recent call last): File "/opt/ros/diamondback/stacks/hrl/hrl_rfid/src/hrl_rfid/ros_M5e.py", line 37, in <module> from hrl.hrl_rfid.msg import RFIDread ImportError: No module named hrl.hrl_rfid.msg

Would someone with some开发者_Go百科 expertise please shine some light on this problem for me? It seems like just a rudimentary file location problem, but I just don't know the appropriate Python conventions to fix it. I've tried putting the ros_M5e.py file in the same directory as the files it calls and changing the filepaths but to no avail.

Thanks a lot,

Khiya


Sure, I can help you get it up and running.

From the StackOverflow posting, it would seem that you're checking out the stack to /opt/ros/diamondback. This is no good, as it is a system path. You need to install into your local path. The reason for "readonly" on the repository is that you do not have permissions to make changes to the code -- it will still work just fine for you on your local machine. I spent a fair amount of time showing how to use this package (at least the python version) here:

http://www.ros.org/wiki/hrl_rfid

I'll try to do a quick run-through for installing it.... Run the following commands:

cd
mkdir sandbox
cd sandbox/
svn checkout http://gt-ros-pkg.googlecode.com/svn/trunk/hrl/hrl_rfid hrl_rfid  (double-check that this checkout works OK!)

Add the following line to the bottom of your bashrc to tell ROS where to find the new package. (You may use "gedit ~/.bashrc")

export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$HOME/sandbox/hrl_rfid

Now execute the following:

roscd hrl_rfid  (did you end up in the correct directory?)
rosmake hrl_rfid  (did it make without errors?)
roscd hrl_rfid/src/hrl_rfid

At this point everything is actually installed correctly. By default, ros_M5e.py assumes that the reader is located at "/dev/robot/RFIDreader". Unless you've already altered udev rules, this will not be the case on your machine. I suggest running through the code:

http://www.ros.org/wiki/hrl_rfid 

using iPython (a command-line python prompt that will let you execute python commands one at a time) to make sure everything is working (replace /dev/ttyUSB0 with whatever device your RFID reader is connected as):

import lib_M5e as M5e

r = M5e.M5e( '/dev/ttyUSB0', readPwr = 3000 )
r.ChangeAntennaPorts( 1, 1 )
r.QueryEnvironment()

r.TrackSingleTag( 'test_tag_id_' )
r.ChangeTagID( 'test_tag_id_' )
r.QueryEnvironment()
r.TrackSingleTag( 'test_tag_id_' )

r.ChangeAntennaPorts( 2, 2 )
r.QueryEnvironment()

This means that the underlying library is working just fine. Next, test ROS (make sure "roscore" is running!), by putting this in a python file and executing:

import lib_M5e as M5e

def P1(r):
    r.ChangeAntennaPorts(1,1)
    return 'AntPort1'

def P2(r):
    r.ChangeAntennaPorts(2,2)
    return 'AntPort2'

def PrintDatum(data):
    ant, ids, rssi = data
    print data

r = M5e.M5e( '/dev/ttyUSB0', readPwr = 3000 )
q = M5e.M5e_Poller(r, antfuncs=[P1, P2], callbacks=[PrintDatum])
q.query_mode()

t0 = time.time()
while time.time() - t0 < 3.0:
    time.sleep( 0.1 )

q.track_mode( 'test_tag_id_' )

t0 = time.time()
while time.time() - t0 < 3.0:
    time.sleep( 0.1 )

q.stop()

OK, everything works now. You can make your own node that is tuned to your setup:

#!/usr/bin/python
import ros_M5e as rm

def P1(r):
    r.ChangeAntennaPorts(1,1)
    return 'AntPort1'

def P2(r):
    r.ChangeAntennaPorts(2,2)
    return 'AntPort2'

ros_rfid = rm.ROS_M5e( name = 'my_rfid_server',
                       readPwr = 3000,
                       portStr = '/dev/ttyUSB0',
                       antFuncs = [P1, P2],
                       callbacks = [] )

rospy.spin()
ros_rfid.stop()

Or, ping me back and I can tweak ros_M5e.py to take an optional "portStr" -- though I recommend making your own so that you can name your antennas sensibly. Also, I highly recommend setting udev rules to ensure that the RFID reader always gets assigned to the same device: http://www.hsi.gatech.edu/hrl-wiki/index.php/Linux_Tools#udev_for_persistent_device_naming

BUS=="usb", KERNEL=="ttyUSB*", SYSFS{idVendor}=="0403", SYSFS{idProduct}=="6001", SYSFS{serial}=="ftDXR6FS", SYMLINK+="robot/RFIDreader" 

If you do not do this... there is no guarantee that the reader will always be enumerated at /dev/ttyUSBx.

Let me know if you have any further problems.

~Travis Deyle (Hizook.com)

PS -- Did you modify ros_M5e.py to "from hrl.hrl_rfid.msg import RFIDread"? In the repo, it is "from hrl_rfid.msg import RFIDread". The latter is correct. As long as you have your ROS_PACKAGE_PATH correctly defined, and you've run rosmake on the package, then the import statement should work just fine. Also, I would not recommend posting ROS-related questions to StackOverflow. Very few people on here are going to be familiar with the ROS ecosystem (which is VERY complex). Please post questions here instead:

http://answers.ros.org/
http://code.google.com/p/gt-ros-pkg/issues/list


You need to make sure that following are true:

  • Directory /opt/ros/diamondback/stacks/ is in your python path.
  • /opt/ros/diamondback/stacks/hr1 contains __init__.py
  • /opt/ros/diamondback/stacks/hr1/hr1_rfid contians __init__.py
  • /opt/ros/diamondback/stacks/hr1/hr1_rfid/msg contians __init__.py

As the asker explained in comments that the RFIDRead does not have .py extension, so here is how that can be imported.

import imp
imp.load_source('RFIDRead', '/opt/ros/diamondback/stacks/hr1/hr1_rfid/msg/RFIDRead.msg')

Check out imp documentation for more information.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号