Go to the documentation of this file.00001
00002 import rospy
00003
00004 from flexbe_core.core.operatable_state import OperatableState
00005 from flexbe_core.core.preemptable_state import PreemptableState
00006 from flexbe_core.core.priority_container import PriorityContainer
00007
00008 from flexbe_core.proxy import ProxyPublisher, ProxySubscriberCached
00009 from flexbe_msgs.msg import CommandFeedback
00010 from std_msgs.msg import Bool, Empty
00011
00012
00013 class EventState(OperatableState):
00014 """
00015 A state that allows implementing certain events.
00016 """
00017
00018 def __init__(self, *args, **kwargs):
00019 super(EventState, self).__init__(*args, **kwargs)
00020
00021 self._entering = True
00022 self._skipped = False
00023 self.__execute = self.execute
00024 self.execute = self._event_execute
00025
00026 self._paused = False
00027 self._last_active_container = None
00028
00029 self._feedback_topic = 'flexbe/command_feedback'
00030 self._repeat_topic = 'flexbe/command/repeat'
00031 self._pause_topic = 'flexbe/command/pause'
00032
00033 self._pub = ProxyPublisher()
00034 self._sub = ProxySubscriberCached()
00035
00036
00037 def _event_execute(self, *args, **kwargs):
00038 if self._is_controlled and self._sub.has_msg(self._pause_topic):
00039 msg = self._sub.get_last_msg(self._pause_topic)
00040 if msg.data:
00041 self._sub.remove_last_msg(self._pause_topic)
00042 rospy.loginfo("--> Pausing in state %s", self.name)
00043 self._pub.publish(self._feedback_topic, CommandFeedback(command="pause"))
00044 self._last_active_container = PriorityContainer.active_container
00045 PriorityContainer.active_container = ''
00046 self._paused = True
00047
00048 if self._paused and not PreemptableState.preempt:
00049 self._notify_skipped()
00050 return self._loopback_name
00051
00052 if self._entering:
00053 self._entering = False
00054 self.on_enter(*args, **kwargs)
00055 if self._skipped:
00056 self._skipped = False
00057 self.on_resume(*args, **kwargs)
00058
00059 execute_outcome = self.__execute(*args, **kwargs)
00060
00061 repeat = False
00062 if self._is_controlled and self._sub.has_msg(self._repeat_topic):
00063 rospy.loginfo("--> Repeating state %s", self.name)
00064 self._sub.remove_last_msg(self._repeat_topic)
00065 self._pub.publish(self._feedback_topic, CommandFeedback(command="repeat"))
00066 repeat = True
00067
00068 if execute_outcome != self._loopback_name and not PreemptableState.switching \
00069 or repeat:
00070 self._entering = True
00071 self.on_exit(*args, **kwargs)
00072
00073 return execute_outcome
00074
00075 def _notify_skipped(self):
00076 if not self._skipped:
00077 self.on_pause()
00078 self._skipped = True
00079 if self._is_controlled and self._sub.has_msg(self._pause_topic):
00080 msg = self._sub.get_last_msg(self._pause_topic)
00081 if not msg.data:
00082 self._sub.remove_last_msg(self._pause_topic)
00083 rospy.loginfo("--> Resuming in state %s", self.name)
00084 self._pub.publish(self._feedback_topic, CommandFeedback(command="resume"))
00085 PriorityContainer.active_container = self._last_active_container
00086 self._last_active_container = None
00087 self._paused = False
00088 super(EventState, self)._notify_skipped()
00089
00090
00091 def _enable_ros_control(self):
00092 super(EventState, self)._enable_ros_control()
00093 self._pub.createPublisher(self._feedback_topic, CommandFeedback)
00094 self._sub.subscribe(self._repeat_topic, Empty)
00095 self._sub.subscribe(self._pause_topic, Bool)
00096
00097 def _disable_ros_control(self):
00098 super(EventState, self)._disable_ros_control()
00099 self._sub.unsubscribe_topic(self._repeat_topic)
00100 self._sub.unsubscribe_topic(self._pause_topic)
00101 self._last_active_container = None
00102 if self._paused:
00103 PriorityContainer.active_container = None
00104
00105
00106
00107
00108
00109 def on_start(self):
00110 """
00111 Will be executed once when the behavior starts.
00112 """
00113 pass
00114
00115 def on_stop(self):
00116 """
00117 Will be executed once when the behavior stops or is preempted.
00118 """
00119 pass
00120
00121 def on_pause(self):
00122 """
00123 Will be executed each time this state is paused.
00124 """
00125 pass
00126
00127 def on_resume(self, userdata):
00128 """
00129 Will be executed each time this state is resumed.
00130 """
00131 pass
00132
00133 def on_enter(self, userdata):
00134 """
00135 Will be executed each time the state is entered from any other state (but not from itself).
00136 """
00137 pass
00138
00139 def on_exit(self, userdata):
00140 """
00141 Will be executed each time the state will be left to any other state (but not to itself).
00142 """
00143 pass