$search
00001 /********************************************************************* 00002 * 00003 * Copyright (c) 2009, Willow Garage, Inc. 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above 00013 * copyright notice, this list of conditions and the following 00014 * disclaimer in the documentation and/or other materials provided 00015 * with the distribution. 00016 * * Neither the name of the Willow Garage nor the names of its 00017 * contributors may be used to endorse or promote products derived 00018 * from this software without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00021 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00022 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00023 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00024 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00025 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00026 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00027 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00028 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00029 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00030 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00031 * POSSIBILITY OF SUCH DAMAGE. 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 //compute the name of the service 00138 std::string client_name = prefix_ + arm_name + suffix_; 00139 00140 //check if the service is already there 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 //new service; wait for it 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 //insert new service in list 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 //and return it 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 //compute the name of the action 00276 std::string client_name = prefix_ + arm_name + suffix_; 00277 00278 //check if the action client is already there 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 //create new action client and insert in map 00289 actionlib::SimpleActionClient<ActionDataType>* new_client = 00290 new actionlib::SimpleActionClient<ActionDataType>(nh_, action_name, param_ ); 00291 00292 //wait for the server 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 //insert new client in map 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 //and return it 00312 return *(new_pair.first->second); 00313 00314 } 00315 }; 00316 00317 00318 } //namespace object_manipulator 00319 00320 #endif