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 
00032 
00033 
00034 
00035 
00036 
00037 
00038 import roslib; roslib.load_manifest('navigation_task')
00039 import rospy
00040 import smach
00041 import smach_ros
00042 import actionlib
00043 import random
00044 
00045 from smach_ros import SimpleActionState
00046 
00047 from move_base_msgs.msg import MoveBaseAction, MoveBaseGoal
00048 from continuous_ops_msgs.msg import TaskAction
00049 from geometry_msgs.msg import PoseStamped, Pose, Quaternion, Point
00050 from pr2_common_action_msgs.msg import TuckArmsAction, TuckArmsGoal
00051 from std_msgs.msg import Header
00052 
00053 nav_goals = [
00054     [(19.380, 24.061, 0.000), (0.000, 0.000, 0.953, -0.304)],
00055     [(27.193, 15.448, 0.000), (0.000, 0.000, 0.526, 0.851)],
00056     [(29.872, 21.884, 0.000), (0.000, 0.000, 0.979, 0.206)],
00057     [(18.632, 26.155, 0.000), (0.000, 0.000, 0.807, 0.590)],
00058     [(20.772, 38.251, 0.000), (0.000, 0.000, 0.980, 0.201)],
00059     [(5.184, 22.094, 0.000), (0.000, 0.000, 0.559, 0.829)],
00060     [(17.346, 54.900, 0.000), (0.000, 0.000, 0.160, 0.987)],
00061     [(25.170, 52.124, 0.000), (0.000, 0.000, -0.099, 0.995)],
00062     [(20.409, 38.265, 0.000), (0.000, 0.000, -0.678, 0.735)],
00063     [(24.109, 20.406, 0.000), (0.000, 0.000, 0.973, 0.230)]
00064 ]
00065 
00066 
00067 class NavigateSM(smach.State):
00068     def __init__(self, goals, desired_num_goals):
00069         smach.State.__init__(self, outcomes=['succeeded', 'aborted', 'preempted'])
00070         self.goals = goals
00071         self.desired_num_goals = desired_num_goals
00072         self.goal_count = 0
00073         
00074         random.shuffle(self.goals)
00075         rospy.loginfo("Goals are: %s" % goals)
00076         self.client = actionlib.SimpleActionClient('pr2_move_base', MoveBaseAction)
00077         self.goal_timeout = rospy.Duration.from_sec(rospy.get_param('~goal_timeout', 300.0))
00078 
00079     def mb_goal(self, goal):
00080         return MoveBaseGoal(PoseStamped(Header(frame_id = 'map'),
00081                                       Pose(Point(goal[0][0], goal[0][1],
00082                                                  goal[0][2]),
00083                                            Quaternion(goal[1][0], goal[1][1],
00084                                                       goal[1][2], goal[1][3])))) 
00085 
00086     def execute(self, userdata):
00087         
00088         random.shuffle(self.goals)
00089 
00090         
00091         self.goal_count = 0
00092         rospy.loginfo("Waiting for server")
00093         
00094         self.client.wait_for_server()
00095         rospy.loginfo("Server is up")
00096         for goal in self.goals:
00097             
00098             if self.desired_num_goals != 0 and self.goal_count >= self.desired_num_goals:
00099                 rospy.loginfo("We've been to %d goals... success." % self.goal_count)
00100                 return 'succeeded'
00101 
00102             
00103             rospy.loginfo("Sending goal %s" % goal)
00104             self.client.send_goal(self.mb_goal(goal))
00105             start_time = rospy.Time.now()
00106 
00107             r = rospy.Rate(10.0)
00108 
00109             
00110             
00111             
00112             while not self.client.wait_for_result(rospy.Duration.from_sec(0.001)):
00113                 if self.preempt_requested():
00114                     self.service_preempt()
00115                     
00116                     self.client.cancel_goal()
00117                     return 'preempted'
00118 
00119                 
00120                 if start_time + self.goal_timeout < rospy.Time.now():
00121                     rospy.logwarn('Navigation task timed out trying to get to a goal after %.2f seconds, sending a new goal' % self.goal_timeout.to_sec())
00122                     break
00123 
00124                 r.sleep()
00125 
00126             
00127             self.goal_count += 1
00128 
00129         return 'succeeded'
00130 
00131 def main():
00132     rospy.init_node('navigation_task')
00133     
00134     sm = smach.StateMachine(outcomes=['succeeded', 'aborted', 'preempted'])
00135     with sm:
00136         tuck_goal = TuckArmsGoal()
00137         tuck_goal.tuck_left=True
00138         tuck_goal.tuck_right=True
00139         tucking_succeeded = False
00140         smach.StateMachine.add('TUCK_ARMS', SimpleActionState('tuck_arms', TuckArmsAction,
00141                                                               goal=tuck_goal),
00142                                transitions={'succeeded':'NAVIGATE'})
00143         smach.StateMachine.add('NAVIGATE', NavigateSM(nav_goals, 0), transitions = {'succeeded':'NAVIGATE','preempted':'preempted'})
00144 
00145     asw = smach_ros.ActionServerWrapper(
00146         'navigation_task', TaskAction,
00147         wrapped_container = sm,
00148         succeeded_outcomes = ['succeeded'],
00149         aborted_outcomes = ['aborted'],
00150         preempted_outcomes = ['preempted'])
00151 
00152     asw.run_server()
00153 
00154     rospy.spin()
00155 
00156 if __name__ == '__main__':
00157     main()