示例#1
0
  def __init__(self, monitor_port=11611, domain=''):
    '''..........................................................................
    Initialize method of the local master.
    @param monitor_port: The port of the RPC Server, used to get more information about the ROS master.
    @type monitor_port:  int
    ..........................................................................'''
    if rospy.has_param('~rosmaster_hz'):
      Discoverer.ROSMASTER_HZ = rospy.get_param('~rosmaster_hz')

    self.master_monitor = MasterMonitor(monitor_port)
    name = self.master_monitor.getMastername()
    # create the txtArray for the zeroconf service of the ROS master
    materuri = self.master_monitor.getMasteruri()
    # test the host for local entry
    masterhost, masterport = MasterInfo.MasteruriToAddr(materuri)
    if (masterhost in ['localhost', '127.0.0.1']):
      sys.exit("'%s' is not reachable for other systems. Change the ROS_MASTER_URI!", masterhost)
    rpcuri = ''.join(['http://', socket.gethostname(), ':', str(monitor_port), '/'])
    txtArray = ["timestamp=%s"%str(0), "master_uri=%s"%materuri, "zname=%s"%rospy.get_name(), "rpcuri=%s"%rpcuri]
    # the Zeroconf class, which contains the QMainLoop to receive the signals from avahi
    Zeroconf.__init__(self, name, '_ros-master._tcp', masterhost, masterport, domain, txtArray)
    # the list with all ROS master neighbors with theirs SyncThread's and all Polling threads
    self.masters = MasterList(self.masterInfo, self.requestResolve, self.checkLocalMaster)
    # set the callback to finish all running threads
    rospy.on_shutdown(self.finish)
示例#2
0
def getDefaultRPCPort(zeroconf=False):
  try:
    masteruri = MasterMonitor._masteruri_from_ros()
    rospy.loginfo("ROS Master URI: %s", masteruri)
    from urlparse import urlparse
    return urlparse(masteruri).port+(600 if zeroconf else 300) 
  except:
    import traceback
    print traceback.format_exc()
    return 11911 if zeroconf else 11611
示例#3
0
def getDefaultRPCPort(zeroconf=False):
  try:
    masteruri = MasterMonitor._masteruri_from_ros()
    rospy.loginfo("ROS Master URI: %s", masteruri)
    from urlparse import urlparse
    return urlparse(masteruri).port+(600 if zeroconf else 300) 
  except:
    import traceback
    print traceback.format_exc()
    return 11911 if zeroconf else 11611
示例#4
0
class Discoverer(Zeroconf):
  '''
  This class is a subclass of Zeroconf to handle the callback of the avahi daemon.
  Furthermore the informations of the local ROS master will be stored and a 
  method to check the state of the local ROS master and update it in avahi if 
  needed. A list with all remote ROS masters is managed by MasterList.
  '''
  ROSMASTER_HZ = 2 # the test rate of ROS master state in hz

  def __init__(self, monitor_port=11611, domain=''):
    '''..........................................................................
    Initialize method of the local master.
    @param monitor_port: The port of the RPC Server, used to get more information about the ROS master.
    @type monitor_port:  int
    ..........................................................................'''
    if rospy.has_param('~rosmaster_hz'):
      Discoverer.ROSMASTER_HZ = rospy.get_param('~rosmaster_hz')

    self.master_monitor = MasterMonitor(monitor_port)
    name = self.master_monitor.getMastername()
    # create the txtArray for the zeroconf service of the ROS master
    materuri = self.master_monitor.getMasteruri()
    # test the host for local entry
    masterhost, masterport = MasterInfo.MasteruriToAddr(materuri)
    if (masterhost in ['localhost', '127.0.0.1']):
      sys.exit("'%s' is not reachable for other systems. Change the ROS_MASTER_URI!", masterhost)
    rpcuri = ''.join(['http://', socket.gethostname(), ':', str(monitor_port), '/'])
    txtArray = ["timestamp=%s"%str(0), "master_uri=%s"%materuri, "zname=%s"%rospy.get_name(), "rpcuri=%s"%rpcuri]
    # the Zeroconf class, which contains the QMainLoop to receive the signals from avahi
    Zeroconf.__init__(self, name, '_ros-master._tcp', masterhost, masterport, domain, txtArray)
    # the list with all ROS master neighbors with theirs SyncThread's and all Polling threads
    self.masters = MasterList(self.masterInfo, self.requestResolve, self.checkLocalMaster)
    # set the callback to finish all running threads
    rospy.on_shutdown(self.finish)
