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

[ros2] Why does sleep not work inside callback?

asked 2022-07-30 21:07:19 -0600

ravijoshi gravatar image

I noticed that sleep does not work inside callback in default settings, i.e., SingleThreadedExecutor with MutuallyExclusiveCallbackGroup. Please see a sample code snippet below:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from example_interfaces.action import Fibonacci

import rclpy
from rclpy.action import ActionServer
from rclpy.node import Node


class MinimalActionServer(Node):
    def __init__(self):
        super().__init__('minimal_action_server')
        self.as_ = ActionServer(self, Fibonacci, 'fib', execute_callback=self.execute_cb)

    def execute_cb(self, goal_handle):
        fb = Fibonacci.Feedback(sequence=[0, 1])
        loop_rate = self.create_rate(1, self.get_clock())  # 1 Hz
        for i in range(1, goal_handle.request.order):
            self.get_logger().info(f'[{i}] Executing goal...')
            fb.sequence.append(fb.sequence[i] + fb.sequence[i - 1])
            self.get_logger().info(f'Publishing feedback: {fb.sequence}')
            goal_handle.publish_feedback(fb)
            loop_rate.sleep()  # commenting this line makes the callback work

        goal_handle.succeed()
        return Fibonacci.Result(sequence=fb.sequence)


def main(args=None):
    rclpy.init(args=args)
    node = MinimalActionServer()
    try:
        rclpy.spin(node)
    except KeyboardInterrupt:
        pass
    finally:
        rclpy.shutdown()


if __name__ == '__main__':
    main()

Question

Why does sleep not work inside callback?

Additional Info

  • Operating System: Ubuntu 20.04.4 LTS
  • Installation type: binaries
  • Version or commit hash: ROS Galactic
  • DDS implementation: Default
  • Client library: rclpy
edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
0

answered 2023-02-22 02:18:55 -0600

tlipps gravatar image

So I'm coming in late, but I had the same problem. There are two ways to make the code above work.

  1. Use MultiThreadedExecutor
  2. Initialize loop_rate in the constructor

Code for 1:

  def main(args=None):
    rclpy.init(args=args)
    node = MinimalActionServer()
    executor = MultiThreadedExecutor()
    try:
        rclpy.spin(node, executor=executor)
    except KeyboardInterrupt:
        pass
    finally:
        rclpy.shutdown()

Code for 2:

class MinimalActionServer(Node):
def __init__(self):
    super().__init__('minimal_action_server')
    self.loop_rate = self.create_rate(1, self.get_clock())  # 1 Hz This can be initialized after self.as_ as well
    self.as_ = ActionServer(self, Fibonacci, 'fib', execute_callback=self.execute_cb)

I currently have not figured out where exactly the problem is located by at least it runs for now.

edit flag offensive delete link more
-1

answered 2022-07-31 20:39:09 -0600

qilin_gundamenjoyer gravatar image

Above the loop_rate.sleep() command, add a ros::spinOnce() command.

ros::spin() and ros::spinOnce() are commands that are tasked to handle communication events, such as messages. Any subscription to a message, service, or an action must be called by spin to process the events.


ros::spinOnce() : Handles the events and returns immediately with more controllability.
ros::spin(): Blocks incoming events until ROS invokes a shutdown command.
rate.sleep(): A threadwith a duration defined by a frequency.


Source: Callback & Spinnings

edit flag offensive delete link more

Comments

Sorry, it seems you are referring to ROS 1. The question is related to ROS 2.

ravijoshi gravatar image ravijoshi  ( 2022-07-31 20:44:43 -0600 )edit

My bad. You are right.

qilin_gundamenjoyer gravatar image qilin_gundamenjoyer  ( 2022-08-01 00:19:00 -0600 )edit

Question Tools

2 followers

Stats

Asked: 2022-07-30 21:07:19 -0600

Seen: 1,313 times

Last updated: Jul 31 '22