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 import roslib; roslib.load_manifest('sr_example')
00029 import rospy
00030
00031 import time, mutex, subprocess, math
00032
00033 from sr_robot_msgs.msg import sendupdate, joint, Biotac, BiotacAll, ShadowPST
00034 from sensor_msgs.msg import *
00035 from std_msgs.msg import Float64
00036
00037
00038 PDC_THRESHOLD = 2000
00039
00040 PST_THRESHOLD = 400
00041
00042 class FancyDemo(object):
00043
00044
00045
00046 controller_type = "_position_controller"
00047
00048
00049 start_pos_hand = { "THJ1":21,
00050 "THJ2":25,
00051 "THJ3":0,
00052 "THJ4":50,
00053 "THJ5":-6,
00054 "FFJ0":180,
00055 "FFJ3":90,
00056 "FFJ4":0,
00057 "MFJ0":180,
00058 "MFJ3":90,
00059 "MFJ4":0,
00060 "RFJ0":180,
00061 "RFJ3":90,
00062 "RFJ4":0,
00063 "LFJ0":180,
00064 "LFJ3":90,
00065 "LFJ4":0,
00066 "LFJ5":0,
00067 "WRJ1":0,
00068 "WRJ2":0 }
00069
00070 extended_pos_hand = { "THJ1":0,
00071 "THJ2":0,
00072 "THJ3":0,
00073 "THJ4":0,
00074 "THJ5":-6,
00075 "FFJ0":0,
00076 "FFJ3":0,
00077 "FFJ4":0,
00078 "MFJ0":0,
00079 "MFJ3":0,
00080 "MFJ4":0,
00081 "RFJ0":0,
00082 "RFJ3":0,
00083 "RFJ4":0,
00084 "LFJ0":0,
00085 "LFJ3":0,
00086 "LFJ4":0,
00087 "LFJ5":0,
00088 "WRJ1":0,
00089 "WRJ2":0 }
00090
00091
00092 thumb_up_pos_hand = { "THJ1":0,
00093 "THJ2":0,
00094 "THJ3":0,
00095 "THJ4":0,
00096 "THJ5":0,
00097 "FFJ0":180,
00098 "FFJ3":90,
00099 "FFJ4":0,
00100 "MFJ0":180,
00101 "MFJ3":90,
00102 "MFJ4":0,
00103 "RFJ0":180,
00104 "RFJ3":90,
00105 "RFJ4":0,
00106 "LFJ0":180,
00107 "LFJ3":90,
00108 "LFJ4":0,
00109 "LFJ5":0,
00110 "WRJ1":0,
00111 "WRJ2":10 }
00112
00113
00114 start_pos_arm = [ joint(joint_name = "ElbowJRotate", joint_target = 0),
00115 joint(joint_name = "ElbowJSwing", joint_target = 59),
00116 joint(joint_name = "ShoulderJRotate", joint_target = 0),
00117 joint(joint_name = "ShoulderJSwing", joint_target = 33)
00118 ]
00119
00120
00121
00122
00123 arm_publisher = rospy.Publisher('/sr_arm/sendupdate', sendupdate)
00124
00125
00126
00127 action_running = mutex.mutex()
00128
00129 def __init__(self):
00130
00131
00132 self.fingers_pressed_functions = [self.ff_pressed, self.mf_pressed, self.rf_pressed,
00133 self.lf_pressed, self.th_pressed]
00134
00135
00136
00137
00138 self.hand_publishers = self.create_hand_publishers()
00139
00140
00141 self.hand_publish(self.start_pos_hand)
00142
00143 self.arm_publisher.publish( sendupdate(len(self.start_pos_arm), self.start_pos_arm) )
00144
00145
00146 time.sleep(1)
00147 rospy.loginfo("OK, ready for the demo")
00148
00149
00150 self.sub_biotacs = rospy.Subscriber("tactiles", BiotacAll, self.callback_biotacs, queue_size=1)
00151 self.sub_psts = rospy.Subscriber("tactile", ShadowPST, self.callback_psts, queue_size=1)
00152
00153 def create_hand_publishers(self):
00154 """
00155 Creates a dictionnary of publishers to send the targets to the controllers
00156 on /sh_??j?_position_controller/command
00157 """
00158 hand_pub = {}
00159
00160 for joint in ["FFJ0", "FFJ3", "FFJ4",
00161 "MFJ0", "MFJ3", "MFJ4",
00162 "RFJ0", "RFJ3", "RFJ4",
00163 "LFJ0", "LFJ3", "LFJ4", "LFJ5",
00164 "THJ1", "THJ2", "THJ3", "THJ4", "THJ5",
00165 "WRJ1", "WRJ2" ]:
00166 hand_pub[joint] = rospy.Publisher('sh_'+joint.lower() + self.controller_type + '/command', Float64, latch=True)
00167
00168 return hand_pub
00169
00170 def hand_publish(self, pose):
00171 """
00172 Publishes the given pose to the correct controllers for the hand.
00173 The targets are converted in radians.
00174 """
00175 for joint, pos in pose.iteritems():
00176 self.hand_publishers[joint].publish( math.radians(pos) )
00177
00178 def callback_biotacs(self, msg):
00179 """
00180 The callback function for the biotacs. Checks if one of the fingers
00181 was pressed (filter the noise). If it is the case, call the
00182 corresponding function.
00183
00184 @msg is the message containing the biotac data
00185 """
00186
00187 for index,tactile in enumerate(msg.tactiles):
00188
00189
00190
00191
00192 if tactile.pdc >= PDC_THRESHOLD:
00193
00194
00195 self.fingers_pressed_functions[index](tactile.pdc)
00196
00197 def callback_psts(self, msg):
00198 """
00199 The callback function for the PSTs. Checks if one of the fingers
00200 was pressed (filter the noise). If it is the case, call the
00201 corresponding function.
00202
00203 @msg is the message containing the biotac data
00204 """
00205
00206 for index,tactile in enumerate(msg.pressure):
00207
00208
00209
00210 if tactile >= PST_THRESHOLD and tactile != 18456:
00211
00212
00213 self.fingers_pressed_functions[index](tactile)
00214
00215 def ff_pressed(self,data):
00216 """
00217 The first finger was pressed.
00218
00219 If no action is currently running, we set the ShoulderJRotate
00220 to a negative value proportional to the pressure received.
00221
00222 @param data: the pressure value (pdc)
00223 """
00224
00225 if not self.action_running.testandset():
00226 return
00227
00228
00229 p = subprocess.Popen('beep')
00230
00231
00232
00233 data /= 4000.
00234 if data > 1.:
00235 data = 1.
00236 target_sh_rot = 0. + data * (-45.0)
00237 target_sh_swing = 20. + data * (-10.0)
00238 target_elb_swing = 90. + data * (-10.0)
00239 target_elb_rot = 0. + data * (-45.0)
00240
00241 rospy.loginfo("FF touched, going to new target ")
00242
00243
00244 time.sleep(.2)
00245 message = [joint(joint_name = "ShoulderJRotate", joint_target = target_sh_rot),
00246 joint(joint_name = "ShoulderJSwing", joint_target = target_sh_swing),
00247 joint(joint_name = "ElbowJRotate", joint_target = target_elb_rot),
00248 joint(joint_name = "ElbowJSwing", joint_target = target_elb_swing)
00249 ]
00250
00251 self.arm_publisher.publish(sendupdate(len(message), message))
00252
00253
00254 self.hand_publish( self.extended_pos_hand )
00255
00256
00257 time.sleep(.2)
00258 self.action_running.unlock()
00259
00260 def mf_pressed(self, data):
00261 """
00262 The middle finger was pressed.
00263
00264 If no action is currently running, we move the arm angles
00265 to a positive value proportional to the pressure received.
00266
00267 @param data: the pressure value (pdc)
00268 """
00269
00270 if not self.action_running.testandset():
00271 return
00272
00273
00274 p = subprocess.Popen('beep')
00275
00276
00277
00278 data /= 4000.
00279 if data > 1.:
00280 data = 1.
00281 target_sh_rot = 0. + data * (45.0)
00282 target_sh_swing = 20. + data * (20.0)
00283 target_elb_swing = 90. + data * (20.0)
00284 target_elb_rot = 0. + data * (45.0)
00285
00286 rospy.loginfo("MF touched, going to new target ")
00287
00288
00289 time.sleep(.2)
00290 message = [joint(joint_name = "ShoulderJRotate", joint_target = target_sh_rot),
00291 joint(joint_name = "ShoulderJSwing", joint_target = target_sh_swing),
00292 joint(joint_name = "ElbowJRotate", joint_target = target_elb_rot),
00293 joint(joint_name = "ElbowJSwing", joint_target = target_elb_swing)
00294 ]
00295
00296 self.arm_publisher.publish(sendupdate(len(message), message))
00297
00298
00299 time.sleep(.2)
00300 self.action_running.unlock()
00301
00302
00303 def rf_pressed(self, data):
00304 """
00305 The ring finger was pressed.
00306
00307 If no action is currently running, we make a beep
00308 but don't do anything else.
00309
00310 @param data: the pressure value (pdc)
00311 """
00312
00313 if not self.action_running.testandset():
00314 return
00315
00316
00317 p = subprocess.Popen('beep')
00318
00319 rospy.loginfo("RF touched, not doing anything.")
00320
00321
00322 time.sleep(.2)
00323 self.action_running.unlock()
00324
00325 def lf_pressed(self, data):
00326 """
00327 The little finger was pressed.
00328
00329 If no action is currently running, we reset the arm and
00330 hand to their starting position
00331
00332 @param data: the pressure value (pdc)
00333 """
00334
00335 if not self.action_running.testandset():
00336 return
00337
00338
00339 p = subprocess.Popen('beep')
00340
00341 rospy.loginfo("LF touched, going to start position.")
00342
00343
00344 time.sleep(.2)
00345
00346
00347 self.hand_publish( self.start_pos_hand )
00348
00349 self.arm_publisher.publish(sendupdate(len(self.start_pos_arm), self.start_pos_arm))
00350
00351
00352 time.sleep(.2)
00353 self.action_running.unlock()
00354
00355 def th_pressed(self, data):
00356 """
00357 The thumb was pressed.
00358
00359 If no action is currently running, we send the thumb_up
00360 targets to the hand.
00361
00362 @param data: the pressure value (pdc)
00363 """
00364
00365 if not self.action_running.testandset():
00366 return
00367
00368
00369 p = subprocess.Popen('beep')
00370
00371 rospy.loginfo("TH touched, going to thumb up position.")
00372
00373
00374 time.sleep(.2)
00375
00376
00377 self.hand_publish( self.thumb_up_pos_hand )
00378
00379
00380 time.sleep(.2)
00381 self.action_running.unlock()
00382
00383 def main():
00384 """
00385 The main function
00386 """
00387
00388 rospy.init_node('fancy_touch_demo', anonymous=True)
00389
00390 fancy_demo = FancyDemo()
00391
00392
00393 rospy.spin()
00394
00395
00396 if __name__ == '__main__':
00397 main()
00398