Program Listing for File topic_service_server.h
↰ Return to documentation for file (/tmp/ws/src/marti_common/swri_roscpp/include/swri_roscpp/topic_service_server.h
)
// *****************************************************************************
//
// Copyright (c) 2018, Southwest Research Institute® (SwRI®)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Southwest Research Institute® (SwRI®) nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL SOUTHWEST RESEARCH INSTITUTE BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// *****************************************************************************
#ifndef SWRI_ROSCPP_TOPIC_SERVICE_SERVER_H_
#define SWRI_ROSCPP_TOPIC_SERVICE_SERVER_H_
#include <rclcpp/rclcpp.hpp>
namespace swri
{
class ImplRoot
{
public:
virtual ~ImplRoot() = default;
};
template<class MReq, class MRes, class T>
class TopicServiceServerImpl: public ImplRoot
{
std::shared_ptr<rclcpp::Subscription<MReq> > request_sub_;
std::shared_ptr<rclcpp::Publisher<MRes> > response_pub_;
bool(T::*callback_)(const MReq &, MRes &);
T* obj_;
public:
explicit TopicServiceServerImpl() :
ImplRoot(),
node_(nullptr)
{}
void initialize(rclcpp::Node &nh,
const std::string &service,
bool(T::*srv_func)(const MReq &, MRes &),
T *obj)
{
node_ = &nh;
callback_ = srv_func;
obj_ = obj;
response_pub_ = nh.create_publisher<MRes>(service + "/response", 10);
request_sub_ = nh.create_subscription<MReq>(service + "/request",
10, std::bind(&TopicServiceServerImpl<MReq, MRes, T>::request_callback, this, std::placeholders::_1));
}
private:
void request_callback(const std::shared_ptr<MReq> message)
{
RCLCPP_DEBUG(node_->get_logger(),
"Got request from %s with sequence %i", message->srv_header.sender.c_str(), message->srv_header.sequence);
MRes response;
bool result = (obj_->*callback_)(*message, response);
response.srv_header.result = result;
response.srv_header.sequence = message->srv_header.sequence;
response.srv_header.sender = message->srv_header.sender;
response_pub_->publish(response);
}
rclcpp::Node* node_;
};
class TopicServiceServer
{
private:
std::shared_ptr<ImplRoot> impl_;
public:
TopicServiceServer() = default;
template<class MReq, class MRes, class T>
void initialize(rclcpp::Node &nh,
const std::string &service,
bool(T::*srv_func)(const MReq&, MRes&),
T *obj);
}; // class TopicServiceServer
template<class MReq, class MRes, class T>
inline
void TopicServiceServer::initialize(rclcpp::Node &nh,
const std::string &service,
bool(T::*srv_func)(const MReq&, MRes&),
T *obj)
{
auto* impl = new TopicServiceServerImpl<MReq, MRes, T>();
impl->initialize(nh, service, srv_func, obj);
impl_ = std::shared_ptr<ImplRoot>(impl);
}
} // namespace swri
#endif // SWRI_ROSCPP_TOPIC_SERVICE_SERVER_H_