#    #start the signal main loop
#    if (not rospy.is_shutdown()):
#      self.start()


  @property
  def getName(self):
    return self.masterInfo.name

  def finish(self, *args):
    '''..........................................................................
    Removes all remote masters and unregister their topics and services. Stops 
    the QMainLoop of avahi.
    ..........................................................................'''
    rospy.logdebug("Stop zeroconf DBusGMainLoop")
    if hasattr(self.master_monitor, 'rpcServer'):
      self.master_monitor.rpcServer.shutdown()
    self.stop()
    self.masters.removeAll()

  def __repr__(self):
    '''..........................................................................
    String representation of local ros manager
    ..........................................................................'''
    return ''.join(['Discoverer: ', repr(self.masterInfo)])

  def on_server_running(self):
    rospy.loginfo("Zeroconf server now running.")

  def on_server_collision(self):
    rospy.logfatal("Zeroconf server collision.")
    self.collision = True
    self.finish()
    rospy.signal_shutdown("Zeroconf server collision.")

  def on_server_failure(self):
    rospy.logfatal("Zeroconf server error.")
    self.finish()
    rospy.signal_shutdown("on_server_failure")

  def on_group_established(self):
    rospy.logdebug("Service %s established.", self.masterInfo.name)

  def on_group_collision(self):
    if not self.isStopped():
      rospy.logwarn("ERROR: Service name collision. %s already exists. Retry in 3 sec...", self.masterInfo.name)
      self._removeService()
      time.sleep(3)
      self._registerService()

  def on_group_failure(self, error):
    rospy.logfatal("Error in group %s: %s", self.masterInfo.name, error)
    self.finish()
    rospy.signal_shutdown("Error in group")

  def on_group_removed(self, name):
    if (name != self.masterInfo.name):
      rospy.loginfo("%s group removed from zeroconf.", name)
      self.masters.removeMaster(name)

  def on_resolve_reply(self, master_info):
    rospy.logdebug("on_resolve_reply: %s", master_info.name)
    self.masters.updateMaster(master_info)

  def on_service_updated(self):
    self.masters.updateMaster(self.masterInfo)
     
  def on_resolve_error(self):
    self.masters.checkMastersState()

  def checkLocalMaster(self, master_info):
    '''..........................................................................
    Compares the current state of the local ROS master. If the state was changed
    the avahi sevice will be updated
    @param master_info: will not be used, is only for compatibility to the Polling class.
    ..........................................................................'''
    # get the state of the local ROS master
    try:
      # compare the current system state of ROS master with stored one and update the timestamp if needed
      if self.master_monitor.checkState():
        # sets a new timestamp in zeroconf
#        rospy.logdebug("state of local master changed")
        rpcuri = self.masterInfo.getTXTValue('rpcuri', '')
        masteruri = self.masterInfo.getTXTValue('master_uri', '')
        self.masterInfo.txt = ["timestamp=%s"%str(self.master_monitor.getCurrentState().timestamp), "master_uri=%s"%masteruri, "zname=%s"%rospy.get_name(), "rpcuri=%s"%rpcuri]
        self.updateService(self.masterInfo.txt)
      return self.masterInfo
    except:
      import traceback
      rospy.logerr("Error while check local master: %s", traceback.format_exc())
    return None