Go to the documentation of this file.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 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
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
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
00085
00086
00087 def _setup_introspection(self):
00088
00089 if not rospy.core.is_initialized():
00090 rospy.init_node('rgoap_runner_introspector')
00091
00092 if self._introspector is None:
00093 self._introspector = Introspector()
00094 thread.start_new_thread(rospy.spin, ())
00095 _logger.info("introspection spinner started")
00096
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
00146 self._current_smach = sm
00147 outcome = execute_smach_container(sm, introspection, name='/RGOAP_GENERATED_SMACH')
00148 self._current_smach = None
00149 return outcome