$search
00001 #! /usr/bin/env python 00002 # Copyright (c) 2008, Willow Garage, Inc. 00003 # All rights reserved. 00004 # 00005 # Redistribution and use in source and binary forms, with or without 00006 # modification, are permitted provided that the following conditions are met: 00007 # 00008 # * Redistributions of source code must retain the above copyright 00009 # notice, this list of conditions and the following disclaimer. 00010 # * Redistributions in binary form must reproduce the above copyright 00011 # notice, this list of conditions and the following disclaimer in the 00012 # documentation and/or other materials provided with the distribution. 00013 # * Neither the name of the Willow Garage, Inc. nor the names of its 00014 # contributors may be used to endorse or promote products derived from 00015 # this software without specific prior written permission. 00016 # 00017 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00018 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00021 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00022 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00023 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00025 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00026 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00027 # POSSIBILITY OF SUCH DAMAGE. 00028 00029 # Author: Jon Scholz 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 #from pr2_controllers_msgs.msg import * 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 # call parent to set up goal topics and load params and stuff 00057 articulateCartServer.__init__(self, use_tf_grippers, use_gripper_midpoint, tf_object_name) 00058 00059 # a tf broadcaster for spoofing gripper poses 00060 rospy.loginfo("Creating a tf broadcaster") 00061 self._tb = tf.TransformBroadcaster() 00062 00063 ## Initialize gripper poses from cart initial pose (for update loop) 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 # start main update loop 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 # send gripper poses to tf 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) # 1hz should be sufficient for this 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()