ROS2 service : spin_until_future_complete blocking when calling a service that calls another service [closed]
Hello,
I'm using ROS2 Bouncy, built from source on Ubuntu 18.04.
I have a node which create a service A. The callback from this service A calls a function which calls another service B from another node. The service B does answer but the service A still get stuck on rclpy.spin_until_future_complete(self, future)
.
When I use the function to call the service B from the code it works, the problems comes when this function is called from a service. Is it how it's supposed to work ? Any suggestion on how I could call a service from another service without getting stuck ?
You can find the full file here : https://github.com/MarcTestier/kone_o...
You can run the full thing by running :
ros2 run kone_open_opc_server_simu kone_simu
then
ros2 run kone_open_opc_client kone_client
and then call the service :
ros2 service call /send_lift_to_floor kone_open_opc_interfaces/SendLiftToFloor "site: 'a'
location: 'b'
group: 'c'
lift: 'd'
floor: 3
door_side: 1"
Here is just the interesting part of the function called by service A :
req = AgvCmd.Request()
req.id = self.agvID
req.cmd = cmd
req.value = 0
self.read_agv_cmd = self.create_client(AgvCmd, 'read_agv_cmd')
# Wait for the read_agv_cmd service to be running
while not self.read_agv_cmd.wait_for_service(timeout_sec=1.0):
self.get_logger().info('Service read_agv_cmd not available, waiting again...')
future = self.read_agv_cmd.call_async(req)
self.get_logger().info('OK 1')
rclpy.spin_until_future_complete(self, future)
self.get_logger().info('OK 2')
if future.result() is not None:
self.get_logger().info("AGV [%s] called the read service for command [%s] and heard [%d]" % (self.agvID, cmd, future.result().value))
return 1, future.result().value
EDIT : same problem when trying to use :
self.read_agv_cmd = self.create_client(AgvCmd, 'read_agv_cmd')
while not self.read_agv_cmd.wait_for_service(timeout_sec=1.0):
self.get_logger().info('Service read_agv_cmd not available, waiting again...')
future = self.read_agv_cmd.call_async(req)
while rclpy.ok():
self.get_logger().info('OK 1')
rclpy.spin_once(self)
self.get_logger().info('OK 2')
if future.done():
if future.result() is not None:
self.get_logger().info("AGV [%s] called the read service for command [%s] and heard [%d]" % (self.agvID, cmd, future.result().value))
return 1, future.result().value
else:
self.get_logger().error('AGV [%s] tried to call the read service but failed %r' % (self.agvID, future.exception()))
It blocks on rclpy.spin_once(self)
.
EDIT 2 : Same thing when using self.read_agv_cmd.call(req)
EDIT 3: I tried to change Service A to a Subscriber and the result is the same, the callback stay stuck on rclpy.spin_until_future_complete(self, future)
EDIT 4: Actually, I get stuck when trying to rclpy.spin_once(self)
in the callback function of a subscriber in the node.
EDIT 5: You can find a minimal example of the problem here : https://answers.ros.org/question/3020...
I tried to change Service A to a Subscriber and the result is the same, the callback stay stuck on
rclpy.spin_until_future_complete(self, future)
Actually, I get stuck when trying to
rclpy.spin_once(self)
in the callback function of a subscriber in the node.Did you ever figure out how to call a service from inside a service callback?
you can see a solution here: [https://answers.ros.org/question/3020...]