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

How to check whether the topic is publishing msg?

asked 2019-10-07 02:30:35 -0500

pumpkin gravatar image

updated 2019-10-07 03:11:08 -0500

Hello,

Actually, I have a topic which is used to publish something about Object Detection. The problem is when I perform the operation, the node may detect nothing and publish nothing. Because the current angle of the robot may not see anything useful.

So this is my question: this topic may have published msg a second ago, but not at this moment. What can I do to detect it?

I have try this before:

while true:
    try:
        msg = rospy.wait_for_message(topic, topic_type, 1)
    except rospy.exceptions.ROSException:

    else:

But it works at the beginning and fails during use.

Thanks

edit retag flag offensive close merge delete

Comments

1

wait_for_message will get the first message that is published. If you want continuous subscription use normal subscriber.

Choco93 gravatar image Choco93  ( 2019-10-07 03:51:43 -0500 )edit

Is the question how to detect stale/hung-up topics?

gvdhoorn gravatar image gvdhoorn  ( 2019-10-07 04:22:55 -0500 )edit

To complete the comment above, you can use a normal subscriber in rospy (rospy.subscribe(...) at the beginning of your code), since the spinning is threaded in rospy, you will always execute the callback function (without calling rospy.spin())

lmathieu gravatar image lmathieu  ( 2019-10-07 04:24:42 -0500 )edit

Actually, when the topic is not publishing msg, I need do some action. So its important for me to detect whether the topic is publishing...

pumpkin gravatar image pumpkin  ( 2019-10-07 04:41:28 -0500 )edit

take a look here, with this you can get list of all topics that are advertising, you can look for your topic in there and if it's not then do your action.

Choco93 gravatar image Choco93  ( 2019-10-07 04:48:37 -0500 )edit

Thank you for the answer but I have just tried the get_published_topics and I think it will list all topics which is registered in master, without checking whether it is publishing msg or not...

pumpkin gravatar image pumpkin  ( 2019-10-07 06:17:59 -0500 )edit

I have used its counterpart in c++, I wanted to know when a topic is being advertised and that worked for me, and documentation says that it should report all topics that are being published so it should work. But you can verify its working easily.

Choco93 gravatar image Choco93  ( 2019-10-07 06:23:10 -0500 )edit

Yes, it's work for advertised topics (I use it too in c++), but pumpkin want to know when a message is published (Well, actually 'not' published), and get_published_topics will report a topics as a publisher when calling rospy.Publisher(..), even if the Publisher never .publish(..)

lmathieu gravatar image lmathieu  ( 2019-10-07 06:58:09 -0500 )edit

1 Answer

Sort by » oldest newest most voted
7

answered 2019-10-07 05:54:22 -0500

updated 2019-10-08 02:21:51 -0500

I can see 2 solution based on your comment :

1)

Check this solution : https://answers.ros.org/question/2443... (the one at the bottom) You can get more info here : http://wiki.ros.org/Topics#Topic_stat... It give you a nice approach to detect if message are not received (by using TopicStatistics.traffic or TopicStatistics.delivered_msgs, by checking for how long the data remain the same). I just discovered TopicStatistics, so I cannot give you any insight on how to use it (and how it affect performance, if it do)

EDIT: Topics statistics messages are send by the subscriber, when the subscriber received a message, hence it will not be usable in your use case (when the subscriber doesn't received a message).

2)

You can use some Python basic library to do the job :

import rospy
import threading # Needed for Timer
from std_msgs.msg import String

rospy.init_node("test")

def timeout():
    print("No message received for 5 seconds")
    # Do something

def callback(msg):
    global timer
    print("Message received")
    timer.cancel()
    timer = threading.Timer(5,timeout)
    timer.start()
    # Do Other thing

rospy.Subscriber("/test",String, callback) # When receiving a message, call callback()
timer = threading.Timer(5,timeout) # If 5 seconds elapse, call timeout()
timer.start()

while not rospy.is_shutdown():
    #Do something else
    rospy.sleep(1)

This code give you the idea, by using a timer you can check when no message are received. If a message is received, you reset the timer (By cancelling and starting a new timer). If no message are received, then you can do what you want in the timeout() function.

edit flag offensive delete link more

Comments

Thank you for answering, it helps me a lot. Its a very ingenious method by using thread, I'll also check the TopicStatistics later. Thank you so much again!

pumpkin gravatar image pumpkin  ( 2019-10-07 21:26:11 -0500 )edit

No problem, I edited my answers after some test with topics statistics, I don't think it will help you a lot for this problem, as no statistics are sent when the subscriber doesn't receive a message (the statistics are sent by the subscriber)

lmathieu gravatar image lmathieu  ( 2019-10-08 02:24:58 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2019-10-07 02:30:35 -0500

Seen: 6,116 times

Last updated: Oct 08 '19