rtt_rosservice_proxy.h
Go to the documentation of this file.
1 #ifndef __RTT_ROSCOMM_RTT_ROSSERVICE_PROXY_H
2 #define __RTT_ROSCOMM_RTT_ROSSERVICE_PROXY_H
3 
4 #include <ros/ros.h>
5 
6 #include <rtt/RTT.hpp>
9 
12 {
13 public:
14  ROSServiceProxyBase(const std::string &service_name) : service_name_(service_name) { }
15  virtual ~ROSServiceProxyBase() { }
17  const std::string& getServiceName() const { return service_name_; }
18 private:
20  std::string service_name_;
21 };
22 
23 
26 {
27 public:
28  ROSServiceServerProxyBase(const std::string &service_name) :
29  ROSServiceProxyBase(service_name)
30  { }
31 
33  virtual bool connect(RTT::TaskContext *owner, RTT::OperationInterfacePart* operation) = 0;
34 
35 protected:
38 };
39 
40 template<class ROS_SERVICE_T>
42 public:
45  virtual bool call(typename ROS_SERVICE_T::Request& request, typename ROS_SERVICE_T::Response& response) const = 0;
46 };
47 
48 template<class ROS_SERVICE_T, int variant = 0>
50 
51 // Default implementation of an OperationCaller that fowards ROS service calls to Orocos operations
52 // that have the default bool(Request&, Response&) signature. You can add more variants of this class
53 // to add support for custom operation types.
54 //
55 // See package std_srvs for an example.
56 //
57 template<class ROS_SERVICE_T>
58 struct ROSServiceServerOperationCallerWrapper<ROS_SERVICE_T,0> {
59  typedef bool Signature(typename ROS_SERVICE_T::Request&, typename ROS_SERVICE_T::Response&);
61  template <typename Callable> static bool call(Callable& call, typename ROS_SERVICE_T::Request& request, typename ROS_SERVICE_T::Response& response) {
62  return call(request, response);
63  }
64 };
65 
66 template<class ROS_SERVICE_T, int variant = 0>
68 public:
70 
73 
75  typedef typename Wrapper::ProxyOperationCallerType ProxyOperationCallerType;
77 
79  ProxyOperationCallerTypePtr proxy_operation_caller
80  = boost::make_shared<ProxyOperationCallerType>(operation->getLocalOperation(), RTT::internal::GlobalEngine::Instance());
81  if (proxy_operation_caller->ready()) {
82  return Ptr(new ROSServiceServerOperationCaller<ROS_SERVICE_T, variant>(proxy_operation_caller));
83  }
84  return NextVariant<void>::connect(operation);
85  }
86 
87  virtual bool call(typename ROS_SERVICE_T::Request& request, typename ROS_SERVICE_T::Response& response) const {
88  // Check if the operation caller is ready, and then call it.
89  if (!proxy_operation_caller_->ready()) return false;
90  return Wrapper::call(*proxy_operation_caller_, request, response);
91  }
92 
93 private:
94  template<typename Dummy> struct Void { typedef void type; };
95 
96  template<typename R = void, typename Enabled = void> struct EnableIfHasNextVariant { };
97 
98  template<typename R> struct EnableIfHasNextVariant<R,
99  typename Void<typename ROSServiceServerOperationCallerWrapper<ROS_SERVICE_T, variant + 1>::ProxyOperationCallerType>::type> {
100  typedef R type;
101  };
102 
103  template<typename R = void, typename Enabled = void>
104  struct NextVariant {
106  };
107 
108  template<typename R>
109  struct NextVariant<R, typename EnableIfHasNextVariant<R>::type> {
112  }
113  };
114 
116  : proxy_operation_caller_(impl) {}
117 
118  ProxyOperationCallerTypePtr proxy_operation_caller_;
119 };
120 
121 template<class ROS_SERVICE_T>
123 {
124 public:
128  ROSServiceServerProxy(const std::string &service_name) :
129  ROSServiceServerProxyBase(service_name)
130  {
131  // Construct the ROS service server
132  ros::NodeHandle nh;
133  server_ = nh.advertiseService(
134  service_name,
136  this);
137  }
138 
140  {
141  // Clean-up advertized ROS services
142  server_.shutdown();
143  }
144 
146  {
148  return (impl_.get() != 0);
149  }
150 
151 private:
153  bool ros_service_callback(typename ROS_SERVICE_T::Request& request, typename ROS_SERVICE_T::Response& response) {
154  if (!impl_) return false;
155  return impl_->call(request, response);
156  }
157 
159 };
160 
161 
164 {
165 public:
166  ROSServiceClientProxyBase(const std::string &service_name) :
167  ROSServiceProxyBase(service_name),
168  proxy_operation_()
169  { }
170 
173  return proxy_operation_.get() != NULL &&
174  operation_caller->setImplementation(
175  proxy_operation_->getImplementation(),
176  owner->engine());
177  }
178 
179 protected:
184 };
185 
186 template<class ROS_SERVICE_T>
188 {
189 public:
190 
193 
194  ROSServiceClientProxy(const std::string &service_name) :
195  ROSServiceClientProxyBase(service_name)
196  {
197  // Construct a new
198  proxy_operation_.reset(new ProxyOperationType("ROS_SERVICE_CLIENT_PROXY"));
199 
200  // Construct the underlying service client
201  ros::NodeHandle nh;
202  client_ = nh.serviceClient<ROS_SERVICE_T>(service_name);
203 
204  // Link the operation with the service client
205  dynamic_cast<ProxyOperationType*>(proxy_operation_.get())->calls(
207  this,
209  }
210 
211 private:
212 
214  bool orocos_operation_callback(typename ROS_SERVICE_T::Request& request, typename ROS_SERVICE_T::Response& response) {
215  // Make sure the ROS service client exists and then call it (blocking)
216  return client_.exists() && client_.isValid() && client_.call(request, response);
217  }
218 };
219 
220 
223 {
224 public:
225 
226  ROSServiceProxyFactoryBase(const std::string &service_type) : service_type_(service_type) { }
227 
229  const std::string& getType() { return service_type_; }
230 
232  virtual ROSServiceClientProxyBase* create_client_proxy(const std::string &service_name) = 0;
234  virtual ROSServiceServerProxyBase* create_server_proxy(const std::string &service_name) = 0;
235 
236 private:
237  std::string service_type_;
238 };
239 
240 template<class ROS_SERVICE_T>
242 {
243 public:
244 
245  ROSServiceProxyFactory(const std::string &service_type) : ROSServiceProxyFactoryBase(service_type) { }
246 
247  virtual ROSServiceClientProxyBase* create_client_proxy(const std::string &service_name) {
248  return new ROSServiceClientProxy<ROS_SERVICE_T>(service_name);
249  }
250 
251  virtual ROSServiceServerProxyBase* create_server_proxy( const std::string &service_name) {
252  return new ROSServiceServerProxy<ROS_SERVICE_T>(service_name);
253  }
254 };
255 
256 #endif // ifndef __RTT_ROSCOMM_RTT_ROSSERVICE_PROXY_H
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
ROSServiceServerProxy(const std::string &service_name)
Construct a ROS service server and associate it with an Orocos task&#39;s required interface and operatio...
virtual bool setImplementation(boost::shared_ptr< base::DisposableInterface > impl, ExecutionEngine *caller=0)=0
ros::ServiceServer server_
The underlying ROS service server.
static Ptr connect(RTT::OperationInterfacePart *)
ProxyOperationCallerTypePtr proxy_operation_caller_
bool connect(RTT::TaskContext *owner, RTT::base::OperationCallerBaseInvoker *operation_caller)
Connect an operation caller with this proxy.
Wrapper::ProxyOperationCallerType ProxyOperationCallerType
Default operation caller for a ROS service server proxy.
bool call(const std::string &service_name, MReq &req, MRes &res)
boost::shared_ptr< ROSServiceServerOperationCallerBase< ROS_SERVICE_T > > Ptr
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
static bool call(Callable &call, typename ROS_SERVICE_T::Request &request, typename ROS_SERVICE_T::Response &response)
ROSServiceServerOperationCaller(const boost::shared_ptr< ProxyOperationCallerType > &impl)
ROSServiceClientProxyBase(const std::string &service_name)
ROSServiceClientProxy(const std::string &service_name)
ROSServiceProxyBase(const std::string &service_name)
virtual bool call(typename ROS_SERVICE_T::Request &request, typename ROS_SERVICE_T::Response &response) const
ROSServiceProxyFactory(const std::string &service_type)
boost::shared_ptr< RTT::base::OperationBase > proxy_operation_
The underlying RTT operation.
bool Signature(typename ROS_SERVICE_T::Request &, typename ROS_SERVICE_T::Response &)
virtual bool connect(RTT::TaskContext *, RTT::OperationInterfacePart *operation)
Connect an RTT Operation to this ROS service server.
static Ptr connect(RTT::OperationInterfacePart *operation)
static RTT_API ExecutionEngine * Instance()
bool orocos_operation_callback(typename ROS_SERVICE_T::Request &request, typename ROS_SERVICE_T::Response &response)
The callback for the RTT operation.
boost::shared_ptr< ROSServiceServerOperationCallerBase< ROS_SERVICE_T > > impl_
virtual ROSServiceClientProxyBase * create_client_proxy(const std::string &service_name)
Get a proxy to a ROS service client.
Abstract factory for ROS Service Proxy Factories.
virtual RTT_API boost::shared_ptr< base::DisposableInterface > getLocalOperation() const
RTT::Operation< bool(typename ROS_SERVICE_T::Request &, typename ROS_SERVICE_T::Response &)> ProxyOperationType
The proxy RTT operation type for this ROS service.
std::string service_name_
ROS Service name (fully qualified)
Abstract ROS Service Client Proxy.
ROSServiceProxyFactoryBase(const std::string &service_type)
ROSServiceServerProxyBase(const std::string &service_name)
ROSServiceServerOperationCallerWrapper< ROS_SERVICE_T, variant > Wrapper
The wrapper type for this variant.
const std::string & getServiceName() const
Get the name of the ROS service.
Abstract ROS Service Server Proxy.
bool ros_service_callback(typename ROS_SERVICE_T::Request &request, typename ROS_SERVICE_T::Response &response)
The callback called by the ROS service server when this service is invoked.
boost::shared_ptr< ProxyOperationCallerType > ProxyOperationCallerTypePtr
const std::string & getType()
Get the ROS service type.
ClientThread
Abstract ROS Service Proxy.
const ExecutionEngine * engine() const
const std::string response
ros::ServiceClient client_
The underlying ROS service client.
virtual ROSServiceServerProxyBase * create_server_proxy(const std::string &service_name)
Get a proxy to a ROS service server.


rtt_roscomm
Author(s): Ruben Smits, Jonathan Bohren
autogenerated on Sat Jun 8 2019 18:05:17