Does a service always have a request and response in the parameters for a callback?

Hi,

I have a question regarding a service server I’m implementing for the ‘wall follower’ rosject. In the class server constructor I have declared:

srv_ = create_service<FindWall_srv>(
        "FindWall",
        std::bind(&FindWall_Server::findwall_callback, this, _1, _2));

and in private:

void findwall_callback(const std::shared_ptr<FindWall_srv::Request> request,
                       const std::shared_ptr<FindWall_srv::Response> response) {}

The custom interface is:

                   #request
---
bool wallfound     #response

As you can see there is no request so I’ve tried

srv_ = create_service<FindWall_srv>(
        "FindWall",
        std::bind(&FindWall_Server::findwall_callback, this, _1));

void findwall_callback(const std::shared_ptr<FindWall_srv::Response> response) {}

and this has been spouting a lot of errors. Does this callback always require both request and response when there is no request? I’m assuming there’s another way to code this because there is no request. May I get help?

Many Thanks in advance,
William

Hi @william.lubiantoro ,

Yes, the parameters for the service callback function must have (request, response).
Since you are using C++, any and all parameters defined for a function must be supplied to the function.
Property of polymorphism applies only to argument of a parameter, not for the function definition itself.
Therefore, even if one of the parameters are empty, you cannot eliminate that parameter from the function definition.

So,

This line will not work and will never work.

This line will always work, even if one of the parameter is an empty message.

This is because of the structure of the service message itself.
If you have either the request or the response as empty, conventionally, you must leave a horizontal blank space (carriage return) for that part of the service interface (message) definition.

So, you can technically do the following:

---
bool data   # response

but the following is better for readability and follows convention:

            # request is a blank line
---
bool data   # response

OR:

bool state   # request
---
             # response is a blank line

OR even this way (same as Empty service message):

            # request is a blank line
---
            # response is a blank line

If request is not specified in the service interface definition file, it means that part of message uses Empty as message type. It does not mean it is unused or undefined or unnecessary.

No, you have a minor misunderstanding. Empty part of interface does not mean it is non-existent.

Also, when you build a custom service interface/message, ROS(1/2) will also generate a class for the empty part of the message. Therefore, you must also use ServiceMsg::Request and ServiceMsg::Response in your program code.

So, you MUST ALWAYS define both the request and response as function parameters to a service callback function for a service server. There are no other options or any shortcuts.

I hope I have clarified your doubt(s). Let me know if anything is still unclear.

Regards,
Girish

Thank you for the clarification @girishkumar.kannan

HI @william.lubiantoro ,

Yes.

It won’t work, because both the commands are wrong.
The proper syntax is:

ros2 service call <service_name> <service_interface_type> <interface_data>
ros2 service call /FindWall custom_interfaces/srv/FindWall "{}"

This should work.

EDIT: I have answered after you deleted your post.

Regards,
Girish

1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.