00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 """
00019 Minimizes the mapping matrix using a simplex algorithm
00020
00021 @author: Ugo Cupcic
00022 @contact: ugo@shadowrobot.com, contact@shadowrobot.com
00023 """
00024
00025 import roslib
00026
00027 import rospy
00028 from scipy.optimize import fmin
00029 from cyberglove_library import Cyberglove
00030
00031
00032 class MappingConfiguration:
00033
00034 def __init__(self, glove_data=[], hand_data=[], description=""):
00035 self.glove_data = glove_data
00036 self.hand_data = hand_data
00037 self.description = description
00038
00039 def copy(self):
00040 tmp = MappingConfiguration(
00041 self.glove_data, self.hand_data, self.description)
00042 return tmp
00043
00044
00045 class MappingMinimizer:
00046
00047 def __init__(self, verbose=1):
00048 rospy.init_node("cyberglove_mapper_minimizer")
00049
00050 self.cyberglove = Cyberglove()
00051
00052 self.verbose = verbose
00053
00054 glove_sensors = [
00055 "G_ThumbRotate", "G_ThumbMPJ", "G_ThumbIJ", "G_ThumbAb", "G_IndexMPJ", "G_IndexPIJ",
00056 "G_IndexDIJ", "G_MiddleMPJ", "G_MiddlePIJ", "G_MiddleDIJ", "G_MiddleIndexAb", "G_RingMPJ",
00057 "G_RingPIJ", "G_RingDIJ", "G_RingMiddleAb", "G_PinkieMPJ", "G_PinkiePIJ", "G_PinkieDIJ",
00058 "G_PinkieRingAb", "G_PalmArch", "G_WristPitch", "G_WristYaw"]
00059
00060 index = 0
00061 self.glove_name_index_map = {}
00062 for sensor in glove_sensors:
00063 self.glove_name_index_map[sensor] = index
00064 index += 1
00065
00066
00067 hand_joints = [
00068 "TH1", "TH2", "TH3", "TH4", "TH5", "FF0", "FF3", "FF4", "MF0", "MF3", "MF4", "RF0", "RF3", "RF4", "LF0",
00069 "LF3", "LF4", "LF5", "WR1", "WR2"]
00070
00071 index = 0
00072 self.hand_name_index_map = {}
00073 for sensor in hand_joints:
00074 self.hand_name_index_map[sensor] = index
00075 index += 1
00076
00077 self.thumb_glove = {"G_ThumbRotate": 0,
00078 "G_ThumbMPJ": 1,
00079 "G_ThumbAb": 2}
00080
00081 self.thumb_hand = {"TH2": 0,
00082 "TH4": 1,
00083 "TH5": 2}
00084
00085 self.configurations = []
00086 self.initialise_configurations()
00087
00088 self.simplex_iteration_index = 0
00089
00090 if(self.verbose == 1):
00091 for conf in self.configurations:
00092 print "-------"
00093 print conf.description
00094 print conf.glove_data
00095 print conf.hand_data
00096 print "-------"
00097 print ""
00098
00099 self.minerror = 1000000
00100 self.maxerror = 0
00101
00102 def initialise_configurations(self):
00103 configuration = MappingConfiguration()
00104
00105
00106
00107 configuration.description = "All fingers and thumb are curved maximum in a punch form ... "
00108 configuration.glove_data = []
00109
00110 configuration.hand_data = [[30.0, 52.0, 5.0],
00111 [30.0, 43.0, 0.0],
00112 [30.0, 68.0, 16.0]
00113 ]
00114
00115 self.configurations.append(configuration.copy())
00116
00117
00118
00119 configuration.description = "Thumb touching first finger tip ... "
00120 configuration.glove_data = []
00121
00122 configuration.hand_data = [[30.0, 54.0, -5.0],
00123 [19.0, 58.0, 28.0]]
00124
00125 self.configurations.append(configuration.copy())
00126
00127
00128
00129 configuration.description = "Thumb touching middle finger tip ... "
00130 configuration.glove_data = []
00131
00132 configuration.hand_data = [[30.0, 64.0, 9.0],
00133 [1.0, 68.0, 29.0]]
00134
00135 self.configurations.append(configuration.copy())
00136
00137
00138
00139 configuration.description = "Thumb touching ring finger tip ... "
00140 configuration.glove_data = []
00141
00142 configuration.hand_data = [[30.0, 75.0, 19.0],
00143 [1.0, 75.0, 42.0]]
00144
00145 self.configurations.append(configuration.copy())
00146
00147
00148
00149 configuration.description = "Thumb touching little finger tip ... "
00150 configuration.glove_data = []
00151
00152 configuration.hand_data = [[30.0, 75.0, 3.0],
00153 [1.0, 75.0, 35.0]]
00154
00155 self.configurations.append(configuration.copy())
00156
00157
00158
00159 configuration.description = "Thumb touching all the finger tips ... "
00160 configuration.glove_data = []
00161
00162 configuration.hand_data = [[-30.0, 75.0, 60.0],
00163 [-7.0, 63.0, 60.0]]
00164
00165 self.configurations.append(configuration.copy())
00166
00167
00168
00169 configuration.description = "hand flat, thumb relaxed along the fingers "
00170 configuration.glove_data = []
00171
00172 configuration.hand_data = [[0.0, 0.0, -60.0]]
00173
00174 self.configurations.append(configuration.copy())
00175
00176
00177
00178 configuration.description = "hand flat, thumb opened "
00179 configuration.glove_data = []
00180
00181 configuration.hand_data = [[0.0, 75.0, -60.0]]
00182
00183 self.configurations.append(configuration.copy())
00184
00185 def evaluation_function(self, matrix):
00186 """
00187 The error is computed by adding the square error for each configuration.
00188 """
00189 error = 0
00190
00191
00192
00193 matrix_tmp = []
00194 for i in range(len(self.thumb_glove)):
00195 line = []
00196 for j in range(len(self.thumb_hand)):
00197 line.append(matrix[i * len(self.thumb_hand) + j])
00198 matrix_tmp.append(line)
00199
00200 matrix = matrix_tmp
00201 computed_vector_hand = []
00202
00203 for config in self.configurations:
00204
00205 for vec_glove in config.glove_data:
00206 computed_vector_hand.append(self.multiply(vec_glove, matrix))
00207
00208
00209 for vec_comp, vec_hand in zip(computed_vector_hand, config.hand_data):
00210 for computed_hand_data in vec_comp:
00211 for hand_data in vec_hand:
00212 error += (computed_hand_data - hand_data) * (
00213 computed_hand_data - hand_data)
00214
00215 if self.verbose == 1:
00216 print "error: " + str(error)
00217
00218 if error < self.minerror:
00219 self.minerror = error
00220
00221 if error > self.maxerror:
00222 self.maxerror = error
00223
00224 return error
00225
00226 def multiply(self, vector_glove, matrix):
00227 """
00228 multiply the vector by the matrix. Returns a vector.
00229 """
00230 vector_hand = []
00231 index_col = 0
00232 print vector_glove
00233 print matrix
00234 for glove_data in vector_glove:
00235 data = 0
00236 for line in matrix:
00237 data += (glove_data * line[index_col])
00238 vector_hand.append(data)
00239 index_col += 1
00240
00241 return vector_hand
00242
00243 def callback(self, xk):
00244 """
00245 Function called at each iteration
00246 """
00247 self.simplex_iteration_index += 1
00248 if self.simplex_iteration_index % 50 == 0:
00249 print "-------------------------"
00250 print "iteration number: " + str(self.simplex_iteration_index)
00251
00252
00253 def minimize(self):
00254 start = []
00255 for i in range(0, len(self.thumb_hand)):
00256 line = []
00257 for j in range(0, len(self.thumb_glove)):
00258 line.append(0.1)
00259 start.append(line)
00260
00261 xopt = fmin(self.evaluation_function, start,
00262 callback=self.callback, maxiter=5000)
00263
00264
00265
00266 output = []
00267 for i in range(len(self.thumb_glove)):
00268 line = []
00269 for j in range(len(self.thumb_hand)):
00270 line.append(xopt[i * len(self.thumb_hand) + j])
00271 output.append(line)
00272
00273 print "min error: " + str(self.minerror)
00274 print "max error: " + str(self.maxerror)
00275
00276 return output
00277
00278 def write_full_mapping(self, output_path="../../../param/GloveToHandMappings"):
00279 """
00280 Writes the mapping matrix to a file:
00281 the glove values are the lines, the hand values are the columns
00282 """
00283
00284
00285 mapping_matrix = []
00286 for i in range(0, len(self.glove_name_index_map)):
00287 line = []
00288 for j in range(0, len(self.hand_name_index_map)):
00289 line.append(0.0)
00290 mapping_matrix.append(line)
00291
00292
00293
00294 mapping_matrix[self.glove_name_index_map["G_IndexDIJ"]][
00295 self.hand_name_index_map["FF0"]] = 1.0
00296 mapping_matrix[self.glove_name_index_map["G_IndexPIJ"]][
00297 self.hand_name_index_map["FF0"]] = 1.0
00298 mapping_matrix[self.glove_name_index_map["G_IndexMPJ"]][
00299 self.hand_name_index_map["FF3"]] = 1.0
00300 mapping_matrix[self.glove_name_index_map["G_MiddleIndexAb"]][
00301 self.hand_name_index_map["FF4"]] = -1.0
00302
00303 mapping_matrix[self.glove_name_index_map["G_MiddleDIJ"]][
00304 self.hand_name_index_map["MF0"]] = 1.0
00305 mapping_matrix[self.glove_name_index_map["G_MiddlePIJ"]][
00306 self.hand_name_index_map["MF0"]] = 1.0
00307 mapping_matrix[self.glove_name_index_map["G_MiddleMPJ"]][
00308 self.hand_name_index_map["MF3"]] = 1.0
00309 mapping_matrix[self.glove_name_index_map["G_RingMiddleAb"]][
00310 self.hand_name_index_map["MF4"]] = -1.0
00311
00312 mapping_matrix[self.glove_name_index_map["G_RingDIJ"]][
00313 self.hand_name_index_map["RF0"]] = 1.0
00314 mapping_matrix[self.glove_name_index_map["G_RingPIJ"]][
00315 self.hand_name_index_map["RF0"]] = 1.0
00316 mapping_matrix[self.glove_name_index_map["G_RingMPJ"]][
00317 self.hand_name_index_map["RF3"]] = 1.0
00318
00319 mapping_matrix[self.glove_name_index_map["G_PinkieDIJ"]][
00320 self.hand_name_index_map["LF0"]] = 1.0
00321 mapping_matrix[self.glove_name_index_map["G_PinkiePIJ"]][
00322 self.hand_name_index_map["LF0"]] = 1.0
00323 mapping_matrix[self.glove_name_index_map["G_PinkieMPJ"]][
00324 self.hand_name_index_map["LF3"]] = 1.0
00325 mapping_matrix[self.glove_name_index_map["G_PinkieRingAb"]][
00326 self.hand_name_index_map["LF4"]] = -1.0
00327 mapping_matrix[self.glove_name_index_map["G_PalmArch"]][
00328 self.hand_name_index_map["LF5"]] = 1.0
00329
00330 mapping_matrix[self.glove_name_index_map["G_WristPitch"]][
00331 self.hand_name_index_map["WR1"]] = 1.0
00332 mapping_matrix[self.glove_name_index_map["G_WristYaw"]][
00333 self.hand_name_index_map["WR2"]] = 1.0
00334
00335 mapping_matrix[self.glove_name_index_map["G_ThumbIJ"]][
00336 self.hand_name_index_map["TH1"]] = 1.0
00337
00338
00339
00340
00341
00342
00343
00344 thumb_mapping = self.minimize()
00345
00346
00347 for glove_name in self.thumb_glove.keys():
00348 for hand_name in self.thumb_hand.keys():
00349
00350 tmp_index_glove = self.thumb_glove[glove_name]
00351 tmp_index_hand = self.thumb_hand[hand_name]
00352
00353
00354 mapping_value = thumb_mapping[tmp_index_glove][tmp_index_hand]
00355
00356
00357 final_index_glove = self.glove_name_index_map[glove_name]
00358 final_index_hand = self.hand_name_index_map[hand_name]
00359
00360
00361 mapping_matrix[final_index_glove][
00362 final_index_hand] = mapping_value
00363
00364 file = open(output_path, "w")
00365 for line in mapping_matrix:
00366 for col in line:
00367 file.write(" " + str(col))
00368 file.write("\n")
00369
00370 file.close()
00371
00372 def record(self, config):
00373 for i in range(0, 2):
00374 raw_input(str(i) + ": " + config.description)
00375 vector_data = [0] * len(self.thumb_glove)
00376 for sensor_name in self.thumb_glove.keys():
00377 data = self.cyberglove.read_calibrated_average_value(
00378 sensor_name)
00379 vector_data[self.thumb_glove[sensor_name]] = data
00380 config.glove_data.append(vector_data)
00381
00382 if(self.verbose == 1):
00383 print "read values:"
00384 print config.glove_data
00385
00386
00387
00388
00389
00390 def main():
00391 cyber_mapper = MappingMinimizer()
00392
00393 for config in cyber_mapper.configurations:
00394 cyber_mapper.record(config)
00395
00396 cyber_mapper.write_full_mapping()
00397
00398 return 0
00399
00400
00401
00402 if __name__ == "__main__":
00403 main()