runner.py
Go to the documentation of this file.
00001 # Copyright (c) 2013, Felix Kolbe
00002 # All rights reserved. BSD License
00003 #
00004 # Redistribution and use in source and binary forms, with or without
00005 # modification, are permitted provided that the following conditions
00006 # are met:
00007 #
00008 # * Redistributions of source code must retain the above copyright
00009 #   notice, this list of conditions and the following disclaimer.
00010 #
00011 # * Redistributions in binary form must reproduce the above copyright
00012 #   notice, this list of conditions and the following disclaimer in the
00013 #   documentation and/or other materials provided with the distribution.
00014 #
00015 # * Neither the name of the {organization} nor the names of its
00016 #   contributors may be used to endorse or promote products derived
00017 #   from this software without specific prior written permission.
00018 #
00019 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00022 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00023 # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00024 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00025 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00026 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00027 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00028 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00029 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 
00031 
00032 import roslib; roslib.load_manifest('rgoap_ros')
00033 import rospy
00034 
00035 import thread
00036 
00037 from smach import UserData
00038 from smach_ros import IntrospectionServer
00039 
00040 from rgoap import Runner
00041 
00042 from rgoap_ros import Introspector
00043 from rgoap_smach import SMACHStateWrapperAction
00044 from rgoap_smach import rgoap_path_to_smach_container
00045 
00046 
00047 import logging
00048 _logger = logging.getLogger('rgoap.ros')
00049 
00050 
00051 
00052 ## from uashh_smach.util import execute_smach_container
00053 def execute_smach_container(smach_container, enable_introspection=False,
00054                             name='/SM_ROOT', userdata=UserData()):
00055     if not rospy.core.is_initialized():
00056         rospy.init_node('smach')
00057 
00058     if enable_introspection:
00059         # Create and start the introspection server
00060         sis = IntrospectionServer('smach_executor', smach_container, name)
00061         sis.start()
00062 
00063     outcome = smach_container.execute(userdata)
00064     _logger.info("smach outcome: %s", outcome)
00065 
00066     if enable_introspection:
00067         sis.stop()
00068 
00069     return outcome
00070 
00071 
00072 class SMACHRunner(Runner):
00073     """
00074     This Runner subclass uses SMACH instead of the rgoap.PlanExecutor to
00075     execute an RGOAP plan.
00076 
00077     If enabled the smach viewer can be used for introspection.
00078     """
00079 
00080     def __init__(self, *args, **kwargs):
00081         Runner.__init__(self, *args, **kwargs)
00082 
00083         self._introspector = None
00084         self._current_smach = None # used to propagate preemption into generated smach
00085 
00086 
00087     def _setup_introspection(self):
00088         # init what could have been initialized externally
00089         if not rospy.core.is_initialized():
00090             rospy.init_node('rgoap_runner_introspector')
00091         # init everything else but only once
00092         if self._introspector is None:
00093             self._introspector = Introspector()
00094             thread.start_new_thread(rospy.spin, ())
00095             _logger.info("introspection spinner started")
00096         # TODO: check why spinner does not work [when runner called from unittest?]
00097 
00098 
00099     def request_preempt(self):
00100         Runner.request_preempt(self)
00101         if self._current_smach is not None:
00102             self._current_smach.request_preempt()
00103 
00104     def preempt_requested(self):
00105         return Runner.preempt_requested(self) or (self._current_smach.preempt_requested()
00106                                                    if self._current_smach is not None
00107                                                    else False)
00108 
00109     def service_preempt(self):
00110         Runner.service_preempt(self)
00111         if self._current_smach is not None:
00112             self._current_smach.service_preempt()
00113 
00114 
00115     def plan(self, goal, introspection=False):
00116         """plan for given goal and return start_node of plan or None
00117 
00118         introspection: introspect RGOAP planning via smach.introspection
00119         """
00120         if introspection:
00121             self._setup_introspection()
00122 
00123         start_node = Runner.plan(self, goal, introspection)
00124 
00125         if introspection:
00126             if start_node is not None:
00127                 self._introspector.publish(start_node)
00128             self._introspector.publish_net(self.planner.last_goal_node, start_node)
00129 
00130         return start_node
00131 
00132     def plan_and_execute_goals(self, goals):
00133         """Sort goals by usability and try to plan and execute one by one until
00134         one goal is achieved"""
00135         self._setup_introspection()
00136         return Runner.plan_and_execute_goals(self, goals)
00137 
00138 
00139     def execute(self, start_node, introspection=False):
00140         outcome = self.execute_as_smach(start_node, introspection)
00141         return outcome
00142 
00143     def execute_as_smach(self, start_node, introspection=False):
00144         sm = rgoap_path_to_smach_container(start_node)
00145         # TODO: create proxies / userdata info for inner-sm introspection
00146         self._current_smach = sm
00147         outcome = execute_smach_container(sm, introspection, name='/RGOAP_GENERATED_SMACH')
00148         self._current_smach = None
00149         return outcome


rgoap_ros
Author(s): Felix Kolbe
autogenerated on Sun Oct 5 2014 23:53:07