0
$\begingroup$

Rosanswers logo

Hi,

I want to get a value from a topic and after perform some operations on the value retrieved (can't be in the callback function).

I imagine a subscriber and this simple loop (python)

while self.__var is None:
    self.get_logger().info("__var has no value yet.")
    # wait

On my first attempt, I used time.sleep for the "wait", which pause the whole Node, including the subscriber if I don't misunderstand. Then I used a callback_group to handle the subscription, it didn't work either. I read that time.sleep should never be used and prefer rate.sleep instead, inside another thread. So i tried this

def retrieve_value(self):
    self.__var = None
    # Spin in a separate thread
    thread = threading.Thread(target=rclpy.spin, args=(self, ), daemon=True)
    thread.start()
    self.get_logger().info("thread starts.")

    rate = self.create_rate(1)
    self.__sub_var = self.create_subscription(
        String,
        f'/var_values',
        self.__set_var_value,  # simply self.__var = msg.data
        10,
        callback_group=self.__listener_cb_grp
    )
    while self.__var is None:
        self.get_logger().info("¤¤¤__var has not value yet.")
        rate.sleep()

    # rclpy.shutdown()  # the node crash if uncomment and the node seem to stop when commented
    self.get_logger().info("thread stops.")
    thread.join()

Last I used a MultiThreadedExecutor and it still did not work. Obviously I don't understand the thread management here.

Can someone help me ?


Originally posted by SébastienL on ROS Answers with karma: 32 on 2023-07-18

Post score: 0


Original comments

Comment by jdlangs on 2023-07-18:
Can you provide the full program context? How is retrieve_value being run?

Comment by SébastienL on 2023-07-19:
I'll post more code. I suspect I did not understand how ROS2 nodes are supposed to be used.

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

Looking at the additional info posted, I think your second design more-or-less makes sense. You should not use spin though because that's intended to move program control to callbacks only, and it only ends when the node shuts down. Instead, you can create the subscription and then in the while self.__var is None loop you can call spin_once on an executor. This will let callbacks run but return control to you afterwards. I don't think you need a reentrant callback group or a multi-threaded executor in this scenario.


Originally posted by jdlangs with karma: 971 on 2023-07-19

This answer was ACCEPTED on the original site

Post score: 0


Original comments

Comment by SébastienL on 2023-07-19:
Thank you for the explanations. I tried to spin_once and it worked. I'll work with that on my real case.

$\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.