Robotics StackExchange | Archived questions

rate.sleep() blocks node after first callback function

After receiving the first callback function in the following code, the node blocks and stops running, that is, it doesn't execute the instructions inside the while loop nor the callback function anymore. By removing the rate.sleep() function it fixes the problem but the while loop is not running at the desired rate of 10 hz anymore.... Is this a bug or I'm missing something? The rate.sleep() works well if it doesn't have any callback.

 #!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from rclpy.executors import SingleThreadedExecutor
from gazebo_msgs.msg import ModelStates

class MyNode(Node):
    def __init__(self):
        super().__init__('my_node')
        self.subs_model_states = self.create_subscription(
            ModelStates,
            '/gazebo/model_states',
            self.model_states_callback,
            10)
        self.subs_model_states  # prevent unused variable warning

    def model_states_callback(self, msg):
        try:
            self.get_logger().info(f"Callback")
        except Exception as e:
            self.get_logger().error(f"Error in callback: {e}")


def main(args=None):
    rclpy.init(args=args)
    node = MyNode()
    executor = SingleThreadedExecutor()
    executor.add_node(node)
    rate = node.create_rate(10) # 10 Hz
    while rclpy.ok():
        rclpy.logging.get_logger("main").info(f"Running!")
        executor.spin_once(timeout_sec=0.1)
        rate.sleep()
    node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

Asked by andrestoga on 2023-04-25 16:48:03 UTC

Comments

How do you start your node? Using ros2 run <package> <your_prog> works in my system. The line #!/usr/bin/env python3 suggests to me, that you start the file directly from the command line as a normal python file (e.g. $python3 file.py )

Asked by Andromeda on 2023-04-26 04:13:45 UTC

I'm using the same command as you to start the node.

The reason of the line:

#!/usr/bin/env python3

it's because I'm starting a python node in the same package as C++ nodes. Basically, I'm using CMake. Do you think it has something to do with that?

Asked by andrestoga on 2023-04-26 10:31:36 UTC

I do not know... In my humble installation, your code works without any change. What happens if you remove that line and you use ros2 run ... to start the node?

Asked by Andromeda on 2023-04-26 11:18:35 UTC

If I do it in a C++ package I'll get an error.

Anyways, I removed that line, I put that Python node in a Python only package, and I still got the same behavior...

You can see an screenshot here(I don't know how to add pictures in comments) https://imgur.com/a/XykgTRG

Asked by andrestoga on 2023-04-26 15:42:29 UTC

I have no idea... tomorrow I have access to another PC, where I developed some programs using spin_once and I try to compare them to your code, to investigate the problem

Asked by Andromeda on 2023-04-27 11:36:01 UTC

Ok, can you try the same identical code above but putting the following line: rclpy.spin_once() after executor.spin_once(timeout_sec = 0.1) (BUT BEFORE the rate.sleep() )? Build, try and report.

Asked by Andromeda on 2023-04-28 02:02:26 UTC

To be clear:

...
executor.spin_once(timeout_sec=0.1)
rclpy.spin_once()
rate.sleep()
...

Asked by Andromeda on 2023-04-28 02:05:26 UTC

I have to add to the spin_once:

rclpy.spin_once(node)

because I was getting this error:

TypeError: spin_once() missing 1 required positional argument: 'node'

Unfortunately, I'm getting the same behavior.

Asked by andrestoga on 2023-04-29 17:17:06 UTC

Ok, then I have really no idea... could you try in another distro (galactic, foxy, ...)?

Asked by Andromeda on 2023-04-30 14:26:49 UTC

I can but my work is based on Humble :c

Asked by andrestoga on 2023-05-29 18:21:28 UTC

Answers