36 from .
import BondSM_sm
38 from bond.msg
import Constants, Status
42 if not isinstance(d, rospy.Duration):
43 return rospy.Duration.from_sec(d)
48 if isinstance(d, rospy.Duration):
58 self.timer.daemon =
True 64 self.
timer = threading.Timer(self.duration.to_sec(), self.
_on_timer)
65 self.timer.daemon =
True 67 self.
deadline = time.time() + self.duration.to_sec()
74 return max(rospy.Duration(0), rospy.Duration(self.
deadline - time.time()))
94 def __init__(self, topic, id, on_broken=None, on_formed=None):
126 self.
pub = rospy.Publisher(self.
topic, Status, queue_size=1)
135 connect_timeout = property(get_connect_timeout, set_connect_timeout)
144 heartbeat_timeout = property(get_heartbeat_timeout, set_heartbeat_timeout)
153 disconnect_timeout = property(get_disconnect_timeout, set_disconnect_timeout)
161 heartbeat_period = property(get_heartbeat_period, set_heartbeat_period)
166 self.connect_timer.reset()
170 self.thread.daemon =
True 176 self.sm.ConnectTimeout()
181 disable_heartbeat_timeout = rospy.get_param(
182 Constants.DISABLE_HEARTBEAT_TIMEOUT_PARAM,
False)
183 if disable_heartbeat_timeout:
185 "Heartbeat timeout is disabled. Not breaking bond (topic: %s, id: %s)" %
190 self.sm.HeartbeatTimeout()
195 self.sm.DisconnectTimeout()
203 if self.
sub is not None:
204 self.sub.unregister()
207 if self.sm.getState().getName() !=
'SM.Dead':
209 self.pub.unregister()
210 self.condition.notify_all()
211 self.connect_timer.cancel()
213 self.deadline.cancel()
217 if msg.id == self.
id and msg.instance_id != self.
instance_id:
224 "More than two locations are trying to use a single bond (topic: %s, id: %s). " +
225 "You should only instantiate at most two bond instances for each (topic, id) pair." %
230 self.sm.SisterAlive()
241 msg.header.stamp = rospy.Time.now()
247 self.pub.publish(msg)
252 while not self.
is_shutdown and self.sm.getState().getName()
in [
'SM.WaitingForSister',
'SM.Alive']:
257 while not self.
is_shutdown and self.sm.getState().getName() ==
'SM.AwaitSisterDeath':
259 self.condition.wait(Constants.DEAD_PUBLISH_PERIOD)
271 self.connect_timer.cancel()
272 self.condition.notify_all()
274 self.pending_callbacks.append(self.
on_formed)
278 self.heartbeat_timer.reset()
286 self.condition.notify_all()
287 self.heartbeat_timer.cancel()
288 self.disconnect_timer.cancel()
290 self.pending_callbacks.append(self.
on_broken)
294 self.heartbeat_timer.cancel()
295 self.disconnect_timer.reset()
313 self.deadline.cancel()
318 while self.sm.getState().getName() ==
'SM.WaitingForSister':
319 if rospy.is_shutdown():
321 if self.
deadline and self.deadline.left() == rospy.Duration(0):
325 wait_duration = min(wait_duration, self.deadline.left().to_sec())
326 self.condition.wait(wait_duration)
327 return self.sm.getState().getName() !=
'SM.WaitingForSister' 335 self.deadline.cancel()
340 while self.sm.getState().getName() !=
'SM.Dead':
341 if rospy.is_shutdown():
343 if self.
deadline and self.deadline.left() == rospy.Duration(0):
347 wait_duration = min(wait_duration, self.deadline.left().to_sec())
348 self.condition.wait(wait_duration)
349 return self.sm.getState().getName() ==
'SM.Dead' 355 return self.sm.getState().getName() ==
'SM.Dead' 365 return "[Bond %s, Instance %s (%s)]" % \
def wait_until_formed(self, timeout=None)
Blocks until the bond is formed for at most 'duration'.
def Connected(self)
INTERNAL.
def _on_bond_status(self, msg)
def get_disconnect_timeout(self)
def set_disconnect_timeout(self, dur)
def StartDying(self)
INTERNAL.
def get_connect_timeout(self)
def get_heartbeat_period(self)
def _on_heartbeat_timeout(self)
def get_heartbeat_timeout(self)
def wait_until_broken(self, timeout=None)
Blocks until the bond is broken for at most 'duration'.
def set_heartbeat_timeout(self, dur)
def is_broken(self)
Indicates if the bond is broken.
def __init__(self, duration, on_timeout=None)
def _publishing_thread(self)
def __init__(self, topic, id, on_broken=None, on_formed=None)
Constructs a bond, but does not connect.
def _on_disconnect_timeout(self)
def set_broken_callback(self, on_broken)
Sets the broken callback.
def set_connect_timeout(self, dur)
def _flush_pending_callbacks(self)
Forms a bond to monitor another process.
def start(self)
Starts the bond and connects to the sister process.
def _publish(self, active)
def break_bond(self)
Breaks the bond, notifying the other process.
def set_heartbeat_period(self, per)
def set_formed_callback(self, on_formed)
Sets the formed callback.
def Heartbeat(self)
INTERNAL.
def SisterDied(self)
INTERNAL.
def _on_connect_timeout(self)