Synchronous service client call from C++
Trying to call a service from one node to another in C++ feels very complex. I have this situation:
auto c = create_client<std_srvs::srv::SetBool>("targetService");
auto r = c->async_send_request(
std::make_shared<std_srvs::srv::SetBool::Request>());
while (rclcpp::ok() && !(r.wait_for(std::chrono::seconds(1)) ==
std::future_status::ready)) {
RCLCPP_INFO(get_logger(), "Waiting");
}
This is never done, even if targetService exists and executes its callback to a finishing state. The problem occurs when the service is hosted by a node in a separate docker container, so frustratingly I can't make it appear in unit testing, where it works totally fine even using different executors in different threads. How do I go forward in a situation like this? Feels kinda basic, I wanna call a service and use the output from one node to another as if I were a user. Hope I'm missing something basic.
If it matters, the service (branded as targetService) in the minimal example above is a custom planner from the nav2 stack, which is being spun by the planner server node. It executes the callback correctly, but the future in the client is never finished. What can I do?
Asked by Per Edwardsson on 2022-12-09 04:11:43 UTC
Answers
I haven't used ros2 yet, but I notice that your code does not look the tutorial code.
- You are not checking that the server-side has actually started.
Is your client node spinning as it waits? The above tutorial uses the following method to wait for a response:
rclcpp::spin_until_future_complete(node, result) == rclcpp::executor::FutureReturnCode::SUCCESS)
Asked by Mike Scheutzow on 2022-12-10 10:48:32 UTC
Comments
The problem is that this is part of a node which is being spun from elsewhere. If I try to spin a node which is already being spun, I get a runtime errors since you are not supposed to spin a node with two separate executors.
Asked by Per Edwardsson on 2022-12-12 03:41:40 UTC
Comments