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

Revision history [back]

click to hide/show revision 1
initial version

You'll need to add a second node that you attach the "send_recieve_canopy" client to instead of attaching it to the "self" node object. The issue I think you're running into is that the "self" node cannot spin until that callback is finished. So by creating a second private node, you can independently spin that node inside the callback of the "self" node.

At least that's what I have to do in rclcpp. So it should be very similar in rclpy.

Let me know if you need a more concrete example.

You'll need to add a second node that you attach the "send_recieve_canopy" client to instead of attaching it to the "self" node object. The issue I think you're running into is that the "self" node cannot spin until that callback is finished. So by creating a second private node, you can independently spin that node inside the callback of the "self" node.

At least that's what I have to do in rclcpp. So it should be very similar in rclpy.

Let me know if you need a more concrete example.

Edit 1:

Here an example:

import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoInts


class ServiceNode(Node):
    def __init__(self):
        super().__init__('main_node')
        self.sub_node = rclpy.create_node('sub_node')
        self.server = self.create_service(AddTwoInts, 'example_service', self.add_two_ints_callback)
        self.sub_client = self.sub_node.create_client(AddTwoInts, 'add_two_ints')

    def add_two_ints_callback(self, request: AddTwoInts.Request, response: AddTwoInts.Response):
        self.sub_client.wait_for_service()
        sub_request = AddTwoInts.Request()
        sub_request.a = request.a
        sub_request.b = request.b
        future = self.sub_client.call_async(sub_request)
        rclpy.spin_until_future_complete(self.sub_node, future)
        if future.result() is not None:
            result: AddTwoInts.Response = future.result()
            self.get_logger().info('Result of add_two_ints: {}'.format(result.sum))
            response.sum = result.sum
            return response
        else:
            self.get_logger().error('Exception while calling service: {}'.format(future.exception()))


if __name__ == '__main__':
    rclpy.init()
    node = ServiceNode()
    rclpy.spin(node)
    rclpy.shutdown()

To show it works, first in a terminal start

$ ros2 run demo_nodes_cpp add_two_ints_server

in another terminal run this example node. In yet another terminal run

$ ros2 run demo_nodes_cpp add_two_ints_client -s example_service

Hope that answers your question.