6 from flexbe_core.core import PreemptableState, PreemptableStateMachine, LockableStateMachine
7 from .mirror_state
import MirrorState
10 from flexbe_msgs.msg
import ContainerStructure, BehaviorSync, BEStatus
11 from std_msgs.msg
import Empty, String, Int32, UInt8
21 self.
_pub = ProxyPublisher({
'flexbe/behavior_update': String,
22 'flexbe/request_mirror_structure': Int32})
35 self.
_sub = ProxySubscriberCached()
39 self._sub.subscribe(
'flexbe/mirror/structure', ContainerStructure, self.
_mirror_callback)
41 self._sub.subscribe(
'flexbe/mirror/sync', BehaviorSync, self.
_sync_callback)
50 rospy.logwarn(
'Received a new mirror structure while mirror is already running, ' 51 'adding to buffer (checksum: %s).' % str(msg.behavior_id))
53 rospy.logwarn(
'Checksum of received mirror structure (%s) does not match expected (%s), ' 54 'will ignore.' % (str(msg.behavior_id), str(self.
_active_id)))
57 rospy.loginfo(
'Received a new mirror structure for checksum %s' % str(msg.behavior_id))
59 self._struct_buffer.append(msg)
64 rospy.loginfo(
'Mirror built.')
69 if msg.code == BEStatus.STARTED:
70 thread = threading.Thread(target=self.
_start_mirror, args=[msg])
74 thread = threading.Thread(target=self.
_stop_mirror, args=[msg])
85 rospy.logwarn(
'Tried to start mirror while it is already running, will ignore.')
89 self.
_starting_path =
"/" + msg.args[0][1:].replace(
"/",
"_mirror/") +
"_mirror" 98 rospy.loginfo(
'Mirror built for checksum %s.' % self.
_active_id)
100 rospy.logwarn(
'Discarded mismatching buffered structure for checksum %s' % str(struct.behavior_id))
103 rospy.logwarn(
'Missing correct mirror structure, requesting...')
105 self._pub.publish(
'flexbe/request_mirror_structure', Int32(msg.behavior_id))
115 if msg
is not None and msg.code == BEStatus.FINISHED:
116 rospy.loginfo(
'Onboard behavior finished successfully.')
117 self._pub.publish(
'flexbe/behavior_update', String())
118 elif msg
is not None and msg.code == BEStatus.SWITCHING:
120 rospy.loginfo(
'Onboard performing behavior switch.')
121 elif msg
is not None and msg.code == BEStatus.READY:
122 rospy.loginfo(
'Onboard engine just started, stopping currently running mirror.')
123 self._pub.publish(
'flexbe/behavior_update', String())
124 elif msg
is not None:
125 rospy.logwarn(
'Onboard behavior failed!')
126 self._pub.publish(
'flexbe/behavior_update', String())
128 PreemptableState.preempt =
True 129 rate = rospy.Rate(10)
133 rospy.loginfo(
'No onboard behavior is active.')
140 if msg
is not None and msg.code != BEStatus.SWITCHING:
141 rospy.loginfo(
'\033[92m--- Behavior Mirror ready! ---\033[0m')
151 rospy.logerr(
'Cannot synchronize! Different behavior is running onboard, please stop execution!')
152 thread = threading.Thread(target=self.
_stop_mirror, args=[
None])
158 rospy.loginfo(
'Restarting mirror for synchronization...')
161 PreemptableState.preempt =
True 162 rate = rospy.Rate(10)
168 self.
_starting_path =
"/" + current_state_path[1:].replace(
"/",
"_mirror/") +
"_mirror" 169 rospy.loginfo(
'Current state: %s' % current_state_path)
172 rospy.loginfo(
'Mirror built.')
173 except (AttributeError, RuntimeError):
174 rospy.loginfo(
'Stopping synchronization because behavior has stopped.')
181 rospy.loginfo(
"Executing mirror...")
189 result = self._sm.spin()
190 except Exception
as e:
191 rospy.loginfo(
'Caught exception on preempt:\n%s' % str(e))
196 rospy.loginfo(
'Mirror finished with result ' + result)
202 for con_msg
in msg.containers:
203 if con_msg.path.find(
'/') == -1:
208 for con_msg
in msg.containers:
209 if con_msg.path.find(
'/') != -1:
210 self.
_state_checksums[zlib.adler32(con_msg.path.encode()) & 0x7fffffff] = con_msg.path
214 for con_msg
in msg.containers:
215 if con_msg.path == path:
220 if container.transitions
is not None:
222 for i
in range(len(container.transitions)):
223 transitions[container.outcomes[i]] = container.transitions[i] +
'_mirror' 225 path_frags = path.split(
'/')
226 container_name = path_frags[len(path_frags)-1]
227 if len(container.children) > 0:
229 for outcome
in container.outcomes:
230 sm_outcomes.append(outcome +
'_mirror')
231 sm = PreemptableStateMachine(outcomes=sm_outcomes)
233 for child
in container.children:
235 if len(transitions) > 0:
236 container_transitions = {}
237 for i
in range(len(container.transitions)):
238 container_transitions[sm_outcomes[i]] = transitions[container.outcomes[i]]
239 PreemptableStateMachine.add(container_name +
'_mirror', sm, transitions=container_transitions)
243 PreemptableStateMachine.add(container_name +
'_mirror',
244 MirrorState(container_name, path, container.outcomes, container.autonomy),
245 transitions=transitions)
248 if self.
_sm is not None:
249 rospy.logwarn(
'Explicit preempting is currently ignored, mirror should be preempted by onboard behavior.')
251 rospy.logwarn(
'Could not preempt mirror because it seems not to be running!')
def _stop_mirror(self, msg)
def _mirror_callback(self, msg)
def _status_callback(self, msg)
def _preempt_callback(self, msg)
def _add_node(self, msg, path)
def _mirror_state_machine(self, msg)
def _restart_mirror(self, msg)
def _sync_callback(self, msg)
def _start_mirror(self, msg)
def _execute_mirror(self)