00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 import roslib
00020 roslib.load_manifest('sr_gui_hand_calibration')
00021 import rospy
00022
00023 from etherCAT_hand_lib import EtherCAT_Hand_Lib
00024 from QtGui import QTreeWidgetItem, QTreeWidgetItemIterator, QColor, QIcon, QMessageBox
00025 from PyQt4.Qt import QTimer
00026 from PyQt4.QtCore import SIGNAL
00027
00028 import yaml
00029 try:
00030 from yaml import CLoader as Loader, CDumper as Dumper
00031 except ImportError:
00032 from yaml import Loader, Dumper
00033 import os
00034
00035 from collections import deque
00036
00037 green = QColor(153, 231, 96)
00038 orange = QColor(247, 206, 134)
00039 red = QColor(236, 178, 178)
00040
00041 class IndividualCalibration( QTreeWidgetItem ):
00042 """
00043 """
00044
00045 def __init__(self, joint_name,
00046 raw_value, calibrated_value,
00047 parent_widget, tree_widget,
00048 robot_lib):
00049 """
00050 """
00051 self.joint_name = joint_name
00052 self.raw_value = int(raw_value)
00053 self.calibrated_value = calibrated_value
00054 self.tree_widget = tree_widget
00055 self.robot_lib = robot_lib
00056
00057 QTreeWidgetItem.__init__(self, parent_widget, ["", "", str(self.raw_value), str(self.calibrated_value)])
00058
00059 for col in xrange(self.tree_widget.columnCount()):
00060 self.setBackgroundColor(col, QColor(red))
00061
00062 self.tree_widget.addTopLevelItem( self )
00063
00064 self.is_calibrated = False
00065
00066 def remove(self):
00067 self.tree_widget.remove
00068
00069 def calibrate(self):
00070 self.raw_value = self.robot_lib.get_average_raw_value(self.joint_name, 100)
00071 self.setText( 2, str(self.raw_value) )
00072
00073 for col in xrange(self.tree_widget.columnCount()):
00074
00075
00076 if self.text(2) != "":
00077 self.setBackgroundColor(col, QColor(green))
00078
00079 self.is_calibrated = True
00080
00081 def set_is_loaded_calibration(self):
00082 for col in xrange(self.tree_widget.columnCount()):
00083
00084
00085 if self.text(2) != "":
00086 self.setBackgroundColor(col, QColor(orange))
00087
00088 self.is_calibrated = True
00089
00090
00091 def get_calibration(self):
00092 return [self.raw_value, self.calibrated_value]
00093
00094 class JointCalibration( QTreeWidgetItem ):
00095 """
00096 """
00097
00098 nb_values_to_check = 5
00099 def __init__(self, joint_name,
00100 calibrations,
00101 parent_widget, tree_widget,
00102 robot_lib):
00103 """
00104 """
00105 self.joint_name = joint_name
00106 self.tree_widget = tree_widget
00107 self.robot_lib = robot_lib
00108
00109 self.calibrations = []
00110
00111 self.last_raw_values = deque()
00112
00113 QTreeWidgetItem.__init__(self, parent_widget, ["", joint_name, "", ""] )
00114
00115 for calibration in calibrations:
00116 self.calibrations.append( IndividualCalibration(joint_name,
00117 calibration[0], calibration[1],
00118 self, tree_widget, robot_lib) )
00119
00120
00121 self.timer = QTimer()
00122 self.timer.start(200)
00123 tree_widget.addTopLevelItem(self)
00124 tree_widget.connect(self.timer, SIGNAL('timeout()'), self.update_joint_pos)
00125
00126 def load_joint_calibration(self, new_calibrations):
00127 for calibration in self.calibrations:
00128 self.removeChild( calibration )
00129 self.calibrations = []
00130
00131 for calibration in new_calibrations:
00132 new_calib = IndividualCalibration(self.joint_name,
00133 calibration[0], calibration[1],
00134 self, self.tree_widget, self.robot_lib)
00135 new_calib.set_is_loaded_calibration()
00136 self.calibrations.append( new_calib )
00137
00138
00139 def get_joint_calibration(self):
00140 config = []
00141 for calibration in self.calibrations:
00142 if calibration.is_calibrated:
00143 config.append( calibration.get_calibration() )
00144
00145 if len(config) <= 1:
00146
00147
00148 config = [[0, 0.0], [1, 0.0]]
00149 return [self.joint_name, config]
00150
00151 def update_joint_pos(self):
00152 raw_value = self.robot_lib.get_raw_value( self.joint_name )
00153 self.setText( 2, str(raw_value) )
00154
00155
00156
00157 self.last_raw_values.append(raw_value)
00158 if len(self.last_raw_values) > self.nb_values_to_check:
00159 self.last_raw_values.popleft()
00160
00161
00162 all_equal = True
00163 last_data = self.last_raw_values[0]
00164 for data in self.last_raw_values:
00165 if data != last_data:
00166 all_equal = False
00167 break
00168 if all_equal == True:
00169 self.setIcon(0, QIcon( os.path.join(os.path.dirname(os.path.realpath(__file__)), '../icons/warn.gif')))
00170 self.setToolTip(0,"No noise on the data for the last " + str(self.nb_values_to_check) + " values, there could be a problem with the sensor.")
00171 else:
00172 self.setIcon(0, QIcon())
00173 self.setToolTip(0, "")
00174
00175 def on_close(self):
00176 self.timer.stop()
00177
00178
00179 class FingerCalibration( QTreeWidgetItem ):
00180 """
00181 """
00182
00183 def __init__(self, finger_name,
00184 finger_joints,
00185 parent_widget, tree_widget,
00186 robot_lib):
00187 """
00188 """
00189
00190 QTreeWidgetItem.__init__(self, parent_widget, [finger_name, "", "", ""] )
00191
00192 self.joints = []
00193 for joint in finger_joints:
00194 self.joints.append( JointCalibration( joint_name = joint[0],
00195 calibrations = joint[1],
00196 parent_widget = self,
00197 tree_widget = tree_widget,
00198 robot_lib = robot_lib) )
00199
00200 tree_widget.addTopLevelItem(self)
00201
00202 class HandCalibration( QTreeWidgetItem ):
00203 """
00204 """
00205
00206 joint_map = {"First Finger":[ [ "FFJ1", [ [0.0, 0.0],
00207 [0.0, 22.5],
00208 [0.0, 45.0],
00209 [0.0, 67.5],
00210 [0.0, 90.0] ] ],
00211 [ "FFJ2", [ [0.0, 0.0],
00212 [0.0, 22.5],
00213 [0.0, 45.0],
00214 [0.0, 67.5],
00215 [0.0, 90.0] ] ],
00216 [ "FFJ3", [ [0.0, 0.0],
00217 [0.0, 22.5],
00218 [0.0, 45.0],
00219 [0.0, 67.5],
00220 [0.0, 90.0] ] ],
00221 [ "FFJ4", [ [0.0, -25.0],
00222 [0.0, 0.0],
00223 [0.0, 25.0] ] ] ],
00224
00225 "Middle Finger":[ [ "MFJ1", [ [0.0, 0.0],
00226 [0.0, 22.5],
00227 [0.0, 45.0],
00228 [0.0, 67.5],
00229 [0.0, 90.0] ] ],
00230 [ "MFJ2", [ [0.0, 0.0],
00231 [0.0, 22.5],
00232 [0.0, 45.0],
00233 [0.0, 67.5],
00234 [0.0, 90.0] ] ],
00235 [ "MFJ3", [ [0.0, 0.0],
00236 [0.0, 22.5],
00237 [0.0, 45.0],
00238 [0.0, 67.5],
00239 [0.0, 90.0] ] ],
00240 [ "MFJ4", [ [0.0, -25.0],
00241 [0.0, 0.0],
00242 [0.0, 25.0] ] ] ],
00243
00244 "Ring Finger":[ [ "RFJ1", [ [0.0, 0.0],
00245 [0.0, 22.5],
00246 [0.0, 45.0],
00247 [0.0, 67.5],
00248 [0.0, 90.0] ] ],
00249 [ "RFJ2", [ [0.0, 0.0],
00250 [0.0, 22.5],
00251 [0.0, 45.0],
00252 [0.0, 67.5],
00253 [0.0, 90.0] ] ],
00254 [ "RFJ3", [ [0.0, 0.0],
00255 [0.0, 22.5],
00256 [0.0, 45.0],
00257 [0.0, 67.5],
00258 [0.0, 90.0] ] ],
00259 [ "RFJ4", [ [0.0, -25.0],
00260 [0.0, 0.0],
00261 [0.0, 25.0] ] ] ],
00262
00263 "Little Finger":[ [ "LFJ1", [ [0.0, 0.0],
00264 [0.0, 22.5],
00265 [0.0, 45.0],
00266 [0.0, 67.5],
00267 [0.0, 90.0] ] ],
00268 [ "LFJ2", [ [0.0, 0.0],
00269 [0.0, 22.5],
00270 [0.0, 45.0],
00271 [0.0, 67.5],
00272 [0.0, 90.0] ] ],
00273 [ "LFJ3", [ [0.0, 0.0],
00274 [0.0, 22.5],
00275 [0.0, 45.0],
00276 [0.0, 67.5],
00277 [0.0, 90.0] ] ],
00278 [ "LFJ4", [ [0.0, -25.0],
00279 [0.0, 0.0],
00280 [0.0, 25.0] ] ] ,
00281 [ "LFJ5", [ [0.0, 0.0],
00282 [0.0, 22.5],
00283 [0.0, 45.0],
00284 [0.0, 67.5],
00285 [0.0, 90.0] ] ] ],
00286
00287 "Thumb":[ [ "THJ1", [ [0.0, 0.0],
00288 [0.0, 22.5],
00289 [0.0, 45.0],
00290 [0.0, 67.5],
00291 [0.0, 90.0] ] ],
00292 [ "THJ2", [ [0.0, -30.0],
00293 [0.0, -15.0],
00294 [0.0, 0.0],
00295 [0.0, 15.0],
00296 [0.0, 30.0] ] ],
00297 [ "THJ3", [ [0.0, -15.0],
00298 [0.0, 0.0],
00299 [0.0, 15.0] ] ],
00300 [ "THJ4", [ [0.0, 0.0],
00301 [0.0, 22.5],
00302 [0.0, 45.0],
00303 [0.0, 67.5] ] ],
00304 [ "THJ5", [ [0.0, -60.0],
00305 [0.0, -30.0],
00306 [0.0, 0.0],
00307 [0.0, 30.0],
00308 [0.0, 60.0] ] ] ],
00309
00310 "Wrist":[ [ "WRJ1", [ [0.0, -45.0],
00311 [0.0, -22.5],
00312 [0.0, 0.0],
00313 [0.0, 22.5],
00314 [0.0, 35.0] ] ],
00315 [ "WRJ2", [ [0.0, -30.0],
00316 [0.0, 0.0],
00317 [0.0, 10.0] ] ] ]
00318 }
00319
00320 def __init__(self,
00321 tree_widget,
00322 progress_bar,
00323 fingers = ["First Finger", "Middle Finger",
00324 "Ring Finger", "Little Finger",
00325 "Thumb", "Wrist"]):
00326 """
00327 """
00328 self.fingers = []
00329
00330
00331 self.is_active = True
00332
00333 QTreeWidgetItem.__init__(self, ["Hand", "", "", ""] )
00334
00335 self.robot_lib = EtherCAT_Hand_Lib()
00336 if not self.robot_lib.activate():
00337 btn_pressed = QMessageBox.warning(tree_widget, "Warning", "The EtherCAT Hand node doesn't seem to be running, or the debug topic is not being published. Do you still want to continue? The calibration will be useless.",
00338 buttons = QMessageBox.Ok | QMessageBox.Cancel)
00339
00340 if btn_pressed == QMessageBox.Cancel:
00341 self.is_active = False
00342
00343
00344 for finger in fingers:
00345 if finger in self.joint_map.keys():
00346 self.fingers.append( FingerCalibration( finger,
00347 self.joint_map[finger],
00348 self, tree_widget,
00349 self.robot_lib) )
00350
00351 else:
00352 print finger, " not found in the calibration map"
00353
00354 self.joint_0_calibration_index = 0
00355
00356 self.progress_bar = progress_bar
00357
00358 self.tree_widget = tree_widget
00359 self.tree_widget.addTopLevelItem(self)
00360 self.tree_widget.itemActivated.connect(self.calibrate_item)
00361
00362 def unregister(self):
00363 it = QTreeWidgetItemIterator( self )
00364 while it.value():
00365 try:
00366 it.value().on_close()
00367 except:
00368 pass
00369 it += 1
00370
00371 self.robot_lib.on_close()
00372
00373 def calibrate_item(self, item):
00374 try:
00375
00376 item.calibrate()
00377 except:
00378 pass
00379
00380 self.progress()
00381
00382
00383 self.tree_widget.setItemSelected( item, False )
00384 next_item = self.tree_widget.itemBelow(item)
00385 self.tree_widget.setItemSelected( next_item, True )
00386 self.tree_widget.setCurrentItem( next_item )
00387
00388 def calibrate_joint0s(self, btn_joint_0s):
00389 joint0s = [ "FFJ1", "FFJ2",
00390 "MFJ1", "MFJ2",
00391 "RFJ1", "RFJ2",
00392 "LFJ1", "LFJ2" ]
00393
00394 it = QTreeWidgetItemIterator( self )
00395 while it.value():
00396 if it.value().text(1) in joint0s:
00397 it += self.joint_0_calibration_index + 1
00398 it.value().calibrate()
00399 it += 1
00400
00401 self.joint_0_calibration_index += 1
00402 if self.joint_0_calibration_index == len( self.joint_map["First Finger"][0][1] ):
00403 self.joint_0_calibration_index = 0
00404
00405
00406 btn_joint_0s.setText( "Save all Joint 0s (angle = "+ str(self.joint_map["First Finger"][0][1][self.joint_0_calibration_index][1]) +")" )
00407
00408 self.progress()
00409
00410 def progress(self):
00411 it = QTreeWidgetItemIterator( self )
00412 nb_of_items = 0
00413 nb_of_calibrated_items = 0
00414 while it.value():
00415 it += 1
00416 try:
00417 if it.value().is_calibrated:
00418 nb_of_calibrated_items += 1
00419 nb_of_items += 1
00420 except:
00421 pass
00422
00423 self.progress_bar.setValue( int( float(nb_of_calibrated_items) / float(nb_of_items) * 100.0 ) )
00424
00425 def load(self, filepath):
00426 f = open(filepath,'r')
00427 document = ""
00428 for line in f.readlines():
00429 document += line
00430 f.close()
00431 yaml_config = yaml.load(document)
00432
00433 for joint in yaml_config["sr_calibrations"]:
00434 it = QTreeWidgetItemIterator( self )
00435 while it.value():
00436 if it.value().text(1) == joint[0]:
00437 it.value().load_joint_calibration( joint[1] )
00438 it += 1
00439
00440 def save(self, filepath):
00441 yaml_config = {}
00442
00443 joint_configs = []
00444 it = QTreeWidgetItemIterator( self )
00445 while it.value():
00446 try:
00447 joint_configs.append( it.value().get_joint_calibration() )
00448 except:
00449 pass
00450 it += 1
00451
00452
00453
00454
00455 full_config_to_write = "{\'sr_calibrations\': [\n"
00456 for joint_config in joint_configs:
00457 full_config_to_write += "[\""
00458 full_config_to_write += joint_config[0] + "\", "
00459
00460
00461 for index,calib in enumerate(joint_config[1]):
00462 joint_config[1][index][0] = float(calib[0])
00463 joint_config[1][index][1] = float(calib[1])
00464
00465 full_config_to_write += str(joint_config[1])
00466 full_config_to_write += "], \n"
00467 full_config_to_write += "]}"
00468
00469 f = open(filepath, 'w')
00470 f.write(full_config_to_write)
00471 f.close()
00472
00473 def is_calibration_complete(self):
00474 it = QTreeWidgetItemIterator( self )
00475 while it.value():
00476 try:
00477 if not it.value().is_calibrated:
00478 return False
00479 except:
00480 pass
00481 it += 1
00482
00483 return True
00484