00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef _SERVICE_ACTION_WRAPPERS_H_
00034 #define _SERVICE_ACTION_WRAPPERS_H_
00035
00036 #include <ros/ros.h>
00037 #include <actionlib/client/simple_action_client.h>
00038
00039 #include <string>
00040 #include <map>
00041
00042 #include "object_manipulator/tools/exceptions.h"
00043
00044 namespace object_manipulator {
00045
00047
00050 template <class ServiceDataType>
00051 class ServiceWrapper
00052 {
00053 private:
00055 bool initialized_;
00057 std::string service_name_;
00059 ros::NodeHandle nh_;
00061 ros::ServiceClient client_;
00062 public:
00063 ServiceWrapper(std::string service_name) : initialized_(false),
00064 service_name_(service_name),
00065 nh_("")
00066 {}
00067
00069 ros::ServiceClient& client(ros::Duration timeout = ros::Duration(5.0))
00070 {
00071 if (!initialized_)
00072 {
00073 ros::Duration ping_time = ros::Duration(1.0);
00074 if (timeout >= ros::Duration(0) && ping_time > timeout) ping_time = timeout;
00075 ros::Time start_time = ros::Time::now();
00076 while (1)
00077 {
00078 if (ros::service::waitForService(service_name_, ping_time)) break;
00079 ROS_INFO_STREAM("Waiting for service " << service_name_);
00080 if (!ros::ok()) throw ServiceNotFoundException(service_name_);
00081 ros::Time current_time = ros::Time::now();
00082 if (timeout >= ros::Duration(0) && current_time - start_time >= timeout)
00083 throw ServiceNotFoundException(service_name_);
00084 }
00085 client_ = nh_.serviceClient<ServiceDataType>(service_name_);
00086 initialized_ = true;
00087 }
00088 return client_;
00089 }
00090 };
00091
00093
00102 template <class ServiceDataType>
00103 class MultiArmServiceWrapper
00104 {
00105 private:
00107 ros::NodeHandle nh_;
00108
00110 std::string prefix_;
00111
00113 std::string suffix_;
00114
00115 typedef std::map<std::string, ros::ServiceClient> map_type;
00116
00118 map_type clients_;
00119
00121
00122 bool resolve_names_;
00123
00124 public:
00126 MultiArmServiceWrapper(std::string prefix, std::string suffix, bool resolve_names) :
00127 nh_(""), prefix_(prefix), suffix_(suffix), resolve_names_(resolve_names)
00128 {}
00129
00131
00135 ros::ServiceClient& client(std::string arm_name, ros::Duration timeout = ros::Duration(5.0))
00136 {
00137
00138 std::string client_name = prefix_ + arm_name + suffix_;
00139
00140
00141 map_type::iterator it = clients_.find(client_name);
00142 if ( it != clients_.end() )
00143 {
00144 return it->second;
00145 }
00146
00147 std::string service_name = client_name;
00148 if (resolve_names_) service_name = nh_.resolveName(client_name);
00149
00150
00151 ros::Duration ping_time = ros::Duration(1.0);
00152 if (timeout >= ros::Duration(0) && ping_time > timeout) ping_time = timeout;
00153 ros::Time start_time = ros::Time::now();
00154 while(1)
00155 {
00156 if (ros::service::waitForService(service_name, ping_time)) break;
00157 if (!ros::ok()) throw ServiceNotFoundException(client_name + " remapped to " + service_name);
00158 ros::Time current_time = ros::Time::now();
00159 if (timeout >= ros::Duration(0) && current_time - start_time >= timeout)
00160 throw ServiceNotFoundException(client_name + " remapped to " + service_name);
00161 ROS_INFO_STREAM("Waiting for service " << client_name << " remapped to " << service_name);
00162 }
00163
00164
00165 std::pair<map_type::iterator, bool> new_pair;
00166 new_pair = clients_.insert(std::pair<std::string, ros::ServiceClient>
00167 (client_name, nh_.serviceClient<ServiceDataType>(service_name) ) );
00168
00169
00170 return new_pair.first->second;
00171 }
00172 };
00173
00174
00176 template <class ActionDataType>
00177 class ActionWrapper
00178 {
00179 private:
00181 bool initialized_;
00183 std::string action_name_;
00185 ros::NodeHandle nh_;
00187 actionlib::SimpleActionClient<ActionDataType> client_;
00188 public:
00189 ActionWrapper(std::string action_name, bool param) : initialized_(false),
00190 action_name_(action_name),
00191 nh_(""),
00192 client_(nh_, action_name, param) {}
00193
00194 actionlib::SimpleActionClient<ActionDataType>& client(ros::Duration timeout = ros::Duration(5.0))
00195 {
00196 if (!initialized_)
00197 {
00198 ros::Duration ping_time = ros::Duration(1.0);
00199 if (timeout >= ros::Duration(0) && ping_time > timeout) ping_time = timeout;
00200 ros::Time start_time = ros::Time::now();
00201 while (1)
00202 {
00203 if (client_.waitForServer(ping_time)) break;
00204 if (!ros::ok()) throw ServiceNotFoundException(action_name_);
00205 ros::Time current_time = ros::Time::now();
00206 if (timeout >= ros::Duration(0) && current_time - start_time >= timeout)
00207 throw ServiceNotFoundException(action_name_);
00208 ROS_INFO_STREAM("Waiting for action client: " << action_name_);
00209 }
00210 initialized_ = true;
00211 }
00212 return client_;
00213 }
00214 };
00215
00216
00218
00227 template <class ActionDataType>
00228 class MultiArmActionWrapper
00229 {
00230 private:
00232 ros::NodeHandle nh_;
00233
00235 std::string prefix_;
00236
00238 std::string suffix_;
00239
00241 bool param_;
00242
00244 typedef std::map<std::string, actionlib::SimpleActionClient<ActionDataType>* > map_type;
00245
00247 map_type clients_;
00248
00250
00251 bool resolve_names_;
00252
00253 public:
00255 MultiArmActionWrapper(std::string prefix, std::string suffix, bool param, bool resolve_names) :
00256 nh_(""), prefix_(prefix), suffix_(suffix), param_(param), resolve_names_(resolve_names)
00257 {}
00258
00259 ~MultiArmActionWrapper()
00260 {
00261 for (typename map_type::iterator it = clients_.begin(); it!=clients_.end(); it++)
00262 {
00263 delete it->second;
00264 }
00265 }
00266
00268
00272 actionlib::SimpleActionClient<ActionDataType>& client(std::string arm_name,
00273 ros::Duration timeout = ros::Duration(5.0))
00274 {
00275
00276 std::string client_name = prefix_ + arm_name + suffix_;
00277
00278
00279 typename map_type::iterator it = clients_.find(client_name);
00280 if ( it != clients_.end() )
00281 {
00282 return *(it->second);
00283 }
00284
00285 std::string action_name = client_name;
00286 if (resolve_names_) action_name = nh_.resolveName(client_name);
00287
00288
00289 actionlib::SimpleActionClient<ActionDataType>* new_client =
00290 new actionlib::SimpleActionClient<ActionDataType>(nh_, action_name, param_ );
00291
00292
00293 ros::Duration ping_time = ros::Duration(1.0);
00294 if (timeout >= ros::Duration(0) && ping_time > timeout) ping_time = timeout;
00295 ros::Time start_time = ros::Time::now();
00296 while (1)
00297 {
00298 if (new_client->waitForServer(ping_time)) break;
00299 if (!ros::ok()) throw ServiceNotFoundException(client_name + " remapped to " + action_name);
00300 ros::Time current_time = ros::Time::now();
00301 if (timeout >= ros::Duration(0) && current_time - start_time >= timeout)
00302 throw ServiceNotFoundException(client_name + " remapped to " + action_name);
00303 ROS_INFO_STREAM("Waiting for action client " << client_name << ", remapped to " << action_name);
00304 }
00305
00306
00307 std::pair< typename map_type::iterator, bool> new_pair =
00308 clients_.insert( std::pair<std::string,actionlib::SimpleActionClient<ActionDataType>* >
00309 (client_name, new_client ) );
00310
00311
00312 return *(new_pair.first->second);
00313
00314 }
00315 };
00316
00317
00318 }
00319
00320 #endif