Calling client based on a timer
I have created a node to read serial data from an Arduino in the form of bytes. I had to do this because the Arduino does not support micro-ros or rosserial. I had to run the callback that reads this data on a timer using self.create_timer
. Every time data is properly received, I am using a service to decode this data and return it. My problem is that when I create a service and call it every time data is received the service completes its entire task, but nothing is ever returned.
Here is a stripped down version of my node.
class SerialReader(Node):
def __init__(self):
super().__init__('serial_read_node')
# Declare parameters
# Initialize serial connection
self.cli = self.create_client(
DecodeMessage,
'decode_serial_message'
)
while not self.cli.wait_for_service(timeout_sec=1.0):
self.get_logger().info('service not available, waiting again...')
self.req = DecodeMessage.Request()
self.create_timer(1, self.receiveData)
def receiveData(self):
# Receive bytes from Arduino as 'message'
result = self.sendRequest(reading_bytes)
def sendRequest(self, message): #call client for data
self.req.message_received = message
self.future = self.cli.call(self.req)
rclpy.spin_until_future_complete(self, self.future)
self.get_logger().info(f'Future = {self.future}')
return self.future.result()
def main():
rclpy.init()
node = SerialReader()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
if __name__ == "__main__":
main()
My question are:
- Is my problem that the client is not its own node?
- Is there a way to use
rclpy.spin_until_future_complete()
on a callback function? - Is multithreading and using executors a path to solving my problem?
I did not include my service as I have found that I can print to the logger the line before the return statement with everything working properly, but nothing here gets past the line rclpy.spin_until_future_complete(self, self.future)
.