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()