ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
2

How to check if network connection or remote ROS Master is down?

asked 2018-08-21 09:43:35 -0500

pavel92 gravatar image

updated 2018-08-21 09:47:29 -0500

I am running ROS (Kinetic on Ubuntu 16.04) on two machines (desktop pc and Jackal pc) and the Jackal pc is set as the ROS Master. The both machines are connected over a wireless network. I am writing a python node which is supposed to run on my machine and in case of being disconnected from the wifi to perform some action. To keep it simple for now, this action can be just a ROS warning. So my question is:

What is the best way in ROS to check/detect in the node code if the connection is down (i.e. my machine has disconnected from the network)?

When the connection goes down, the nodes that are run on my machine (in sourced terminals) are waiting for the master which is on the Jackal to be reconnected so that the publishers can continue to publish the messages. In this case when the connection is down if I run rostopic list in a sourced terminal there is no output at all. The same goes for any rosrun/roslaunch commands.
I am sure that there is also a way to check if there is a connection to the ROS Master but I could not find a working solution. I can always write my own timeout method but I would like to know if an proper way to do this already exists.

edit retag flag offensive close merge delete

Comments

If this definitely isn't a 'proper' method but you could use a system call to ifconfig <NIC_name> to find out if your wi-fi connection is down very quickly.

PeteBlackerThe3rd gravatar image PeteBlackerThe3rd  ( 2018-08-21 11:32:17 -0500 )edit

An alternative to checking (but something that might actually be better): a multimaster setup.

gvdhoorn gravatar image gvdhoorn  ( 2018-08-22 02:20:14 -0500 )edit

2 Answers

Sort by ยป oldest newest most voted
1

answered 2018-08-22 02:17:31 -0500

Reamees gravatar image

updated 2018-08-22 02:22:50 -0500

Seems like ros::master::check () would be one way to go.

API

techno74 asking and answering a similar question.

A similar function for python is mentioned in the previous question.

rosgraph.is_master_online()

edit flag offensive delete link more

Comments

1

I tried the rosgraph.is_master_online() and it works without a problem when there is a network connection. The problem still occurs when the network goes down as the node is in limbo state. In this case rosgraph blocks the node and fails to check for the master

pavel92 gravatar image pavel92  ( 2018-08-22 03:14:39 -0500 )edit

having same issue as pavel92, every method which somehow relies on rosgraph, somehow blocks. it s as though resorption until reconnecting

Ariel_GLR gravatar image Ariel_GLR  ( 2019-04-11 03:24:26 -0500 )edit

I'm also facing this issue. I've raised a PR with rosgraph here adding an optional timeout parameter to rosgraph.is_master_online(). In the meantime, the following solution seems to be sufficient, despite feeling a little hacky

import socket
...
socket.setdefaulttimeout(timeout)
rosgraph.is_master_online()
socket.setdefaulttimeout(None)
...
aa-tom gravatar image aa-tom  ( 2021-10-20 16:59:50 -0500 )edit
1

@aa-tom: might be nicer to do:

old_def_timeout = socket.getdefaulttimeout()
socket.setdefaulttimeout(timeout)
rosgraph.is_master_online()
socket.setdefaulttimeout(old_def_timeout)

that would future-proof it a little more (if it ever changes).

gvdhoorn gravatar image gvdhoorn  ( 2021-10-21 02:32:41 -0500 )edit

Is there anything like this for ROS2 as well? I mean obviously you can't check if the remote master is online, because there is no master. But can I check if another machine is online or if a specific node is running on the network?

max11gen gravatar image max11gen  ( 2022-03-07 02:37:58 -0500 )edit
1

answered 2022-08-18 06:32:29 -0500

ekptwtos gravatar image

updated 2022-08-18 07:13:52 -0500

ljaniec gravatar image

I would also like to add my input on this matter! The above solution is working fine and its native to ROS, however it stopped working for me when I started using Gstreamer to get a UDP webcam stream off of a RPI.

A bit more about the setup:

  • ROS Noetic on Linux 20.04
  • Static Network 10.0.0.x/24 ( 255.255.255.0 )
  • Laptop ( master ) address 10.0.0.1

                             Laptop (ROS master) <---- ethernet -----> RPI <--- USB camera 
       UDP stream receivever <-/                                        \-> UDP stream sender
    

using rosgraph.is_master_online() would detect the connection, however when the ethernet cable was disconnected, everything ROS related on the RPI side would halt.

What solved that issue, was an approach that slightly deviated from the pure ROS methods. I created a function following this tutorial that would check if there is a connection with the master:

 def ping_master(self):
    # try to ping the master IP
    try:
        socket.setdefaulttimeout(1)
        # if we do not receive data for 1 second except will kick in

        soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # AF_INET: address family
        # SOCK_STREAM: type for TCP

        host = "10.0.0.1"
        port = 11311

        server_address = (host, port)
        soc.connect(server_address)

    except OSError as error:
        return False
        # function returns false value
        # disconnection is detected

    else:
        soc.close()
        # closing the connection after the
        # communication with the master is complete
        return True

Do not forget to change the host and port based on your network setup!

And call it in the main loop like so:

while not rospy.is_shutdown():
    try:
        mainRate.sleep()
    except rospy.ROSInterruptException:  # shutdown
        break


    if self.ping_master():

        print("{}: {} - Ros Master Is Online".format(time.strftime("%d.%m.%Y-%H:%M:%S"),self.node_name))
        # do stuff here when master is online 

    else:

        print("{}: {} - Ros Master Went Offine".format(time.strftime("%d.%m.%Y-%H:%M:%S"),self.node_name))
        # do stuff here when master is offline 


    rospy.on_shutdown(self.on_shutdown_cb)

Hope this helps someone in the future!

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2018-08-21 09:43:35 -0500

Seen: 3,348 times

Last updated: Aug 18 '22