Ask Your Question
0

ROS Service (client inside server node)

asked 2022-03-30 12:36:49 -0500

naihart gravatar image

updated 2022-03-31 13:53:55 -0500

Is it possible to put a client node inside a server node when making service?

Iam trying to make a Service and as far as I know, all the functions are stored in the server node and inside the client node is where the parameters or arguments you want for the server. What Im trying to make is a service that will spawn turtle n times. The code compiles flawlessly also gives me the response when using rosservice command. Problem is I cant spawn any turtle, (turtlesim_spawn_client.call(srv)) always returns to false. Please help

 #include "ros/ros.h"
 #include "srv_turtlesim/spawn_turtle.h"
 #include "turtlesim/Spawn.h"

 ros::ServiceClient turtlesim_spawn_client;

 class spawn_turtle_class
{
public:
spawn_turtle_class(ros::NodeHandle& nh)
{
    turtlesim_spawn_client = nh.serviceClient<turtlesim::Spawn>("turtlesim_spawn");
}

bool spawn_callback(srv_turtlesim::spawn_turtle::Request &req,
                    srv_turtlesim::spawn_turtle::Response &res)
{
    bool not_spawn=false;
    turtlesim::Spawn srv;
    ROS_INFO("request: n=%d", (int)req.num_turtle);

/----------------------------------------------------------------------------------------/

    for (int i = 0; req.num_turtle > i; i++)
    {
        srv.request.x = random() % 12;
        srv.request.y = random() % 12;
        srv.request.theta = random() % 360;

        if (turtlesim_spawn_client.call(srv))
        {
            ROS_INFO("response: You got turt");
        }
        else
        {
            ROS_INFO("response: No turt :(");
            not_spawn = true;
        }        
    }

/----------------------------------------------------------------------------------------/

    if (not_spawn)
    {
        res.status = "Incomplete";
    }
    else
    {
        res.status = "Done";
    }

    return true;
}

};

int main (int argc, char**argv)
{
ros::init(argc,argv, "spawn_node");
ros::NodeHandle nh;
spawn_turtle_class spawn2(nh);
ros::ServiceServer service = nh.advertiseService("spawn_turtle_srv", &spawn_turtle_class::spawn_callback, &spawn2);
ros::spin();
return 0;
}
edit retag flag offensive close merge delete

Comments

Can you prepare a MWE (Minimal Working Example) of your project with these node and service (or at least your attempts)? Then we can try to help easier :)

ljaniec gravatar image ljaniec  ( 2022-03-30 15:55:15 -0500 )edit

include "ros/ros.h"

     #include "srv_turtlesim/spawn_turtle.h"

     #include "turtlesim/Spawn.h"

    bool spawn_turtle(srv_turtlesim::spawn_turtle::Request &req,
             srv_turtlesim::spawn_turtle::Response &res)
    {

        ROS_INFO("request: n=%d", (int)req.num_turtle);
        for (int i = 0; req.num_turtle > i; i++){

      //Im trying to call turtlesim/Spawn service client here

         turtlesim::Spawn srv
         srv.request.x = random() % 12;
         srv.request.y = random() % 12;
         srv.request.theta = random() % 360;
            if (spawn_client.call(srv)) {
               res.status= "You got turt";
            }
            else{
               res.status= "No turt :(";
            }
        }
        return true;

    }

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

    ros::init(argc, argv, "spawn_turtle_service");
    ros::NodeHandle nh;
    ros::ServiceServer service = nh.advertiseService("spawn_turtle2", spawn_turtle);
    ros::ServiceClient spawn_client = nh.serviceClient<turtlesim::Spawn>("spawn");
    ros::spin();

}
naihart gravatar image naihart  ( 2022-03-31 00:32:45 -0500 )edit

From that comment on my callback, I want to call the turtlesim/Spawn service client but the creation of the client is inside the main function making my request for turtlesim/Spawn undefined

naihart gravatar image naihart  ( 2022-03-31 00:37:30 -0500 )edit

Can you add this code in the question? Formatting will be better

ljaniec gravatar image ljaniec  ( 2022-03-31 01:57:08 -0500 )edit

Im sorry for that, Im new with this ROS and with this forum.

naihart gravatar image naihart  ( 2022-03-31 11:11:14 -0500 )edit

No problem, you will find out everything. BTW there is no ; after the turtlesim::Spawn srv, what kind of error does this show you? Can you copy & paste the entire compile errror from the terminal to the question?

ljaniec gravatar image ljaniec  ( 2022-03-31 11:37:30 -0500 )edit

Hi I finally managed to make a decent code than the previous code. It compiles and gives me the response. One problem tho is that turtlesim_spawn_client.call(srv) is not working. it always returns to false. I edited the question already. the separated lines of code are where I got problem.

naihart gravatar image naihart  ( 2022-03-31 13:44:29 -0500 )edit

2 Answers

Sort by ยป oldest newest most voted
0

answered 2022-04-05 12:23:23 -0500

naihart gravatar image

This is stupid. The only problem with the code is the line

   turtlesim_spawn_client = nh.serviceClient<turtlesim::Spawn>("turtlesim_spawn");

I only need to change the name "turtlesim_spawn" to "spawn". Iam new at ROS and I thought that this name can be change for easy reading. Lesson learned

edit flag offensive delete link more

Comments

Well, it was right there in the mentioned example below (Listing 8.1, lines 12-16). It's good that you found it yourself.

ljaniec gravatar image ljaniec  ( 2022-04-05 22:06:53 -0500 )edit
0

answered 2022-03-31 15:27:57 -0500

ljaniec gravatar image

I am not sure if your code is correct based on this "A Gentle Introduction to ROS" Chapter: Services - e.g. it seems like you don't have a pointer to the function there. Can you rework your code based on these examples?

Overall, there is maybe another approach worth trying:

Maybe this answer and it's gist could help you?

I would try to use the wrapper to non-blocking 'n' service calls of the spawn_turtle_service.

edit flag offensive delete link more

Comments

Hi, Im following this example https://industrial-training-master.re... I follow the Service Client. but then implement it on my Service Server. I tried editing my code based on the link you've provided

*

    bool not_spawn=false;
    turtlesim::SpawnRequest t_req;
    turtlesim::SpawnResponse t_res;
    ROS_INFO("request: n=%d", (int)req.num_turtle);

    for (int i = 0; req.num_turtle > i; i++)
    {
        t_req.x = random() % 12;
        t_req.y = random() % 12;
        t_req.theta = random() % 360;

        if (turtlesim_spawn_client.call(t_req, t_res))
        {
            ROS_INFO("response: You got turt");
        }
        else
        {
            ROS_INFO("response: No turt :(");
            not_spawn = true;
        }

    }

* And still doesnt spawn any turtles.

Ill research about wrapper and non-blocking service.

naihart gravatar image naihart  ( 2022-04-01 01:32:57 -0500 )edit
1

update on this, I have different approach for this one. It could work but still have a minor issue, Ill post my working code once done, to think that it could help others also with the same problem

naihart gravatar image naihart  ( 2022-04-01 20:19:09 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

2 followers

Stats

Asked: 2022-03-30 12:36:49 -0500

Seen: 80 times

Last updated: Apr 05