3 import roslib; roslib.load_manifest(
'flexbe_mirror')
9 from flexbe_core
import JumpableStateMachine, LockableStateMachine
11 from mirror_state
import MirrorState
14 from flexbe_msgs.msg
import ContainerStructure, BehaviorSync, BEStatus
15 from std_msgs.msg
import Empty, String, Int32, UInt8
20 @author: Philipp Schillinger 43 self.
_pub = ProxyPublisher({
'flexbe/behavior_update': String,
44 'flexbe/request_mirror_structure': Int32})
58 self.
_sub = ProxySubscriberCached()
62 self._sub.subscribe(
'flexbe/mirror/structure', ContainerStructure, self.
_mirror_callback)
64 self._sub.subscribe(
'flexbe/mirror/sync', BehaviorSync, self.
_sync_callback)
74 rospy.logwarn(
'Received a new mirror structure while mirror is already running, adding to buffer (checksum: %s).' % str(msg.behavior_id))
76 rospy.logwarn(
'checksum of received mirror structure (%s) does not match expected checksum (%s), will ignore.' % (str(msg.behavior_id), str(self.
_active_id)))
79 rospy.loginfo(
'Received a new mirror structure for checksum %s' % str(msg.behavior_id))
81 self._struct_buffer.append(msg)
86 rospy.loginfo(
'Mirror built.')
92 if msg.code == BEStatus.STARTED:
93 thread = threading.Thread(target=self.
_start_mirror, args=[msg])
97 thread = threading.Thread(target=self.
_stop_mirror, args=[msg])
103 self._sync_lock.acquire()
104 rate = rospy.Rate(10)
109 rospy.logwarn(
'Tried to start mirror while it is already running, will ignore.')
112 if len(msg.args) > 0:
113 self.
_starting_path =
"/" + msg.args[0][1:].replace(
"/",
"_mirror/") +
"_mirror" 122 rospy.loginfo(
'Mirror built.')
124 rospy.logwarn(
'Discarded mismatching buffered structure for checksum %s' % str(struct.behavior_id))
127 rospy.logwarn(
'Missing correct mirror structure, requesting...')
129 self._pub.publish(
'flexbe/request_mirror_structure', Int32(msg.behavior_id))
132 self._sync_lock.release()
138 self._sync_lock.acquire()
141 if msg
is not None and msg.code == BEStatus.FINISHED:
142 rospy.loginfo(
'Onboard behavior finished successfully.')
143 self._pub.publish(
'flexbe/behavior_update', String())
144 elif msg
is not None and msg.code == BEStatus.SWITCHING:
146 rospy.loginfo(
'Onboard performing behavior switch.')
147 elif msg
is not None and msg.code == BEStatus.READY:
148 rospy.loginfo(
'Onboard engine just started, stopping currently running mirror.')
149 self._pub.publish(
'flexbe/behavior_update', String())
150 elif msg
is not None:
151 rospy.logwarn(
'Onboard behavior failed!')
152 self._pub.publish(
'flexbe/behavior_update', String())
154 PreemptableState.preempt =
True 155 rate = rospy.Rate(10)
159 rospy.loginfo(
'No onboard behavior is active.')
166 if msg
is not None and msg.code != BEStatus.SWITCHING:
167 rospy.loginfo(
'\033[92m--- Behavior Mirror ready! ---\033[0m')
170 self._sync_lock.release()
179 rospy.logerr(
'Cannot synchronize! Different behavior is running onboard, please stop execution!')
180 thread = threading.Thread(target=self.
_stop_mirror, args=[
None])
186 self._sync_lock.acquire()
187 rospy.loginfo(
'Restarting mirror for synchronization...')
190 PreemptableState.preempt =
True 191 rate = rospy.Rate(10)
197 self.
_starting_path =
"/" + current_state_path[1:].replace(
"/",
"_mirror/") +
"_mirror" 198 rospy.loginfo(
'Current state: %s' % current_state_path)
201 rospy.loginfo(
'Mirror built.')
202 except (AttributeError, smach.InvalidStateError):
203 rospy.loginfo(
'Stopping synchronization because behavior has stopped.')
204 self._sync_lock.release()
212 rospy.loginfo(
"Executing mirror...")
220 result = self._sm.execute()
221 except Exception
as e:
222 rospy.loginfo(
'Caught exception on preempt:\n%s' % str(e))
225 if self.
_sm is not None:
229 rospy.loginfo(
'Mirror finished with result ' + result)
236 for con_msg
in msg.containers:
237 if con_msg.path.find(
'/') == -1:
242 for con_msg
in msg.containers:
243 if con_msg.path.find(
'/') != -1:
250 for con_msg
in msg.containers:
251 if con_msg.path == path:
256 if container.transitions
is not None:
258 for i
in range(len(container.transitions)):
259 transitions[container.outcomes[i]] = container.transitions[i] +
'_mirror' 261 path_frags = path.split(
'/')
262 container_name = path_frags[len(path_frags)-1]
263 if len(container.children) > 0:
265 for outcome
in container.outcomes: sm_outcomes.append(outcome +
'_mirror')
266 sm = JumpableStateMachine(outcomes=sm_outcomes)
268 for child
in container.children:
270 if len(transitions) > 0:
271 container_transitions = {}
272 for i
in range(len(container.transitions)): container_transitions[sm_outcomes[i]] = transitions[container.outcomes[i]]
273 JumpableStateMachine.add(container_name +
'_mirror', sm, transitions=container_transitions)
277 JumpableStateMachine.add(container_name +
'_mirror', MirrorState(container_name, path, container.outcomes, container.autonomy), transitions=transitions)
281 start_time = rospy.Time.now()
284 while self.
_sm is None or not self._sm.is_running():
285 current_elapsed = rospy.Time.now() - start_time
286 if current_elapsed > rospy.Duration.from_sec(10):
291 self._sm.jump_to(msg.stateName)
293 rospy.logwarn(
'Could not jump in mirror: Mirror does not exist or is not running!')
297 if self.
_sm is not None and self._sm.is_running():
298 rospy.logwarn(
'Explicit preempting is currently ignored, mirror should be preempted by onboard behavior.')
300 rospy.logwarn(
'Could not preempt mirror because it seems not to be running!')
def _start_mirror(self, msg)
def _status_callback(self, msg)
def _restart_mirror(self, msg)
def _mirror_state_machine(self, msg)
def _execute_mirror(self)
def _preempt_callback(self, msg)
def _sync_callback(self, msg)
def _mirror_callback(self, msg)
def _stop_mirror(self, msg)
def _jump_callback(self, msg)
def _add_node(self, msg, path)