Communication of multiple clients through a service.

asked 2018-09-01 16:19:50 -0500

porompompom gravatar image

updated 2018-09-02 10:26:05 -0500

Hi guys, i am new to ROS and i would like to know if it is possible for a service to save the response of a client and pass it to the next client. And if it is possible how would it be done? As i see it the client should take somehow an input of type service.srv which would contain the saved response but i haven't found anything similar to this. This is my code for the server and the clients. My second client is the same except from the variable id which is given the value 2

server

#include "ros/ros.h"
#include "two_clients/Publish_table.h"
#include "stdlib.h"
#include "time.h"
bool add(two_clients::Publish_table::Request &req,two_clients::Publish_table::Response &res){
    int i;
    for(i=0;i<9;i++){
      res.old_table[i]=req.new_table[i];
      printf("%u\n", res.old_table[i]);
    }
    printf("\n");
  res.table_incomplete=false;
  for(i=0;i<9;i++){
    if(res.old_table[i]==0){
      res.table_incomplete=true;
    }
  }
  if(res.table_incomplete==false){
    ros::shutdown();
  }
}

  int main(int argc,char **argv){
  ros::init(argc,argv,"server1");
  ros::NodeHandle n;
  ros::Rate loop_rate(10);
  two_clients::Publish_table a;
  int i;
  for(i=0;i<9;i++){
    a.request.new_table[i]=0;
    a.response.old_table[i]=0;
  }
  while(ros::ok()){
    ros::ServiceServer service=n.advertiseService("com",add);
    printf("Ready for next client \n " );
    ros::spin();
  }
  return 0;
}

client

#include "ros/ros.h"
#include "two_clients/Publish_table.h"
#include "stdlib.h"
#include "time.h"

int main(int argc,char **argv){
  ros::init(argc,argv,"client_1");
  ros::NodeHandle n;
  ros::ServiceClient client=n.serviceClient<two_clients::Publish_table>("com");
  two_clients::Publish_table srv;
  int i, id ;
  id=1;
  srand(time(NULL));
  while(ros::ok()){
    bool tmp=true;
    while(tmp){
      i=rand()%9;
      if(srv.response.old_table[i]==0){
        srv.request.new_table[i]=id;
        tmp=false;
      }
    }
    if(client.call(srv)){
      printf("Client : %u added to the table at position : %u \n", id,i);
    }
    else{
      ROS_ERROR("Failed to call service com");
      return 1;
    }
  }
  return 0;

}

uint8[9] new_table
---
bool table_incomplete
uint8[9] old_table

launch file

<launch>
  <node
    name="server1"
    pkg="two_clients"
    type="server1"
    output="screen"
  />
  <node
    name="client1"
    pkg="two_clients"
    type="client1"
    output="screen"
  />
  <node
    name="client2"
    pkg="two_clients"
    type="client2"
    output="screen"
  />

</launch>
edit retag flag offensive close merge delete

Comments

Just to clarify what you're asking. You want a service server to remember the most recent service call so it can use that information to process the next service call. This is perfectly possible but what is the problem you're actually trying to solve?

PeteBlackerThe3rd gravatar image PeteBlackerThe3rd  ( 2018-09-01 18:01:45 -0500 )edit

Yes that is what i am trying to do. I wasn't trying anything in particular. I happened to stumble across it now that i am getting to know ROS. I uploaded my code if you could suggest any change it would be great help. Thanks in advance.

porompompom gravatar image porompompom  ( 2018-09-02 10:27:53 -0500 )edit
1

Your service callback handler in the server node could access any global variables to store a persistent state between callbacks. if you declare two_clients::Publish_table a; as a global variable instead then the callback can use it.

PeteBlackerThe3rd gravatar image PeteBlackerThe3rd  ( 2018-09-02 11:17:46 -0500 )edit