hello there,
I’m trying to do the service client node for the quiz 4.7 on services.
My service works well when I do
ros2 service call /rotate services_quiz_srv/srv/Spin "{direction: 'right', angular_velocity: 1, time: 3}"
My services gives me back the good behaviour and this message:
user:~/ros2_ws$ ros2 launch services_quiz services_quiz_server.launch.py
[INFO] [launch]: All log files can be found below /home/user/.ros/log/2023-06-21-16-36-24-289049-4_xterm-1148
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [rotate_server-1]: process started with pid [1149]
[rotate_server-1] [INFO] [1687365401.469843609] [rotate_service]: start rotating right
[rotate_server-1] [INFO] [1687365404.470299481] [rotate_service]: stop rotating right
When I try to do the client in a class I don’t have the same behaviour:
user:~/ros2_ws$ ros2 launch services_quiz services_quiz_server.launch.py
[INFO] [launch]: All log files can be found below /home/user/.ros/log/2023-06-21-16-45-08-354879-4_xterm-2032
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [rotate_server-1]: process started with pid [2033]
[rotate_server-1] [INFO] [1687365908.995054596] [rotate_service]: start rotating right
[rotate_server-1] [INFO] [1687365911.996097658] [rotate_service]: stop rotating right
[rotate_server-1] [INFO] [1687365911.996305815] [rotate_service]: start rotating right
[rotate_server-1] [INFO] [1687365914.996546838] [rotate_service]: stop rotating right
[rotate_server-1] [INFO] [1687365914.996641613] [rotate_service]: start rotating right
[rotate_server-1] [INFO] [1687365917.996940060] [rotate_service]: stop rotating right
[rotate_server-1] [INFO] [1687365917.997047116] [rotate_service]: start rotating right
[rotate_server-1] [INFO] [1687365920.997297565] [rotate_service]: stop rotating right
[rotate_server-1] [INFO] [1687365920.997418616] [rotate_service]: start rotating right
[rotate_server-1] [INFO] [1687365923.997756524] [rotate_service]: stop rotating right
My code looks like this:
#include "rclcpp/rclcpp.hpp"
#include "rclcpp/timer.hpp"
#include "services_quiz_srv/srv/spin.hpp"
#include <chrono>
#include <cstdlib>
#include <future>
#include <memory>
using namespace std::chrono_literals;
using Spin = services_quiz_srv::srv::Spin;
class ServiceClient : public rclcpp::Node {
private:
rclcpp::Client<Spin>::SharedPtr client_;
rclcpp::TimerBase::SharedPtr timer_;
bool service_done_ = false;
void timer_callback() {
RCLCPP_INFO(this->get_logger(), "timer callback");
while (!client_->wait_for_service(1s)) {
if (!rclcpp::ok()) {
RCLCPP_ERROR(
this->get_logger(),
"Client interrupted while waiting for service. Terminating...");
return;
}
RCLCPP_INFO(this->get_logger(),
"Service Unavailable. Waiting for Service...");
}
RCLCPP_INFO(this->get_logger(), "service reached");
auto request = std::make_shared<Spin::Request>();
request->direction = "right";
request->angular_velocity = 1;
request->time = 3;
service_done_ = false;
auto result_future = client_->async_send_request(
request, std::bind(&ServiceClient::response_callback, this,
std::placeholders::_1));
RCLCPP_INFO(this->get_logger(), "end of timer callback");
}
void response_callback(rclcpp::Client<Spin>::SharedFuture future) {
RCLCPP_INFO(this->get_logger(), "response callback");
auto status = future.wait_for(1s);
if (status == std::future_status::ready) {
RCLCPP_INFO(this->get_logger(), "Result: success");
service_done_ = true;
} else {
RCLCPP_INFO(this->get_logger(), "Service In-Progress...");
}
RCLCPP_INFO(this->get_logger(), "end response callback");
}
public:
ServiceClient() : Node("rotate_client") {
RCLCPP_INFO(this->get_logger(), "rotate_client launched");
client_ = this->create_client<Spin>("rotate");
timer_ = this->create_wall_timer(
1s, std::bind(&ServiceClient::timer_callback, this));
}
bool is_service_done() const { return this->service_done_; }
};
int main(int argc, char *argv[]) {
rclcpp::init(argc, argv);
auto service_client = std::make_shared<ServiceClient>();
while (!service_client->is_service_done()) {
rclcpp::spin_some(service_client);
}
rclcpp::shutdown();
return 0;
}
and displays this:
user:~$ ros2 launch services_quiz services_quiz_client.launch.py
[INFO] [launch]: All log files can be found below /home/user/.ros/log/2023-06-21-16-45-05-194765-4_xterm-2010
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [rotate_client-1]: process started with pid [2011]
[rotate_client-1] [INFO] [1687365905.358862317] [rotate_client]: rotate_client launched
[rotate_client-1] [INFO] [1687365906.360016374] [rotate_client]: timer callback
[rotate_client-1] [INFO] [1687365907.360192368] [rotate_client]: Service Unavailable. Waiting for Service...
[rotate_client-1] [INFO] [1687365908.360392928] [rotate_client]: Service Unavailable. Waiting for Service...
[rotate_client-1] [INFO] [1687365908.865549225] [rotate_client]: service reached
[rotate_client-1] [INFO] [1687365908.865757831] [rotate_client]: end of timer callback
[rotate_client-1] [INFO] [1687365908.865839867] [rotate_client]: timer callback
[rotate_client-1] [INFO] [1687365908.865877264] [rotate_client]: service reached
[rotate_client-1] [INFO] [1687365908.865957374] [rotate_client]: end of timer callback
[rotate_client-1] [INFO] [1687365909.359922030] [rotate_client]: timer callback
[rotate_client-1] [INFO] [1687365909.360033576] [rotate_client]: service reached
[rotate_client-1] [INFO] [1687365909.360135143] [rotate_client]: end of timer callback
[rotate_client-1] [INFO] [1687365910.359893384] [rotate_client]: timer callback
[rotate_client-1] [INFO] [1687365910.359983630] [rotate_client]: service reached
[rotate_client-1] [INFO] [1687365910.360072448] [rotate_client]: end of timer callback
[rotate_client-1] [INFO] [1687365911.359869095] [rotate_client]: timer callback
[rotate_client-1] [INFO] [1687365911.359959513] [rotate_client]: service reached
[rotate_client-1] [INFO] [1687365911.360050950] [rotate_client]: end of timer callback
[rotate_client-1] [INFO] [1687365911.996393542] [rotate_client]: response callback
[rotate_client-1] [INFO] [1687365911.996450567] [rotate_client]: Result: success
[rotate_client-1] [INFO] [1687365911.996471368] [rotate_client]: end response callback
[INFO] [rotate_client-1]: process has finished cleanly [pid 2011]
The robot starts rotating at the first “service reached”. I never get to see “Service In-Progress…”.
It seems that while the robot executes the first service it starts a new timer callback…
I don’t understand what I did wrong. My code is inspired by the service client code using node inheritance of the course.
Thank you in advance for your help.
Pablo