00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 PKG = 'qualification'
00039 import roslib; roslib.load_manifest(PKG)
00040
00041 import os, sys
00042 from optparse import OptionParser
00043
00044 import getpass
00045 import subprocess
00046
00047 from wg_invent_client import Invent
00048
00049 class GetIDException(Exception): pass
00050
00051 WGE100_PN = '68050'
00052
00053 FWPROG_PATH = os.path.join(roslib.packages.get_pkg_dir(PKG), 'fwprog')
00054 PR2_GRANT = 'pr2_grant'
00055
00056 def get_wge100_serials():
00057 cmd = '%s/bin/discover lan1' % roslib.packages.get_pkg_dir('wge100_camera')
00058 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr = subprocess.PIPE, shell=True)
00059 (o, e) = p.communicate()
00060 if p.returncode != 0:
00061 raise GetIDException("Unable to run \"discover\" to find camera serials!")
00062
00063 serials = []
00064
00065 lines = o.split('\n')
00066 for ln in lines:
00067 if len(ln.split()) < 5:
00068 continue
00069
00070 serial_start = 'serial://'
00071 idx = ln.find(serial_start)
00072 if idx < 0:
00073 continue
00074 ser = ln[idx + len(serial_start): idx + len(serial_start) + 7]
00075
00076 serial = WGE100_PN + ser
00077
00078 serials.append(serial)
00079
00080 return serials
00081
00082 def get_prosilica_ref():
00083 cmd = '%s/bin/ListAttributes' % roslib.packages.get_pkg_dir('prosilica_gige_sdk')
00084 p = subprocess.Popen([cmd, '10.68.0.20'], stdout = subprocess.PIPE,
00085 stderr= subprocess.PIPE)
00086
00087 (o, e) = p.communicate()
00088 if p.returncode != 0:
00089 raise GetIDException("Unable to get Prosilica ID")
00090
00091 lines = o.split('\n')
00092 for ln in lines:
00093 if ln.find('UniqueId') == -1:
00094 continue
00095
00096 return ln.split()[-1]
00097
00098 return ''
00099
00100 def get_imu_ref():
00101 cmd = '%s/get_id' % roslib.packages.get_pkg_dir('microstrain_3dmgx2_imu')
00102 p = subprocess.Popen([cmd, '/etc/ros/sensors/imu', '-q'], stdout = subprocess.PIPE,
00103 stderr= subprocess.PIPE)
00104
00105 (o, e) = p.communicate()
00106 if p.returncode != 0:
00107 raise GetIDException("Unable to get IMU device ID")
00108
00109 lines = o.split('\n')
00110 return lines[0].strip()
00111
00112
00113 def get_hk_refs():
00114 ids = []
00115 for port in [ 'base_hokuyo', 'tilt_hokuyo' ]:
00116 cmd = 'source /etc/ros/setup.sh; rosrun hokuyo_node getID /etc/ros/sensors/' + port
00117 p = subprocess.Popen(['ssh', 'c2', cmd], stdout = subprocess.PIPE,
00118 stderr = subprocess.PIPE)
00119 (o, e) = p.communicate()
00120 if p.returncode != 0:
00121 raise GetIDException("Unable to get HK ID for %s" % port)
00122
00123 if len(o.split()) < 3:
00124 raise GetIDException("Unable to get HK ID for %s. Output invalid: %s" % (port, o))
00125
00126 hk_id = o.split()[-1]
00127 ids.append(hk_id)
00128
00129 return ids
00130
00131 def get_mcb_serials():
00132 serials = []
00133
00134 count_cmd = PR2_GRANT + ' ' + os.path.join(FWPROG_PATH, 'eccount') + ' -iecat0'
00135
00136 count = subprocess.call(count_cmd, shell=True)
00137 if count != 37:
00138 raise Exception("Invalid MCB count. Should be 37. Count: %d" % count)
00139
00140
00141 for dev in range(1, 38):
00142 cmd = PR2_GRANT + ' ' + os.path.join(FWPROG_PATH, 'device') + ' -iecat0 -K -p %d' % dev
00143 p = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.PIPE,
00144 shell = True)
00145 o, e = p.communicate()
00146 if p.returncode != 0:
00147 raise Exception("Unable to recover serial number from device %d. Returned %d" % (dev, p.returncode))
00148
00149 for ln in o.split('\n'):
00150 if ln.startswith('serial :'):
00151 sn = ln[9:].strip()
00152 if sn not in serials:
00153 serials.append(sn)
00154
00155 return serials
00156
00157 def get_wan0_mac():
00158 p = subprocess.Popen(['ifconfig', 'wan0'], stdout=subprocess.PIPE,
00159 stderr=subprocess.PIPE)
00160
00161 (o, e) = p.communicate()
00162 if p.returncode != 0:
00163 raise GetIDException("Unable to recover wan0 mac address")
00164
00165 lines = o.split('\n')
00166 first = lines[0]
00167
00168 words = first.split()
00169 if len(words) < 5 or not words[3].strip() == 'HWaddr':
00170 raise GetIDException("Unable to parse mac address output: %s. Got: %s. Length: %d" % (first, words[3], len(words)))
00171 mac = words[4].replace(':', '').lower()
00172
00173 if not len(mac) == 12:
00174 raise GetIDException("Unable to parse mac address output: %s. Recovered: %s" % (first, mac))
00175
00176 return mac
00177
00178
00179 if __name__ == '__main__':
00180 parser = OptionParser(usage="%prog -u USERNAME -r ROBOT\nMust be run on c1 of PR2")
00181 parser.add_option('-u', '--username', action="store", dest="username",
00182 default=None, metavar="USERNAME",
00183 help="Username for WG inventory system")
00184 parser.add_option('-r', '--robot', action="store", dest="robot",
00185 default=None, metavar="ROBOT",
00186 help="Robot SN (10XX) to store data.")
00187
00188 options,args = parser.parse_args()
00189 if not options.username:
00190 parser.error("Must provide username to WG inverntory system")
00191 if not options.robot:
00192 parser.error("Must provide valid robot SN to log")
00193
00194 robot = '68029670' + options.robot
00195
00196 if not len(robot) == 12:
00197 parser.error("%s is not a valid robot serial number" % options.robot)
00198
00199 print 'Enter your password to the Willow Garage Inventory system'
00200 my_pass = getpass.getpass()
00201
00202 iv = Invent(options.username, my_pass)
00203 if not iv.login():
00204 parser.error("Must provide valid username and password to WG inventory system")
00205 if not iv.check_serial_valid(robot):
00206 parser.error("Robot serial number %s is invalid" % options.robot)
00207
00208 print 'Pulling devices from robot'
00209
00210 ok = True
00211
00212 wan0_mac = get_wan0_mac()
00213 imu_id = get_imu_ref()
00214 prosilica = get_prosilica_ref()
00215 hks = get_hk_refs()
00216 wge100s = get_wge100_serials()
00217 mcbs = get_mcb_serials()
00218
00219 print 'Getting parts from Invent'
00220 my_parts = iv.get_sub_items(robot, True)
00221
00222
00223 mac_serials = iv.lookup_by_reference(wan0_mac)
00224 if not len(mac_serials) == 1 and mac_serials[0] == robot:
00225 print >> sys.stderr, "Mac address for wan0 doesn't match robot. Mac address: %s" % wan0_mac
00226 ok = False
00227
00228
00229 serials = iv.lookup_by_reference(imu_id)
00230 if not len(serials) == 1:
00231 print >> sys.stderr, "Invalid serial numbers listed for IMU. %s" % ', '.join(serials)
00232 ok = False
00233
00234 if len(serials) == 1 and serials[0] not in my_parts:
00235 print >> sys.stderr, "IMU serial %s is not listed in Invent. ID: %s" % (serials[0], imu_id)
00236 ok = False
00237
00238
00239 serials = iv.lookup_by_reference(prosilica)
00240 if not len(serials) == 1:
00241 print >> sys.stderr, "Invalid serial numbers listed for Prosilica camera. %s" % ', '.join(serials)
00242 ok = False
00243
00244 if len(serials) == 1 and serials[0] not in my_parts:
00245 print >> sys.stderr, "Prosilica serial %s is not listed in Invent. ID: %s" % (serials[0], prosilica)
00246 ok = False
00247
00248
00249 for wge in wge100s:
00250 if not wge in my_parts:
00251 print >> sys.stderr, "Camera %s was not found in parts list" % wge
00252 ok = False
00253
00254 if not len(wge100s) == 6:
00255 print >> sys.stderr, "Not all wge100's found on robot. Expected 6, found %d" % len(wge100s)
00256 ok = False
00257
00258
00259 for hk in hks:
00260 serials = iv.lookup_by_reference(hk)
00261 if not len(serials) == 1:
00262 print >> sys.stderr, "Invalid serial numbers for HK reference %s. Serials: %s" % (hk, ', '.join(serials))
00263 ok = False
00264 continue
00265
00266 if not serials[0] in my_parts:
00267 print >> sys.stderr, "Hokuyo %s not found in parts list. Device ID: %s" % (serials[0], hk)
00268 ok = False
00269
00270
00271 for mcb in mcbs:
00272 if not mcb in my_parts:
00273 print >> sys.stderr, "EtherCAT device %s was not found in parts list" % mcb
00274 ok = False
00275
00276 if ok:
00277 print "All devices matched robot."
00278 sys.exit()
00279
00280 print >> sys.stderr, "Error matching devices to robot"
00281 sys.exit(1)