Skip to content

Instantly share code, notes, and snippets.

@Alabate
Created May 1, 2019 19:01
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Alabate/9b2467018503e8d96c366e3448d34d2c to your computer and use it in GitHub Desktop.
Save Alabate/9b2467018503e8d96c366e3448d34d2c to your computer and use it in GitHub Desktop.
rosbridge watcher
#!/usr/bin/env python3
import rospy
import urllib.request
import urllib.error
import socket
import os
# This is not a param to avoid param injection
# or unexpected programm killed because of a simple rosparam set with a wrong value
ROSBRIDGE_BIN_PATH = '/opt/ros/melodic/lib/rosbridge_server/rosbridge_websocket'
class RosbridgeWatcher():
"""
Watch the health of the rosbridge and restart it if not available.
"""
def __init__(self):
self.rosbridge_uri = rospy.get_param('rosbridge_uri', 'http://localhost:9090')
self.watch_period = rospy.get_param('watch_period', 1.0)
self.grace_period = rospy.get_param('grace_period', 60.0)
self.timeout = rospy.get_param('timeout', 10)
self.watch_timer = rospy.Timer(rospy.Duration(self.watch_period), self.watch)
self.last_kill = rospy.Time()
rospy.get_rostime()
def watch(self, req):
"""
Try to connect to websocket bridge to check if bridge is OK
"""
# Check if in gace period
last_kill_sec = (rospy.get_rostime() - self.last_kill).to_sec()
if last_kill_sec < self.grace_period:
rospy.logdebug('Grace period.')
return
# Try to do a simple http request, we don't care about the result
# We just want to know if it fails because of timeout or not
try:
urllib.request.urlopen(self.rosbridge_uri, timeout=self.timeout)
except socket.timeout as e:
self.restart_rosbridge()
except urllib.error.URLError as e:
if isinstance(e.reason, socket.timeout):
self.restart_rosbridge()
def restart_rosbridge(self):
rospy.logwarn('Rosbridge not responding, need to restart it!')
self.last_kill = rospy.get_rostime()
# Using rosnode.kill_nodes doens't work, so use linux signals..
os.system('pkill -QUIT -f ' + ROSBRIDGE_BIN_PATH)
if __name__ == "__main__":
rospy.init_node('rosbridge_watcher', log_level=rospy.INFO)
rosbridge_watcher = RosbridgeWatcher()
rospy.spin()
@Alabate
Copy link
Author

Alabate commented May 1, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment