0
$\begingroup$

Rosanswers logo

I want to publish a single /initialpose message when a node is run. How can I make sure it's only published once?

This is what I have:

#!/usr/bin/env python

import rospy
from geometry_msgs.msg import Pose, PoseWithCovarianceStamped
from std_msgs.msg import Header
from numpy import matrix

class PoseChange:
    def __init__(self):
        self.msg = PoseWithCovarianceStamped()
        rospy.init_node("pose_change", anonymous=True)
        rospy.Subscriber('/pose', Pose, self.callback)
        self.pub = rospy.Publisher('/initialpose', PoseWithCovarianceStamped, queue_size=3)

    def callback(self, data):
        self.msg.header = Header()
        self.msg.header.stamp = rospy.Time.now()
        self.msg.header.frame_id = "map"
        self.msg.pose.pose = data
        self.msg.pose.covariance = matrix([[0.09, 0, 0, 0, 0, 0], 
                                           [0, 0.09, 0, 0, 0, 0],
                                           [0, 0, 0.09, 0, 0, 0],
                                           [0, 0, 0, 0.25, 0, 0],
                                           [0, 0, 0, 0, 0.25, 0],
                                           [0, 0, 0, 0, 0, 0.25]])

    def run(self):
        self.pub.publish(self.msg)

if __name__ == "__main__":
    try:
        m = PoseChange()
        m.run()
    except rospy.ROSInterruptException:
        raise e

However, this never publishes when run. The /pose topic it's listening to is continuously publishing at 50 Hz.


Originally posted by j1337 on ROS Answers with karma: 25 on 2017-07-24

Post score: 1

$\endgroup$

3 Answers 3

0
$\begingroup$

Rosanswers logo

Hi @j1337,

ROS takes some time to notify the publishers and subscribers of the topics. So, you have two options:

1 - Sleep some seconds before publish the first message. In the "main" part of your code could be done like:

if __name__ == "__main__":
    try:

        from time import sleep
        print 'Sleeping 10 seconds to publish'
        sleep(10)
        print 'Sleep finished.'

        m = PoseChange()
        m.run()
    except rospy.ROSInterruptException:
        raise e

2 - Make sure that there are subscribers (using get_num_connections) when you starts publishing. In the "main" part of your code it would be like:

if __name__ == "__main__":
    try:
        m = PoseChange()
        rate = rospy.Rate(10)  # 10hz
        while not rospy.is_shutdown():
            connections = m.pub.get_num_connections()
            rospy.loginfo('Connections: %d', connections)
            if connections > 0:
                m.run()
                rospy.loginfo('Published')
                break
            rate.sleep()

    except rospy.ROSInterruptException, e:
        raise e

If you still have doubts, I made a video (https://youtu.be/BGV6DI_PItA) that shows how to solve exactly this question by checking the subscribers.


Originally posted by Ruben Alves with karma: 1038 on 2017-07-24

This answer was ACCEPTED on the original site

Post score: 4


Original comments

Comment by j1337 on 2017-07-24:
Thank you. This was extremely helpful.

Comment by jayess on 2017-08-09:
Why not explain exactly how to solve this question here? The problem with linking to a video for more steps is that now part of the answer is external and this answer is not self-contained. What if the video gets taken down?

Comment by Ruben Alves on 2017-10-09:
Ok, now the answer is self contained, @jayess.

Thanks for the advice.

Comment by AlessandroSaviolo on 2020-03-19:
THANK YOU!

$\endgroup$
0
$\begingroup$

Rosanswers logo

I think it's a known problem. The thing is that when you create a publisher, it's not connect yet to ROS master server. That's why you are not able to publish the message. You can try to "sleep" for a while, like 1~5 seconds, and the publisher will be connected.

If you need to publish something just once, I'd recommend you to use a ROS service.

You can check other related questions:


Originally posted by marcoarruda with karma: 541 on 2017-07-24

This answer was NOT ACCEPTED on the original site

Post score: 1

$\endgroup$
0
$\begingroup$

Rosanswers logo

I think the problem is related to this similar question : "How do I publish exactly one message?"

The problem there was that the message was being published before the publisher or it's subscriber had time to setup all the way, the solution was to wait for a subscriber to subscribe before publishing (in rospy that would use get_num_connections.)


Originally posted by Airuno2L with karma: 3460 on 2017-07-24

This answer was NOT ACCEPTED on the original site

Post score: 2

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.