microscribe.py
Go to the documentation of this file.
00001 #! /usr/bin/python
00002 # Copyright (c) 2009, Willow Garage, Inc.
00003 # All rights reserved.
00004 # 
00005 # Redistribution and use in source and binary forms, with or without
00006 # modification, are permitted provided that the following conditions are met:
00007 # 
00008 #     * Redistributions of source code must retain the above copyright
00009 #       notice, this list of conditions and the following disclaimer.
00010 #     * Redistributions in binary form must reproduce the above copyright
00011 #       notice, this list of conditions and the following disclaimer in the
00012 #       documentation and/or other materials provided with the distribution.
00013 #     * Neither the name of the Willow Garage, Inc. nor the names of its
00014 #       contributors may be used to endorse or promote products derived from
00015 #       this software without specific prior written permission.
00016 # 
00017 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027 # POSSIBILITY OF SUCH DAMAGE.
00028 
00029 # Author: Stuart Glaser
00030 
00031 import usb
00032 import time
00033 from math import pi
00034 
00035 import roslib
00036 roslib.load_manifest('microscribe')
00037 import rospy
00038 from sensor_msgs.msg import *
00039 from joy.msg import *
00040 
00041 import atexit
00042 atexit.register(rospy.signal_shutdown, 'exit')
00043 
00044 rospy.init_node('microscribe', disable_signals=True)
00045 
00046 def dump_list():
00047     for bus in usb.busses():
00048         print "%s" % bus
00049         for dev in bus.devices:
00050             print "  ", dev.iManufacturer, dev.iProduct, dev.idProduct, dev.idVendor
00051 
00052 def get_microscribes():
00053     ms = []
00054     for bus in usb.busses():
00055         for dev in bus.devices:
00056             if dev.idVendor == 0x0563 and dev.idProduct == 0x0050:
00057                 ms.append(dev)
00058     return ms
00059 
00060 def get_microscribe(serial_number = None):
00061     ms = get_microscribes()
00062     if serial_number is None:
00063         return ms[0]
00064     for dev in ms:
00065         h = dev.open()
00066         try:
00067             if h.getString(4, 100) == serial_number:
00068                 return dev
00069             if dev.iSerialNumber == serial_number:
00070                 return dev
00071         except usb.USBError:
00072             print "Difficulty opening %s" % dev
00073 
00074 #dump_list()
00075 
00076 serial_number = None
00077 try:
00078     serial_number = rospy.get_param(rospy.get_name() + '/serial_number')
00079 except:
00080     pass
00081 ms = get_microscribe(serial_number)
00082 #print "Got microscribe:", ms.iSerialNumber
00083 
00084 h = ms.open()
00085 try:
00086     h.detachKernelDriver(0)
00087 except:
00088     print "Didn't detach kernel driver"
00089 h.claimInterface(0)
00090 print "Opened microscribe:"
00091 for i in range(1,6):
00092     print "    %s" % h.getString(i, 40)
00093 
00094 def p_datum(datum):
00095     for i, d in enumerate(datum):
00096         if i in [2, 14, 16, 18]:
00097             print "   ",
00098         #elif i in [2, 4, 16, 18]:
00099         elif i in [4, 6, 8, 10, 12]:
00100             print "",
00101         print "%02x" % d,
00102 
00103     # Buttons
00104     buttons = datum[1]
00105     buttons_str = ""
00106     if buttons & 1:
00107         buttons_str += 'G'
00108     else:
00109         buttons_str += ' '
00110     if buttons & 2:
00111         buttons_str += 'W'
00112     else:
00113         buttons_str += ' '
00114     print "  [%s]" % buttons_str,
00115 
00116     # Time
00117     time = datum[16] + datum[17] * 0x100
00118     print " %5i" % time,
00119 
00120     # Joints
00121     joint_d = datum[2:14]
00122     enc = []
00123     for i in range(6):
00124         enc.append(joint_d[2*i] + joint_d[2*i+1] * 0x100)
00125     print " ", enc,
00126     
00127     print
00128     
00129     
00130 def lis():
00131     while True:
00132         try:
00133             datum = h.bulkRead(0x81, 100)
00134             p_datum(datum)
00135         except usb.USBError:
00136             time.sleep(0.1)
00137 
00138 TICKS = [16000, 16000, 8000, 4000, 4000, 2000]
00139 REF = [2.756, pi, 8.0, 0, 6.4, 0]
00140 
00141 
00142 pub_joints = rospy.Publisher(rospy.get_name() + '/joint_states', JointState)
00143 pub_buttons = rospy.Publisher(rospy.get_name() + '/buttons', Joy)
00144 
00145 def pub_loop():
00146     while True:
00147         try:
00148             datum = h.bulkRead(0x81, 100)
00149 
00150             enc = []
00151             for i in range(6):
00152                 enc.append(datum[2+2*i] + datum[2+2*i+1] * 0x100)
00153             if enc[0] > 50000:
00154                 enc[0] = enc[0] - 0x10000
00155 
00156             q = [2*pi * float(e) / float(T) - R for e, T, R in zip(enc, TICKS, REF)]
00157 
00158             #print "ENC:", ["%i" % ee for ee in enc]
00159             #print "Q:", ["%6.3f" % qq for qq in q]
00160 
00161             msg = JointState()
00162             msg.header.stamp = rospy.get_rostime()
00163             msg.name = ['base_joint', 'shoulder_joint', 'elbow_joint',
00164                         'wrist_roll_joint', 'wrist_flex_joint', 'stylus_joint']
00165             msg.position = q
00166             msg.velocity = [0] * 6
00167             msg.effort = [0] * 6
00168             pub_joints.publish(msg)
00169 
00170             but = Joy()
00171             but.buttons = [0, 0]
00172             if datum[1] & 1:
00173                 but.buttons[0] = 1
00174             if datum[1] & 2:
00175                 but.buttons[1] = 1
00176             pub_buttons.publish(but)
00177         except usb.USBError:
00178             time.sleep(0.1)
00179 
00180 pub_loop()
00181 '''
00182 handle.bulkRead(0x81, 30, 100)
00183 
00184 
00185 
00186 
00187 Bus 001 Device 012: ID 0563:0050 Immersion Corp. 
00188 Device Descriptor:
00189   bLength                18
00190   bDescriptorType         1
00191   bcdUSB               2.00
00192   bDeviceClass            0 (Defined at Interface level)
00193   bDeviceSubClass         0 
00194   bDeviceProtocol         0 
00195   bMaxPacketSize0         8
00196   idVendor           0x0563 Immersion Corp.
00197   idProduct          0x0050 
00198   bcdDevice            3.17
00199   iManufacturer           1 
00200   iProduct                2 
00201   iSerial                 4 
00202   bNumConfigurations      1
00203   Configuration Descriptor:
00204     bLength                 9
00205     bDescriptorType         2
00206     wTotalLength           34
00207     bNumInterfaces          1
00208     bConfigurationValue     1
00209     iConfiguration          0 
00210     bmAttributes         0x80
00211       (Bus Powered)
00212     MaxPower              500mA
00213     Interface Descriptor:
00214       bLength                 9
00215       bDescriptorType         4
00216       bInterfaceNumber        0
00217       bAlternateSetting       0
00218       bNumEndpoints           1
00219       bInterfaceClass         3 Human Interface Device
00220       bInterfaceSubClass      0 No Subclass
00221       bInterfaceProtocol      0 None
00222       iInterface              0 
00223       ** UNRECOGNIZED:  09 21 00 01 00 01 22 a6 01
00224       Endpoint Descriptor:
00225         bLength                 7
00226         bDescriptorType         5
00227         bEndpointAddress     0x81  EP 1 IN
00228         bmAttributes            3
00229           Transfer Type            Interrupt
00230           Synch Type               None
00231           Usage Type               Data
00232         wMaxPacketSize     0x0020  1x 32 bytes
00233         bInterval               1
00234 
00235 
00236 00 02 Constant
00237 01 00 Buttons
00238 
00239 02 55 Changes with pan
00240 03 d7 ^^
00241 
00242 04 3d Tilt?
00243 05 18
00244 06 09 Elbow?
00245 07 1a
00246 08 00 Cant?
00247 09 10
00248 10 e2 Flex?
00249 11 0c
00250 12 83 Roll?
00251 13 07
00252 
00253 14 00 Constant
00254 15 00 ^^
00255 
00256 16 31 Time in ms
00257 17 10 ^^
00258 
00259 18 00 Constant
00260 
00261 
00262 Pan over 90 degrees:
00263 57969, 62023,
00264 
00265 Tilt over 90 degrees:
00266 78, 4058,
00267 
00268 Elbow over 90 degrees:
00269 10198, 8250,
00270 
00271 Twist over 360 degrees:
00272 2164, 6145,
00273 
00274 Flex over 90 degrees:
00275 2546, 3599,
00276 
00277 Roll over 180 degrees:
00278 131, 1120
00279 
00280 Ticks per revolution
00281 Pan    16216  (16000)
00282 Tilt   15920  (16000)
00283 Elbow  7792   ( 8000)
00284 Twist  3981   ( 4000)
00285 Flex   4212   ( 4000)
00286 Roll   1978   ( 2000)
00287 
00288 
00289 '''


microscribe
Author(s): Stuart Glaser
autogenerated on Sat Dec 28 2013 17:24:23