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 import rospy 
00035 from pyHand_api import *
00036 
00037 from std_msgs.msg import String
00038 from bhand_controller.msg import State, TactileArray, Service
00039 from bhand_controller.srv import Actions, SetControlMode
00040 from sensor_msgs.msg import JointState
00041 
00042 import time, threading
00043 import math
00044 
00045 DEFAULT_FREQ = 100.0
00046 MAX_FREQ = 250.0
00047 
00048 
00049 CONTROL_MODE_POSITION = "POSITION"
00050 CONTROL_MODE_VELOCITY = "VELOCITY"
00051 
00052 WATCHDOG_VELOCITY = 0.1 
00053 
00054 
00055 class JointHand:
00056         
00057         def __init__(self, id, name):
00058                 self.id = id
00059                 self.joint_name = name
00060                 self.desired_position = 0.0
00061                 self.desired_velocity = 0.0
00062                 self.real_position = 0.0
00063                 self.real_velocity = 0.0
00064                 
00065         
00066 
00067 class BHand:
00068         
00069         def __init__(self, args):
00070                 
00071                 self.port = args['port']
00072                 self.topic_state_name = args['topic_state']
00073                 self.desired_freq = args['desired_freq'] 
00074                 if self.desired_freq <= 0.0 or self.desired_freq > MAX_FREQ:
00075                         rospy.loginfo('%s::init: Desired freq (%f) is not possible. Setting desired_freq to %f'%(rospy.get_name(), self.desired_freq, DEFAULT_FREQ))
00076                         self.desired_freq = DEFAULT_FREQ
00077                 self.tactile_sensors = args['tactile_sensors'] 
00078                 self.real_freq = 0.0
00079                 
00080                 joint_ids_arg = args['joint_ids']
00081                 joint_names_arg = args['joint_names']
00082                 
00083                 self.control_mode = args['control_mode']
00084                 if self.control_mode != CONTROL_MODE_POSITION and self.control_mode != CONTROL_MODE_VELOCITY:
00085                         rospy.loginfo('%s: init: setting control mode by default to %s'%(rospy.get_name(), CONTROL_MODE_POSITION))
00086                         self.control_mode = CONTROL_MODE_POSITION
00087                 
00088                 self.state = State.INIT_STATE
00089                 
00090                 self.can_initialized = False
00091                 
00092                 self.hand_initialized = False
00093                 
00094                 self.ros_initialized = False
00095                 
00096                 self.running = False
00097                 
00098                 self.time_sleep = 1.0
00099                 
00100                 self.hand = pyHand(self.port)
00101                 
00102                 self.joint_state = JointState()
00103                 
00104                 self.msg_tact_array = TactileArray()
00105                 
00106                 self.msg_state = State()
00107                 
00108                 self.publish_state_timer = 1
00109                 
00110                 self.new_command = False
00111                 
00112                 self.temp_command = False
00113                 
00114                 self.temp_current_sensor = 0
00115                 
00116                 self.temp_sensor_number = 8
00117                 
00118                 self.temp_read_timer = 5
00119                 
00120                 self.can_errors = 0
00121                 
00122                 self.max_can_errors = 5
00123                 
00124                 self.failure_recover = False
00125                 
00126                 self.failure_recover_timer = 5  
00127                 
00128                 self.timer_command = time.time()
00129                 self.watchdog_command = float(WATCHDOG_VELOCITY)
00130                 
00131                 
00132                 self.actions_list = []
00133                 
00134                 self.grasp_mode = Service.SET_GRASP_1
00135                 
00136                 
00137                 
00138                 
00139                 
00140                 
00141                 
00142                 
00143                 
00144                 
00145                 
00146                 
00147                 
00148                 
00149                 
00150                 
00151                 
00152                 
00153                 self.joint_names = {}
00154                 
00155                 for i in range(len(joint_ids_arg)):
00156                         self.joint_names[joint_ids_arg[i]] = [joint_names_arg[i], i]
00157                 
00158                 print   self.joint_names
00159                 
00160                 
00161                 self.temperatures = {'F1': [0.0,  0.0], 'F2': [0.0,  0.0], 'F3': [0.0,  0.0], 'SPREAD': [0.0,  0.0]}
00162                 
00163                 
00164                 k = 0
00165                 for i in self.joint_names:
00166                         self.joint_state.name.append(self.joint_names[i][0])
00167                         self.joint_names[i][1] = k 
00168                         k = k + 1
00169                         
00170                         self.joint_state.position.append(0.0)
00171                         self.joint_state.velocity.append(0.0)
00172                         self.joint_state.effort.append(0.0)
00173                 
00174                 
00175                 self.desired_joints_position = {self.joint_names['F1'][0]: 0.0, self.joint_names['F2'][0]: 0.0, self.joint_names['F3'][0]: 0.0, self.joint_names['SPREAD_1'][0]: 0.0, self.joint_names['SPREAD_2'][0]: 0.0}
00176                 self.desired_joints_velocity = {self.joint_names['F1'][0]: 0.0, self.joint_names['F2'][0]: 0.0, self.joint_names['F3'][0]: 0.0, self.joint_names['SPREAD_1'][0]: 0.0, self.joint_names['SPREAD_2'][0]: 0.0}
00177                 
00178                 self.sent_joints_velocity = {self.joint_names['F1'][0]: 0.0, self.joint_names['F2'][0]: 0.0, self.joint_names['F3'][0]: 0.0, self.joint_names['SPREAD_1'][0]: 0.0, self.joint_names['SPREAD_2'][0]: 0.0}
00179                 
00180                 self.t_publish_state = threading.Timer(self.publish_state_timer, self.publishROSstate)
00181                 self.t_read_temp = threading.Timer(self.temp_read_timer, self.readTemp)
00182                 
00183                 rospy.loginfo('%s: port %s, freq = %d, topic = %s, tactile_sensors = %s'%(rospy.get_name() , self.port, self.desired_freq, self.topic_state_name, self.tactile_sensors))
00184         
00185         
00186         def setup(self):
00187                 '''
00188                         Initializes de hand
00189                         @return: True if OK, False otherwise
00190                 '''
00191                 if self.can_initialized or self.hand.initialize() == True:
00192                         self.can_initialized = True
00193                         return 0
00194                 else:
00195                         self.hand.can_uninit()
00196                         rospy.logerr('%s: Error initializing the hand'%rospy.get_name() )
00197                         return -1
00198                 
00199                 
00200         def rosSetup(self):
00201                 '''
00202                         Creates and inits ROS components
00203                 '''
00204                 if self.ros_initialized:
00205                         return 0
00206                         
00207                 
00208                 
00209                 self._state_publisher = rospy.Publisher('%s/state'%rospy.get_name(), State)
00210                 self._joints_publisher = rospy.Publisher('/joint_states', JointState)
00211                 self._tact_array_publisher = rospy.Publisher('%s/tact_array'%rospy.get_name(), TactileArray)
00212                 
00213                 self._joints_subscriber = rospy.Subscriber('%s/command'%rospy.get_name(), JointState, self.commandCallback)
00214                 
00215                 
00216                 self._hand_service = rospy.Service('%s/actions'%rospy.get_name(), Actions, self.handActions)
00217                 self._set_control_mode_service = rospy.Service('%s/set_control_mode'%rospy.get_name(), SetControlMode, self.setControlModeServiceCb)
00218         
00219                 self.ros_initialized = True
00220                 
00221                 self.publishROSstate()
00222                 
00223                 return 0
00224                 
00225                 
00226         def shutdown(self):
00227                 '''
00228                         Shutdowns device
00229                         @return: 0 if it's performed successfully, -1 if there's any problem or the component is running
00230                 '''
00231                 if self.running or not self.can_initialized:
00232                         return -1
00233                 rospy.loginfo('%s::shutdown'%rospy.get_name())
00234                 self.setControlMode('POSITION')
00235                 
00236                 self.hand.can_uninit()
00237                 
00238                 self.t_publish_state.cancel()
00239                 self.t_read_temp.cancel()
00240                 
00241                 
00242                 self.can_initialized = False
00243                 self.hand_initialized = False
00244                 
00245                 return 0
00246         
00247         
00248         def rosShutdown(self):
00249                 '''
00250                         Shutdows all ROS components
00251                         @return: 0 if it's performed successfully, -1 if there's any problem or the component is running
00252                 '''
00253                 if self.running or not self.ros_initialized:
00254                         return -1
00255                 
00256                 
00257                 self._state_publisher.unregister()
00258                 self._joints_publisher.unregister()
00259                 self._tact_array_publisher.unregister()
00260                 self._joints_subscriber.unregister()
00261                 self._set_control_mode_service.shutdown()
00262                 self._hand_service.shutdown()
00263                 
00264                 self.ros_initialized = False
00265                 
00266                 return 0
00267                         
00268         
00269         def stop(self):
00270                 '''
00271                         Creates and inits ROS components
00272                 '''
00273                 self.running = False
00274                 
00275                 return 0
00276         
00277         
00278         def start(self):
00279                 '''
00280                         Runs ROS configuration and the main control loop
00281                         @return: 0 if OK
00282                 '''
00283                 self.rosSetup()
00284                 
00285                 if self.running:
00286                         return 0
00287                         
00288                 self.running = True
00289                 
00290                 self.controlLoop()
00291                 
00292                 return 0
00293         
00294         
00295         def controlLoop(self):
00296                 '''
00297                         Main loop of the component
00298                         Manages actions by state
00299                 '''
00300                 
00301                 while self.running and not rospy.is_shutdown():
00302                         t1 = time.time()
00303                         
00304                         if self.state == State.INIT_STATE:
00305                                 self.initState()
00306                                 
00307                         elif self.state == State.STANDBY_STATE:
00308                                 self.standbyState()
00309                                 
00310                         elif self.state == State.READY_STATE:
00311                                 self.readyState()
00312                                 
00313                         elif self.state == State.EMERGENCY_STATE:
00314                                 self.emergencyState()
00315                                 
00316                         elif self.state == State.FAILURE_STATE:
00317                                 self.failureState()
00318                                 
00319                         elif self.state == State.SHUTDOWN_STATE:
00320                                 self.shutdownState()
00321                                 
00322                         self.allState()
00323                         
00324                         t2 = time.time()
00325                         tdiff = (t2 - t1)
00326                         
00327                         
00328                         t_sleep = self.time_sleep - tdiff
00329                         
00330                         if t_sleep > 0.0:
00331                                 
00332                                 rospy.sleep(t_sleep)
00333                         
00334                         t3= time.time()
00335                         self.real_freq = 1.0/(t3 - t1)
00336                 
00337                 self.running = False
00338                 
00339                 self.shutdownState()
00340                 
00341                 self.rosShutdown()
00342                 rospy.loginfo('%s::controlLoop: exit control loop'%rospy.get_name())
00343                 
00344                 return 0
00345                 
00346         
00347         
00348         def rosPublish(self):
00349                 '''
00350                         Publish topics at standard frequency
00351                 '''
00352                 
00353                 
00354                 
00355                 t = rospy.Time.now()
00356                 
00357                 self.joint_state.header.stamp = t
00358                 self._joints_publisher.publish(self.joint_state)
00359                 
00360                 if self.tactile_sensors:
00361                         self.msg_tact_array.header.stamp = t
00362                         self._tact_array_publisher.publish(self.msg_tact_array)
00363                         
00364                 return 0
00365                 
00366         
00367         
00368         def initState(self):
00369                 '''
00370                         Actions performed in init state
00371                 '''
00372                 error = 0
00373                 if not self.can_initialized:
00374                         ret = self.setup()
00375                         if ret == -1:
00376                                 error = 1
00377                                 
00378                 if self.hand_initialized and self.can_initialized:
00379                         self.switchToState(State.STANDBY_STATE)
00380                 
00381                 self.canError(error)
00382                 
00383                 return
00384         
00385         def standbyState(self):
00386                 '''
00387                         Actions performed in standby state
00388                 '''
00389                 
00390                 self.switchToState(State.READY_STATE)
00391                 
00392                 return
00393         
00394         
00395         def readyState(self):
00396                 '''
00397                         Actions performed in ready state
00398                 '''
00399                 f1_index = self.joint_names['F1'][1]
00400                 f2_index = self.joint_names['F2'][1]
00401                 f3_index = self.joint_names['F3'][1]
00402                 f1_tip_index = self.joint_names['F1_TIP'][1]
00403                 f2_tip_index = self.joint_names['F2_TIP'][1]
00404                 f3_tip_index = self.joint_names['F3_TIP'][1]
00405                 spread1_index = self.joint_names['SPREAD_1'][1]
00406                 spread2_index = self.joint_names['SPREAD_2'][1]
00407                 errors = 0
00408                 
00409                 
00410                 try:
00411                         
00412                         self.hand.read_packed_position(SPREAD)
00413                         self.hand.read_packed_position(FINGER1)
00414                         self.hand.read_packed_position(FINGER2)
00415                         self.hand.read_packed_position(FINGER3)
00416                         
00417                         
00418                         self.hand.read_strain(FINGER1)
00419                         self.hand.read_strain(FINGER2)
00420                         self.hand.read_strain(FINGER3)
00421                         
00422                         
00423                         if self.temp_command:
00424                                 self.hand.read_temp(FINGER1)
00425                                 self.hand.read_temp(FINGER2)
00426                                 self.hand.read_temp(FINGER3)
00427                                 self.hand.read_temp(SPREAD)
00428                                 self.hand.read_therm(FINGER1)
00429                                 self.hand.read_therm(FINGER2)
00430                                 self.hand.read_therm(FINGER3)
00431                                 self.hand.read_therm(SPREAD)
00432                                 self.initReadTempTimer()
00433                         
00434                         
00435                         if self.tactile_sensors:
00436                                 self.hand.read_full_tact(SPREAD)
00437                                 self.hand.read_full_tact(FINGER1)
00438                                 self.hand.read_full_tact(FINGER2)
00439                                 self.hand.read_full_tact(FINGER3)
00440                                 
00441                                 
00442                 except Exception, e:
00443                         rospy.logerr('%s::readyState: error getting info: %s'%(rospy.get_name(), e))
00444                         errors = errors + 1
00445                 
00446                 
00447                 if len(self.actions_list) > 0:
00448                         action = self.actions_list[0]
00449                         
00450                         self.actions_list.remove(action)
00451                         
00452                         
00453                         if self.control_mode == CONTROL_MODE_VELOCITY:
00454                                 self.setControlMode(CONTROL_MODE_POSITION)
00455                         
00456                         if action == Service.CLOSE_GRASP:
00457                                 self.closeFingers(3.14)
00458                         
00459                         if action == Service.CLOSE_HALF_GRASP:
00460                                 self.closeFingers(1.57)
00461                                 
00462                         elif action == Service.OPEN_GRASP:
00463                                 self.openFingers()
00464                                 
00465                         elif action == Service.SET_GRASP_1:
00466                                 if self.joint_state.position[f1_index] > 0.1 or self.joint_state.position[f2_index] > 0.1 or self.joint_state.position[f3_index] > 0.1:
00467                                         
00468                                         self.openFingers()
00469                                         time.sleep(2.0)
00470                                 
00471                                 self.desired_joints_position['SPREAD_1'] = 0.0
00472                                 self.desired_joints_position['SPREAD_2'] = 0.0
00473                                 self.hand.move_to(SPREAD, self.hand.rad_to_enc(self.desired_joints_position['SPREAD_1'], BASE_TYPE), False)
00474                                 self.grasp_mode = action
00475                                         
00476                         elif action == Service.SET_GRASP_2:
00477                                 if self.joint_state.position[f1_index] > 0.1 or self.joint_state.position[f2_index] > 0.1 or self.joint_state.position[f3_index] > 0.1:
00478                                         
00479                                         self.openFingers()
00480                                         time.sleep(2.0)
00481                                 
00482                                 self.desired_joints_position['SPREAD_1'] = 3.14
00483                                 self.desired_joints_position['SPREAD_2'] = 3.14
00484                                 self.hand.move_to(SPREAD, self.hand.rad_to_enc(self.desired_joints_position['SPREAD_1'], BASE_TYPE), False)
00485                                 self.grasp_mode = action
00486                         
00487                 
00488                 else: 
00489                         if self.control_mode == CONTROL_MODE_POSITION:
00490                         
00491                                 
00492                                 if self.new_command:
00493                                         try:
00494                                                 f1_joint = self.joint_names['F1'][0]            
00495                                                 if self.desired_joints_position[f1_joint] != self.joint_state.position[f1_index]:
00496                                                         
00497                                                         self.hand.move_to(FINGER1, self.hand.rad_to_enc(self.desired_joints_position[f1_joint], BASE_TYPE), False)
00498                                                 
00499                                                 f2_joint = self.joint_names['F2'][0]
00500                                                 if self.desired_joints_position[f2_joint] != self.joint_state.position[f2_index]:
00501                                                         
00502                                                         self.hand.move_to(FINGER2, self.hand.rad_to_enc(self.desired_joints_position[f2_joint], BASE_TYPE), False)
00503                                                         
00504                                                 f3_joint = self.joint_names['F3'][0]
00505                                                 if self.desired_joints_position[f3_joint] != self.joint_state.position[f3_index]:
00506                                                         
00507                                                         self.hand.move_to(FINGER3, self.hand.rad_to_enc(self.desired_joints_position[f3_joint], BASE_TYPE), False)
00508                                                         
00509                                                 spread1_joint = self.joint_names['SPREAD_1'][0]
00510                                                 spread2_joint = self.joint_names['SPREAD_2'][0]
00511                                                 if self.desired_joints_position[spread1_joint] != self.joint_state.position[spread1_index]:
00512                                                         
00513                                                         self.hand.move_to(SPREAD, self.hand.rad_to_enc(self.desired_joints_position[spread1_joint], SPREAD_TYPE), False)
00514                                                 elif self.desired_joints_position[spread2_joint] != self.joint_state.position[spread2_index]:
00515                                                         
00516                                                         self.hand.move_to(SPREAD, self.hand.rad_to_enc(self.desired_joints_position[spread2_joint], SPREAD_TYPE), False)
00517                                                 
00518                                         except Exception, e:
00519                                                 rospy.logerr('%s::readyState: error sending command: %s'%(rospy.get_name(), e))
00520                                                 errors = errors + 1
00521                                         
00522                                         self.new_command = False
00523                         
00524                         else:
00525                                 
00526                                 if ((time.time() - self.timer_command) >= self.watchdog_command):
00527                                         try:
00528                                                 
00529                                                 self.desired_joints_velocity[self.joint_names['F1'][0]] = 0.0
00530                                                 self.desired_joints_velocity[self.joint_names['F2'][0]] = 0.0
00531                                                 self.desired_joints_velocity[self.joint_names['F3'][0]] = 0.0
00532                                                 self.desired_joints_velocity[self.joint_names['SPREAD_1'][0]] = 0.0
00533                                                 self.desired_joints_velocity[self.joint_names['SPREAD_2'][0]] = 0.0
00534                                                 self.setJointVelocity('F1')
00535                                                 self.setJointVelocity('F2')
00536                                                 self.setJointVelocity('F3')
00537                                                 self.setJointVelocity('SPREAD_1')
00538                                         except Exception, e:
00539                                                 rospy.logerr('%s::readyState: error sending command: %s'%(rospy.get_name(), e))
00540                                                 errors = errors + 1
00541                                 
00542                                 if self.new_command:
00543                         
00544                                         try:
00545                                                 self.setJointVelocity('F1')
00546                                                 self.setJointVelocity('F2')
00547                                                 self.setJointVelocity('F3')
00548                                                 self.setJointVelocity('SPREAD_1')
00549                                                 
00550                                                 
00551                                         except Exception, e:
00552                                                 rospy.logerr('%s::readyState: error sending command: %s'%(rospy.get_name(), e))
00553                                                 errors = errors + 1
00554                                         
00555                                         self.new_command = False
00556                         
00557                 time.sleep(0.002)
00558                 
00559                 
00560                 if self.hand.process_can_messages() != 0:
00561                         
00562                         self.canError(1)
00563                 
00564                 
00565                 
00566                 self.joint_state.position[f1_index], self.joint_state.position[f1_tip_index] = self.hand.get_packed_position(FINGER1)
00567                 self.joint_state.position[f2_index], self.joint_state.position[f2_tip_index] = self.hand.get_packed_position(FINGER2)
00568                 self.joint_state.position[f3_index], self.joint_state.position[f3_tip_index] = self.hand.get_packed_position(FINGER3)
00569                 self.joint_state.position[spread1_index], e = self.hand.get_packed_position(SPREAD)
00570                 self.joint_state.position[spread2_index] = self.joint_state.position[spread1_index]
00571                 
00572                 
00573                 self.joint_state.effort[f1_index] = self.joint_state.effort[f1_tip_index] = self.strain_to_nm(self.hand.get_strain(FINGER1))
00574                 self.joint_state.effort[f2_index] = self.joint_state.effort[f2_tip_index] = self.strain_to_nm(self.hand.get_strain(FINGER2))
00575                 self.joint_state.effort[f3_index] = self.joint_state.effort[f3_tip_index] = self.strain_to_nm(self.hand.get_strain(FINGER3))
00576                 
00577                 
00578                 self.msg_state.temp_f1[1] = self.hand.get_temp(FINGER1)
00579                 self.msg_state.temp_f2[1] = self.hand.get_temp(FINGER2)
00580                 self.msg_state.temp_f3[1] = self.hand.get_temp(FINGER3)
00581                 self.msg_state.temp_spread[1] = self.hand.get_temp(SPREAD)
00582                 self.msg_state.temp_f1[0] = self.hand.get_therm(FINGER1)
00583                 self.msg_state.temp_f2[0] = self.hand.get_therm(FINGER2)
00584                 self.msg_state.temp_f3[0] = self.hand.get_therm(FINGER3)
00585                 self.msg_state.temp_spread[0] = self.hand.get_therm(SPREAD)
00586                 
00587                 
00588                 self.msg_tact_array.finger1 = self.hand.get_full_tact(FINGER1)
00589                 self.msg_tact_array.finger2 = self.hand.get_full_tact(FINGER2)
00590                 self.msg_tact_array.finger3 = self.hand.get_full_tact(FINGER3)
00591                 self.msg_tact_array.palm = self.hand.get_full_tact(SPREAD)
00592                 
00593                 '''     e21, e22 = self.hand.get_packed_position(FINGER2, 1)
00594                         e31, e32 = self.hand.get_packed_position(FINGER3, 1)
00595                         espread, e_ = self.hand.get_packed_position(SPREAD, 1)
00596                         
00597                         self.joint_state.position[f2_index] = self.hand.enc_to_rad(e21, BASE_TYPE)
00598                         self.joint_state.position[f2_tip_index] = self.hand.enc_to_rad(e22, TIP_TYPE)
00599                         self.joint_state.position[f3_index] = self.hand.enc_to_rad(e31, BASE_TYPE)
00600                         self.joint_state.position[f3_tip_index] = self.hand.enc_to_rad(e32, TIP_TYPE)
00601                         self.joint_state.position[spread1_index] = self.joint_state.position[spread2_index] = self.hand.enc_to_rad(espread, SPREAD_TYPE)
00602                 '''
00603                 
00604                 
00605                 self.canError(errors)
00606                 
00607                 return
00608         
00609         
00610         def setJointVelocity(self, finger):
00611                 '''
00612                         Sets the joint velocity of the desired joint
00613                         Takes the velocity value from the attribute desired_joints_velocity
00614                         @param joint: finger of the hand (F1, F2, F3, SPREAD)
00615                         @type joint: string
00616                 '''
00617                 if self.joint_names.has_key(finger):
00618                         joint = self.joint_names[finger][0]     
00619                                                 
00620                         if self.desired_joints_velocity[joint] != self.sent_joints_velocity[joint]:
00621                                         
00622                                 value = self.hand.rad_to_enc(self.desired_joints_velocity[joint], BASE_TYPE) / 1000
00623                                 self.sent_joints_velocity[joint] = self.desired_joints_velocity[joint]  
00624                                 
00625                                 
00626                                 if finger == 'F1':
00627                                         self.hand.set_velocity(FINGER1, value)
00628                                 elif finger == 'F2':
00629                                         self.hand.set_velocity(FINGER2, value)
00630                                 elif finger == 'F3':
00631                                         self.hand.set_velocity(FINGER3, value)
00632                                 elif finger == 'SPREAD_1' or finger == 'SPREAD_2':
00633                                         self.hand.set_velocity(SPREAD, value)
00634                                                 
00635         
00636         def shutdownState(self):
00637                 '''
00638                         Actions performed in shutdown state 
00639                 '''
00640                 print 'shutdownState'
00641                 if self.shutdown() == 0:
00642                         self.switchToState(State.INIT_STATE)
00643                 
00644                 return
00645         
00646         def emergencyState(self):
00647                 '''
00648                         Actions performed in emergency state
00649                 '''
00650                 
00651                 return
00652         
00653         def failureState(self):
00654                 '''
00655                         Actions performed in failure state
00656                 '''
00657                 if self.failure_recover:
00658                         
00659                         self.hand.can_uninit()
00660                         self.can_initialized = False
00661                         self.switchToState(State.INIT_STATE)
00662                         self.failure_recover = False
00663                         self.can_errors = 0
00664                         
00665                 return
00666         
00667         def switchToState(self, new_state):
00668                 '''
00669                         Performs the change of state
00670                 '''
00671                 if self.state != new_state:
00672                         self.state = new_state
00673                         rospy.loginfo('BHand::switchToState: %s', self.stateToString(self.state))
00674                         
00675                         if self.state == State.READY_STATE:
00676                                 
00677                                 self.time_sleep = 1.0 / self.desired_freq
00678                                 self.initReadTempTimer()
00679                         elif self.state == State.FAILURE_STATE:
00680                                 
00681                                 self.time_sleep = 1.0
00682                                 self.initFailureRecoverTimer(self.failure_recover_timer)
00683                         else:
00684                                 
00685                                 self.time_sleep = 1.0
00686                 
00687                 return
00688                 
00689         def allState(self):
00690                 '''
00691                         Actions performed in all states
00692                 '''
00693                 self.rosPublish()
00694                 
00695                 return
00696         
00697         
00698         def stateToString(self, state):
00699                 '''
00700                         @param state: state to convert
00701                         @type state: bhand_controller.msg.State
00702                         @returns the equivalent string of the state
00703                 '''
00704                 if state == State.INIT_STATE:
00705                         return 'INIT_STATE'
00706                                 
00707                 elif state == State.STANDBY_STATE:
00708                         return 'STANDBY_STATE'
00709                         
00710                 elif state == State.READY_STATE:
00711                         return 'READY_STATE'
00712                         
00713                 elif state == State.EMERGENCY_STATE:
00714                         return 'EMERGENCY_STATE'
00715                         
00716                 elif state == State.FAILURE_STATE:
00717                         return 'FAILURE_STATE'
00718                         
00719                 elif state == State.SHUTDOWN_STATE:
00720                         return 'SHUTDOWN_STATE'
00721                 else:
00722                         return 'UNKNOWN_STATE'
00723         
00724         
00725         def actionsToString(self, action):
00726                 '''
00727                         @param action: action to convert
00728                         @type state: bhand_controller.msg.Service
00729                         @returns the equivalent string of the action
00730                 '''
00731                 if action == Service.INIT_HAND:
00732                         return 'INIT_HAND'
00733                                 
00734                 elif action == Service.CLOSE_GRASP:
00735                         return 'CLOSE_GRASP'
00736                         
00737                 elif action == Service.OPEN_GRASP:
00738                         return 'OPEN_GRASP'
00739                         
00740                 elif action == Service.SET_GRASP_1:
00741                         return 'SET_GRASP_1'
00742                         
00743                 elif action == Service.SET_GRASP_2:
00744                         return 'SET_GRASP_2'
00745                 
00746                 elif action == Service.CLOSE_HALF_GRASP:
00747                         return 'CLOSE_HALF_GRASP'
00748                         
00749                 else:
00750                         return 'UNKNOWN_ACTION'
00751         
00752         
00753         def commandCallback(self, data):
00754                 '''
00755                         Function called when receive a new value
00756                         @param data: state to convert
00757                         @type data: sensor_msgs.JointState
00758                 '''
00759                 bingo = False
00760                 
00761                 for i in range(len(data.name)):
00762                         if self.desired_joints_position.has_key(data.name[i]):
00763                                 self.desired_joints_position[data.name[i]] = data.position[i]
00764                                 self.desired_joints_velocity[data.name[i]] = data.velocity[i]
00765                                 bingo = True
00766                                 
00767                 
00768                 if bingo:
00769                         self.new_command = True
00770                         self.timer_command = time.time()
00771                 
00772         
00773         
00774         def readTemp(self):
00775                 '''
00776                         Function periodically to enable the read of temperature
00777                 '''
00778                 
00779                 self.temp_current_sensor = self.temp_current_sensor + 1
00780                 
00781                 if self.temp_current_sensor > self.temp_sensor_number:
00782                         self.temp_current_sensor = 1
00783                 
00784                 self.temp_command = True
00785                 
00786                 
00787         def initReadTempTimer(self):
00788                 '''
00789                         Function to start the timer to read the temperature
00790                 '''
00791                 self.temp_command = False
00792                 
00793                 self.t_read_temp = threading.Timer(self.temp_read_timer, self.readTemp)
00794                 self.t_read_temp.start()
00795         
00796                 
00797         def publishROSstate(self):
00798                 '''
00799                         Publish the State of the component at the desired frequency
00800                 '''
00801                 self.msg_state.state = self.state
00802                 self.msg_state.state_description = self.stateToString(self.state)
00803                 self.msg_state.desired_freq = self.desired_freq
00804                 self.msg_state.real_freq = self.real_freq
00805                 self.msg_state.hand_initialized = self.hand_initialized 
00806                 self.msg_state.control_mode = self.control_mode 
00807                 self._state_publisher.publish(self.msg_state)
00808                 
00809                 self.t_publish_state = threading.Timer(self.publish_state_timer, self.publishROSstate)
00810                 self.t_publish_state.start()
00811         
00812         
00813         def strain_to_nm(self, x):
00814                 '''
00815                 Converts from raw encoder unit reading to Newton-meters.
00816 
00817                 @param x: value to convert
00818 
00819                 @returns nm: the torque value in Newton-meters. 
00820                 '''
00821                 p1 = 2.754e-10
00822                 p2 = -1.708e-06
00823                 p3 = 0.003764
00824                 p4 = -2.85
00825                 nm= p1*x**3 + p2*x**2 + p3*x + p4
00826                 
00827                 return nm
00828                 
00829                 
00830         def handActions(self, req):
00831                 '''
00832                 Handles the callback to Actions ROS service. Allows a set of predefined actions like init_hand, close_grasp, ...
00833 
00834                 @param req: action id to perform
00835                 @type req: bhand_controller.srv.Actions
00836 
00837                 @returns: True or false depending on the result
00838                 '''
00839                 if req.action == Service.INIT_HAND:
00840                         if self.state != State.INIT_STATE:
00841                                 rospy.logerr('%s::handActions: action INIT_HAND not allowed in state %s'%(rospy.get_name() ,self.stateToString(self.state)))
00842                                 
00843                                 return False
00844                         else:
00845                                 ret = self.hand.init_hand()
00846                                 if ret:
00847                                         self.hand_initialized = True
00848                                         rospy.loginfo('%s::handActions: INIT HAND service OK'%rospy.get_name() )
00849                                         return True
00850                                 else:
00851                                         rospy.logerr('%s::handActions: error on INIT_HAND service'%rospy.get_name() )
00852                                         
00853                                         self.canError(self.max_can_errors + 1)
00854                                         return False
00855                         
00856                 if self.state != State.READY_STATE:
00857                         rospy.logerr('%s::handActions: action not allowed in state %s'%(rospy.get_name(), self.stateToString(self.state)))
00858                         return False
00859                 else:
00860                         rospy.loginfo('%s::handActions: Received new action %s'%(rospy.get_name(), self.actionsToString(req.action)))
00861                         self.actions_list.append(req.action)
00862                         
00863                 return True
00864 
00865 
00866         def canError(self, n):
00867                 '''
00868                 Manages the CAN errors ocurred
00869 
00870                 @param n: number of produced
00871                 @type n: int
00872 
00873                 @returns: True or false depending on the result
00874                 '''
00875                 
00876                 self.can_errors = self.can_errors + n   
00877                 
00878                 
00879                 
00880                 if self.can_errors > self.max_can_errors:
00881                         rospy.logerr('%s::canError: Errors on CAN bus'%rospy.get_name())
00882                         self.switchToState(State.FAILURE_STATE)
00883         
00884         
00885         def initFailureRecoverTimer(self, timer = 5):
00886                 '''
00887                         Function to start the timer to recover from FAILURE STATE
00888                 '''
00889                 t = threading.Timer(timer, self.failureRecover)
00890                 t.start()
00891         
00892                 
00893         def failureRecover(self):               
00894                 '''
00895                         Sets the recovery flag TRUE. Function called after timer
00896                 '''
00897                 self.failure_recover = True
00898         
00899         
00900         def setControlModeServiceCb(self, req):
00901                 '''
00902                         Sets the hand control mode
00903                         @param req: Requested service
00904                         @type req: bhand_controller.srv.SetControlMode
00905                 '''
00906                 if self.state != State.READY_STATE:
00907                         rospy.logerr('%s:setControlModeServiceCb: bhand is not in a valid state to change the mode'%rospy.get_name() )
00908                         return False
00909                         
00910                 if req.mode != CONTROL_MODE_POSITION and req.mode != CONTROL_MODE_VELOCITY:
00911                         rospy.logerr('%s:setControlModeServiceCb: invalid control mode %s'%(rospy.get_name(), req.mode))
00912                         return False
00913                         
00914                 else:
00915                         if self.setControlMode(req.mode):
00916                                 rospy.loginfo('%s:setControlModeServiceCb: control mode %s set successfully'%(rospy.get_name(), req.mode))
00917                                 return True
00918                                 
00919                         else:
00920                                 return False
00921         
00922         
00923         def setControlMode(self, mode):         
00924                 '''
00925                         Configures the hand to work under the desired control mode
00926                         @param mode: new mode
00927                         @type mode: string
00928                 '''
00929                 if self.control_mode == mode:
00930                         return True
00931                                 
00932                 if mode == CONTROL_MODE_POSITION:
00933                         self.hand.set_mode(HAND_GROUP, 'IDLE')
00934                         
00935                         
00936                 elif mode == CONTROL_MODE_VELOCITY:
00937                         self.hand.set_mode(HAND_GROUP, 'VEL')
00938                         
00939                 self.control_mode = mode
00940         
00941         
00942         def openFingers(self):
00943                 '''
00944                         Opens all the fingers
00945                 '''             
00946                 self.desired_joints_position['F1'] = 0.0
00947                 self.desired_joints_position['F2'] = 0.0
00948                 self.desired_joints_position['F3'] = 0.0
00949                 self.hand.move_to(FINGER1, self.hand.rad_to_enc(self.desired_joints_position['F1'], BASE_TYPE), False)
00950                 self.hand.move_to(FINGER2, self.hand.rad_to_enc(self.desired_joints_position['F2'], BASE_TYPE), False)
00951                 self.hand.move_to(FINGER3, self.hand.rad_to_enc(self.desired_joints_position['F3'], BASE_TYPE), False)
00952                                 
00953         
00954         def closeFingers(self, value):
00955                 '''
00956                         Closes all the fingers
00957                 '''             
00958                 self.desired_joints_position['F1'] = value
00959                 self.desired_joints_position['F2'] = value
00960                 self.desired_joints_position['F3'] = value
00961                 self.hand.move_to(FINGER1, self.hand.rad_to_enc(self.desired_joints_position['F1'], BASE_TYPE), False)
00962                 self.hand.move_to(FINGER2, self.hand.rad_to_enc(self.desired_joints_position['F2'], BASE_TYPE), False)
00963                 self.hand.move_to(FINGER3, self.hand.rad_to_enc(self.desired_joints_position['F3'], BASE_TYPE), False)
00964                 
00965                 
00966                 
00967 def main():
00968 
00969         rospy.init_node("bhand_node")
00970         
00971         
00972         _name = rospy.get_name()
00973         
00974         arg_defaults = {
00975           'port':  '/dev/pcan32',
00976           'topic_state': 'state',
00977           'desired_freq': DEFAULT_FREQ,
00978           'tactile_sensors': True,
00979           'control_mode': 'POSITION',
00980           'joint_ids': [ 'F1', 'F1_TIP', 'F2', 'F2_TIP', 'F3', 'F3_TIP', 'SPREAD_1', 'SPREAD_2'],
00981           'joint_names': ['bh_j12_joint', 'bh_j13_joint', 'bh_j22_joint', 'bh_j23_joint', 'bh_j32_joint', 'bh_j31_joint', 'bh_j11_joint', 'bh_j21_joint']
00982         }
00983         
00984         args = {}
00985         
00986         for name in arg_defaults:
00987                 try:
00988                         if rospy.search_param(name): 
00989                                 args[name] = rospy.get_param('%s/%s'%(_name, name)) 
00990                         else:
00991                                 args[name] = arg_defaults[name]
00992                         
00993                 except rospy.ROSException, e:
00994                         rospy.logerror('bhand_node: %s'%e)
00995                         
00996         
00997         bhand_node = BHand(args)
00998         
00999         rospy.loginfo('bhand_node: starting')
01000 
01001         bhand_node.start()
01002 
01003 
01004 if __name__ == "__main__":
01005         main()