Explain about publish_once_cmd_vel()

Hi,

I see this code:

def publish_once_in_cmd_vel(self):
    while self.controlC == False:
        connections = self.cmdVelPublisher.get_num_connections()
        print(f"connections: {connections}")

        if connections > 0:
            self.cmdVelPublisher.publish(self.twist)
            rospy.loginfo("/cmd_vel Published")
            break
        else:
            self.rate.sleep()

I am curious about connections then I print connections to see the result.

  1. The first case: only 1 connection
    Connections are 0 for several loops then connections are 1 => Published => Robot moves. It’s ok. I understood

  2. The second case: more than 1 connection
    I use 3 other terminals to subscribe /cmd_vel. I turn them on before running the above code
    Connections are 0 for the first loop then connections are 3 => Published => Robot does not move.

Could you explain why?

Hi @NguyenDuyDuc,

Regarding your question, I believe the purpose of connections is to get the number of subscribers that are connected or are listening to the topic /cmd_vel which essentially publishes or contains the movement commands to make the robot move. As such, should the condition above be met, then essentially what occurs is the program will be prompted to send or publish a message in the form of a Twist type whose contents I have specified below into the /cmd_vel topic that will then be acquired by any active subscribers. Afterwards, you will then be notified once the message has been published through the line “rospy.loginfo(“/cmd_vel Published”)”.

Going over your second question, I believe the primary reason as to why it fails to make the robot move in the other terminals could perhaps be attributed to its structure – that is, it only checks for any listening subscribers once. One factor that may be considered could be in terms of synchronization whereby some subscribers are unable to effectively receive the published message and at the same time, the timing as well; furthermore, given that it will be publishing this information into multiple subscribers that are perhaps intended to control the same robot, there could possibly be conflicts in terms of the nature of the operations present in each of these scripts.

One possible way for you to check is to perhaps echo the contents of the topic or in separate terminals, try to create a subscriber that would simply print the contents of the topic it is subscribing to to make sure that the messages are being correctly published into a particular topic which in this case would be that of /cmd_vel through the use of ‘rostopic echo [topic_name]’.

Hope this helps!

Regards,
Christian

I have one more question:

def publish_once(self, publisher, data):
    rospy.sleep(0.5)
    while self.ctrlC == False:
        connections = publisher.get_num_connections()
        rospy.loginfo(f"connections: {connections}")
        if connections > 10:
            publisher.publish(data)
            rospy.loginfo(f"publish: {publisher.name}")
            break
        else:
            self.rate10.sleep()
    else:
        print("ctrlC = True")

def shutDownHook(self):
    self.ctrlC = True
    print("shutdown")

My code will be always in while loop. Then I press Ctrl + C → it will go into shutDownHook → print(shutdown) → but it never come back to while loop anymore to print (ctrlC = True).

If it never comeback, why do we have to use: while self.ctrlC == False:

Thanks

Hi,
To trigger event on the shutdown of the node, the getter rospy.is_shutdown() could be a good way.
I used it as condition in the code and it should work as expected:
def publish_once(self, publisher, data):
rospy.sleep(0.5)

    while not rospy.is_shutdown():
        print(self.ctrlC)
        connections = publisher.get_num_connections()
        rospy.loginfo(f"connections: {connections}")
        if connections > 10:
            publisher.publish(data)
            rospy.loginfo(f"publish: {publisher.name}")
            break
        else:
            self.rate10.sleep()
    else:
        print("ctrlC = True")

def shutDownHook(self):
    self.ctrlC = True
    print("shutdown")

I try the piece of code provided and I have the same bahavior than you.

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.