00001 #ifndef SWRI_ROSCPP_PARAMETERS_H_
00002 #define SWRI_ROSCPP_PARAMETERS_H_
00003
00004 #include <algorithm>
00005 #include <set>
00006 #include <string>
00007 #include <vector>
00008
00009 #include <boost/bind.hpp>
00010
00011 #include <ros/console.h>
00012 #include <ros/node_handle.h>
00013
00014 namespace swri
00015 {
00016
00019 static std::set<std::string> _used_params;
00020
00021 static inline
00022 bool getParam(const ros::NodeHandle &nh,
00023 const std::string &name,
00024 int &variable)
00025 {
00026 std::string resolved_name = nh.resolveName(name);
00027 _used_params.insert(resolved_name);
00028 if (!nh.getParam(name, variable))
00029 {
00030 ROS_ERROR("Required int parameter %s does not exist", name.c_str());
00031 return false;
00032 }
00033 ROS_INFO("Read parameter %s = %d", name.c_str(), variable);
00034 return true;
00035 }
00036
00037 static inline
00038 bool getParam(const ros::NodeHandle &nh,
00039 const std::string &name,
00040 double &variable)
00041 {
00042 std::string resolved_name = nh.resolveName(name);
00043 _used_params.insert(resolved_name);
00044 if (!nh.getParam(name, variable))
00045 {
00046 ROS_ERROR("Required double parameter %s does not exist", name.c_str());
00047 return false;
00048 }
00049 ROS_INFO("Read parameter %s = %lf", name.c_str(), variable);
00050 return true;
00051 }
00052
00053 static inline
00054 bool getParam(const ros::NodeHandle &nh,
00055 const std::string &name,
00056 float &variable)
00057 {
00058 double dbl_value;
00059 if (!nh.getParam(name, dbl_value))
00060 {
00061 ROS_ERROR("Required double parameter %s does not exist", name.c_str());
00062 return false;
00063 }
00064 variable = dbl_value;
00065 ROS_INFO("Read parameter %s = %f", name.c_str(), variable);
00066 return true;
00067 }
00068
00069 static inline
00070 bool getParam(const ros::NodeHandle &nh,
00071 const std::string &name,
00072 std::string &variable)
00073 {
00074 std::string resolved_name = nh.resolveName(name);
00075 _used_params.insert(resolved_name);
00076 if (!nh.getParam(name, variable))
00077 {
00078 ROS_ERROR("Required string parameter %s does not exist", name.c_str());
00079 return false;
00080 }
00081 ROS_INFO("Read parameter %s = %s", name.c_str(), variable.c_str());
00082 return true;
00083 }
00084
00085 static inline
00086 bool getParam(const ros::NodeHandle &nh,
00087 const std::string &name,
00088 bool &variable)
00089 {
00090 std::string resolved_name = nh.resolveName(name);
00091 _used_params.insert(resolved_name);
00092 if (!nh.getParam(name, variable))
00093 {
00094 ROS_ERROR("Required bool parameter %s does not exist", name.c_str());
00095 return false;
00096 }
00097 ROS_INFO("Read parameter %s = %s", name.c_str(), variable ? "true" : "false");
00098 return true;
00099 }
00100
00101 static inline
00102 void param(const ros::NodeHandle &nh,
00103 const std::string &name,
00104 int &variable,
00105 const int default_value)
00106 {
00107 std::string resolved_name = nh.resolveName(name);
00108 _used_params.insert(resolved_name);
00109 nh.param(name, variable, default_value);
00110 ROS_INFO("Read parameter %s = %d", name.c_str(), variable);
00111 }
00112
00113 static inline
00114 void param(const ros::NodeHandle &nh,
00115 const std::string &name,
00116 double &variable,
00117 const double default_value)
00118 {
00119 std::string resolved_name = nh.resolveName(name);
00120 _used_params.insert(resolved_name);
00121 nh.param(name, variable, default_value);
00122 ROS_INFO("Read parameter %s = %lf", name.c_str(), variable);
00123 }
00124
00125 static inline
00126 void param(const ros::NodeHandle &nh,
00127 const std::string &name,
00128 float &variable,
00129 const float default_value)
00130 {
00131 double dbl_value;
00132 double dbl_default = default_value;
00133 nh.param(name, dbl_value, dbl_default);
00134 variable = dbl_value;
00135 ROS_INFO("Read parameter %s = %f", name.c_str(), variable);
00136 }
00137
00138 static inline
00139 void param(const ros::NodeHandle &nh,
00140 const std::string &name,
00141 std::string &variable,
00142 const std::string default_value)
00143 {
00144 std::string resolved_name = nh.resolveName(name);
00145 _used_params.insert(resolved_name);
00146 nh.param(name, variable, default_value);
00147 ROS_INFO("Read parameter %s = \"%s\"", name.c_str(), variable.c_str());
00148 }
00149
00150 static inline
00151 void param(const ros::NodeHandle &nh,
00152 const std::string &name,
00153 bool &variable,
00154 const bool default_value)
00155 {
00156 std::string resolved_name = nh.resolveName(name);
00157 _used_params.insert(resolved_name);
00158 nh.param(name, variable, default_value);
00159 ROS_INFO("Read parameter %s = %s", name.c_str(), variable ? "true" : "false");
00160 }
00161
00172 inline int comparePrefix(std::string const& string, std::string const& prefix)
00173 {
00174 return string.compare(0, prefix.size(), prefix);
00175 }
00176
00186 inline bool isPrefixOf(std::string const& string, std::string const& prefix)
00187 {
00188 return comparePrefix(string, prefix) == 0;
00189 }
00190
00202 inline int prefixLessThan(std::string const& string, std::string const& prefix)
00203 {
00204 return comparePrefix(string, prefix) < 0;
00205 }
00206
00223 static inline
00224 std::vector<std::string> getUnusedParamKeys(ros::NodeHandle const& n)
00225 {
00226
00227 std::string const& n_namespace = n.getNamespace();
00228 std::vector<std::string> all_params;
00229 n.getParamNames(all_params);
00230
00231
00232 std::sort(all_params.begin(), all_params.end());
00233
00234
00235
00236 boost::function<bool(std::string)> inNamespace = boost::bind(isPrefixOf, _1, n_namespace);
00237
00238 std::vector<std::string>::const_iterator first_param_in_namespace = find_if(all_params.begin(), all_params.end(), inNamespace);
00239
00240 std::vector<std::string>::const_iterator after_last_param_in_namespace = find_if(all_params.begin(), all_params.end(), std::not1(inNamespace));
00241
00242
00243
00244
00245 std::vector<std::string> unused_params(all_params.size());
00246
00247
00248 std::vector<std::string>::iterator last_unused_param = std::set_difference(
00249 first_param_in_namespace, after_last_param_in_namespace,
00250 _used_params.begin(), _used_params.end(),
00251 unused_params.begin(),
00252 prefixLessThan);
00253
00254
00255
00256 unused_params.resize(last_unused_param - unused_params.begin());
00257
00258 return unused_params;
00259 }
00260
00266 static inline
00267 void warnUnusedParams(ros::NodeHandle const& n)
00268 {
00269 std::vector<std::string> unused_params = getUnusedParamKeys(n);
00270 for (std::vector<std::string>::const_iterator itr = unused_params.begin(); itr != unused_params.end(); ++itr)
00271 {
00272 ROS_WARN("Parameter %s was set, but not used by this node", itr->c_str());
00273 }
00274 }
00275 }
00276 #endif // SWRI_ROSCPP_PARAMETERS_H_