How to log service operations with ROS?

asked 2021-12-20 15:32:09 -0500

sp1derm4n gravatar image

I've made a simple server and client node whereby the client node takes in a calculation from user using service file format:

float64 a
string op
float64 b
----------
float64 result
string status

where the string is an arithmetic operator ("+" or "-") etc. The server then returns the result of this operation back to the client for it to output to terminal.

Client node:

int main(int argc, char **argv)          // Node Main Function
{
      ros::init(argc, argv, "service_client");
      if (argc != 4)

      {
          ROS_INFO("cmd : rosrun ros_tutorials_service service_client arg0 arg1");
          ROS_INFO("arg0: double number, arg1: double number");
          return 1;
      }

      ros::NodeHandle nh;

      ros::ServiceClient ros_tutorials_service_client = nh.serviceClient<calculator::Operation>("caclServ");

      // Declares the 'srv' service that uses the service file
      calculator::Operation srv;

      // Parameters entered when the node is executed as a service request value are stored at 'a' and 'b'
      srv.request.a = atof(argv[1]);
      srv.request.op = argv[2];
      srv.request.b = atof(argv[3]);


      // Request the service. If the request is accepted, display the response value
      if (ros_tutorials_service_client.call(srv)){
          ROS_INFO("Sending: %f %s %f", srv.request.a, srv.request.op.c_str() ,srv.request.b);
          ROS_INFO("Recieved: %s %f", srv.response.status.c_str(), srv.response.result);
      }
      else{
        ROS_ERROR("Failed to call service ros_tutorial_srv");
        return 1;
      }
      return 0;
}

Server node:

bool calculation(calculator::Operation::Request &req, calculator::Operation::Response &res)
{
  res.status = "SUCCESSFUL RESULT: ";
    if(req.op == "+"){
              res.result = req.a + req.b;
    }else if(req.op == "-"){
        res.result = req.a - req.b;
    }else if(req.op == "*"){
        res.result = req.a * req.b;
    }else if(req.op == "/"){
      res.result = req.a / req.b;
    }else if(req.op == "^"){
      float temp = req.a;
      for (int x = 0; x < req.b-1;x++){
        temp = req.a * temp;
      }
        res.result=temp;
    }else{
      ROS_INFO("ERROR: Invalid Operation");
      res.result = 0;
      res.status = "ERROR: Invalid Operation";
    }


    // Displays 'a' and 'b' values used in the service request and
    // the 'result' value corresponding to the service response
    ROS_INFO("request: x=%f, y=%f", req.a, req.b);
    ROS_INFO("sending back response: %f", res.result);

    return true;

}


int main(int argc, char **argv)
{
    ros::init(argc, argv, "service_server"); // Initializes Node Name
    ros::NodeHandle nh; // Node handle declaration


    ros::ServiceServer ros_tutorials_service_server = nh.advertiseService("caclServ",calculation);
    ROS_INFO("Calculator Server: ONLINE");
    ros::spin();

    // Wait for the service request
    return 0;
}

I want to log every operation that occurs into a file or store where from the client node I can view every operation thats been sent whether invalid or successful so far, how do I do this?

I thought of creating a publisher within the server node that publishes every operation to a topic but the service system in ROS uses a callback function to respond to the request and so I can't access the publisher object.

I want to log every operation that gets sent across. I tried doing this with rosbag

edit retag flag offensive close merge delete