Hello, I am new to ROS2 and working on making a package for communicating with 8 Bit MCUs (arduinos) which seems to have been left behind by ROS2.
I have made a service which simply uses pyserial to send a message to the Arduino then receive and return the response. This service works fine however I am trying to make another layer of services which use that service as a client and that is where I am not quite getting it. Below is an example where I am trying to create another service for reading the oxygen sensor, which must use the serial service to request from the sensor and then get the return value. My problem is that I am not really getting how to make the async calls or use/setup the client node inside of the service node and haven't found a good example of this. Additionally, the message send (service request) works but it is specifically getting the return value back that I don't have down.
The code is below, I believe most of the issues and the solution should be in the callback_sense_oxygen method.
#!/usr/bin/env python3
import sys
import rclpy
from rclpy.node import Node
from functools import partial
from garden_interfaces.srv import OxygenSense
from garden_interfaces.srv import SerialMessage
class SenseOxygenServerNode(Node):
def __init__(self):
super().__init__("sense_oxygen_server")
self.server_ = self.create_service(
OxygenSense, "sense_oxygen", self.callback_sense_oxygen)
self.get_logger().info("starting sense oxygen server")
def callback_sense_oxygen(self, request, response):
# create and send serial service request
msg = "rdo2"
skey = "oxgn"
self.call_send_recieve_canopy_server(msg, skey)
call_result = future.result()
# create sensor service response
if (call_result.success):
response.success = call_result.success
response.concentration = call_result.reply_data
response.unit = "%"
return response
def call_send_recieve_canopy_server(self, message, success_key):
# create client
client = self.create_client(SerialMessage, "send_recieve_canopy")
while not client.wait_for_service(1.0):
self.get_logger().warn("waiting for canopy server...")
# create request
request = SerialMessage.Request()
request.message = message
request.success_key = success_key
# send request asyncronously
future = client.call_async(request)
# create callback for the future
future.add_done_callback(partial(self.callback_call_send_recieve_canopy_server, message=message, success_key=success_key))
#return future
def callback_call_send_recieve_canopy_server(self, future, message, success_key):
try:
response = future.result()
self.get_logger().info("success message here")
return response
except Exception as err:
self.get_logger().error("service call failed %r" % (err))
def main(args=None):
rclpy.init(args=args)
node = SenseOxygenServerNode()
rclpy.spin(node)
rclpy.shutdown()
if __name__ == "__main__":
main()
Originally posted by masynthetic on ROS Answers with karma: 55 on 2021-03-02
Post score: 0