How to use class methods as callback functions for services.

asked 2021-10-18 08:42:57 -0500

keihigu gravatar image

Hello

I would like to use the class method as a callback function for the service, referring to the ros2 tutorial (service and client) However, when the class is initialized, the deconstructor is called multiple times.
I would appreciate your comments and suggestions on how to fix this problem.

The ubuntu/ros versions, codes and result are shown below. I have not changed the client code from the tutorial.

Ubuntu : 18.04
ROS2 : crystal

code(Service)

#include "rclcpp/rclcpp.hpp"
#include "tutorial_interfaces/srv/add_three_ints.hpp"
#include "my_srv.hpp"
#include <memory>

int main(int argc, char **argv)
{

  MySrv mysrv(argc, argv);

  rclcpp::init(argc, argv);

  std::shared_ptr<rclcpp::Node> node = rclcpp::Node::make_shared("add_three_ints_server"); 
  rclcpp::Service<tutorial_interfaces::srv::AddThreeInts>::SharedPtr service =             
    node->create_service<tutorial_interfaces::srv::AddThreeInts>("add_three_ints",std::bind(&MySrv::handleService, mysrv,std::placeholders::_1, std::placeholders::_2));   

  RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Ready to add three ints.");     

  rclcpp::spin(node);
  rclcpp::shutdown();
}

code (The header file for class)

#include <rclcpp/rclcpp.hpp>
#include "tutorial_interfaces/srv/add_three_ints.hpp"

class MySrv{
public:
  MySrv(int argc, char** argv);
  ~MySrv();
  void handleService(
    const std::shared_ptr<tutorial_interfaces::srv::AddThreeInts::Request> request,
    const std::shared_ptr<tutorial_interfaces::srv::AddThreeInts::Response> response
  );
};

code (The cpp file for class)

#include <rclcpp/rclcpp.hpp>
#include "my_srv.hpp"
#include "tutorial_interfaces/srv/add_three_ints.hpp"

void MySrv::handleService(
  const std::shared_ptr<tutorial_interfaces::srv::AddThreeInts::Request> request,
  const std::shared_ptr<tutorial_interfaces::srv::AddThreeInts::Response> response
){
  response->sum = request->a + request->b + request->c;      
  RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Incoming request\na: %ld" " b: %ld" " c: %ld", 
                request->a, request->b, request->c);                                         
  RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "sending back response: [%ld]", (long int)response->sum);
}

MySrv::MySrv(int argc, char** argv){
  RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Called constructor");
}

MySrv::~MySrv(){
  RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Called destructor");
}

terminal output when the service is run.

xxx@ubuntu:~/ros2_example_ws$ ros2 run tutorial_interfaces server 
[INFO] [rclcpp]: Called constructor
[INFO] [rclcpp]: Called destructor
[INFO] [rclcpp]: Called destructor
[INFO] [rclcpp]: Called destructor
[INFO] [rclcpp]: Called destructor
[INFO] [rclcpp]: Called destructor
[INFO] [rclcpp]: Ready to add three ints.

thanks.

edit retag flag offensive close merge delete