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 PKG="articulate_cart"
00032 import roslib; roslib.load_manifest(PKG)
00033 import rospy
00034 import tf
00035 import thread
00036 
00037 from articulate_cart_server import articulateCartServer
00038 from manipulation_transforms.srv import *
00039 
00040 from std_msgs.msg import *
00041 from geometry_msgs.msg import *
00042 
00043 from math import pi, pow, atan, sin, cos, sqrt
00044 import exceptions, sys
00045 
00046 class fakeArticulateCartServer(articulateCartServer):
00047   """ A fake version of the articulate_cart server which allows us to run the 
00048 cart_pushing task in stage (real runs require cart pose estimates from 
00049 either the checkerboard or the arms).  To do this, we present the same
00050 interface as the regular articulate_cart server, but rather than talking
00051 to the arms, we just use the solver to give us target poses for the grippers
00052 and write them directly to tf.
00053   """
00054 
00055   def __init__(self, use_tf_grippers, use_gripper_midpoint, tf_object_name):
00056     
00057     articulateCartServer.__init__(self, use_tf_grippers, use_gripper_midpoint, tf_object_name)
00058 
00059     
00060     rospy.loginfo("Creating a tf broadcaster")
00061     self._tb = tf.TransformBroadcaster()
00062 
00063     
00064     rospy.loginfo("Initializing gripper poses from cart initial pose")
00065     try:
00066       self._pose_resp = self._cartPoseToGrippers_srv(self._cart_pose_msg)
00067     except rospy.ServiceException, e:
00068       print "Service did not process request: %s"%str(e)
00069 
00070     rospy.loginfo("Successfully initialized gripper poses")    
00071     
00072     rospy.loginfo("starting thread for tf update")
00073     thread.start_new_thread(self._slow_tf_update_loop, ())
00074     rospy.loginfo("Fake Articulate Cart Server initialization complete!")
00075 
00076   def send_effector_poses_to_tf(self):
00077      
00078     if len(self._pose_resp.effector_poses) != 2:
00079       rospy.logerr("Expected 2 gripper poses but got %d" % len(self._pose_resp.effector_poses))
00080     else:
00081       self._tb.sendTransform((self._pose_resp.effector_poses[0].pose.position.x,
00082                               self._pose_resp.effector_poses[0].pose.position.y,
00083                               self._pose_resp.effector_poses[0].pose.position.z),
00084                              (self._pose_resp.effector_poses[0].pose.orientation.x,
00085                               self._pose_resp.effector_poses[0].pose.orientation.y,
00086                               self._pose_resp.effector_poses[0].pose.orientation.z,
00087                               self._pose_resp.effector_poses[0].pose.orientation.w),
00088                              rospy.get_rostime(),
00089                              'r_gripper_tool_frame',
00090                              'base_footprint')
00091 
00092       self._tb.sendTransform((self._pose_resp.effector_poses[1].pose.position.x,
00093                               self._pose_resp.effector_poses[1].pose.position.y,
00094                               self._pose_resp.effector_poses[1].pose.position.z),
00095                              (self._pose_resp.effector_poses[1].pose.orientation.x,
00096                               self._pose_resp.effector_poses[1].pose.orientation.y,
00097                               self._pose_resp.effector_poses[1].pose.orientation.z,
00098                               self._pose_resp.effector_poses[1].pose.orientation.w),
00099                              rospy.get_rostime(),
00100                              'l_gripper_tool_frame',
00101                              'base_footprint')
00102 
00103   def _pose_command_action(self):
00104     """Send the target effector poses to the arm control topics"""
00105     if len(self._pose_resp.effector_poses) != 2:
00106       rospy.logerr("Expected 2 gripper poses, but got %d" % len(self._pose_resp.effector_poses))
00107     else:
00108         self.send_effector_poses_to_tf()
00109 
00110   def _slow_tf_update_loop(self, r = 3):
00111       try:
00112           rate = rospy.Rate(r) 
00113           while not rospy.is_shutdown():
00114             with self._pose_mutex:
00115               self.send_effector_poses_to_tf()
00116             rate.sleep()
00117       except (exceptions.AttributeError) as e:
00118           print e
00119           raise e
00120       except:
00121           print "Unexpected error:", sys.exc_info()[0]
00122           raise
00123 
00124 if __name__ == '__main__':
00125     from optparse import OptionParser
00126     parser = OptionParser()
00127     parser.add_option("-g", action="store_true", dest="use_tf_grippers", default=False,
00128                       help="use current gripper poses for initial grasp transforms (otherwise leaves defaults from param server)")
00129     parser.add_option("-m", "--midpoint", action="store_true", dest="midpoint", default=False,
00130                       help="set object initial pose to midpoint between grippers [default=%default]")
00131     parser.add_option("-o", "--object", dest="object", default="",
00132                       help="attempt to load an initial object transform with name OBJECT from tf [default=\"%default\"]")
00133     parser.add_option("-f", "--fake-twist-controller", dest="fake_twist_controller", default=True,
00134                       help="use the fake twist message callback, which simulates twists with pose messages [default=\"%default\"]")
00135     (options, args) = parser.parse_args()
00136     
00137     rospy.init_node("fake"+PKG+"_server")
00138     server = fakeArticulateCartServer(options.use_tf_grippers, options.midpoint, options.object)
00139     rospy.spin()