添加srv文件
srv和msg有很多是想通的,特别是在package.xml和CmakeLists.txt的修改中,不同的就是目录和后缀的写法(srv,msg)。
首先在srv目录下创建一个SrvTutorial.srv,
int64 a
int64 b
---
int64 result
后续在编译时,roscpp会将该srv文件转换为头文件SrvTutorial.h SrvTutorialRequest.h SrvTutorialResponse.h
,大概格式如下,定义了SrvTutorial这个class,内部有请求和返回的消息Request和Response。
namespace my_package
{
struct SrvTutorial
{
class Request
{
...
};
class Response
{
...
};
Request request;
Response response;
};
}
The Request class provides the input to the service. The Response class is returned to the client as the service’s output.
client
对于client,利用NodeHandle去调用service,
ros::NodeHandle nh;
ros::ServiceClient client = nh.serviceClient<my_package::SrvTutorial>("my_service_name");
my_package::SrvTutorial srv;
...
if (client.call(srv))
{
...
}
其中serviceClient模板函数为如下所示,
template<class Service>
ServiceClient serviceClient(const std::string& service_name, bool persistent = false,
const M_string& header_values = M_string())
{
ServiceClientOptions ops;
ops.template init<Service>(service_name, persistent, header_values);
return serviceClient(ops);
}
server
In roscpp you provide a service by creating a ros::ServiceServer
through the ros::NodeHandle::advertiseService()
method.
其中advertiseService
模板函数为,
template<class MReq, class MRes>
ros::ServiceServer nh.advertiseService(const std::string& service, <callback>);
其中,callback可以为functions,class methods,functor objects,这里只描述函数指针,
bool callback(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response)
{
return true;
}
ros::ServiceServer service = nh.advertiseService("my_service", callback);
ros::spin();
when using functor objects you must explicitly specify the request and response types as template arguments, because the compiler cannot deduce them in this case.在使用函数指针和class时,调用advertiseService函数可以不用添加模板参数,编译器会自动推导,但是对functor来说你必须指明,如下所示
ros::ServiceServer srv = nh.advertiseService<std_srvs::Empty::Request, std_srvs::Empty::Response>("my_service", Foo());