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

How to make C++'s service call method wait for server's response?

asked 2019-05-23 11:00:32 -0600

achmad_fathoni gravatar image

updated 2019-05-23 11:23:19 -0600

I need to call three consecutive service call from c++ node like this

ros::ServiceClient srvcl1 = n.serviceClient<gazebo::Randomize>(
    "/randomize", false
);
ros::ServiceClient srvcl2 = n.serviceClient<amcl::Localization>(
    "/localization", false
);
ros::ServiceClient srvcl3 = n.serviceClient<std_srvs::Empty>(
    "/check", false
);

gazebo::Randomize srv1;
amcl::Localization srv2;
std_srvs::Empty srv3;

while(ros::ok()){
    if(srvcl1.call(srv1)){
        if(srvcl2.call(srv2)){
            if(srvcl3.call(srv3)){
            }
        }
    }
}

The problem is the service server sometime takes long time to process client's request but in C++, srvcl.call(srv) method always done instantaneously regardless server progress. In order to make current service call perform correctly, it must wait for server that serve previous service call to finish. I try to avoid using wait function that require time constant like ros::Duration(0.5).sleep(). This problem doesn't occur when using bash script such as

rosservice call /randomize;
rosservice call /localization;
rosservice call /check;

Does python have same problem? My last resort is using actionlib.

edit retag flag offensive close merge delete

Comments

1

It would help to know what the implementations of those services are.

Geoff gravatar image Geoff  ( 2019-05-23 19:46:02 -0600 )edit

2 Answers

Sort by ยป oldest newest most voted
3

answered 2019-05-23 19:57:15 -0600

Namal Senarathne gravatar image

updated 2019-05-23 19:57:47 -0600

I have a suspicion that may be the service clients are returning prematurely (check http://docs.ros.org/api/roscpp/html/service__client_8h_source.html#l00081) because the service calls are issued before the services are actually up and ready. So adding

srvcl1.waitForExistence();
srvcl2.waitForExistence();
srvcl3.waitForExistence();

before the loop should solve this issue.

(I am assuming the service servers are working fine since the rosservice call commands are working fine. It would always help to post a more descriptive code than just snippets to provide a more authoritative answer :))

edit flag offensive delete link more
1

answered 2019-05-23 19:45:47 -0600

Geoff gravatar image

Services in roscpp are blocking by default. What you are trying to do should be working if the service implementations are taking time before they return. Check if your service implementations are not returning early for some reason.

However, I think that if you will always call these three services together in this order, then using an action is a more appropriate semantic construct.

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2019-05-23 11:00:32 -0600

Seen: 5,904 times

Last updated: May 23 '19