service_server_impl.h
Go to the documentation of this file.
1 // *****************************************************************************
2 //
3 // Copyright (c) 2015, Southwest Research Institute® (SwRI®)
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of Southwest Research Institute® (SwRI®) nor the
14 // names of its contributors may be used to endorse or promote products
15 // derived from this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL SOUTHWEST RESEARCH INSTITUTE BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28 // *****************************************************************************
29 #ifndef SWRI_ROSCPP_SERVICE_SERVER_IMPL_H_
30 #define SWRI_ROSCPP_SERVICE_SERVER_IMPL_H_
31 
33 
34 namespace swri
35 {
36 class ServiceServer;
38 {
39  protected:
41  std::string unmapped_service_;
42  std::string mapped_service_;
43 
46  std::map<std::string, ServiceServerStatistics> client_stats_;
47 
48  bool log_calls_;
49 
50  void processServing(const std::string caller_name,
51  bool success,
52  const ros::WallDuration &runtime)
53  {
54  total_stats_.merge(success, runtime);
55  if (instrument_per_client_) {
56  client_stats_[caller_name].merge(success, runtime);
57  }
58  }
59 
60  public:
62  :
63  unmapped_service_("uninitialized"),
64  mapped_service_("initialized"),
65  instrument_per_client_(false),
66  log_calls_(false)
67  {
68  }
69 
71  {
72 
73  }
74 
76  {
77  total_stats_.reset();
78  client_stats_.clear();
79  }
80 
81  const std::string& unmappedService() const { return unmapped_service_; }
82  const std::string& mappedService() const { return mapped_service_; }
83 
84  const ServiceServerStatistics& totalStats() const { return total_stats_; }
85 
86  void setInstrumentPerClient(bool enable)
87  {
88  instrument_per_client_ = enable;
89  if (!instrument_per_client_) {
90  client_stats_.clear();
91  }
92  }
93 
95 
96  std::vector<std::string> clientNames() const
97  {
98  std::vector<std::string> names;
99  names.reserve(client_stats_.size());
100 
101  std::map<std::string, ServiceServerStatistics>::const_iterator it;
102  for (it = client_stats_.begin(); it != client_stats_.end(); it++) {
103  names.push_back(it->first);
104  }
105  return names;
106  }
107 
109  const std::string &name) const
110  {
111  std::map<std::string, ServiceServerStatistics>::const_iterator it;
112  it = client_stats_.find(name);
113  if (it == client_stats_.end()) {
114  return ServiceServerStatistics();
115  } else {
116  return it->second;
117  }
118  }
119 
120  void setLogCalls(bool enable)
121  {
122  log_calls_ = enable;
123  }
124 
125  bool logCalls() const { return log_calls_; }
126 };
127 
128 template<class MReq, class MRes, class T>
130 {
131  T *obj_;
132  bool (T::*callback_plain_)(MReq &, MRes &);
133  bool (T::*callback_with_event_)(ros::ServiceEvent< MReq, MRes > &);
134  bool (T::*callback_with_name_)(const std::string &, const MReq &, MRes &);
135 
137  const std::string &service)
138  {
139  unmapped_service_ = service;
140  mapped_service_ = nh.resolveName(service);
141 
143  ROS_INFO("Serving to '%s'.", mapped_service_.c_str());
144  } else {
145  ROS_INFO("Serving to '%s' at '%s'.",
146  unmapped_service_.c_str(),
147  mapped_service_.c_str());
148  }
149 
152  this);
153  }
154 
156  {
157  if (logCalls()) {
158  ROS_INFO("Service '%s' called by '%s'",
159  mapped_service_.c_str(),
160  event.getCallerName().c_str());
161  }
162 
163  bool result;
165 
166  try {
167  if (callback_plain_) {
168  result = (obj_->*callback_plain_)(
169  const_cast<MReq&>(event.getRequest()), event.getResponse());
170  } else if (callback_with_name_) {
171  result = (obj_->*callback_with_name_)(
172  event.getCallerName(), event.getRequest(), event.getResponse());
173  } else {
174  result = (obj_->*callback_with_event_)(event);
175  }
176  } catch (...) {
177  result = false;
178  }
180 
181  processServing(event.getCallerName(), result, finish-start);
182  return result;
183  }
184 
185  public:
187  :
188  obj_(NULL),
189  callback_plain_(NULL),
190  callback_with_event_(NULL),
191  callback_with_name_(NULL)
192  {
193  }
194 
196  const std::string &service,
197  bool(T::*srv_func)(MReq &, MRes &),
198  T *obj)
199  {
200  obj_ = obj;
201  callback_plain_ = srv_func;
202  callback_with_event_ = NULL;
203  callback_with_name_ = NULL;
204  initialize(nh, service);
205  }
206 
208  const std::string &service,
209  bool(T::*srv_func)(ros::ServiceEvent<MReq, MRes> &),
210  T *obj)
211  {
212  obj_ = obj;
213  callback_plain_ = NULL;
214  callback_with_event_ = srv_func;
215  callback_with_name_ = NULL;
216  initialize(nh, service);
217  }
218 
220  const std::string &service,
221  bool(T::*srv_func)(const std::string &, const MReq &, MRes &),
222  T *obj)
223  {
224  obj_ = obj;
225  callback_plain_ = NULL;
226  callback_with_event_ = NULL;
227  callback_with_name_ = srv_func;
228  initialize(nh, service);
229  }
230 }; // class TypedServiceServerImpl
231 } // namespace swri
232 #endif // SWRI_ROSCPP_SERVICE_SERVER_IMPL_H_
233 
const ServiceServerStatistics & totalStats() const
ServiceServerStatistics total_stats_
void setLogCalls(bool enable)
ROSCPP_DECL void start()
const std::string & getCallerName() const
ROSCONSOLE_DECL void initialize()
void setInstrumentPerClient(bool enable)
TypedServiceServerImpl(ros::NodeHandle &nh, const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
ros::ServiceServer server_
void processServing(const std::string caller_name, bool success, const ros::WallDuration &runtime)
std::map< std::string, ServiceServerStatistics > client_stats_
void initialize(ros::NodeHandle &nh, const std::string &service)
const std::string & mappedService() const
#define ROS_INFO(...)
TypedServiceServerImpl(ros::NodeHandle &nh, const std::string &service, bool(T::*srv_func)(ros::ServiceEvent< MReq, MRes > &), T *obj)
void merge(bool success, const ros::WallDuration &runtime)
std::string resolveName(const std::string &name, bool remap=true) const
const RequestType & getRequest() const
ResponseType & getResponse() const
TypedServiceServerImpl(ros::NodeHandle &nh, const std::string &service, bool(T::*srv_func)(const std::string &, const MReq &, MRes &), T *obj)
const std::string & unmappedService() const
std::vector< std::string > clientNames() const
static WallTime now()
bool handleService(ros::ServiceEvent< MReq, MRes > &event)
ServiceServerStatistics clientStatistics(const std::string &name) const


swri_roscpp
Author(s):
autogenerated on Sat Jan 21 2023 03:13:16