8 from flexbe_msgs.msg
import Container, ContainerStructure, BehaviorSync, CommandFeedback
9 from std_msgs.msg
import Empty, UInt8, Int32
16 A state machine that can be operated. 17 It synchronizes its current state with the mirror and supports some control mechanisms. 23 super(OperatableStateMachine, self).
__init__(*args, **kwargs)
32 def add(label, state, transitions, autonomy=None, remapping=None):
34 Add a state to the opened state machine. 37 @param label: The label of the state being added. 39 @param state: An instance of a class implementing the L{State} interface. 41 @param transitions: A dictionary mapping state outcomes to other state 42 labels or container outcomes. 44 @param autonomy: A dictionary mapping state outcomes to their required 47 @param remapping: A dictionary mapping local userdata keys to userdata 48 keys in the container. 50 self = OperatableStateMachine.get_opened_container()
51 PreemptableStateMachine.add(label, state, transitions, remapping)
56 Creates a message to describe the structure of this state machine. 58 structure_msg = ContainerStructure()
60 container_msg.outcomes = self.
outcomes 61 structure_msg.behavior_id = self.
id 66 Adds this state machine and all children to the structure message. 68 @type structure_msg: ContainerStructure 69 @param structure_msg: The message that will finally contain the structure message. 72 container_msg = Container()
73 container_msg.path = self.
path 74 container_msg.children = [state.name
for state
in self.
_states]
75 structure_msg.containers.append(container_msg)
79 if isinstance(state, OperatableStateMachine):
80 state_msg = state._add_to_structure_msg(structure_msg)
82 state_msg = Container(path=state.path)
83 structure_msg.containers.append(state_msg)
85 state_msg.outcomes = state.outcomes
86 state_msg.transitions = [self.
_transitions[state.name][outcome]
for outcome
in state.outcomes]
87 state_msg.autonomy = [self.
_autonomy[state.name][outcome]
for outcome
in state.outcomes]
97 except Exception
as e:
107 self.parent._inner_sync_request =
True 110 msg.behavior_id = self.
id 111 msg.current_state_checksum = zlib.adler32(self.
get_deep_state().path.encode()) & 0x7fffffff
112 self._pub.publish(
'flexbe/mirror/sync', msg)
116 return self.
_autonomy[label].get(outcome, -1) < OperatableStateMachine.autonomy_level
124 self._sub.unsubscribe_topic(
'flexbe/command/autonomy')
125 self._sub.unsubscribe_topic(
'flexbe/command/sync')
126 self._sub.unsubscribe_topic(
'flexbe/command/attach')
127 self._sub.unsubscribe_topic(
'flexbe/request_mirror_structure')
128 StateLogger.shutdown()
132 Confirms the state machine and triggers the creation of the structural message. 133 It is mandatory to call this function at the top-level state machine 134 between building it and starting its execution. 137 @param name: The name of this state machine to identify it. 143 self._pub.createPublisher(
'flexbe/mirror/sync', BehaviorSync)
145 self._pub.createPublisher(
'flexbe/mirror/structure', ContainerStructure)
147 self._pub.createPublisher(
'flexbe/command_feedback', CommandFeedback)
150 self._sub.subscribe(
'flexbe/command/sync', Empty, self.
_sync_callback)
154 StateLogger.initialize(name)
155 StateLogger.log(
'flexbe.initialize',
None, behavior=name, autonomy=OperatableStateMachine.autonomy_level)
156 if OperatableStateMachine.autonomy_level != 255:
159 self.
wait(seconds=0.2)
165 """ Sets the current autonomy level. """ 166 if OperatableStateMachine.autonomy_level != msg.data:
167 Logger.localinfo(
'--> Autonomy changed to %d' % msg.data)
171 OperatableStateMachine.autonomy_level = msg.data
172 self._pub.publish(
'flexbe/command_feedback', CommandFeedback(command=
"autonomy", args=[]))
175 Logger.localinfo(
"--> Synchronization requested...")
177 msg.behavior_id = self.
id 180 msg.current_state_checksum = zlib.adler32(self.
get_deep_state().path.encode()) & 0x7fffffff
181 self._pub.publish(
'flexbe/mirror/sync', msg)
182 self._pub.publish(
'flexbe/command_feedback', CommandFeedback(command=
"sync", args=[]))
183 Logger.localinfo(
"<-- Sent synchronization message for mirror.")
186 Logger.localinfo(
"--> Enabling control...")
188 OperatableStateMachine.autonomy_level = msg.data
193 cfb = CommandFeedback(command=
"attach")
194 cfb.args.append(self.
name)
195 self._pub.publish(
'flexbe/command_feedback', cfb)
196 Logger.localinfo(
"<-- Sent attach confirm.")
199 Logger.localinfo(
"--> Creating behavior structure for mirror...")
201 Logger.localinfo(
"<-- Sent behavior structure for mirror.")
209 if isinstance(state, OperatableState):
211 if isinstance(state, OperatableStateMachine):
212 state._notify_start()
216 if isinstance(state, OperatableState):
218 if isinstance(state, OperatableStateMachine):
220 if state._is_controlled:
221 state._disable_ros_control()
225 ud =
UserData(reference=self.
userdata, input_keys=self._current_state.input_keys,
226 output_keys=self._current_state.output_keys,
228 self._current_state._entering =
True 229 self._current_state.on_exit(ud)
def _sync_callback(self, msg)
def add(label, state, transitions, autonomy=None, remapping=None)
def wait(self, seconds=None, condition=None)
def _add_to_structure_msg(self, structure_msg)
def _execute_current_state(self)
def _attach_callback(self, msg)
def on_exit(self, userdata)
def _mirror_structure_callback(self, msg)
def _build_structure_msg(self)
def _disable_ros_control(self)
def set_name(self, value)
def __init__(self, args, kwargs)
def confirm(self, name, id)
def current_state_label(self)
def _set_autonomy_level(self, msg)
def _enable_ros_control(self)
def get_required_autonomy(self, outcome)
def is_transition_allowed(self, label, outcome)