ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

This is my oop approach to the problem you stated:

#include "ros/ros.h"
#include <boost/thread.hpp>
#include "beginner_tutorials/TwoIntsCustom.h"

class AddTwo
{
  private:
    ros::ServiceServer ss_;
    ros::ServiceClient sc_;

    ros::NodeHandle& nh_, private_nh_;

  public:
    AddTwo(ros::NodeHandle* nh, ros::NodeHandle* private_nh)
    :nh_(*nh)
    , private_nh_(*private_nh)
    {
      this->sc_ = nh_.serviceClient<beginner_tutorials::TwoIntsCustom>("add_two_ints");
    }

    ~AddTwo()
    {
    }

    boost::thread* ss_thread_;

    bool add(beginner_tutorials::TwoIntsCustom::Request& req,
      beginner_tutorials::TwoIntsCustom::Response& res);
    bool client_call(int a, int b);
    bool spin_server();
};

bool AddTwo::add(beginner_tutorials::TwoIntsCustom::Request& req,
                 beginner_tutorials::TwoIntsCustom::Response& res)
{
  res.sum = req.a + req.b;
  ROS_INFO("SS: request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
  ROS_INFO("SS: sending back response: [%ld]", (long int)res.sum);
  return true;
}

bool AddTwo::client_call(int a, int b)
{
  ROS_INFO("Calling Server...");
  this->sc_.waitForExistence();

  beginner_tutorials::TwoIntsCustom srv;
  srv.request.a = a;
  srv.request.b = b;
  if (this->sc_.call(srv))
  {
    ROS_INFO("SC: Sum: %ld", (long int)srv.response.sum);
  }
  else
  {
    ROS_ERROR("SC: Failed to call service add_two_ints");
    return 1;
  }
}

bool AddTwo::spin_server()
{

  this->ss_ = nh_.advertiseService("add_two_ints", &AddTwo::add, this);
  ROS_INFO("Ready to add two ints.");
  ros::spin();

  return 0;
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "add_two_ints_server");
  ros::NodeHandle nh, private_nh("~");

  AddTwo at = AddTwo(&nh, &private_nh);

  at.ss_thread_ = new boost::thread(
    boost::bind(&AddTwo::spin_server, &at));

  ros::Rate r (3.0);

  for (int ia=0, ib=0 ; ia < 10 && ib < 10 ; ia++, ib++)
  {
    ROS_INFO("Main calling server with: a=%d, b=%d ....", ia,ib);
    at.client_call(ia,ib);
    r.sleep();
  }

  return 0;
}

If someone provide a better approach I will be glad to discuss it here.

This is my oop approach to the problem you stated:stated, note that I modified the service_client version of the beginners tutorial for roscpp.

#include "ros/ros.h"
#include <boost/thread.hpp>
#include "beginner_tutorials/TwoIntsCustom.h"

class AddTwo
{
  private:
    ros::ServiceServer ss_;
    ros::ServiceClient sc_;

    ros::NodeHandle& nh_, private_nh_;

  public:
    AddTwo(ros::NodeHandle* nh, ros::NodeHandle* private_nh)
    :nh_(*nh)
    , private_nh_(*private_nh)
    {
      this->sc_ = nh_.serviceClient<beginner_tutorials::TwoIntsCustom>("add_two_ints");
    }

    ~AddTwo()
    {
    }

    boost::thread* ss_thread_;

    bool add(beginner_tutorials::TwoIntsCustom::Request& req,
      beginner_tutorials::TwoIntsCustom::Response& res);
    bool client_call(int a, int b);
    bool spin_server();
};

bool AddTwo::add(beginner_tutorials::TwoIntsCustom::Request& req,
                 beginner_tutorials::TwoIntsCustom::Response& res)
{
  res.sum = req.a + req.b;
  ROS_INFO("SS: request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
  ROS_INFO("SS: sending back response: [%ld]", (long int)res.sum);
  return true;
}

bool AddTwo::client_call(int a, int b)
{
  ROS_INFO("Calling Server...");
  this->sc_.waitForExistence();

  beginner_tutorials::TwoIntsCustom srv;
  srv.request.a = a;
  srv.request.b = b;
  if (this->sc_.call(srv))
  {
    ROS_INFO("SC: Sum: %ld", (long int)srv.response.sum);
  }
  else
  {
    ROS_ERROR("SC: Failed to call service add_two_ints");
    return 1;
  }
}

bool AddTwo::spin_server()
{

  this->ss_ = nh_.advertiseService("add_two_ints", &AddTwo::add, this);
  ROS_INFO("Ready to add two ints.");
  ros::spin();

  return 0;
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "add_two_ints_server");
  ros::NodeHandle nh, private_nh("~");

  AddTwo at = AddTwo(&nh, &private_nh);

  at.ss_thread_ = new boost::thread(
    boost::bind(&AddTwo::spin_server, &at));

  ros::Rate r (3.0);

  for (int ia=0, ib=0 ; ia < 10 && ib < 10 ; ia++, ib++)
  {
    ROS_INFO("Main calling server with: a=%d, b=%d ....", ia,ib);
    at.client_call(ia,ib);
    r.sleep();
  }

  return 0;
}

If someone provide a better approach I will be glad to discuss it here.