Go to the documentation of this file.00001
00002 import rospy
00003
00004 from flexbe_core.core.preemptable_state import PreemptableState
00005 from flexbe_core.core.operatable_state_machine import OperatableStateMachine
00006
00007 from flexbe_core.proxy import ProxyPublisher, ProxySubscriberCached
00008 from flexbe_msgs.msg import Container, OutcomeRequest
00009 from std_msgs.msg import UInt8, String
00010
00011 from flexbe_core.state_logger import StateLogger
00012
00013
00014 class OperatableState(PreemptableState):
00015 """
00016 A state that supports autonomy levels and silent mode.
00017 Also, it allows being tracked by a GUI or anything else
00018 as it reports each transition and its initial structure.
00019 An additional method is provided to report custom status messages to the widget.
00020 """
00021
00022 def __init__(self, *args, **kwargs):
00023 super(OperatableState, self).__init__(*args, **kwargs)
00024 self.transitions = None
00025 self.autonomy = None
00026
00027 self._mute = False
00028 self._sent_outcome_requests = []
00029
00030 self._outcome_topic = 'flexbe/mirror/outcome'
00031 self._request_topic = 'flexbe/outcome_request'
00032 self._debug_topic = 'flexbe/debug/current_state'
00033 self._pub = ProxyPublisher()
00034
00035 self.__execute = self.execute
00036 self.execute = self._operatable_execute
00037
00038
00039 def _build_msg(self, prefix, msg):
00040 """
00041 Adds this state to the initial structure message.
00042
00043 @type prefix: string
00044 @param prefix: A path consisting of the container hierarchy containing this state.
00045
00046 @type msg: ContainerStructure
00047 @param msg: The message that will finally contain the structure message.
00048 """
00049
00050
00051 name = prefix + self.name
00052
00053
00054 children = None
00055
00056
00057 outcomes = self._outcome_list
00058
00059
00060 transitions = []
00061 autonomy = []
00062 for i in range(len(outcomes)):
00063 outcome = outcomes[i]
00064 if outcome == 'preempted':
00065 transitions.append('preempted')
00066 autonomy.append(-1)
00067 else:
00068 transitions.append(str(self.transitions[outcome]))
00069 autonomy.append(self.autonomy[outcome])
00070
00071
00072 msg.containers.append(Container(name, children, outcomes, transitions, autonomy))
00073
00074
00075 def _operatable_execute(self, *args, **kwargs):
00076 outcome = self.__execute(*args, **kwargs)
00077
00078 if self._is_controlled:
00079 log_requested_outcome = outcome
00080
00081
00082 if not self._force_transition and (self.autonomy.has_key(outcome) and self.autonomy[outcome] >= OperatableStateMachine.autonomy_level):
00083 if self._sent_outcome_requests.count(outcome) == 0:
00084 self._pub.publish(self._request_topic, OutcomeRequest(outcome=self._outcome_list.index(outcome), target=self._parent._get_path() + "/" + self.name))
00085 rospy.loginfo("<-- Want result: %s > %s", self.name, outcome)
00086 StateLogger.log_state_execution(self._get_path(), self.__class__.__name__, outcome, not self._force_transition, False)
00087 self._sent_outcome_requests.append(outcome)
00088 outcome = OperatableState._loopback_name
00089
00090
00091 elif outcome != OperatableState._loopback_name:
00092 self._sent_outcome_requests = []
00093 rospy.loginfo("State result: %s > %s", self.name, outcome)
00094 self._pub.publish(self._outcome_topic, UInt8(self._outcome_list.index(outcome)))
00095 self._pub.publish(self._debug_topic, String("%s > %s" % (self._get_path(), outcome)))
00096 StateLogger.log_state_execution(self._get_path(), self.__class__.__name__, outcome, not self._force_transition, True)
00097
00098 self._force_transition = False
00099
00100 return outcome
00101
00102 def _notify_skipped(self):
00103 super(OperatableState, self)._notify_skipped()
00104
00105
00106 def _enable_ros_control(self):
00107 super(OperatableState, self)._enable_ros_control()
00108 self._pub.createPublisher(self._outcome_topic, UInt8)
00109 self._pub.createPublisher(self._debug_topic, String)
00110 self._pub.createPublisher(self._request_topic, OutcomeRequest)
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132