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
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #ifndef __eddiebot_follower__FOLLOWERCONFIG_H__
00048 #define __eddiebot_follower__FOLLOWERCONFIG_H__
00049
00050 #include <dynamic_reconfigure/config_tools.h>
00051 #include <limits>
00052 #include <ros/node_handle.h>
00053 #include <dynamic_reconfigure/ConfigDescription.h>
00054 #include <dynamic_reconfigure/ParamDescription.h>
00055 #include <dynamic_reconfigure/Group.h>
00056 #include <dynamic_reconfigure/config_init_mutex.h>
00057 #include <boost/any.hpp>
00058
00059 namespace eddiebot_follower
00060 {
00061 class FollowerConfigStatics;
00062
00063 class FollowerConfig
00064 {
00065 public:
00066 class AbstractParamDescription : public dynamic_reconfigure::ParamDescription
00067 {
00068 public:
00069 AbstractParamDescription(std::string n, std::string t, uint32_t l,
00070 std::string d, std::string e)
00071 {
00072 name = n;
00073 type = t;
00074 level = l;
00075 description = d;
00076 edit_method = e;
00077 }
00078
00079 virtual void clamp(FollowerConfig &config, const FollowerConfig &max, const FollowerConfig &min) const = 0;
00080 virtual void calcLevel(uint32_t &level, const FollowerConfig &config1, const FollowerConfig &config2) const = 0;
00081 virtual void fromServer(const ros::NodeHandle &nh, FollowerConfig &config) const = 0;
00082 virtual void toServer(const ros::NodeHandle &nh, const FollowerConfig &config) const = 0;
00083 virtual bool fromMessage(const dynamic_reconfigure::Config &msg, FollowerConfig &config) const = 0;
00084 virtual void toMessage(dynamic_reconfigure::Config &msg, const FollowerConfig &config) const = 0;
00085 virtual void getValue(const FollowerConfig &config, boost::any &val) const = 0;
00086 };
00087
00088 typedef boost::shared_ptr<AbstractParamDescription> AbstractParamDescriptionPtr;
00089 typedef boost::shared_ptr<const AbstractParamDescription> AbstractParamDescriptionConstPtr;
00090
00091 template <class T>
00092 class ParamDescription : public AbstractParamDescription
00093 {
00094 public:
00095 ParamDescription(std::string name, std::string type, uint32_t level,
00096 std::string description, std::string edit_method, T FollowerConfig::* f) :
00097 AbstractParamDescription(name, type, level, description, edit_method),
00098 field(f)
00099 {}
00100
00101 T (FollowerConfig::* field);
00102
00103 virtual void clamp(FollowerConfig &config, const FollowerConfig &max, const FollowerConfig &min) const
00104 {
00105 if (config.*field > max.*field)
00106 config.*field = max.*field;
00107
00108 if (config.*field < min.*field)
00109 config.*field = min.*field;
00110 }
00111
00112 virtual void calcLevel(uint32_t &comb_level, const FollowerConfig &config1, const FollowerConfig &config2) const
00113 {
00114 if (config1.*field != config2.*field)
00115 comb_level |= level;
00116 }
00117
00118 virtual void fromServer(const ros::NodeHandle &nh, FollowerConfig &config) const
00119 {
00120 nh.getParam(name, config.*field);
00121 }
00122
00123 virtual void toServer(const ros::NodeHandle &nh, const FollowerConfig &config) const
00124 {
00125 nh.setParam(name, config.*field);
00126 }
00127
00128 virtual bool fromMessage(const dynamic_reconfigure::Config &msg, FollowerConfig &config) const
00129 {
00130 return dynamic_reconfigure::ConfigTools::getParameter(msg, name, config.*field);
00131 }
00132
00133 virtual void toMessage(dynamic_reconfigure::Config &msg, const FollowerConfig &config) const
00134 {
00135 dynamic_reconfigure::ConfigTools::appendParameter(msg, name, config.*field);
00136 }
00137
00138 virtual void getValue(const FollowerConfig &config, boost::any &val) const
00139 {
00140 val = config.*field;
00141 }
00142 };
00143
00144 class AbstractGroupDescription : public dynamic_reconfigure::Group
00145 {
00146 public:
00147 AbstractGroupDescription(std::string n, std::string t, int p, int i, bool s)
00148 {
00149 name = n;
00150 type = t;
00151 parent = p;
00152 state = s;
00153 id = i;
00154 }
00155
00156 std::vector<AbstractParamDescriptionConstPtr> abstract_parameters;
00157 bool state;
00158
00159 virtual void toMessage(dynamic_reconfigure::Config &msg, const boost::any &config) const = 0;
00160 virtual bool fromMessage(const dynamic_reconfigure::Config &msg, boost::any &config) const =0;
00161 virtual void updateParams(boost::any &cfg, FollowerConfig &top) const= 0;
00162 virtual void setInitialState(boost::any &cfg) const = 0;
00163
00164
00165 void convertParams()
00166 {
00167 for(std::vector<AbstractParamDescriptionConstPtr>::const_iterator i = abstract_parameters.begin(); i != abstract_parameters.end(); i++)
00168 {
00169 parameters.push_back(dynamic_reconfigure::ParamDescription(**i));
00170 }
00171 }
00172 };
00173
00174 typedef boost::shared_ptr<AbstractGroupDescription> AbstractGroupDescriptionPtr;
00175 typedef boost::shared_ptr<const AbstractGroupDescription> AbstractGroupDescriptionConstPtr;
00176
00177 template<class T, class PT>
00178 class GroupDescription : public AbstractGroupDescription
00179 {
00180 public:
00181 GroupDescription(std::string name, std::string type, int parent, int id, bool s, T PT::* f) : AbstractGroupDescription(name, type, parent, id, s), field(f)
00182 {
00183 }
00184
00185 GroupDescription(const GroupDescription<T, PT>& g): AbstractGroupDescription(g.name, g.type, g.parent, g.id, g.state), field(g.field), groups(g.groups)
00186 {
00187 parameters = g.parameters;
00188 abstract_parameters = g.abstract_parameters;
00189 }
00190
00191 virtual bool fromMessage(const dynamic_reconfigure::Config &msg, boost::any &cfg) const
00192 {
00193 PT* config = boost::any_cast<PT*>(cfg);
00194 if(!dynamic_reconfigure::ConfigTools::getGroupState(msg, name, (*config).*field))
00195 return false;
00196
00197 for(std::vector<AbstractGroupDescriptionConstPtr>::const_iterator i = groups.begin(); i != groups.end(); i++)
00198 {
00199 boost::any n = &((*config).*field);
00200 if(!(*i)->fromMessage(msg, n))
00201 return false;
00202 }
00203
00204 return true;
00205 }
00206
00207 virtual void setInitialState(boost::any &cfg) const
00208 {
00209 PT* config = boost::any_cast<PT*>(cfg);
00210 T* group = &((*config).*field);
00211 group->state = state;
00212
00213 for(std::vector<AbstractGroupDescriptionConstPtr>::const_iterator i = groups.begin(); i != groups.end(); i++)
00214 {
00215 boost::any n = boost::any(&((*config).*field));
00216 (*i)->setInitialState(n);
00217 }
00218
00219 }
00220
00221 virtual void updateParams(boost::any &cfg, FollowerConfig &top) const
00222 {
00223 PT* config = boost::any_cast<PT*>(cfg);
00224
00225 T* f = &((*config).*field);
00226 f->setParams(top, abstract_parameters);
00227
00228 for(std::vector<AbstractGroupDescriptionConstPtr>::const_iterator i = groups.begin(); i != groups.end(); i++)
00229 {
00230 boost::any n = &((*config).*field);
00231 (*i)->updateParams(n, top);
00232 }
00233 }
00234
00235 virtual void toMessage(dynamic_reconfigure::Config &msg, const boost::any &cfg) const
00236 {
00237 const PT config = boost::any_cast<PT>(cfg);
00238 dynamic_reconfigure::ConfigTools::appendGroup<T>(msg, name, id, parent, config.*field);
00239
00240 for(std::vector<AbstractGroupDescriptionConstPtr>::const_iterator i = groups.begin(); i != groups.end(); i++)
00241 {
00242 (*i)->toMessage(msg, config.*field);
00243 }
00244 }
00245
00246 T (PT::* field);
00247 std::vector<FollowerConfig::AbstractGroupDescriptionConstPtr> groups;
00248 };
00249
00250 class DEFAULT
00251 {
00252 public:
00253 DEFAULT()
00254 {
00255 state = true;
00256 name = "Default";
00257 }
00258
00259 void setParams(FollowerConfig &config, const std::vector<AbstractParamDescriptionConstPtr> params)
00260 {
00261 for (std::vector<AbstractParamDescriptionConstPtr>::const_iterator i = params.begin(); i != params.end(); i++)
00262 {
00263 boost::any val;
00264 (*i)->getValue(config, val);
00265
00266 if("min_x"==(*i)->name){min_x = boost::any_cast<double>(val);}
00267 if("max_x"==(*i)->name){max_x = boost::any_cast<double>(val);}
00268 if("min_y"==(*i)->name){min_y = boost::any_cast<double>(val);}
00269 if("max_y"==(*i)->name){max_y = boost::any_cast<double>(val);}
00270 if("max_z"==(*i)->name){max_z = boost::any_cast<double>(val);}
00271 if("goal_z"==(*i)->name){goal_z = boost::any_cast<double>(val);}
00272 if("x_scale"==(*i)->name){x_scale = boost::any_cast<double>(val);}
00273 if("z_scale"==(*i)->name){z_scale = boost::any_cast<double>(val);}
00274 }
00275 }
00276
00277 double min_x;
00278 double max_x;
00279 double min_y;
00280 double max_y;
00281 double max_z;
00282 double goal_z;
00283 double x_scale;
00284 double z_scale;
00285
00286 bool state;
00287 std::string name;
00288
00289
00290 }groups;
00291
00292
00293
00294
00295 double min_x;
00296
00297 double max_x;
00298
00299 double min_y;
00300
00301 double max_y;
00302
00303 double max_z;
00304
00305 double goal_z;
00306
00307 double x_scale;
00308
00309 double z_scale;
00310
00311
00312 bool __fromMessage__(dynamic_reconfigure::Config &msg)
00313 {
00314 const std::vector<AbstractParamDescriptionConstPtr> &__param_descriptions__ = __getParamDescriptions__();
00315 const std::vector<AbstractGroupDescriptionConstPtr> &__group_descriptions__ = __getGroupDescriptions__();
00316
00317 int count = 0;
00318 for (std::vector<AbstractParamDescriptionConstPtr>::const_iterator i = __param_descriptions__.begin(); i != __param_descriptions__.end(); i++)
00319 if ((*i)->fromMessage(msg, *this))
00320 count++;
00321
00322 for (std::vector<AbstractGroupDescriptionConstPtr>::const_iterator i = __group_descriptions__.begin(); i != __group_descriptions__.end(); i ++)
00323 {
00324 if ((*i)->id == 0)
00325 {
00326 boost::any n = boost::any(this);
00327 (*i)->updateParams(n, *this);
00328 (*i)->fromMessage(msg, n);
00329 }
00330 }
00331
00332 if (count != dynamic_reconfigure::ConfigTools::size(msg))
00333 {
00334 ROS_ERROR("FollowerConfig::__fromMessage__ called with an unexpected parameter.");
00335 ROS_ERROR("Booleans:");
00336 for (unsigned int i = 0; i < msg.bools.size(); i++)
00337 ROS_ERROR(" %s", msg.bools[i].name.c_str());
00338 ROS_ERROR("Integers:");
00339 for (unsigned int i = 0; i < msg.ints.size(); i++)
00340 ROS_ERROR(" %s", msg.ints[i].name.c_str());
00341 ROS_ERROR("Doubles:");
00342 for (unsigned int i = 0; i < msg.doubles.size(); i++)
00343 ROS_ERROR(" %s", msg.doubles[i].name.c_str());
00344 ROS_ERROR("Strings:");
00345 for (unsigned int i = 0; i < msg.strs.size(); i++)
00346 ROS_ERROR(" %s", msg.strs[i].name.c_str());
00347
00348
00349 return false;
00350 }
00351 return true;
00352 }
00353
00354
00355
00356 void __toMessage__(dynamic_reconfigure::Config &msg, const std::vector<AbstractParamDescriptionConstPtr> &__param_descriptions__, const std::vector<AbstractGroupDescriptionConstPtr> &__group_descriptions__) const
00357 {
00358 dynamic_reconfigure::ConfigTools::clear(msg);
00359 for (std::vector<AbstractParamDescriptionConstPtr>::const_iterator i = __param_descriptions__.begin(); i != __param_descriptions__.end(); i++)
00360 (*i)->toMessage(msg, *this);
00361
00362 for (std::vector<AbstractGroupDescriptionConstPtr>::const_iterator i = __group_descriptions__.begin(); i != __group_descriptions__.end(); i++)
00363 {
00364 if((*i)->id == 0)
00365 {
00366 (*i)->toMessage(msg, *this);
00367 }
00368 }
00369 }
00370
00371 void __toMessage__(dynamic_reconfigure::Config &msg) const
00372 {
00373 const std::vector<AbstractParamDescriptionConstPtr> &__param_descriptions__ = __getParamDescriptions__();
00374 const std::vector<AbstractGroupDescriptionConstPtr> &__group_descriptions__ = __getGroupDescriptions__();
00375 __toMessage__(msg, __param_descriptions__, __group_descriptions__);
00376 }
00377
00378 void __toServer__(const ros::NodeHandle &nh) const
00379 {
00380 const std::vector<AbstractParamDescriptionConstPtr> &__param_descriptions__ = __getParamDescriptions__();
00381 for (std::vector<AbstractParamDescriptionConstPtr>::const_iterator i = __param_descriptions__.begin(); i != __param_descriptions__.end(); i++)
00382 (*i)->toServer(nh, *this);
00383 }
00384
00385 void __fromServer__(const ros::NodeHandle &nh)
00386 {
00387 static bool setup=false;
00388
00389 const std::vector<AbstractParamDescriptionConstPtr> &__param_descriptions__ = __getParamDescriptions__();
00390 for (std::vector<AbstractParamDescriptionConstPtr>::const_iterator i = __param_descriptions__.begin(); i != __param_descriptions__.end(); i++)
00391 (*i)->fromServer(nh, *this);
00392
00393 const std::vector<AbstractGroupDescriptionConstPtr> &__group_descriptions__ = __getGroupDescriptions__();
00394 for (std::vector<AbstractGroupDescriptionConstPtr>::const_iterator i = __group_descriptions__.begin(); i != __group_descriptions__.end(); i++){
00395 if (!setup && (*i)->id == 0) {
00396 setup = true;
00397 boost::any n = boost::any(this);
00398 (*i)->setInitialState(n);
00399 }
00400 }
00401 }
00402
00403 void __clamp__()
00404 {
00405 const std::vector<AbstractParamDescriptionConstPtr> &__param_descriptions__ = __getParamDescriptions__();
00406 const FollowerConfig &__max__ = __getMax__();
00407 const FollowerConfig &__min__ = __getMin__();
00408 for (std::vector<AbstractParamDescriptionConstPtr>::const_iterator i = __param_descriptions__.begin(); i != __param_descriptions__.end(); i++)
00409 (*i)->clamp(*this, __max__, __min__);
00410 }
00411
00412 uint32_t __level__(const FollowerConfig &config) const
00413 {
00414 const std::vector<AbstractParamDescriptionConstPtr> &__param_descriptions__ = __getParamDescriptions__();
00415 uint32_t level = 0;
00416 for (std::vector<AbstractParamDescriptionConstPtr>::const_iterator i = __param_descriptions__.begin(); i != __param_descriptions__.end(); i++)
00417 (*i)->calcLevel(level, config, *this);
00418 return level;
00419 }
00420
00421 static const dynamic_reconfigure::ConfigDescription &__getDescriptionMessage__();
00422 static const FollowerConfig &__getDefault__();
00423 static const FollowerConfig &__getMax__();
00424 static const FollowerConfig &__getMin__();
00425 static const std::vector<AbstractParamDescriptionConstPtr> &__getParamDescriptions__();
00426 static const std::vector<AbstractGroupDescriptionConstPtr> &__getGroupDescriptions__();
00427
00428 private:
00429 static const FollowerConfigStatics *__get_statics__();
00430 };
00431
00432 template <>
00433 inline void FollowerConfig::ParamDescription<std::string>::clamp(FollowerConfig &config, const FollowerConfig &max, const FollowerConfig &min) const
00434 {
00435 return;
00436 }
00437
00438 class FollowerConfigStatics
00439 {
00440 friend class FollowerConfig;
00441
00442 FollowerConfigStatics()
00443 {
00444 FollowerConfig::GroupDescription<FollowerConfig::DEFAULT, FollowerConfig> Default("Default", "", 0, 0, true, &FollowerConfig::groups);
00445
00446 __min__.min_x = -3.0;
00447
00448 __max__.min_x = 3.0;
00449
00450 __default__.min_x = -0.2;
00451
00452 Default.abstract_parameters.push_back(FollowerConfig::AbstractParamDescriptionConstPtr(new FollowerConfig::ParamDescription<double>("min_x", "double", 0, "The minimum x position of the points in the box.", "", &FollowerConfig::min_x)));
00453
00454 __param_descriptions__.push_back(FollowerConfig::AbstractParamDescriptionConstPtr(new FollowerConfig::ParamDescription<double>("min_x", "double", 0, "The minimum x position of the points in the box.", "", &FollowerConfig::min_x)));
00455
00456 __min__.max_x = -3.0;
00457
00458 __max__.max_x = 3.0;
00459
00460 __default__.max_x = 0.2;
00461
00462 Default.abstract_parameters.push_back(FollowerConfig::AbstractParamDescriptionConstPtr(new FollowerConfig::ParamDescription<double>("max_x", "double", 0, "The maximum x position of the points in the box.", "", &FollowerConfig::max_x)));
00463
00464 __param_descriptions__.push_back(FollowerConfig::AbstractParamDescriptionConstPtr(new FollowerConfig::ParamDescription<double>("max_x", "double", 0, "The maximum x position of the points in the box.", "", &FollowerConfig::max_x)));
00465
00466 __min__.min_y = -1.0;
00467
00468 __max__.min_y = 3.0;
00469
00470 __default__.min_y = 0.1;
00471
00472 Default.abstract_parameters.push_back(FollowerConfig::AbstractParamDescriptionConstPtr(new FollowerConfig::ParamDescription<double>("min_y", "double", 0, "The minimum y position of the points in the box.", "", &FollowerConfig::min_y)));
00473
00474 __param_descriptions__.push_back(FollowerConfig::AbstractParamDescriptionConstPtr(new FollowerConfig::ParamDescription<double>("min_y", "double", 0, "The minimum y position of the points in the box.", "", &FollowerConfig::min_y)));
00475
00476 __min__.max_y = -1.0;
00477
00478 __max__.max_y = 3.0;
00479
00480 __default__.max_y = 0.5;
00481
00482 Default.abstract_parameters.push_back(FollowerConfig::AbstractParamDescriptionConstPtr(new FollowerConfig::ParamDescription<double>("max_y", "double", 0, "The maximum y position of the points in the box.", "", &FollowerConfig::max_y)));
00483
00484 __param_descriptions__.push_back(FollowerConfig::AbstractParamDescriptionConstPtr(new FollowerConfig::ParamDescription<double>("max_y", "double", 0, "The maximum y position of the points in the box.", "", &FollowerConfig::max_y)));
00485
00486 __min__.max_z = 0.0;
00487
00488 __max__.max_z = 3.0;
00489
00490 __default__.max_z = 0.8;
00491
00492 Default.abstract_parameters.push_back(FollowerConfig::AbstractParamDescriptionConstPtr(new FollowerConfig::ParamDescription<double>("max_z", "double", 0, "The maximum z position of the points in the box.", "", &FollowerConfig::max_z)));
00493
00494 __param_descriptions__.push_back(FollowerConfig::AbstractParamDescriptionConstPtr(new FollowerConfig::ParamDescription<double>("max_z", "double", 0, "The maximum z position of the points in the box.", "", &FollowerConfig::max_z)));
00495
00496 __min__.goal_z = 0.0;
00497
00498 __max__.goal_z = 3.0;
00499
00500 __default__.goal_z = 0.6;
00501
00502 Default.abstract_parameters.push_back(FollowerConfig::AbstractParamDescriptionConstPtr(new FollowerConfig::ParamDescription<double>("goal_z", "double", 0, "The distance away from the robot to hold the centroid.", "", &FollowerConfig::goal_z)));
00503
00504 __param_descriptions__.push_back(FollowerConfig::AbstractParamDescriptionConstPtr(new FollowerConfig::ParamDescription<double>("goal_z", "double", 0, "The distance away from the robot to hold the centroid.", "", &FollowerConfig::goal_z)));
00505
00506 __min__.x_scale = 0.0;
00507
00508 __max__.x_scale = 3.0;
00509
00510 __default__.x_scale = 1.0;
00511
00512 Default.abstract_parameters.push_back(FollowerConfig::AbstractParamDescriptionConstPtr(new FollowerConfig::ParamDescription<double>("x_scale", "double", 0, "The scaling factor for translational robot speed.", "", &FollowerConfig::x_scale)));
00513
00514 __param_descriptions__.push_back(FollowerConfig::AbstractParamDescriptionConstPtr(new FollowerConfig::ParamDescription<double>("x_scale", "double", 0, "The scaling factor for translational robot speed.", "", &FollowerConfig::x_scale)));
00515
00516 __min__.z_scale = 0.0;
00517
00518 __max__.z_scale = 10.0;
00519
00520 __default__.z_scale = 5.0;
00521
00522 Default.abstract_parameters.push_back(FollowerConfig::AbstractParamDescriptionConstPtr(new FollowerConfig::ParamDescription<double>("z_scale", "double", 0, "The scaling factor for rotational robot speed.", "", &FollowerConfig::z_scale)));
00523
00524 __param_descriptions__.push_back(FollowerConfig::AbstractParamDescriptionConstPtr(new FollowerConfig::ParamDescription<double>("z_scale", "double", 0, "The scaling factor for rotational robot speed.", "", &FollowerConfig::z_scale)));
00525
00526 Default.convertParams();
00527
00528 __group_descriptions__.push_back(FollowerConfig::AbstractGroupDescriptionConstPtr(new FollowerConfig::GroupDescription<FollowerConfig::DEFAULT, FollowerConfig>(Default)));
00529
00530
00531 for (std::vector<FollowerConfig::AbstractGroupDescriptionConstPtr>::const_iterator i = __group_descriptions__.begin(); i != __group_descriptions__.end(); i++)
00532 {
00533 __description_message__.groups.push_back(**i);
00534 }
00535 __max__.__toMessage__(__description_message__.max, __param_descriptions__, __group_descriptions__);
00536 __min__.__toMessage__(__description_message__.min, __param_descriptions__, __group_descriptions__);
00537 __default__.__toMessage__(__description_message__.dflt, __param_descriptions__, __group_descriptions__);
00538 }
00539 std::vector<FollowerConfig::AbstractParamDescriptionConstPtr> __param_descriptions__;
00540 std::vector<FollowerConfig::AbstractGroupDescriptionConstPtr> __group_descriptions__;
00541 FollowerConfig __max__;
00542 FollowerConfig __min__;
00543 FollowerConfig __default__;
00544 dynamic_reconfigure::ConfigDescription __description_message__;
00545
00546 static const FollowerConfigStatics *get_instance()
00547 {
00548
00549
00550
00551
00552 static FollowerConfigStatics instance;
00553 return &instance;
00554 }
00555 };
00556
00557 inline const dynamic_reconfigure::ConfigDescription &FollowerConfig::__getDescriptionMessage__()
00558 {
00559 return __get_statics__()->__description_message__;
00560 }
00561
00562 inline const FollowerConfig &FollowerConfig::__getDefault__()
00563 {
00564 return __get_statics__()->__default__;
00565 }
00566
00567 inline const FollowerConfig &FollowerConfig::__getMax__()
00568 {
00569 return __get_statics__()->__max__;
00570 }
00571
00572 inline const FollowerConfig &FollowerConfig::__getMin__()
00573 {
00574 return __get_statics__()->__min__;
00575 }
00576
00577 inline const std::vector<FollowerConfig::AbstractParamDescriptionConstPtr> &FollowerConfig::__getParamDescriptions__()
00578 {
00579 return __get_statics__()->__param_descriptions__;
00580 }
00581
00582 inline const std::vector<FollowerConfig::AbstractGroupDescriptionConstPtr> &FollowerConfig::__getGroupDescriptions__()
00583 {
00584 return __get_statics__()->__group_descriptions__;
00585 }
00586
00587 inline const FollowerConfigStatics *FollowerConfig::__get_statics__()
00588 {
00589 const static FollowerConfigStatics *statics;
00590
00591 if (statics)
00592 return statics;
00593
00594 boost::mutex::scoped_lock lock(dynamic_reconfigure::__init_mutex__);
00595
00596 if (statics)
00597 return statics;
00598
00599 statics = FollowerConfigStatics::get_instance();
00600
00601 return statics;
00602 }
00603
00604
00605 }
00606
00607 #endif // __FOLLOWERRECONFIGURATOR_H__