rosping_existence.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 """
4 rosping_existence.py
5 
6 check the existence of the ros nodes and publish the result to diagnostics
7 """
8 
9 import rospy
10 try:
11  from xmlrpc.client import ServerProxy
12 except ImportError:
13  from xmlrpclib import ServerProxy
14 
15 from rosnode import *
16 import sys
17 import roslaunch
18 import diagnostic_updater
19 import diagnostic_msgs
20 from sound_play.msg import SoundRequest
21 
22 def _succeed(args):
23  code, msg, val = args
24  if code != 1:
25  raise ROSNodeException("remote call failed: %s"%msg)
26  return val
27 
28 def ping(node_name, max_count=None, verbose=False):
29  """
30  Test connectivity to node by calling its XMLRPC API
31  @param node_name: name of node to ping
32  @type node_name: str
33  @param max_count: number of ping requests to make
34  @type max_count: int
35  @param verbose: print ping information to screen
36  @type verbose: bool
37  @return: True if node pinged
38  @rtype: bool
39  @raise ROSNodeIOException: if unable to communicate with master
40  """
41  master = rosgraph.Master(ID)
42  node_api = get_api_uri(master,node_name)
43  if not node_api:
44  # print "cannot ping [%s]: unknown node" % node_name, file=sys.stderr
45  return False
46 
47  timeout = 3.
48 
49  if verbose:
50  print("pinging %s with a timeout of %ss"%(node_name, timeout))
51  socket.setdefaulttimeout(timeout)
52  node = ServerProxy(node_api)
53  lastcall = 0.
54  count = 0
55  acc = 0.
56  try:
57  while True:
58  try:
59  count += 1
60  start = time.time()
61  pid = _succeed(node.getPid(ID))
62  end = time.time()
63 
64  dur = (end-start)*1000.
65  acc += dur
66 
67 
68  if verbose:
69  print("xmlrpc reply from %s\ttime=%fms"%(node_api, dur))
70  # 1s between pings
71  except socket.error as e:
72  # 3786: catch ValueError on unpack as socket.error is not always a tuple
73  try:
74  # #3659
75  errnum, msg = e
76  if errnum == -2: #name/service unknown
77  p = urlparse.urlparse(node_api)
78  #print("ERROR: Unknown host [%s] for node [%s]"%(p.hostname, node_name), file=sys.stderr)
79  elif errnum == errno.ECONNREFUSED:
80  # check if node url has changed
81  new_node_api = get_api_uri(master,node_name, skip_cache=True)
82  if not new_node_api:
83  #print("cannot ping [%s]: unknown node"%node_name, file=sys.stderr)
84  return False
85  if new_node_api != node_api:
86  if verbose:
87  print("node url has changed from [%s] to [%s], retrying to ping"%(node_api, new_node_api))
88  node_api = new_node_api
89  node = ServerProxy(node_api)
90  continue
91  #print("ERROR: connection refused to [%s]"%(node_api), file=sys.stderr)
92  else:
93  pass
94  #print("connection to [%s] timed out"%node_name, file=sys.stderr)
95  return False
96  except ValueError:
97  print("unknown network error contacting node: %s"%(str(e)))
98  if max_count and count >= max_count:
99  break
100  time.sleep(1.0)
101  except KeyboardInterrupt:
102  pass
103 
104  if verbose and count > 1:
105  print("ping average: %fms"%(acc/count))
106  return True
107 
109  global nodes, speak_text
110  result = {}
111  have_dead = False
112  for n in nodes:
113  res = ping(n, max_count = 1, verbose = False)
114  result[n] = res
115  if not res:
116  have_dead = True
117  if have_dead:
118  stat.summary(diagnostic_msgs.msg.DiagnosticStatus.ERROR,
119  "dead nodes: " + ", ".join([n for (n, res)
120  in result.items() if not res]))
121  if speak:
122  sound = SoundRequest()
123  sound.sound = SoundRequest.SAY
124  sound.command = SoundRequest.PLAY_ONCE
125  if speak_text:
126  sound.arg = speak_text
127  else:
128  sound.arg = " ".join(nodes).replace("/", "").replace("_", " ") + " is dead"
129  g_robotsound_pub.publish(sound)
130  else:
131  stat.summary(diagnostic_msgs.msg.DiagnosticStatus.OK,
132  "every node is alive")
133  for n, res in result.items():
134  stat.add(n, res)
135  return stat
136 
137 if __name__ == "__main__":
138  rospy.init_node('rosping_existence')
140  updater.setHardwareID(rospy.get_name())
141  updater.add("node existence", checkNodeExistence)
142  argv = rospy.myargv()
143  # you can specify the list of the launch files
144  # launch_files = argv[1:]
145  # config = roslaunch.config.load_config_default(launch_files, 0)
146  # nodes = [n.namespace + n.name for n in config.nodes]
147  nodes = argv[1:]
148  speak = rospy.get_param("~speak", False)
149  speak_text = rospy.get_param("~speak_text", "")
150  if speak:
151  g_robotsound_pub = rospy.Publisher("/robotsound", SoundRequest)
152  r = rospy.Rate(0.01)
153  while not rospy.is_shutdown():
154  updater.update()
155  r.sleep()
156 
def ping(node_name, max_count=None, verbose=False)
def checkNodeExistence(stat)


jsk_topic_tools
Author(s): Kei Okada , Yusuke Furuta
autogenerated on Tue Feb 6 2018 03:45:19