My timing accuracy is related to the number of spin_once.
I try to call service 'compute_rectangle_area' at a constant rate. Unfortunately, if I set the rate to 1 Hz, I have to do spin_once four times. If the time of repeats is smaller than four, the programming will get stuck.
If the time of repeats is bigger than four, the programming sleeps longer than expected.
#!/usr/bin/python3
from asyncio import Future
from functools import partial
import rclpy
from rclpy.node import Node
from robot_interfaces1.srv import ComputeRectangleArea
class ComputeRectangleAreaClientNode(Node):
def __init__(self, node_name: str) -> None:
super().__init__(node_name)
self.client_ = self.create_client(ComputeRectangleArea,"compute_rectangle_area")
def call_compute_rectangle_area_server(self,length:float,width:float)->bool:
if(self.client_.wait_for_service(5)):
msg_request = ComputeRectangleArea.Request()
msg_request.length = length
msg_request.width = width
future = self.client_.call_async(msg_request)
future.add_done_callback\
(partial(self.callback_call_compute_rectangle_area_server,length=length,width=width))
return True
else:
self.get_logger().error("Server is not ready.")
return False
def callback_call_compute_rectangle_area_server \
(self,future:Future,length:float,width:float):
if future.exception() == None:
response_:ComputeRectangleArea.Response = future.result()
self.get_logger().info(f"{length} * {width} = {response_.area}.")
else:
self.get_logger().error(f"The {self.get_name()} returns {future.exception()}.")
def main(args=None):
rclpy.init(args=args)
n = ComputeRectangleAreaClientNode("compute_rectangle_area_client")
loop_rate = n.create_rate(1)
counter = 0
while rclpy.ok():
if(n.call_compute_rectangle_area_server(67.4,45.6)):
n.get_logger().info(f"Call {counter} times.")
counter += 1
rclpy.spin_once(n)
rclpy.spin_once(n)
rclpy.spin_once(n)
rclpy.spin_once(n)
rclpy.spin_once(n)
rclpy.spin_once(n)
loop_rate.sleep()
rclpy.shutdown()
if __name__ == "__main__": main()