pr2_drive_life_test.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 #
00003 # Software License Agreement (BSD License)
00004 #
00005 # Copyright (c) 2010, Willow Garage, Inc.
00006 # All rights reserved.
00007 #
00008 # Redistribution and use in source and binary forms, with or without
00009 # modification, are permitted provided that the following conditions
00010 # are met:
00011 #
00012 #  * Redistributions of source code must retain the above copyright
00013 #    notice, this list of conditions and the following disclaimer.
00014 #  * Redistributions in binary form must reproduce the above
00015 #    copyright notice, this list of conditions and the following
00016 #    disclaimer in the documentation and/or other materials provided
00017 #    with the distribution.
00018 #  * Neither the name of the Willow Garage nor the names of its
00019 #    contributors may be used to endorse or promote products derived
00020 #    from this software without specific prior written permission.
00021 #
00022 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033 # POSSIBILITY OF SUCH DAMAGE.
00034 
00035 ##\author Kevin Watts, Eric Berger
00036 ##\brief Drives PR2 base for a burn-in test.
00037 
00038 import roslib; roslib.load_manifest('pr2_drive_life_test')
00039 import tf
00040 import rospy
00041 from std_msgs.msg import Bool
00042 from std_srvs.srv import Empty, EmptyResponse
00043 from geometry_msgs.msg import *
00044 from visualization_msgs.msg import Marker
00045 import copy
00046 from numpy import pi, cos, sin, mean
00047 import time
00048 
00049 base_frame = 'base_link'
00050 map_frame = 'map'
00051 
00052 # Initial pose
00053 x_center = 2.207
00054 y_center = 5.253
00055 th_center = 3.071
00056 x_range = 0.00
00057 y_range = 0.6
00058 th_range = 0.0
00059 x_freq = 1.1
00060 y_freq = 0.52
00061 th_freq = 1.1
00062 
00063 drive_halted = False
00064 
00065 pose_pub = rospy.Publisher('initialpose', PoseWithCovarianceStamped)
00066 
00067 
00068 def halt_drive(srv):
00069   global drive_halted
00070   drive_halted = True
00071   
00072   return EmptyResponse()
00073 
00074 def reset_drive(srv):
00075   global drive_halted
00076   send_initial_pose()
00077   drive_halted = False
00078 
00079   return EmptyResponse()
00080 
00081 def motors_cb(msg):
00082   global drive_halted
00083   
00084   if msg.data:
00085     drive_halted = True
00086   
00087 
00088 def send_initial_pose():
00089   global pose_pub
00090 
00091   msg = PoseWithCovarianceStamped()
00092   msg.header.stamp = rospy.get_rostime()
00093   msg.header.frame_id = '/map'
00094   msg.pose.pose.position.x = x_center
00095   msg.pose.pose.position.y = y_center
00096   msg.pose.pose.orientation.z = 1
00097 
00098   msg.pose.covariance = [0.25, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.25, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.06853891945200942, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
00099 
00100   pose_pub.publish(msg)
00101 
00102 def main():
00103   rospy.init_node('base_life_test')
00104   listener = tf.TransformListener()  
00105   rate = rospy.Rate(500)
00106   
00107   halt_sub = rospy.Service('pr2_base/halt_drive', Empty, halt_drive)
00108   reset_sub = rospy.Service('pr2_base/reset_drive', Empty, reset_drive)
00109 
00110   motors_sub = rospy.Subscriber('pr2_etherCAT/motors_halted', Bool, motors_cb)
00111 
00112 
00113   drive_pub = rospy.Publisher('base_driving', Bool, latch = True)
00114 
00115   marker_pub = rospy.Publisher('visualization_markers', Marker)
00116   cmd_pub = rospy.Publisher('cmd_vel', Twist)
00117 
00118   rospy.sleep(15)
00119   listener.waitForTransform(base_frame, map_frame, rospy.Time(), rospy.Duration(60))
00120 
00121   t_start = rospy.Time.now().to_sec()
00122   started = time.asctime()
00123 
00124   last_drive_update = rospy.get_time()
00125 
00126   global drive_halted
00127   while not rospy.is_shutdown():
00128     #Update target location (sinusoids over the side length - buffer)
00129     t = rospy.Time.now().to_sec() - t_start
00130     x = x_center + sin(t / 2 * pi * x_freq) * x_range
00131     y = y_center + sin(t / 2 * pi * y_freq) * y_range
00132     th = th_center + sin(t / 2 * pi * th_freq) * th_range
00133     if not drive_halted:
00134       command_base_towards(x, y, th, listener, marker_pub, cmd_pub)
00135     rate.sleep()
00136 
00137     if rospy.get_time() - last_drive_update > 0.5:
00138       last_drive_update = rospy.get_time()
00139       drive_pub.publish(drive_halted)
00140 
00141   print "ran from %s to %s"%(started, time.asctime())
00142 
00143 
00144 def command_base_towards(x, y, th, listener, marker_pub, cmd_pub):
00145     target = PoseStamped()
00146     target.header.frame_id = map_frame
00147     target.pose.position.x = x
00148     target.pose.position.y = y
00149     q = tf.transformations.quaternion_about_axis(th, (0, 0, 1))
00150     target.pose.orientation  = Quaternion(q[0], q[1], q[2], q[3])
00151   
00152     local_target = listener.transformPose(base_frame, target)
00153 
00154     marker = Marker()
00155     marker.header.frame_id = local_target.header.frame_id
00156     marker.header.stamp = rospy.Time.now()
00157     marker.id = 10
00158     marker.pose = copy.deepcopy(local_target.pose)
00159     marker.color.r = 1
00160     marker.color.a = 1
00161     marker.scale.x = 0.3
00162     marker.scale.y = 0.3
00163     marker.scale.z = 0.3
00164     marker.type = 0
00165     marker_pub.publish(marker)
00166     #Compute error between target location and actual location
00167 
00168     base_cmd = Twist()
00169     base_cmd.linear.y = 3 * local_target.pose.position.y
00170     #Special-case code for u-only movement to prevent wheel scrub.
00171     if abs(base_cmd.linear.y) > 0.1:
00172       base_cmd.linear.x = 3 * local_target.pose.position.x
00173     if abs(base_cmd.linear.x) + abs(base_cmd.linear.x) > 0.1:
00174       q = local_target.pose.orientation
00175       base_cmd.angular.z = 3 * tf.transformations.euler_from_quaternion([q.x, q.y, q.z, q.w])[2]
00176 
00177     error = []
00178     for x in [local_target.pose.position.x, local_target.pose.position.y, local_target.pose.orientation.z / 5.0]:
00179       error.append(abs(x))
00180       if abs(x) > 1000:
00181         rospy.signal_shutdown("Error, too far from target.  Shutting down to be safe")
00182         print "Shutting down - failed to maintain target trajectory"
00183     #print int(20 * max(error) / 0.6) * "*"
00184     cmd_pub.publish(base_cmd) 
00185     #Command base velocity
00186    
00187 
00188 if __name__=='__main__':
00189   main()


pr2_drive_life_test
Author(s): Eric Berger, Kevin Watts
autogenerated on Sat Dec 28 2013 17:55:15