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):
124 self.
pub = rospy.Publisher(self.
topic, Status, queue_size=1)
133 connect_timeout = property(get_connect_timeout, set_connect_timeout)
142 heartbeat_timeout = property(get_heartbeat_timeout, set_heartbeat_timeout)
151 disconnect_timeout = property(get_disconnect_timeout, set_disconnect_timeout)
159 heartbeat_period = property(get_heartbeat_period, set_heartbeat_period)
164 self.connect_timer.reset()
168 self.thread.daemon =
True 174 self.sm.ConnectTimeout()
179 disable_heartbeat_timeout = rospy.get_param(
180 Constants.DISABLE_HEARTBEAT_TIMEOUT_PARAM,
False)
181 if disable_heartbeat_timeout:
183 "Heartbeat timeout is disabled. Not breaking bond (topic: %s, id: %s)" %
188 self.sm.HeartbeatTimeout()
193 self.sm.DisconnectTimeout()
201 self.sub.unregister()
204 if self.sm.getState().getName() !=
'SM.Dead':
206 self.pub.unregister()
207 self.condition.notify_all()
208 self.connect_timer.cancel()
210 self.deadline.cancel()
214 if msg.id == self.
id and msg.instance_id != self.
instance_id:
221 "More than two locations are trying to use a single bond (topic: %s, id: %s). " +
222 "You should only instantiate at most two bond instances for each (topic, id) pair." %
227 self.sm.SisterAlive()
238 msg.header.stamp = rospy.Time.now()
244 self.pub.publish(msg)
249 while not self.
is_shutdown and self.sm.getState().getName()
in [
'SM.WaitingForSister',
'SM.Alive']:
254 while not self.
is_shutdown and self.sm.getState().getName() ==
'SM.AwaitSisterDeath':
256 self.condition.wait(Constants.DEAD_PUBLISH_PERIOD)
268 self.connect_timer.cancel()
269 self.condition.notify_all()
271 self.pending_callbacks.append(self.
on_formed)
275 self.heartbeat_timer.reset()
283 self.condition.notify_all()
284 self.heartbeat_timer.cancel()
285 self.disconnect_timer.cancel()
287 self.pending_callbacks.append(self.
on_broken)
291 self.heartbeat_timer.cancel()
292 self.disconnect_timer.reset()
310 self.deadline.cancel()
315 while self.sm.getState().getName() ==
'SM.WaitingForSister':
316 if rospy.is_shutdown():
318 if self.
deadline and self.deadline.left() == rospy.Duration(0):
322 wait_duration = min(wait_duration, self.deadline.left().to_sec())
323 self.condition.wait(wait_duration)
324 return self.sm.getState().getName() !=
'SM.WaitingForSister' 332 self.deadline.cancel()
337 while self.sm.getState().getName() !=
'SM.Dead':
338 if rospy.is_shutdown():
340 if self.
deadline and self.deadline.left() == rospy.Duration(0):
344 wait_duration = min(wait_duration, self.deadline.left().to_sec())
345 self.condition.wait(wait_duration)
346 return self.sm.getState().getName() ==
'SM.Dead' 352 return self.sm.getState().getName() ==
'SM.Dead' 362 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)