9 from flexbe_core
import OperatableStateMachine, LockableStateMachine
15 @author: Philipp Schillinger 20 This is the superclass for all implemented behaviors. 25 Please call this superclass constructor first when overriding it with your behavior. 28 self.
name =
"unnamed behavior" 44 Should create the state machine for this behavior and return it. 45 It is called immediately before executing the behavior, so used parameters will have their final value when called. 47 @return The complete state machine for this behavior. 56 Adds a parameter to this behavior. 57 The parameter should be declared in the behavior manifest. 60 @param name: The name of the parameter. 63 @param default: The default value of this parameter. Be sure to set it to the right type. 65 setattr(self, name, default)
69 Adds another behavior as part of this behavior. 70 This other behavior should be declared as contained in the behavior manifest. 72 @type behavior_class: class 73 @param behavior_class: The class implementing the other behavior. 75 @type behavior_id: string 76 @param behavior_id: Unique identifier for this behavior instance. 78 if not hasattr(self,
'contains'):
79 rospy.logerr(
'Behavior was not initialized! Please call superclass constructor.')
81 instance = behavior_class()
82 self.
contains[behavior_id] = instance
84 def use_behavior(self, behavior_class, behavior_id, default_keys=None, parameters=None):
86 Creates a state machine implementing the given behavior to use it in the behavior state machine. 87 Behavior has to be added first. 89 @type behavior_class: class 90 @param behavior_class: The class implementing the other behavior. 92 @type behavior_id: string 93 @param behavior_id: Same identifier as used for adding. 95 @type default_keys: list 96 @param default_keys: List of input keys of the behavior which should be ignored and instead use the default values as given by the behavior. 98 @type parameters: dict 99 @param parameters: Optional assignment of values to behavior parameters. Any assigned parameter will be ignored for runtime customization, i.e., cannot be overwritten by a user who runs the behavior. 101 if not self.contains.has_key(behavior_id):
102 rospy.logerr(
'Tried to use not added behavior!')
105 if parameters
is not None:
106 for parameter, value
in parameters.items():
107 setattr(self.
contains[behavior_id], parameter, value)
111 if default_keys
is not None:
112 state_machine._input_keys = list(set(state_machine._input_keys) - set(default_keys))
121 Prepares this behavior for execution by building its state machine. 126 self._state_machine._input_keys = {}
127 self._state_machine._output_keys = {}
129 for k, v
in input_data.items():
130 if k
in self._state_machine.userdata:
131 self._state_machine.userdata[k] = v
136 Confirms that this behavior is ready for execution. 140 self._state_machine.confirm(self.
name, self.
id)
145 Called when the behavior is executed. 146 Need to call self.execute_behavior when ready to start the state machine and return its result. 148 @return: A string containing the execution result such as finished or failed. 150 PreemptableState.switching =
False 151 result = self._state_machine.execute()
153 self._state_machine.destroy()
160 Prepares the behavior for being executed after a behavior switch. 163 @param name: The name of this behavior. 167 raise smach.InvalidConstructionError(
"Did not find locked state in new behavior!")
168 state_container = state._parent
169 for sm
in states[1:]:
170 sm.set_initial_state([sm._initial_state_label], state_container.userdata)
172 state_container = state_container._parent
173 states[1].replace(state)
179 return self._state_machine._get_deep_state()
182 state = self._state_machine._get_deep_state()
183 while not state
is None:
184 if state.is_locked():
187 state = state._parent
191 PreemptableState.preempt =
True 194 PreemptableState.switching =
True 195 PreemptableState.preempt =
True 212 for state
in sm._ordered_states:
213 if isinstance(state, OperatableStateMachine):
216 state._is_controlled =
False 219 def set_up(self, id, autonomy_level, debug):
225 path_elements = path.split(
'/')
226 if len(path_elements) < 2:
228 state_label = path_elements[1]
229 new_path =
"/".join(path_elements[1:])
231 if container.get_children().has_key(state_label):
233 if childlist
is None:
235 childlist.append(container)
def get_locked_state(self)
def use_behavior(self, behavior_class, behavior_id, default_keys=None, parameters=None)
def set_up(self, id, autonomy_level, debug)
def add_behavior(self, behavior_class, behavior_id)
def _mute_state_machine(self, sm)
def get_current_state(self)
def _get_muted_state_machine(self)
def _get_state_machine(self)
def prepare_for_execution(self, input_data={})
def _get_states_of_path(self, path, container)
def add_parameter(self, name, default)
def preempt_for_switch(self)
def prepare_for_switch(self, state)