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
00039
00040
00041
00042
00043 from pcan_python.pcan_library import *
00044
00045
00046 from puck_properties_consts import*
00047 from ctypes import *
00048 import time
00049
00050 BASE_TYPE = 0
00051 TIP_TYPE = 1
00052 SPREAD_TYPE = 2
00053 BASE_LIMIT = 140.0
00054 TIP_LIMIT = 48.0
00055 SPREAD_LIMIT = 180.0
00056
00057 HAND_GROUP = 0x405
00058
00059
00060 F1_POSITION = 0x563
00061 F2_POSITION = 0x583
00062 F3_POSITION = 0x5A3
00063 SPREAD_POSITION = 0x5C3
00064 F1_STRAIN = 0x566
00065 F2_STRAIN = 0x586
00066 F3_STRAIN = 0x5A6
00067 STRAIN_ID = 0x99
00068 F1_MOTOR_TEMP = 0x566
00069 F2_MOTOR_TEMP = 0x586
00070 F3_MOTOR_TEMP = 0x5A6
00071 SPREAD_MOTOR_TEMP = 0x5C6
00072 MOTOR_TEMP_ID = 0x89
00073 F1_MOTOR_THERM = 0x566
00074 F2_MOTOR_THERM = 0x586
00075 F3_MOTOR_THERM = 0x5A6
00076 SPREAD_MOTOR_THERM = 0x5C6
00077 MOTOR_THERM_ID = 0x94
00078 F1_TACT = 0x569
00079 F2_TACT = 0x589
00080 F3_TACT = 0x5A9
00081 PALM_TACT = 0x5C9
00082 TACT_ID = 0x40
00083
00084
00085
00086
00087
00088 class pyHand:
00089
00090 def __init__(self, port = '/dev/pcan32'):
00091 '''
00092 Creates a PCANBasic object
00093
00094 @param port: CAN port used to communicate with the hand
00095 @type connection: string
00096 '''
00097
00098 self.PCAN = PCANBasic(port)
00099
00100 self.motor_positions = {FINGER1: {'encoder': [0, 0], 'position': [0.0, 0.0]}, FINGER2: {'encoder': [0, 0], 'position': [0.0, 0.0]}, FINGER3: {'encoder': [0, 0], 'position': [0.0, 0.0]},
00101 SPREAD: {'encoder': [0, 0], 'position': [0.0, 0.0]}}
00102 self.strain = {FINGER1: 0, FINGER2: 0, FINGER3: 0}
00103 self.temp = {FINGER1:{ 'temp': 0.0, 'therm': 0.0}, FINGER2: { 'temp': 0.0, 'therm': 0.0}, FINGER3: { 'temp': 0.0, 'therm': 0.0},
00104 SPREAD: { 'temp': 0.0, 'therm': 0.0}}
00105 self.tactile_sensor = {FINGER1: {'values': range(0,24), 'data': range(0,5)}, FINGER2: {'values': range(0,24), 'data': range(0,5)},
00106 FINGER3: {'values': range(0,24), 'data': range(0,5)}, SPREAD: {'values': range(0,24), 'data': range(0,5)}}
00107
00108 def check_error(self, connection,result,location_of_error):
00109 '''
00110 Checks error on the CAN Bus.
00111
00112 @param connection: The connection on which the CAN is talking. For example, PCANBasic()
00113 @type connection: PCANBasic
00114 @param result: The number corresponding to the error returned.
00115 @type resulr: int
00116 @param location_of_error: A description of where the error occurred.
00117 @type location_of_error: str
00118 '''
00119 if result == PCAN_ERROR_OK:
00120 pass
00121 else:
00122 raise Exception("Error Number: " + hex(result) + " while attempting to " + str(location_of_error) + "\n" + connection.GetErrorText(result)[1])
00123
00124 def enum(self):
00125 '''
00126 Finds and returns all of the pucks that are attached to the bus.
00127
00128 @rtype: Array[]
00129 @return: An array containing the pucks attached to the bus.
00130 '''
00131 pucks = []
00132 for i in range(32):
00133 try:
00134 self.get_property(i,1)
00135 pucks.append(i)
00136 except:
00137 pass
00138 return pucks
00139
00140 def can_reset(self):
00141 '''
00142 Resets the CAN connection.
00143 Note that this may cause a loss of data, but may also clear unwanted data. Utilize as needed.
00144 '''
00145 reset_result=self.PCAN.Reset(PCAN_USBBUS1)
00146 try:
00147 self.check_error(self.PCAN,reset_result,"reset")
00148 except:
00149 return False
00150 time.sleep(0.025)
00151 return True
00152
00153 def can_status(self):
00154 '''
00155 Returns the status of the CAN connection as specified in PCANBasic's GetStatus method.
00156 '''
00157 status_result=self.PCAN.GetStatus(PCAN_USBBUS1)
00158 time.sleep(0.025)
00159 return status_result
00160
00161 def can_init(self):
00162 '''
00163 Initializes the CAN connection. Note that this does not initialize the hand itself.
00164 '''
00165
00166 init_result=self.PCAN.Initialize(PCAN_USBBUS1, PCAN_BAUD_1M)
00167 self.check_error(self.PCAN,init_result,"initialize")
00168 time.sleep(0.025)
00169
00170 def can_uninit(self):
00171 '''
00172 Uninitializes the CAN connection. Rarely used.
00173 '''
00174 uninit_result=self.PCAN.Uninitialize(PCAN_USBBUS1)
00175 self.check_error(self.PCAN,uninit_result,"uninitialize")
00176
00177
00178
00179 def initialize(self):
00180 '''
00181 Wakes up pucks and initializes the CAN.
00182 This function must be implemented at the beginning of a program for this library to properly work.
00183
00184 @rtype: ROLE
00185 @return: First finger's ROLE property if initialization is successful. Otherwise it returns False.
00186 '''
00187 try:
00188 self.can_init()
00189
00190 self.can_reset()
00191 time.sleep(0.025)
00192
00193 self.set_property(0x400, 5, 2)
00194 time.sleep(1)
00195 self.can_reset()
00196
00197 return True
00198 except:
00199 return False
00200
00201 def init_hand(self):
00202 '''
00203 Initialize all pucks in the hand.
00204
00205 @rtype: Boolean
00206 @return: Succesfully Initialized Hand?
00207 '''
00208 try:
00209
00210 self.init_finger(FINGER1)
00211 self.init_finger(FINGER2)
00212 self.init_finger(FINGER3)
00213 time.sleep(3)
00214 self.init_finger(SPREAD)
00215 time.sleep(2)
00216
00217
00218 self.get_property(FINGER1, ROLE)
00219 return True
00220 except:
00221
00222
00223 return False
00224
00225 def init_finger(self, msgID):
00226 '''
00227 Sends a command to the puck to wake up the motor attatched to the puck.
00228
00229 @param msgID: The id of the finger to initialize.
00230 @type msgID: int
00231 '''
00232 self.set_property(msgID, CMD, CMD_HI)
00233
00234
00235
00236 def read_msg(self):
00237 '''
00238 Read a general message from PCAN_USBBUS1
00239 Typically, msg[1] (where msg is the thing returned), contains the pertinent information.
00240
00241 @rtype: (TPCANStatus, TPCANMsg, TPCANTimestamp)
00242 @return: A tuple containing the status, message, and timestamp.
00243 '''
00244 return self.PCAN.Read(PCAN_USBBUS1)
00245
00246
00247
00248 def write_msg(self, msgID, data, delay=.002):
00249 '''
00250 Send a general message to PCAN_USBBUS1. This can be a get, set, or even garbage.
00251
00252 @param msgID: The puck or group to which the message will be sent.
00253 @type msgID: int
00254 @param data: The array containing the data for the TPCANMsg.
00255 @type data: Array[]
00256 @param delay: The time delay to wait for the message to be written.
00257 @type delay: float
00258 @rtype: TPCANStatus
00259 @return: Status of the self.PCAN bus.
00260 '''
00261 msg = TPCANMsg()
00262 msg.ID = msgID
00263 msg.LEN = len(data)
00264 msg.MSGTYPE = PCAN_MESSAGE_STANDARD
00265 for j in range(0, len(data)):
00266 msg.DATA[j] = data[j]
00267 stat = self.PCAN.Write(PCAN_USBBUS1, msg)
00268 self.check_error(self.PCAN,stat,"write")
00269 time.sleep(delay)
00270 return stat
00271
00272
00273 def send_msg(self, msgID, data):
00274 '''
00275 Send a general message to PCAN_USBBUS1. This can be a get, set, or even garbage.
00276 It does not apply any sleep
00277
00278 @param msgID: The puck or group to which the message will be sent.
00279 @type msgID: int
00280 @param data: The array containing the data for the TPCANMsg.
00281 @type data: Array[]
00282
00283 @return the return status after writing in the bus
00284 '''
00285 msg = TPCANMsg()
00286 msg.ID = msgID
00287 msg.LEN = len(data)
00288 msg.MSGTYPE = PCAN_MESSAGE_STANDARD
00289 for j in range(0, len(data)):
00290 msg.DATA[j] = data[j]
00291 stat = self.PCAN.Write(PCAN_USBBUS1, msg)
00292 self.check_error(self.PCAN,stat,"write")
00293
00294 return stat
00295
00296 def set_property(self, msgID, propID, value):
00297 '''
00298 Set property to a given value.
00299
00300 @param msgID: The puck or group whose property will be set.
00301 @type msgID: int
00302 @param propID: The number corresponding to the property to be set.
00303 @type propID: int
00304 @param value: The value to which the property will be set.
00305 @type value: int
00306 '''
00307 is32bits = [48, 50, 52, 54, 56, 58, 66, 68, 74, 88, 96, 98]
00308 if propID in is32bits:
00309 self.set_32(msgID, propID, value)
00310 else:
00311 self.set_16(msgID, propID, value)
00312
00313 def set_32(self, msgID, propID, value):
00314 '''
00315 Set property to a given value for a 32 bit property.
00316 Avoid usage of this method. Use self.set_property instead.
00317
00318 @param msgID: The puck or group whose property will be set.
00319 @type msgID: int
00320 @param propID: The number corresponding to the property to be set.
00321 @type propID: int
00322 @param value: The value to which the property will be set.
00323 @type value: int
00324 '''
00325 data = [0x80+propID, 0, value%0x100, int(value/0x100)%0x100, int(value/0x10000)%0x100, int(value/0x1000000)]
00326
00327 return self.send_msg(msgID, data)
00328
00329 def set_16(self, msgID, propID, value):
00330 '''
00331 Set property to a given value for a 16 bit property.
00332 Avoid usage of this method. Use self.set_property instead.
00333
00334 @param msgID: The puck or group whose property will be set.
00335 @type msgID: int
00336 @param propID: The number corresponding to the property to be set.
00337 @type propID: int
00338 @param value: The value to which the property will be set.
00339 @type value: int
00340 '''
00341 data = [0x80+propID, 0, value%256, int(value/256)]
00342
00343 return self.send_msg(msgID, data)
00344
00345
00346
00347 def get_property(self, msgID, propID):
00348 '''
00349 Get property from pucks in msgID.
00350
00351 @param msgID: The puck whose property will be read from.
00352 @type msgID: int
00353 @param propID: The property be read from.
00354 @type propID: int
00355 @rtype: int
00356 @return: The value held in the property.
00357 '''
00358 is32bits = [48, 50, 52, 54, 56, 58, 66, 68, 74, 88, 96, 98]
00359 if propID in is32bits:
00360 return self.get_32(msgID, propID)
00361 else:
00362 if propID == TACT:
00363 return self.get_tact(msgID)
00364 return self.get_16(msgID, propID)
00365
00366
00367 def get_32(self, msgID, propID):
00368 '''
00369 Gets a 32 bit property. Please use get_property instead of this method where applicable.
00370
00371 @param msgID: The puck whose property will be read from.
00372 @type msgID: int
00373 @param propID: The property be read from.
00374 @type propID: int
00375 @rtype: int
00376 @return: The value held in the property.
00377 '''
00378 self.write_msg(msgID, [propID])
00379 time.sleep(0.005)
00380 read_result = self.PCAN.Read(PCAN_USBBUS1)
00381 self.check_error(self.PCAN, read_result[0], "read")
00382 data = read_result[1].DATA
00383 value = (0x1000000 * data[5]) + (0x0010000 * data[4]) + (0x0000100 * data[3]) + (0x0000001 * data[2])
00384 return value
00385
00386
00387 def get_16(self, msgID, propID):
00388 '''
00389 Gets a 16 bit property. Please use get_property instead of this method where applicable.
00390
00391 @param msgID: The puck whose property will be read from.
00392 @type msgID: int
00393 @param propID: The property be read from.
00394 @type propID: int
00395 @rtype: int
00396 @return: The value held in the property.
00397 '''
00398 self.write_msg(msgID, [propID])
00399 time.sleep(0.005)
00400
00401 read_result = self.PCAN.Read(PCAN_USBBUS1)
00402 self.check_error(self.PCAN, read_result[0], "read")
00403 data = read_result[1].DATA
00404 value =(0x0000100 * data[3]) + (0x0000001 * data[2])
00405 return value
00406
00407
00408 def save_property(self, msgID, propID):
00409 '''
00410 Save a property.
00411
00412 @param msgID: The puck or group to have its property saved.
00413 @type msgID: int
00414 @param propID: The property to be saved.
00415 @type propID: int
00416 '''
00417 self.set_property(msgID, SAVE, propID)
00418
00419
00420 def load_property(self, msgID, propID):
00421 '''
00422 Load a property's value for puck's flash memory.
00423
00424 @param msgID: The puck or group to have its property loaded.
00425 @type msgID: int
00426 @param propID: The property to be loaded.
00427 @type propID: int
00428 '''
00429 self.set_property(msgID, LOAD, propID)
00430
00431 def get_prop_quick(self, msgID,propID,speed):
00432 '''
00433 Gets a property timed at a certain rate.
00434
00435 @param msgID: The puck or group to have its property gotten.
00436 @type msgID: int
00437 @param propID: The property to be saved.
00438 @type propID: int
00439 @param speed: The time delay for the get.
00440 @type speed: float
00441 '''
00442 self.write_msg(msgID, [propID],speed)
00443 read_result=self.read_msg_resilient(msgID,propID)
00444 self.check_error(self.PCAN, read_result[0], "read")
00445 data = read_result[1].DATA
00446 value = (0x1000000 * data[5]) + (0x0010000 * data[4]) + (0x0000100 * data[3]) + (0x0000001 * data[2])
00447 return value
00448
00449 def read_msg_resilient(self, expect_puck,expect_prop,max_recurse=10,counter=0):
00450 '''
00451 Reads message given the puckID and the propertyID.
00452 It will read as normal, until it gets some expected output from the puck.
00453
00454 @param expect_puck: The puck to read from.
00455 @type expect_puck: int
00456 @param expect_prop: The property read from.
00457 @type expect_prop: int
00458 @param max_recurse: The most number of times to repeat the get.
00459 @type max_recurse: int
00460 @param counter: Used internally. Do not set.
00461 @type counter: int
00462 @rtype: int
00463 @return: The value held in the property of the given puck.
00464 '''
00465 counter+=1
00466 response=self.PCAN.Read(PCAN_USBBUS1)
00467 received_prop=response[1].DATA[0]-128
00468 received_puck=(response[1].ID-1024)>>5
00469
00470 if (received_prop==expect_prop) and (received_puck==expect_puck):
00471 return response
00472 else:
00473 print "a"
00474 if counter<max_recurse:
00475 return self.read_msg_resilient(expect_puck,expect_prop,counter=counter)
00476 else:
00477 raise Exception("Missed message")
00478
00479 def get_role(self, msgID):
00480 '''
00481 Read from ROLE property and return something that makes sense.
00482 Returns an array of holding the following data:
00483
00484 [4-bit Product Identifier,
00485 Internal Thermistor,
00486 20 MHz (vs 32 MHz),
00487 Hall Motor Encoder,
00488 Enc Motor Encoder,
00489 Strain Gauge,
00490 IMU for Force-Torque Sensor,
00491 Optical Motor Encoder]
00492
00493 @param msgID: The puck to get the ROLE from.
00494 @type msgID: int
00495 @rtype: Array[int,bool,bool,bool,bool,bool,bool,bool]
00496 @return: An array holding the above values.
00497 '''
00498 role = self.get_property(msgID, 1)
00499 data= [0,0,0,0,0,0,0,0,0]
00500 data[0] = role%16
00501 data[1] = int(role/2**6)%2==1
00502 data[2] = int(role/2**7)%2==1
00503 data[3] = int(role/2**8)%2==1
00504 data[4] = int(role/2**9)%2==1
00505 data[5] = int(role/2**10)%2==1
00506 data[6] = int(role/2**11)%2==1
00507 data[7] = int(role/2**12)%2==1
00508 data[8] = int(role/2**13)%2==1
00509 return data
00510
00511 def get_mode(self, msgID):
00512 '''
00513 Read from MODE property, and return a tuple with the number corresponding to the mode, along with
00514 the string name of the mode.
00515
00516 @param msgID: The puck from which to get the mode.
00517 @type msgID: int
00518 @rtype: Tuple(int, str)
00519 @return: A tuple with the number and name of the mode.
00520 '''
00521 m = self.get_property(msgID, MODE)
00522 if m==MODE_IDLE:
00523 return (MODE_IDLE, "IDLE")
00524 elif m==MODE_TORQUE:
00525 return (MODE_TORQUE, "TORQUE")
00526 elif m==MODE_PID:
00527 return (MODE_PID, "PID")
00528 elif m==MODE_VEL:
00529 return (MODE_VEL, "VEL")
00530 elif m==MODE_TRAP:
00531 return (MODE_TRAP, "TRAP")
00532 else:
00533 print "Invalid get_mode() operation: "+str(m)
00534 return (m, "???")
00535
00536 def set_mode(self, msgID, value):
00537 '''
00538 Set the mode property using either strings or numbers.
00539
00540 @param msgID: The puck or group to set the mode.
00541 @type msgID: int
00542 @param value: The value to which the mode should be set.
00543 @type value: int
00544 '''
00545 modes = {"IDLE":MODE_IDLE, "TORQUE":MODE_TORQUE, "PID":MODE_PID, "VEL":MODE_VEL, "TRAP":MODE_TRAP}
00546 m = value
00547 if m in modes:
00548 m = modes[m]
00549 self.set_property(msgID, MODE, m)
00550
00551
00552 def set_puck_like(self, puckID, virtID):
00553 '''
00554 Set the puck to have all the default properties of the indicated puck ID.
00555
00556 @param puckID: The original puck to change.
00557 @type puckID: int
00558 @param virtID: The ID of the puck to load defaults from.
00559 @type virtID: int
00560 '''
00561 self.set_property(puckID, MODE, MODE_IDLE)
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586 is_280 = self.get_property(puckID, HALLH)==7
00587 if virtID in [FINGER1, FINGER2, FINGER3, SPREAD]:
00588 self.set_property(puckID, JIDX, virtID-3)
00589 self.save_property(puckID, JIDX)
00590 self.set_property(puckID, PIDX, virtID-10)
00591 self.save_property(puckID, PIDX)
00592 self.set_property(puckID, TIE, 0)
00593 self.save_property(puckID, TIE)
00594 self.set_property(puckID, ACCEL, 200)
00595 self.save_property(puckID, ACCEL)
00596
00597
00598 self.set_property(puckID, OT, 0)
00599 self.save_property(puckID, OT)
00600 self.set_property(puckID, CTS, 4096)
00601 self.save_property(puckID, CTS)
00602 self.set_property(puckID, MT, 2200)
00603 self.save_property(puckID, MT)
00604 self.set_property(puckID, MCV, 200)
00605 self.save_property(puckID, MCV)
00606 self.set_property(puckID, MOV, 200)
00607 self.save_property(puckID, MOV)
00608 self.set_property(puckID, OTEMP, 60)
00609 self.save_property(puckID, OTEMP)
00610 self.set_property(puckID, PTEMP, 0)
00611 self.save_property(puckID, PTEMP)
00612 self.set_property(puckID, POLES, 6)
00613 self.save_property(puckID, POLES)
00614 self.set_property(puckID, IKCOR, 102)
00615 self.save_property(puckID, IKCOR)
00616 self.set_property(puckID, IOFF, 0)
00617 self.save_property(puckID, IOFF)
00618 self.set_property(puckID, IVEL, -75)
00619 self.save_property(puckID, IVEL)
00620 self.set_property(puckID, DS, 25600)
00621 self.save_property(puckID, DS)
00622 self.set_property(puckID, KI, 0)
00623 self.save_property(puckID, KI)
00624 self.set_property(puckID, IPNM, 20000)
00625 self.save_property(puckID, IPNM)
00626 self.set_property(puckID, GRPA, 0)
00627 self.save_property(puckID, GRPA)
00628 self.set_property(puckID, GRPB, 7)
00629 self.save_property(puckID, GRPB)
00630 self.set_property(puckID, GRPC, 5)
00631 self.save_property(puckID, GRPC)
00632 self.set_property(puckID, IKI, 204)
00633 self.save_property(puckID, IKI)
00634 self.set_property(puckID, IKP, 500)
00635 self.save_property(puckID, IKP)
00636 if virtID == SPREAD:
00637 self.set_property(puckID, CT, 35950)
00638 self.save_property(puckID, CT)
00639 self.set_property(puckID, DP, 17975)
00640 self.save_property(puckID, DP)
00641 self.set_property(puckID, MV, 50)
00642 self.save_property(puckID, MV)
00643 self.set_property(puckID, HSG, 0)
00644 self.save_property(puckID, HSG)
00645 self.set_property(puckID, LSG, 0)
00646 self.save_property(puckID, LSG)
00647 self.set_property(puckID, HOLD, 1)
00648 self.save_property(puckID, HOLD)
00649 self.set_property(puckID, TSTOP, 150)
00650 self.save_property(puckID, TSTOP)
00651 self.set_property(puckID, KP, 1000)
00652 self.save_property(puckID, KP)
00653 self.set_property(puckID, KD, 10000)
00654 self.save_property(puckID, KD)
00655 else:
00656 self.set_property(puckID, CT, 195000)
00657 self.save_property(puckID, CT)
00658 self.set_property(puckID, DP, 45000)
00659 self.save_property(puckID, DP)
00660 self.set_property(puckID, MV, 200)
00661 self.save_property(puckID, MV)
00662 self.set_property(puckID, HSG, 0)
00663 self.save_property(puckID, HSG)
00664 self.set_property(puckID, LSG, 0)
00665 self.save_property(puckID, LSG)
00666 self.set_property(puckID, HOLD, 0)
00667 self.save_property(puckID, HOLD)
00668 self.set_property(puckID, TSTOP, 50)
00669 self.save_property(puckID, TSTOP)
00670 self.set_property(puckID, KP, 500)
00671 self.save_property(puckID, KP)
00672 self.set_property(puckID, KD, 2500)
00673 self.save_property(puckID, KD)
00674 else:
00675 print "Invalid Puck Id for Hand"
00676
00677
00678
00679 def set_hand_targets(self, f1_target, f2_target, f3_target, sp_target):
00680 '''
00681 Given fingers and spread target values, move the hand to that position.
00682 Will mainly be used to load user-defined hand positions.
00683 Takes Barrett Units as inputs.
00684
00685 @param f1_target: The position (in encoder ticks) for finger 1 to move to.
00686 @type f1_target: int
00687 @param f2_target: The position for finger 2 to move to.
00688 @type f2_target: int
00689 @param f3_target: The position for finger 3 to move to.
00690 @type f3_target: int
00691 @param sp_target: The position for spread to move to.
00692 @type sp_target: int
00693 '''
00694 self.set_property(FINGER1, DP, f1_target)
00695 self.set_property(FINGER2, DP, f2_target)
00696 self.set_property(FINGER3, DP, f3_target)
00697 tar = self.get_position(SPREAD)
00698 self.set_property(SPREAD, DP, tar)
00699 self.set_property(0x405, CMD, CMD_MOVE)
00700 time.sleep(2)
00701 self.set_property(SPREAD, DP, sp_target)
00702 self.set_property(SPREAD, CMD, CMD_MOVE)
00703 time.sleep(1)
00704
00705 def move_to(self, puckID, target, autowait=True):
00706 '''
00707 Move the motor to a specific position.
00708
00709 @param puckID: The puck to move.
00710 @type puckID: int
00711 @param target: The end position to move to.
00712 @type target: int
00713 @param autowait: Does the program wait until the motor is done moving?
00714 @type autowait: bool
00715 '''
00716 self.set_property(puckID, M, target)
00717 if autowait:
00718 self.wait_done_moving([puckID])
00719
00720 def done_moving(self, motors_to_check=ALL_FINGERS):
00721 '''
00722 Checks a given list of motors once to see if they have stopped moving, and if so, it returns true
00723
00724 @param motors_to_check: A list of motors to check.
00725 @type motors_to_check: Array[*int]
00726 @rtype: bool
00727 @return: Whether or not the motors are done moving.
00728 '''
00729 for FINGER in motors_to_check:
00730 if (self.get_mode(FINGER)[1]!="IDLE" and (self.get_mode(FINGER)[1]!="PID" or self.get_property(FINGER,77)==0)):
00731 return False
00732 return True
00733
00734
00735 def wait_done_moving(self, motors_to_check=ALL_FINGERS):
00736 '''
00737 Waits until the given list of motors have all stopped moving.
00738
00739 @param motors_to_check: A list of motors to wait for.
00740 @type motors_to_check: Array[*int]
00741 '''
00742 while(not self.done_moving(motors_to_check)):
00743 time.sleep(0.025)
00744
00745 def detect_breakaway(self, finger):
00746 '''
00747
00748 @return: True if the finger has broken away, False if it hasn't
00749 '''
00750 tup = self.get_packed_position(finger)
00751 ratio = tup[0]/tup[1]
00752 return (ratio>3)
00753
00754 def open_grasp(self):
00755 '''
00756 Opens all fingers to the position encoded by Open Target (OT)
00757 '''
00758 self.set_property(0x405, TSTOP, 50)
00759 self.set_property(SPREAD, TSTOP, 150)
00760
00761 open_target=self.get_property(FINGER1,OT)
00762 self.set_property(FINGER1,DP,open_target)
00763
00764 open_target=self.get_property(FINGER2,OT)
00765 self.set_property(FINGER2,DP,open_target)
00766
00767 open_target=self.get_property(FINGER3,OT)
00768 self.set_property(FINGER3,DP,open_target)
00769
00770 spread_stay=self.get_position(SPREAD)
00771 self.set_property(SPREAD,DP,spread_stay)
00772
00773 self.set_property(0x405,CMD,CMD_MOVE)
00774 self.wait_done_moving(GRASP)
00775
00776 def close_grasp(self):
00777 '''
00778 Closes all fingers to the position encoded by Close Target (CT).
00779 '''
00780 self.set_property(0x405, TSTOP, 50)
00781 self.set_property(SPREAD, TSTOP, 150)
00782
00783 close_target=self.get_property(FINGER1,CT)
00784 self.set_property(FINGER1,DP,close_target)
00785
00786 close_target=self.get_property(FINGER2,CT)
00787 self.set_property(FINGER2,DP,close_target)
00788
00789 close_target=self.get_property(FINGER3,CT)
00790 self.set_property(FINGER3,DP,close_target)
00791
00792 spread_stay=self.get_position(SPREAD)
00793 self.set_property(SPREAD,DP,spread_stay)
00794
00795 self.set_property(0x405,CMD,CMD_MOVE)
00796 self.wait_done_moving(GRASP)
00797
00798 def open_spread(self):
00799 '''
00800 Open spread to position determined by Open Target (OT).
00801 '''
00802 self.set_property(SPREAD, TSTOP, 150)
00803 self.set_property(SPREAD, CMD, CMD_OPEN)
00804 self.wait_done_moving([SPREAD])
00805
00806 def close_spread(self):
00807 '''
00808 Close spread to position determined by Close Target (CT).
00809 '''
00810 self.set_property(SPREAD, CMD, CMD_CLOSE)
00811 self.wait_done_moving([SPREAD])
00812
00813 def open_finger(self, puckID, autowait=True):
00814 '''
00815 Open finger and wait for completion.
00816
00817 @param puckID: Finger to be opened.
00818 @type puckID: int
00819 @param autowait: calls wait_done_moving if True. Defaults to True.
00820 @type autowait: bool
00821 '''
00822 if puckID in [FINGER1, FINGER2, FINGER3]:
00823 self.set_property(puckID, TSTOP, 50)
00824 if puckID == SPREAD:
00825 self.set_property(puckID, TSTOP, 150)
00826 self.set_property(puckID, CMD, CMD_OPEN)
00827 if autowait:
00828 self.wait_done_moving([puckID])
00829
00830 def close_finger(self, puckID, autowait=True):
00831 '''
00832 Close finger and wait for completion.
00833
00834 @param puckID: Finger to be closed.
00835 @type puckID: int
00836 @param autowait: calls wait_done_moving if True. Defaults to True.
00837 @type autowait: bool
00838 '''
00839 if puckID in [FINGER1, FINGER2, FINGER3]:
00840 self.set_property(puckID, TSTOP, 50)
00841 if puckID == SPREAD:
00842 self.set_property(puckID, TSTOP, 150)
00843 self.set_property(puckID, CMD, CMD_CLOSE)
00844 if autowait:
00845 self.wait_done_moving([puckID])
00846
00847 def move_grasp(self, position = -1):
00848 '''
00849 Moves all fingers to input argument or default position (50).
00850
00851 @param position: position of fingers. Defaults to -1. Valid position range is from 0-195,000 encoder counts.
00852 @type position: int
00853 '''
00854 default = self.get_position(SPREAD)
00855 self.set_property(SPREAD, DP, default)
00856 if(position != -1):
00857 self.set_property(FINGER1, DP, position)
00858 self.set_property(FINGER2, DP, position)
00859 self.set_property(FINGER3, DP, position)
00860 self.move()
00861
00862 def move(self):
00863 '''
00864 Moves all fingers/spread to their default.
00865 '''
00866 self.set_property(0x405, CMD, CMD_MOVE)
00867 self.wait_done_moving(GRASP)
00868
00869 def open_all(self):
00870 '''
00871 Opens every fingers at once. Mainly used in DEMO. WARNING: can be dangerous because it may cause fingers to collide if the hand is in an unknown position.
00872 '''
00873 open_target = self.get_property(FINGER1, OT)
00874 self.set_property(FINGER1, DP, open_target)
00875 open_target = self.get_property(FINGER2, OT)
00876 self.set_property(FINGER2, DP, open_target)
00877 open_target = self.get_property(FINGER3, OT)
00878 self.set_property(FINGER3, DP, open_target)
00879 open_target = self.get_property(SPREAD, OT)
00880 self.set_property(SPREAD, DP, open_target)
00881 self.move()
00882
00883 def close_all(self):
00884 '''
00885 Closes every finger at once. Mainly for use in DEMO. WARNING: can be dangerous because it may cause fingers to collide if the hand is in an unknown position.
00886 '''
00887 close_target = self.get_property(FINGER1, CT)
00888 self.set_property(FINGER1, DP, close_target)
00889 close_target = self.get_property(FINGER2, CT)
00890 self.set_property(FINGER2, DP, close_target)
00891 close_target = self.get_property(FINGER3, CT)
00892 self.set_property(FINGER3, DP, close_target)
00893 close_target = self.get_property(SPREAD, CT)
00894 self.set_property(SPREAD, DP, close_target)
00895 self.move()
00896
00897
00898
00899 def open_grasp_step(self, step=0):
00900 '''
00901 Open grasp by input increment.
00902
00903 @param step: size of increment in encoder counts. Defaults to 0.
00904 @type step: int
00905 '''
00906 self.open_finger_step(FINGER1, step, False)
00907 self.open_finger_step(FINGER2, step, False)
00908 self.open_finger_step(FINGER3, step, False)
00909 self.wait_done_moving(GRASP)
00910
00911 def close_grasp_step(self, step=0):
00912 '''
00913 Close grasp by input decrement.
00914
00915 @param step: size of decrement in encoder counts. Defaults to 0.
00916 @type step: int
00917 '''
00918 self.close_finger_step(FINGER1, step, False)
00919 self.close_finger_step(FINGER2, step, False)
00920 self.close_finger_step(FINGER3, step, False)
00921 self.wait_done_moving(GRASP)
00922
00923 def open_spread_step(self, step=-1):
00924 '''
00925 Open spread by input increment.
00926
00927 @param step: size of increment in encoder counts. Defaults to -1.
00928 @type step: int
00929 '''
00930 if step == -1:
00931 step = self.get_property(SPREAD, 60)
00932 self.open_finger_step(SPREAD, step)
00933
00934 def close_spread_step(self, step=-1):
00935 '''
00936 Close spread by input decrement.
00937
00938 @param step: size of decrement in encoder counts. Defaults to -1.
00939 @type step: int
00940 '''
00941 if step == -1:
00942 step = self.get_property(SPREAD, 60)
00943 self.close_finger_step(SPREAD, step)
00944
00945 def open_finger_step(self, puckID, step=-1, autowait=True):
00946 '''
00947 Open finger by input increment.
00948
00949 @param puckID: Finger to be opened.
00950 @type puckID: int
00951 @param step: size of increment in encoder counts. Defaults to -1.
00952 @type step: int
00953 @param autowait: calls wait_done_moving if True. Defaults to True.
00954 @type autowait: bool
00955 '''
00956 if step == -1:
00957 step = self.get_property(puckID, 60)
00958 self.set_property(puckID, DS, step)
00959 self.set_property(puckID, CMD, CMD_IO)
00960 if autowait:
00961 self.wait_done_moving([puckID])
00962
00963 def close_finger_step(self, puckID, step=-1, autowait=True):
00964 '''
00965 Close finger by input decrement.
00966
00967 @param puckID: Finger to be closed.
00968 @type puckID: int
00969 @param step: size of decrement in encoder counts. Defaults to -1.
00970 @type step: int
00971 @param autowait: calls wait_done_moving if True. Defaults to True.
00972 @type autowait: bool
00973 '''
00974 if step == -1:
00975 step = self.get_property(puckID, 60)
00976 self.set_property(puckID, DS, step)
00977 self.set_property(puckID, CMD, CMD_IC)
00978 if autowait:
00979 self.wait_done_moving([puckID])
00980
00981
00982 def get_full_pos_packet(msgID):
00983 self.write_msg(msgID, [P])
00984 read_result=self.PCAN.Read(PCAN_USBBUS1)
00985 return read_result
00986
00987 def get_velocity(self, msgID):
00988 '''
00989 Returns velocity values of finger when in motion. Mostly returns garbage. It's used to help tell when finger is stopped or near to it.
00990
00991 @param msgID: The puck or group to get velocity.
00992 @type msgID: int
00993 @rtype: float
00994 @return: A (garbage) value representing the approximate velocity of the finger.
00995 '''
00996 packet1=self.get_full_pos_packet(msgID)
00997 packet2=self.get_full_pos_packet(msgID)
00998
00999 error1=packet1[0]
01000 error2=packet2[0]
01001
01002 msg1=packet1[1]
01003 msg2=packet2[1]
01004
01005 data1=msg1.DATA
01006 data2=msg2.DATA
01007
01008 time1=packet1[2]
01009 time2=packet2[2]
01010
01011 stamp1=time1.micros + 1000 * time1.millis + 0xFFFFFFFF * 1000 * time1.millis_overflow
01012 stamp2=time2.micros + 1000 * time2.millis + 0xFFFFFFFF * 1000 * time2.millis_overflow
01013
01014 delta=(stamp2-stamp1)/1000000.0
01015
01016 self.check_error(self.PCAN,error1,"reading position for fake get_velocity")
01017 self.check_error(self.PCAN,error2,"reading position for fake get_velocity")
01018
01019 val1=(0x0000100 * data1[3]) + (0x0000001 * data1[2])
01020 val2=(0x0000100 * data2[3]) + (0x0000001 * data2[2])
01021
01022 return (val2-val1)/delta
01023
01024 def get_temp(self, msgID):
01025 '''
01026 Gets temperature value for all pucks in msgID.
01027
01028 @param msgID: The puck or group to get temp.
01029 @type msgID: int
01030 @rtype: int
01031 @return: The value of the TEMP property.
01032 '''
01033 return self.temp[msgID]['temp']
01034
01035
01036 def read_temp(self, msgID):
01037 '''
01038 Sends a message to get the temperature value for all pucks in msgID.
01039
01040 @param msgID: The puck or group to get temp.
01041 @type msgID: int
01042 @rtype: int
01043 @return: The value of the TEMP property.
01044 '''
01045 return self.send_msg(msgID, [TEMP])
01046
01047 def get_therm(self, msgID):
01048 '''
01049 Gets motor temperature value for all pucks in msgID.
01050
01051 @param msgID: The puck or group to get motor temperature.
01052 @text msgID: int
01053 @rtype: int
01054 @return: The value of the THERM property.
01055 '''
01056 return self.temp[msgID]['therm']
01057
01058 def read_therm(self, msgID):
01059 '''
01060 Gets motor temperature value for all pucks in msgID.
01061
01062 @param msgID: The puck or group to get motor temperature.
01063 @text msgID: int
01064 @rtype: int
01065 @return: The value of the THERM property.
01066 '''
01067 return self.send_msg(msgID, [THERM])
01068
01069 def get_top_tact(self, msgID):
01070 '''
01071 Unpack the top10 values from TACT.
01072 Returns a dictionary with 10 items like (sensor number):(tact value).
01073
01074 @param msgID: The puck or group to get top 10 tactile data.
01075 @type msgID: int
01076 @rtype: Dictionary{sensorID:value}
01077 @return topVals: Dictionary of the top 10 tactile array sensor values.
01078 '''
01079
01080 self.set_property(msgID, TACT, TACT_10)
01081 self.write_msg(msgID, [TACT])
01082 read_result=self.PCAN.Read(PCAN_USBBUS1)
01083 self.check_error(self.PCAN,read_result[0],"reading top ten tactile values")
01084
01085 output = read_result[1].DATA
01086
01087 top10 = output[0] * 0x10000 + output[1] * 0x100 + output[2] * 0x1
01088 topVals = {}
01089 data = [output[3]/(0x10), output[3]%(0x10), output[4]/(0x10), output[4]%(0x10), output[5]/(0x10), output[5]%(0x10)]
01090 count=0
01091 for sensor in range(0, 24):
01092 if top10%2 == 1:
01093
01094 topVals[sensor] = data[count]
01095 count+=1
01096 top10 = top10/2
01097
01098 return topVals
01099
01100 def read_full_tact(self, msgID):
01101 '''
01102 Read all tactile sensors
01103 '''
01104 return self.set_property(msgID, TACT, TACT_FULL)
01105
01106 def get_full_tact(self, msgID):
01107 '''
01108 Unpack all tactile sensor values in an array.
01109
01110 @param msgID: The puck or group to get full tactile array sensor data.
01111 @type msgID: int
01112 @rtype: Array[*data]
01113 @return: An array containing the tactile data from a given puck.
01114 '''
01115
01116 '''self.set_property(msgID, TACT, TACT_FULL)
01117 #self.write_msg(msgID, [TACT])
01118 output = [0,0,0,0,0]
01119 read_result = self.PCAN.Read(PCAN_USBBUS1)
01120 self.check_error(self.PCAN,read_result[0],"reading full tactile data")
01121 read_result2 = self.PCAN.Read(PCAN_USBBUS1)
01122 self.check_error(self.PCAN,read_result2[0],"reading full tactile data")
01123 read_result3 = self.PCAN.Read(PCAN_USBBUS1)
01124 self.check_error(self.PCAN,read_result3[0],"reading full tactile data")
01125 read_result4 = self.PCAN.Read(PCAN_USBBUS1)
01126 self.check_error(self.PCAN,read_result4[0],"reading full tactile data")
01127 read_result5 = self.PCAN.Read(PCAN_USBBUS1)
01128 self.check_error(self.PCAN,read_result5[0],"reading full tactile data")
01129
01130 output[0] = read_result[1].DATA
01131 output[1] = read_result2[1].DATA
01132 output[2] = read_result3[1].DATA
01133 output[3] = read_result4[1].DATA
01134 output[4] = read_result5[1].DATA
01135
01136 #print 'Init: ID1 = %x, ID2 = %x, ID3 = %x, ID4 = %x, ID5 = %x'%(read_result[1].ID, read_result2[1].ID, read_result3[1].ID, read_result4[1].ID, read_result5[1].ID)
01137 tactileVals = range(0,24)
01138 index_ = 0
01139 for data in output:
01140 index_ = int(data[0]/16) * 5
01141 #print 'index = %d, data[0] = %x'%(index_, data[0])
01142 # Get the bits and then unpack them.
01143 tactileVals[index_ + 0] = round(((data[0]%0x10)*0x100 + data[1])/256.0,2)
01144 tactileVals[index_ + 1] = round((data[2]*0x10 + int(data[3]/0x10))/256.0,2)
01145 tactileVals[index_ + 2] = round(((data[3]%0x10)*0x100 + data[4])/256.0,2)
01146 tactileVals[index_ + 3] = round((data[5]*0x10 + int(data[6]/0x10))/256.0,2)
01147 if index_ != 20:
01148 tactileVals[index_ + 4] = round(((data[6]%0x10)*0x100 + data[7])/256.0,2)
01149 #print 'Return OK : %s'%(tactileVals)
01150 return tactileVals'''
01151
01152 return self.tactile_sensor[msgID]['values']
01153
01154
01155 def get_tact(self, msgID, topOrFull="TOP10"):
01156 '''
01157 Obtain and interpret tactile sensor data.
01158
01159 @param msgID: The puck or group to get full or top 10 tactile array sensor data.
01160 @type msgID: int
01161 @param topOrFull: To get full data, enter "FULL". To get the top 10 values, enter "TOP10". Or anything else, really.
01162 @type topOrFull: str
01163 @return
01164 '''
01165 if topOrFull == "FULL":
01166 return self.get_full_tact(msgID)
01167 else:
01168 return self.get_top_tact(msgID)
01169
01170 def set_velocity(self, puckID, velocity):
01171 '''
01172 Set the velocity and make the motor move.
01173
01174 @param puckID: The ID of the puck to set the velocity of.
01175 @type puckID: int
01176 @param velocity: The velocity (in cts/ms) of the motor.
01177 @type velocity: int
01178 '''
01179
01180 self.set_property(puckID, TSTOP, 0)
01181
01182 self.set_property(puckID, V, velocity)
01183
01184 self.set_property(puckID, MODE, MODE_VEL)
01185
01186
01187 def get_strain(self, msgID):
01188 '''
01189 Gets the fingertip torque sensor value.
01190
01191 @param msgID: The puck or group to get fingertip torque sensor data.
01192 @type msgID: int
01193 @rtype: int
01194 @return: Strain Gauge Reading
01195 '''
01196 return self.strain[msgID]
01197
01198
01199 def read_strain(self, msgID):
01200 '''
01201 Sends the message to get the fingertip torque sensor value.
01202
01203 @param msgID: The puck or group to get fingertip torque sensor data.
01204 @type msgID: int
01205 @rtype: int
01206 @return: CAN status
01207 '''
01208 return self.send_msg(msgID, [SG])
01209
01210
01211
01212 def onescomp(self, binstr):
01213 return ''.join('1' if b=='0' else '0' for b in binstr)
01214
01215 def twoscomp(self, number):
01216 binstr= bin(number)[2:]
01217 a= bin(int(self.onescomp(binstr),2)+1)[2:]
01218 return -1*int(a,2)
01219
01220 def get_position(self, msgID, depth=0):
01221 '''
01222 Get packed position data and return it.
01223
01224 @param msgID: The puck or group to get position data.
01225 @type msgID: int
01226 @rtype: int
01227
01228 @param depth: number of times get message was retried.
01229
01230 @return: The position of the finger in encoder counts.
01231 '''
01232 if depth!=0:
01233 self.write_msg(msgID, [P],.009)
01234 read_result=self.PCAN.Read(PCAN_USBBUS1)
01235 try:
01236 self.check_error(self.PCAN,read_result[0],"getting position data")
01237 received_puck=(read_result[1].ID-1024)>>5
01238 if received_puck!=msgID:
01239 raise Exception("Did not read expected MSGID")
01240 except:
01241 if depth>10:
01242 raise Exception("Failure to get position data.")
01243 else:
01244 return self.get_position(msgID, depth+1)
01245
01246 output = read_result[1].DATA
01247 temp=(output[0]-0x80)*0x10000 + output[1] * 0x100 + output[2]
01248
01249 if (temp & 0b1000000000000000000000):
01250 return self.twoscomp(temp)
01251 else:
01252 return temp
01253
01254 def get_packed_position(self, msgID):
01255 '''
01256 Get packed position data and return both P and JP.
01257
01258 @param msgID: The puck or group to get position data.
01259 @type msgID: int
01260 @rtype: (int, int)
01261
01262 @return: The position and joint position of the finger in encoder counts.
01263 Position in radians
01264 '''
01265
01266 return self.motor_positions[msgID]['position']
01267
01268
01269 def read_packed_position(self, msgID):
01270 '''
01271 Get packed position data and return both P and JP.
01272
01273 @param msgID: The puck or group to get position data.
01274 @type msgID: int
01275 @rtype: (int, int)
01276
01277 @return: sends a msg to read the position.
01278 '''
01279
01280 return self.send_msg(msgID, [P])
01281
01282
01283 def process_can_messages(self):
01284 '''
01285 Reads and process all the msgs in the bus
01286 Depending on the CAN id, it'll use different methods
01287 '''
01288 ret = 0
01289
01290 msg = self.read_msg()
01291
01292
01293 if msg[0] != PCAN_ERROR_OK:
01294 ret = -1
01295
01296 while msg[0] == PCAN_ERROR_OK:
01297
01298 can_id = msg[1].ID
01299
01300
01301 if can_id in [F1_POSITION, F2_POSITION, F3_POSITION, SPREAD_POSITION]:
01302 self.process_packed_position(msg[1])
01303 elif can_id in [F1_STRAIN, F2_STRAIN, F3_STRAIN] and msg[1].DATA[0] == STRAIN_ID:
01304 self.process_strain(msg[1])
01305 elif can_id in [F1_MOTOR_TEMP, F2_MOTOR_TEMP, F3_MOTOR_TEMP, SPREAD_MOTOR_TEMP] and msg[1].DATA[0] == MOTOR_TEMP_ID:
01306 self.process_motor_temp(msg[1])
01307 elif can_id in [F1_MOTOR_THERM, F2_MOTOR_THERM, F3_MOTOR_THERM, SPREAD_MOTOR_THERM] and msg[1].DATA[0] == MOTOR_THERM_ID:
01308 self.process_motor_therm(msg[1])
01309 elif can_id in [F1_TACT, F2_TACT, F3_TACT, PALM_TACT]:
01310 self.process_full_tact(msg[1])
01311
01312 msg = self.read_msg()
01313
01314 return ret
01315
01316 def process_packed_position(self, msg):
01317 '''
01318 Process the CAN msgs and saves the position depending on the MSG ID
01319 '''
01320 data = msg.DATA
01321 pos = (data[0]-0x80)*0x10000 + data[1]*0x100 + data[2]
01322 jpos= (data[3]-0x80)*0x10000 + data[4]*0x100 + data[5]
01323 pos = self.twoscomp(pos) if pos & 0b1000000000000000000000 else pos
01324 jpos= self.twoscomp(jpos) if jpos & 0b1000000000000000000000 else jpos
01325
01326 if msg.ID == F1_POSITION:
01327 self.motor_positions[FINGER1]['encoder'][0] = pos
01328 self.motor_positions[FINGER1]['encoder'][1] = jpos
01329 self.motor_positions[FINGER1]['position'][0] = self.enc_to_rad(pos, BASE_TYPE)
01330 self.motor_positions[FINGER1]['position'][1] = self.enc_to_rad(jpos, BASE_TYPE)
01331
01332
01333 elif msg.ID == F2_POSITION:
01334 self.motor_positions[FINGER2]['encoder'][0] = pos
01335 self.motor_positions[FINGER2]['encoder'][1] = jpos
01336 self.motor_positions[FINGER2]['position'][0] = self.enc_to_rad(pos, BASE_TYPE)
01337 self.motor_positions[FINGER2]['position'][1] = self.enc_to_rad(jpos, BASE_TYPE)
01338
01339
01340 elif msg.ID == F3_POSITION:
01341 self.motor_positions[FINGER3]['encoder'][0] = pos
01342 self.motor_positions[FINGER3]['encoder'][1] = jpos
01343 self.motor_positions[FINGER3]['position'][0] = self.enc_to_rad(pos, BASE_TYPE)
01344 self.motor_positions[FINGER3]['position'][1] = self.enc_to_rad(jpos, BASE_TYPE)
01345
01346
01347
01348 elif msg.ID == SPREAD_POSITION:
01349 self.motor_positions[SPREAD]['encoder'][0] = pos
01350 self.motor_positions[SPREAD]['encoder'][1] = jpos
01351 self.motor_positions[SPREAD]['position'][0] = self.enc_to_rad(pos, SPREAD_TYPE)
01352 self.motor_positions[SPREAD]['position'][1] = self.enc_to_rad(jpos, SPREAD_TYPE)
01353
01354
01355
01356 def process_strain(self, msg):
01357 '''
01358 Process the msg and extract the strain value depending on the CAN ID
01359 '''
01360 data = msg.DATA
01361 value =(0x0000100 * data[3]) + (0x0000001 * data[2])
01362
01363 if msg.ID == F1_STRAIN:
01364 self.strain[FINGER1] = value
01365 if msg.ID == F2_STRAIN:
01366 self.strain[FINGER2] = value
01367 if msg.ID == F3_STRAIN:
01368 self.strain[FINGER3] = value
01369
01370 def process_motor_temp(self, msg):
01371 '''
01372 Process the msg and extract the temperature of the motor puck on the CAN ID
01373 '''
01374 data = msg.DATA
01375 value =(0x0000100 * data[3]) + (0x0000001 * data[2])
01376
01377 if msg.ID == F1_MOTOR_TEMP:
01378 self.temp[FINGER1]['temp'] = value
01379
01380 if msg.ID == F2_MOTOR_TEMP:
01381 self.temp[FINGER2]['temp'] = value
01382
01383 if msg.ID == F3_MOTOR_TEMP:
01384 self.temp[FINGER3]['temp'] = value
01385
01386 if msg.ID == SPREAD_MOTOR_TEMP:
01387 self.temp[SPREAD]['temp'] = value
01388
01389
01390 def process_motor_therm(self, msg):
01391 '''
01392 Process the msg and extract the temperature of the motor on the CAN ID
01393 '''
01394 data = msg.DATA
01395 value =(0x0000100 * data[3]) + (0x0000001 * data[2])
01396
01397 if msg.ID == F1_MOTOR_THERM:
01398 self.temp[FINGER1]['therm'] = value
01399
01400 if msg.ID == F2_MOTOR_THERM:
01401 self.temp[FINGER2]['therm'] = value
01402
01403 if msg.ID == F3_MOTOR_THERM:
01404 self.temp[FINGER3]['therm'] = value
01405
01406 if msg.ID == SPREAD_MOTOR_THERM:
01407 self.temp[SPREAD]['therm'] = value
01408
01409
01410 def process_full_tact(self, msg):
01411 '''
01412 Process and saves all the messages containing the tactile information
01413 '''
01414
01415 data = msg.DATA
01416
01417 if msg.ID == F1_TACT:
01418 if data[0] >= 0x00 and data[0] < 0x10:
01419 self.tactile_sensor[FINGER1]['data'][0] = data
01420 if data[0] >= 0x10 and data[0] < 0x20:
01421 self.tactile_sensor[FINGER1]['data'][1] = data
01422 if data[0] >= 0x20 and data[0] < 0x30:
01423 self.tactile_sensor[FINGER1]['data'][2] = data
01424 if data[0] >= 0x30 and data[0] < 0x40:
01425 self.tactile_sensor[FINGER1]['data'][3] = data
01426 if data[0] >= 0x40:
01427 self.tactile_sensor[FINGER1]['data'][4] = data
01428 self.tactile_sensor[FINGER1]['values'] = self.process_tactile_data(self.tactile_sensor[FINGER1]['data'])
01429 if msg.ID == F2_TACT:
01430 if data[0] >= 0x00 and data[0] < 0x10:
01431 self.tactile_sensor[FINGER2]['data'][0] = data
01432 if data[0] >= 0x10 and data[0] < 0x20:
01433 self.tactile_sensor[FINGER2]['data'][1] = data
01434 if data[0] >= 0x20 and data[0] < 0x30:
01435 self.tactile_sensor[FINGER2]['data'][2] = data
01436 if data[0] >= 0x30 and data[0] < 0x40:
01437 self.tactile_sensor[FINGER2]['data'][3] = data
01438 if data[0] >= 0x40:
01439 self.tactile_sensor[FINGER2]['data'][4] = data
01440 self.tactile_sensor[FINGER2]['values'] = self.process_tactile_data(self.tactile_sensor[FINGER2]['data'])
01441 if msg.ID == F3_TACT:
01442 if data[0] >= 0x00 and data[0] < 0x10:
01443 self.tactile_sensor[FINGER3]['data'][0] = data
01444 if data[0] >= 0x10 and data[0] < 0x20:
01445 self.tactile_sensor[FINGER3]['data'][1] = data
01446 if data[0] >= 0x20 and data[0] < 0x30:
01447 self.tactile_sensor[FINGER3]['data'][2] = data
01448 if data[0] >= 0x30 and data[0] < 0x40:
01449 self.tactile_sensor[FINGER3]['data'][3] = data
01450 if data[0] >= 0x40:
01451 self.tactile_sensor[FINGER3]['data'][4] = data
01452 self.tactile_sensor[FINGER3]['values'] = self.process_tactile_data(self.tactile_sensor[FINGER3]['data'])
01453 if msg.ID == PALM_TACT:
01454 if data[0] >= 0x00 and data[0] < 0x10:
01455 self.tactile_sensor[SPREAD]['data'][0] = data
01456 if data[0] >= 0x10 and data[0] < 0x20:
01457 self.tactile_sensor[SPREAD]['data'][1] = data
01458 if data[0] >= 0x20 and data[0] < 0x30:
01459 self.tactile_sensor[SPREAD]['data'][2] = data
01460 if data[0] >= 0x30 and data[0] < 0x40:
01461 self.tactile_sensor[SPREAD]['data'][3] = data
01462 if data[0] >= 0x40:
01463 self.tactile_sensor[SPREAD]['data'][4] = data
01464 self.tactile_sensor[SPREAD]['values'] = self.process_tactile_data(self.tactile_sensor[SPREAD]['data'])
01465
01466 def process_tactile_data(self, data_array):
01467 '''
01468 Process the array of data and returns a tactile array
01469 '''
01470 tactileVals = range(0,24)
01471 index_ = 0
01472 for data in data_array:
01473 index_ = int(data[0]/16) * 5
01474
01475
01476 tactileVals[index_ + 0] = round(((data[0]%0x10)*0x100 + data[1])/256.0,2)
01477 tactileVals[index_ + 1] = round((data[2]*0x10 + int(data[3]/0x10))/256.0,2)
01478 tactileVals[index_ + 2] = round(((data[3]%0x10)*0x100 + data[4])/256.0,2)
01479 tactileVals[index_ + 3] = round((data[5]*0x10 + int(data[6]/0x10))/256.0,2)
01480 if index_ != 20:
01481 tactileVals[index_ + 4] = round(((data[6]%0x10)*0x100 + data[7])/256.0,2)
01482
01483 return tactileVals
01484
01485
01486 def new_temp_mail(self, fingers_to_change):
01487 former_mailbox_c={}
01488 for finger in fingers_to_change:
01489 former_mailbox_c[finger]=self.get_property(finger,GRPC)
01490 self.set_property(finger,GRPC,12)
01491 return former_mailbox_c
01492
01493 def revert_temp_mail(self, fingers_to_change,former):
01494 for finger in fingers_to_change:
01495 former_mailbox_value=former[finger]
01496 self.set_property(finger,GRPC,former_mailbox_value)
01497
01498
01499 def enc_to_per(self, enc):
01500 '''
01501 Given an angle in encoder counts, return the percentage of the angle that represents.
01502
01503 @param enc: Encoder counts.
01504 @type enc: int
01505 @return: Percentage
01506 @rtype: float
01507 '''
01508 per = enc/1950.0
01509 return round(per, 2)
01510
01511 def enc_to_rad(self, enc, type = BASE_TYPE):
01512 '''
01513 Given an angle in encoder counts, return the radian measure of the angle that represents.
01514
01515 @param enc: Encoder counts.
01516 @type enc: int
01517 @return: Radians
01518 @rtype: float
01519 '''
01520 motion_limit = BASE_LIMIT
01521 tics = MAX_ENCODER_TICKS
01522
01523 if type == TIP_TYPE:
01524 motion_limit = TIP_LIMIT
01525 tics = MAX_FINGERTIP_TICKS
01526 elif type == SPREAD_TYPE:
01527 motion_limit = SPREAD_LIMIT
01528 tics = MAX_SPREAD_TICKS
01529
01530 PI = 3.141592653589
01531 rad = enc * (motion_limit*PI/180)/tics
01532 return round(rad,2)
01533
01534 def enc_to_deg(self, enc):
01535 '''
01536 Given an angle in encoder counts, return the degree measure of the angle that represents.
01537
01538 @param enc: Encoder counts.
01539 @type enc: int
01540 @return: Degrees
01541 @rtype: float
01542 '''
01543 deg = enc * 140/MAX_ENCODER_TICKS
01544 return round(deg,2)
01545
01546 def per_to_enc(self, per):
01547 '''
01548 Given a percentage of an angle, return it in encoder counts.
01549
01550 @param per: Percentage
01551 @type per: float
01552 @return: Encoder counts
01553 @rtype: int
01554 '''
01555 enc = per * 1950.0
01556 return int(enc)
01557
01558 def rad_to_enc(self, rad, type = BASE_TYPE):
01559 '''
01560 Given the readian measure of an angle, return it in encoder counts.
01561
01562 @param rad: Radians
01563 @type rad: float
01564 @return: Encoder counts
01565 @rtype: int
01566 '''
01567 motion_limit = BASE_LIMIT
01568 tics = MAX_ENCODER_TICKS
01569
01570 if type == TIP_TYPE:
01571 motion_limit = TIP_LIMIT
01572 tics = MAX_FINGERTIP_TICKS
01573 elif type == SPREAD_TYPE:
01574 motion_limit = SPREAD_LIMIT
01575 tics = MAX_SPREAD_TICKS
01576
01577 PI = 3.141592653589
01578 enc = rad / ((motion_limit*PI/180)/tics)
01579 return int(enc)
01580
01581 def deg_to_enc(self, deg):
01582
01583 '''
01584 Given a degree measure of an angle, return it in encoder counts.
01585
01586 @param deg: Degrees
01587 @type deg: float
01588 @return: Encoder counts
01589 @rtype: int
01590 '''
01591 enc = deg * 195000.0/140
01592 return int(enc)
01593
01594 def clean_read_buffer(self):
01595
01596 result_ = self.read_msg()
01597
01598 while result_[0] == 0:
01599 result_ = self.read_msg()
01600