pi_trees_ros.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 """
00004     pi_trees_ros.py - Version 0.1 2013-08-28
00005     
00006     ROS wrappers for the pi_trees_lib.py library
00007     
00008     Created for the Pi Robot Project: http://www.pirobot.org
00009     Copyright (c) 2013 Patrick Goebel.  All rights reserved.
00010 
00011     This program is free software; you can redistribute it and/or modify
00012     it under the terms of the GNU General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or
00014     (at your option) any later version.
00015     
00016     This program is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019     GNU General Public License for more details at:
00020     
00021     http://www.gnu.org/licenses/gpl.html
00022 """
00023 
00024 import rospy
00025 import actionlib
00026 from actionlib_msgs.msg import GoalStatus
00027 from pi_trees_lib.pi_trees_lib import *
00028 
00029 class MonitorTask(Task):
00030     """
00031         Turn a ROS subscriber into a Task.
00032     """
00033     def __init__(self, name, topic, msg_type, msg_cb, wait_for_message=True, timeout=5):
00034         super(MonitorTask, self).__init__(name)
00035         
00036         self.topic = topic
00037         self.msg_type = msg_type
00038         self.timeout = timeout
00039         self.msg_cb = msg_cb
00040                 
00041         rospy.loginfo("Subscribing to topic " + topic)
00042         
00043         if wait_for_message:
00044             try:
00045                 rospy.wait_for_message(topic, msg_type, timeout=self.timeout)
00046                 rospy.loginfo("Connected.")
00047             except:
00048                 rospy.loginfo("Timed out waiting for " + topic)
00049                 
00050         # Subscribe to the given topic with the given callback function executed via run() 
00051         rospy.Subscriber(self.topic, self.msg_type, self._msg_cb)
00052         
00053     def _msg_cb(self, msg):
00054         self.set_status(self.msg_cb(msg))
00055         
00056     def run(self):
00057         return self.status
00058     
00059     def reset(self):
00060         pass
00061     
00062 class ServiceTask(Task):
00063     """
00064         Turn a ROS service into a Task.
00065     """
00066     def __init__(self, name, service, service_type, request, result_cb=None, wait_for_service=True, timeout=5):
00067         super(ServiceTask, self).__init__(name)
00068         
00069         self.result = None
00070         self.request = request
00071         self.timeout = timeout
00072         self.result_cb = result_cb
00073                 
00074         rospy.loginfo("Connecting to service " + service)
00075         
00076         if wait_for_service:
00077             rospy.loginfo("Waiting for service")
00078             rospy.wait_for_service(service, timeout=self.timeout)
00079             rospy.loginfo("Connected.")
00080         
00081         # Create a service proxy
00082         self.service_proxy = rospy.ServiceProxy(service, service_type)
00083         
00084     def run(self):
00085         try:
00086             result = self.service_proxy(self.request)
00087             if self.result_cb is not None:
00088                 self.result_cb(result)
00089             return TaskStatus.SUCCESS
00090         except:
00091             rospy.logerr(sys.exc_info())
00092             return TaskStatus.FAILURE
00093         
00094     def reset(self):
00095         pass
00096         
00097 class SimpleActionTask(Task):
00098     """
00099         Turn a ROS action into a Task.
00100     """
00101     def __init__(self, name, action, action_type, goal, rate=5, connect_timeout=10, result_timeout=30, reset_after=False, active_cb=None, done_cb=None, feedback_cb=None):
00102         super(SimpleActionTask, self).__init__(name)
00103         
00104         self.action = action
00105         self.goal = goal
00106         self.tick = 1.0 / rate
00107         self.rate = rospy.Rate(rate)
00108 
00109         self.result = None
00110         self.connect_timeout = connect_timeout
00111         self.result_timeout = result_timeout
00112         self.reset_after = reset_after
00113         
00114         if done_cb == None:
00115             done_cb = self.default_done_cb
00116         self.done_cb = done_cb
00117         
00118         if active_cb == None:
00119             active_cb = self.default_active_cb
00120         self.active_cb = active_cb
00121         
00122         if feedback_cb == None:
00123             feedback_cb = self.default_feedback_cb
00124         self.feedback_cb = feedback_cb
00125                 
00126         self.action_started = False
00127         self.action_finished = False
00128         self.goal_status_reported = False
00129         self.time_so_far = 0.0
00130         
00131         # Goal state return values
00132         self.goal_states = ['PENDING', 'ACTIVE', 'PREEMPTED', 
00133                             'SUCCEEDED', 'ABORTED', 'REJECTED',
00134                             'PREEMPTING', 'RECALLING', 'RECALLED',
00135                             'LOST']
00136     
00137         rospy.loginfo("Connecting to action " + action)
00138 
00139         # Subscribe to the base action server
00140         self.action_client = actionlib.SimpleActionClient(action, action_type)
00141 
00142         rospy.loginfo("Waiting for move_base action server...")
00143         
00144         # Wait up to timeout seconds for the action server to become available
00145         try:
00146             self.action_client.wait_for_server(rospy.Duration(self.connect_timeout))
00147         except:
00148             rospy.loginfo("Timed out connecting to the action server " + action)
00149     
00150         rospy.loginfo("Connected to action server")
00151 
00152     def run(self):
00153         # Send the goal
00154         if not self.action_started:
00155             rospy.loginfo("Sending " + str(self.name) + " goal to action server...")
00156             self.action_client.send_goal(self.goal, done_cb=self.done_cb, active_cb=self.active_cb, feedback_cb=self.feedback_cb)
00157             self.action_started = True 
00158         
00159         ''' We cannot use the wait_for_result() method here as it will block the entire
00160             tree so we break it down in time slices of duration 1 / rate.
00161         '''
00162         if not self.action_finished:
00163             self.time_so_far += self.tick
00164             self.rate.sleep()
00165             if self.time_so_far > self.result_timeout:
00166                 self.action_client.cancel_goal()
00167                 rospy.loginfo("Timed out achieving goal")
00168                 return TaskStatus.FAILURE
00169             else:
00170                 return TaskStatus.RUNNING
00171         else:
00172             # Check the final goal status returned by default_done_cb
00173             if self.goal_status == GoalStatus.SUCCEEDED:
00174                   self.action_finished = True
00175                   if self.reset_after:
00176                       self.reset()
00177                   return TaskStatus.SUCCESS
00178             elif self.goal_status == GoalStatus.ABORTED:
00179                 self.action_started = False
00180                 self.action_finished = False
00181                 return TaskStatus.FAILURE
00182             else:
00183                 self.action_started = False
00184                 self.action_finished = False
00185                 self.goal_status_reported = False
00186                 return TaskStatus.RUNNING
00187                             
00188     def default_done_cb(self, status, result):
00189         # Check the final status
00190         self.goal_status = status
00191         self.action_finished = True
00192         
00193         if not self.goal_status_reported:
00194             rospy.loginfo(str(self.name) + " ended with status " + str(self.goal_states[status]))
00195             self.goal_status_reported = True
00196     
00197     def default_active_cb(self):
00198         pass
00199         
00200     def default_feedback_cb(self, msg):
00201         pass
00202     
00203     def reset(self):
00204         self.action_started = False
00205         self.action_finished = False
00206         self.goal_status_reported = False
00207         self.time_so_far = 0.0


pi_trees_ros
Author(s): Patrick Goebel
autogenerated on Fri Aug 28 2015 12:02:24