0
$\begingroup$

I am trying to be able to control when do I publish so I tried to put the rospy.Timer in a while loop. I did not use rospy.Rate or rate.sleep because I found out that it somehow interferes with the signal of another node(if someone could help on this would be nice too). However when I put the rospy.Timer in a loop it does not seem working as intended

This is my publisher code

   #!/usr/bin/env python

     import rospy
     from std_msgs.msg import Int16
     from std_msgs.msg import String

     pub_1=rospy.Publisher('file_update',Int16,queue_size=30)
     shutdown_signal = False  # Flag to indicate whether to shut down the publisher
     rate=10
     def update_file():

     global shutdown_signal
     while not shutdown_signal:
         rospy.Timer(rospy.Duration(1/rate),publish)

  def publish(event):

     num_msg=23
     pub_1.publish(num_msg)

  def shutdown(data):

     global shutdown_signal
     shutdown_signal = True
     #rospy.loginfo("Received shutdown signal")

 if __name__ == '__main__':

    rospy.init_node('file_update_publisher', anonymous=True)
    rospy.Subscriber('shutdown_publisher', String, shutdown)
    try:
        update_file()
    except rospy.ROSInterruptException:
        print("An exception occured")

And this is my subscriber code

  #!/usr/bin/env python3

  import rospy
  from std_msgs.msg import String
  from std_msgs.msg import Int16

  def file_update_callback(data):

      number=data.data
      print(number)
      shutdown_pub = rospy.Publisher('shutdown_publisher', String, queue_size=1)
      shutdown_pub.publish("Shutdown")

  def listen_file_update():
      rospy.init_node('file_update_listener', anonymous=True)
      rospy.Subscriber('file_update', Int16, file_update_callback)
      rospy.spin()

  if __name__ == '__main__':
     listen_file_update()
$\endgroup$

1 Answer 1

1
$\begingroup$

The rospy.Timer object is designed to operate asynchronously. When you create a Timer inside a while loop, it attempts to create a new timer on each iteration of the loop. This will lead to unexpected behavior, as these timers are not being properly managed or canceled.

The callback publish in the Timer is designed to be called at regular intervals specified by the duration.

Revised publisher code (with minimal changes):

#!/usr/bin/env python

import rospy
from std_msgs.msg import Int16, String

pub_1 = rospy.Publisher('file_update', Int16, queue_size=30)
shutdown_signal = False

def publish(event):
    if not shutdown_signal:
        num_msg = 23
        pub_1.publish(num_msg)

def shutdown(data):
    global shutdown_signal
    shutdown_signal = True

if __name__ == '__main__':
    rate = 10
    rospy.init_node('file_update_publisher', anonymous=True)
    rospy.Subscriber('shutdown_publisher', String, shutdown)
    timer = rospy.Timer(rospy.Duration(1/rate), publish)
    rospy.spin()
    timer.shutdown()

Feel free to build on this code, specifically the update_file function. If you are starting ROS development, I would recommend switching to ROS 2.

$\endgroup$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.