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 #include "ros/param.h"
00029 #include "ros/master.h"
00030 #include "ros/xmlrpc_manager.h"
00031 #include "ros/this_node.h"
00032 #include "ros/names.h"
00033
00034 #include <ros/console.h>
00035
00036 #include <boost/thread/mutex.hpp>
00037 #include <boost/lexical_cast.hpp>
00038
00039 #include <vector>
00040 #include <map>
00041
00042 namespace ros
00043 {
00044
00045 namespace param
00046 {
00047
00048 typedef std::map<std::string, XmlRpc::XmlRpcValue> M_Param;
00049 M_Param g_params;
00050 boost::mutex g_params_mutex;
00051 S_string g_subscribed_params;
00052
00053 void invalidateParentParams(const std::string& key)
00054 {
00055 std::string ns_key = names::parentNamespace(key);
00056 while (ns_key != "" && ns_key != "/")
00057 {
00058 if (g_subscribed_params.find(ns_key) != g_subscribed_params.end())
00059 {
00060
00061 g_params.erase(ns_key);
00062 }
00063 ns_key = names::parentNamespace(ns_key);
00064 }
00065 }
00066
00067 void set(const std::string& key, const XmlRpc::XmlRpcValue& v)
00068 {
00069 std::string mapped_key = ros::names::resolve(key);
00070
00071 XmlRpc::XmlRpcValue params, result, payload;
00072 params[0] = this_node::getName();
00073 params[1] = mapped_key;
00074 params[2] = v;
00075
00076 {
00077
00078
00079 boost::mutex::scoped_lock lock(g_params_mutex);
00080
00081 if (master::execute("setParam", params, result, payload, true))
00082 {
00083
00084
00085 if (g_subscribed_params.find(mapped_key) != g_subscribed_params.end())
00086 {
00087 g_params[mapped_key] = v;
00088 }
00089 invalidateParentParams(mapped_key);
00090 }
00091 }
00092 }
00093
00094 void set(const std::string& key, const std::string& s)
00095 {
00096
00097
00098 XmlRpc::XmlRpcValue v(s);
00099 ros::param::set(key, v);
00100 }
00101
00102 void set(const std::string& key, const char* s)
00103 {
00104
00105
00106 std::string sxx = std::string(s);
00107 XmlRpc::XmlRpcValue v(sxx);
00108 ros::param::set(key, v);
00109 }
00110
00111 void set(const std::string& key, double d)
00112 {
00113 XmlRpc::XmlRpcValue v(d);
00114 ros::param::set(key, v);
00115 }
00116
00117 void set(const std::string& key, int i)
00118 {
00119 XmlRpc::XmlRpcValue v(i);
00120 ros::param::set(key, v);
00121 }
00122
00123 void set(const std::string& key, bool b)
00124 {
00125 XmlRpc::XmlRpcValue v(b);
00126 ros::param::set(key, v);
00127 }
00128
00129 template <class T>
00130 void setImpl(const std::string& key, const std::vector<T>& vec)
00131 {
00132
00133
00134 XmlRpc::XmlRpcValue xml_vec;
00135 xml_vec.setSize(vec.size());
00136
00137
00138 for(size_t i=0; i < vec.size(); i++) {
00139 xml_vec[i] = vec.at(i);
00140 }
00141
00142 ros::param::set(key, xml_vec);
00143 }
00144
00145 void set(const std::string& key, const std::vector<std::string>& vec)
00146 {
00147 setImpl(key, vec);
00148 }
00149
00150 void set(const std::string& key, const std::vector<double>& vec)
00151 {
00152 setImpl(key, vec);
00153 }
00154
00155 void set(const std::string& key, const std::vector<float>& vec)
00156 {
00157 setImpl(key, vec);
00158 }
00159
00160 void set(const std::string& key, const std::vector<int>& vec)
00161 {
00162 setImpl(key, vec);
00163 }
00164
00165 void set(const std::string& key, const std::vector<bool>& vec)
00166 {
00167 setImpl(key, vec);
00168 }
00169
00170 template <class T>
00171 void setImpl(const std::string& key, const std::map<std::string, T>& map)
00172 {
00173
00174
00175 XmlRpc::XmlRpcValue xml_value;
00176 const XmlRpc::XmlRpcValue::ValueStruct& xml_map = (const XmlRpc::XmlRpcValue::ValueStruct &)(xml_value);
00177 (void)xml_map;
00178
00179
00180 for(typename std::map<std::string, T>::const_iterator it = map.begin(); it != map.end(); ++it) {
00181 xml_value[it->first] = it->second;
00182 }
00183
00184 ros::param::set(key, xml_value);
00185 }
00186
00187 void set(const std::string& key, const std::map<std::string, std::string>& map)
00188 {
00189 setImpl(key, map);
00190 }
00191
00192 void set(const std::string& key, const std::map<std::string, double>& map)
00193 {
00194 setImpl(key, map);
00195 }
00196
00197 void set(const std::string& key, const std::map<std::string, float>& map)
00198 {
00199 setImpl(key, map);
00200 }
00201
00202 void set(const std::string& key, const std::map<std::string, int>& map)
00203 {
00204 setImpl(key, map);
00205 }
00206
00207 void set(const std::string& key, const std::map<std::string, bool>& map)
00208 {
00209 setImpl(key, map);
00210 }
00211
00212 bool has(const std::string& key)
00213 {
00214 XmlRpc::XmlRpcValue params, result, payload;
00215 params[0] = this_node::getName();
00216 params[1] = ros::names::resolve(key);
00217
00218
00219
00220
00221 if (!master::execute("hasParam", params, result, payload, false))
00222 {
00223 return false;
00224 }
00225
00226 return payload;
00227 }
00228
00229 bool del(const std::string& key)
00230 {
00231 std::string mapped_key = ros::names::resolve(key);
00232
00233 {
00234 boost::mutex::scoped_lock lock(g_params_mutex);
00235
00236 g_subscribed_params.erase(mapped_key);
00237 g_params.erase(mapped_key);
00238 }
00239
00240 XmlRpc::XmlRpcValue params, result, payload;
00241 params[0] = this_node::getName();
00242 params[1] = mapped_key;
00243
00244
00245
00246 if (!master::execute("deleteParam", params, result, payload, false))
00247 {
00248 return false;
00249 }
00250
00251 return true;
00252 }
00253
00254 bool getImpl(const std::string& key, XmlRpc::XmlRpcValue& v, bool use_cache)
00255 {
00256 std::string mapped_key = ros::names::resolve(key);
00257 if (mapped_key.empty()) mapped_key = "/";
00258
00259 if (use_cache)
00260 {
00261 boost::mutex::scoped_lock lock(g_params_mutex);
00262
00263 if (g_subscribed_params.find(mapped_key) != g_subscribed_params.end())
00264 {
00265 M_Param::iterator it = g_params.find(mapped_key);
00266 if (it != g_params.end())
00267 {
00268 if (it->second.valid())
00269 {
00270 ROS_DEBUG_NAMED("cached_parameters", "Using cached parameter value for key [%s]", mapped_key.c_str());
00271
00272 v = it->second;
00273 return true;
00274 }
00275 else
00276 {
00277 ROS_DEBUG_NAMED("cached_parameters", "Cached parameter is invalid for key [%s]", mapped_key.c_str());
00278 return false;
00279 }
00280 }
00281 }
00282 else
00283 {
00284
00285 if (g_subscribed_params.insert(mapped_key).second)
00286 {
00287 XmlRpc::XmlRpcValue params, result, payload;
00288 params[0] = this_node::getName();
00289 params[1] = XMLRPCManager::instance()->getServerURI();
00290 params[2] = mapped_key;
00291
00292 if (!master::execute("subscribeParam", params, result, payload, false))
00293 {
00294 ROS_DEBUG_NAMED("cached_parameters", "Subscribe to parameter [%s]: call to the master failed", mapped_key.c_str());
00295 g_subscribed_params.erase(mapped_key);
00296 use_cache = false;
00297 }
00298 else
00299 {
00300 ROS_DEBUG_NAMED("cached_parameters", "Subscribed to parameter [%s]", mapped_key.c_str());
00301 }
00302 }
00303 }
00304 }
00305
00306 XmlRpc::XmlRpcValue params, result;
00307 params[0] = this_node::getName();
00308 params[1] = mapped_key;
00309
00310
00311
00312
00313 bool ret = master::execute("getParam", params, result, v, false);
00314
00315 if (use_cache)
00316 {
00317 boost::mutex::scoped_lock lock(g_params_mutex);
00318
00319 ROS_DEBUG_NAMED("cached_parameters", "Caching parameter [%s] with value type [%d]", mapped_key.c_str(), v.getType());
00320 g_params[mapped_key] = v;
00321 }
00322
00323 return ret;
00324 }
00325
00326 bool getImpl(const std::string& key, std::string& s, bool use_cache)
00327 {
00328 XmlRpc::XmlRpcValue v;
00329 if (!getImpl(key, v, use_cache))
00330 return false;
00331 if (v.getType() != XmlRpc::XmlRpcValue::TypeString)
00332 return false;
00333 s = std::string(v);
00334 return true;
00335 }
00336
00337 bool getImpl(const std::string& key, double& d, bool use_cache)
00338 {
00339 XmlRpc::XmlRpcValue v;
00340 if (!getImpl(key, v, use_cache))
00341 {
00342 return false;
00343 }
00344
00345 if (v.getType() == XmlRpc::XmlRpcValue::TypeInt)
00346 {
00347 d = (int)v;
00348 }
00349 else if (v.getType() != XmlRpc::XmlRpcValue::TypeDouble)
00350 {
00351 return false;
00352 }
00353 else
00354 {
00355 d = v;
00356 }
00357
00358 return true;
00359 }
00360
00361 bool getImpl(const std::string& key, float& f, bool use_cache)
00362 {
00363 double d = static_cast<double>(f);
00364 bool result = getImpl(key, d, use_cache);
00365 if (result)
00366 f = static_cast<float>(d);
00367 return result;
00368 }
00369
00370 bool getImpl(const std::string& key, int& i, bool use_cache)
00371 {
00372 XmlRpc::XmlRpcValue v;
00373 if (!getImpl(key, v, use_cache))
00374 {
00375 return false;
00376 }
00377
00378 if (v.getType() == XmlRpc::XmlRpcValue::TypeDouble)
00379 {
00380 double d = v;
00381
00382 if (fmod(d, 1.0) < 0.5)
00383 {
00384 d = floor(d);
00385 }
00386 else
00387 {
00388 d = ceil(d);
00389 }
00390
00391 i = d;
00392 }
00393 else if (v.getType() != XmlRpc::XmlRpcValue::TypeInt)
00394 {
00395 return false;
00396 }
00397 else
00398 {
00399 i = v;
00400 }
00401
00402 return true;
00403 }
00404
00405 bool getImpl(const std::string& key, bool& b, bool use_cache)
00406 {
00407 XmlRpc::XmlRpcValue v;
00408 if (!getImpl(key, v, use_cache))
00409 return false;
00410 if (v.getType() != XmlRpc::XmlRpcValue::TypeBoolean)
00411 return false;
00412 b = v;
00413 return true;
00414 }
00415
00416 bool get(const std::string& key, std::string& s)
00417 {
00418 return getImpl(key, s, false);
00419 }
00420
00421 bool get(const std::string& key, double& d)
00422 {
00423 return getImpl(key, d, false);
00424 }
00425
00426 bool get(const std::string& key, float& f)
00427 {
00428 return getImpl(key, f, false);
00429 }
00430
00431 bool get(const std::string& key, int& i)
00432 {
00433 return getImpl(key, i, false);
00434 }
00435
00436 bool get(const std::string& key, bool& b)
00437 {
00438 return getImpl(key, b, false);
00439 }
00440
00441 bool get(const std::string& key, XmlRpc::XmlRpcValue& v)
00442 {
00443 return getImpl(key, v, false);
00444 }
00445
00446 bool getCached(const std::string& key, std::string& s)
00447 {
00448 return getImpl(key, s, true);
00449 }
00450
00451 bool getCached(const std::string& key, double& d)
00452 {
00453 return getImpl(key, d, true);
00454 }
00455
00456 bool getCached(const std::string& key, float& f)
00457 {
00458 return getImpl(key, f, true);
00459 }
00460
00461 bool getCached(const std::string& key, int& i)
00462 {
00463 return getImpl(key, i, true);
00464 }
00465
00466 bool getCached(const std::string& key, bool& b)
00467 {
00468 return getImpl(key, b, true);
00469 }
00470
00471 bool getCached(const std::string& key, XmlRpc::XmlRpcValue& v)
00472 {
00473 return getImpl(key, v, true);
00474 }
00475
00476 template <class T> T xml_cast(XmlRpc::XmlRpcValue xml_value)
00477 {
00478 return static_cast<T>(xml_value);
00479 }
00480
00481 template <class T> bool xml_castable(int XmlType)
00482 {
00483 return false;
00484 }
00485
00486 template<> bool xml_castable<std::string>(int XmlType)
00487 {
00488 return XmlType == XmlRpc::XmlRpcValue::TypeString;
00489 }
00490
00491 template<> bool xml_castable<double>(int XmlType)
00492 {
00493 return (
00494 XmlType == XmlRpc::XmlRpcValue::TypeDouble ||
00495 XmlType == XmlRpc::XmlRpcValue::TypeInt ||
00496 XmlType == XmlRpc::XmlRpcValue::TypeBoolean );
00497 }
00498
00499 template<> bool xml_castable<float>(int XmlType)
00500 {
00501 return (
00502 XmlType == XmlRpc::XmlRpcValue::TypeDouble ||
00503 XmlType == XmlRpc::XmlRpcValue::TypeInt ||
00504 XmlType == XmlRpc::XmlRpcValue::TypeBoolean );
00505 }
00506
00507 template<> bool xml_castable<int>(int XmlType)
00508 {
00509 return (
00510 XmlType == XmlRpc::XmlRpcValue::TypeDouble ||
00511 XmlType == XmlRpc::XmlRpcValue::TypeInt ||
00512 XmlType == XmlRpc::XmlRpcValue::TypeBoolean );
00513 }
00514
00515 template<> bool xml_castable<bool>(int XmlType)
00516 {
00517 return (
00518 XmlType == XmlRpc::XmlRpcValue::TypeDouble ||
00519 XmlType == XmlRpc::XmlRpcValue::TypeInt ||
00520 XmlType == XmlRpc::XmlRpcValue::TypeBoolean );
00521 }
00522
00523 template<> double xml_cast(XmlRpc::XmlRpcValue xml_value)
00524 {
00525 using namespace XmlRpc;
00526 switch(xml_value.getType()) {
00527 case XmlRpcValue::TypeDouble:
00528 return static_cast<double>(xml_value);
00529 case XmlRpcValue::TypeInt:
00530 return static_cast<double>(static_cast<int>(xml_value));
00531 case XmlRpcValue::TypeBoolean:
00532 return static_cast<double>(static_cast<bool>(xml_value));
00533 default:
00534 return 0.0;
00535 };
00536 }
00537
00538 template<> float xml_cast(XmlRpc::XmlRpcValue xml_value)
00539 {
00540 using namespace XmlRpc;
00541 switch(xml_value.getType()) {
00542 case XmlRpcValue::TypeDouble:
00543 return static_cast<float>(static_cast<double>(xml_value));
00544 case XmlRpcValue::TypeInt:
00545 return static_cast<float>(static_cast<int>(xml_value));
00546 case XmlRpcValue::TypeBoolean:
00547 return static_cast<float>(static_cast<bool>(xml_value));
00548 default:
00549 return 0.0f;
00550 };
00551 }
00552
00553 template<> int xml_cast(XmlRpc::XmlRpcValue xml_value)
00554 {
00555 using namespace XmlRpc;
00556 switch(xml_value.getType()) {
00557 case XmlRpcValue::TypeDouble:
00558 return static_cast<int>(static_cast<double>(xml_value));
00559 case XmlRpcValue::TypeInt:
00560 return static_cast<int>(xml_value);
00561 case XmlRpcValue::TypeBoolean:
00562 return static_cast<int>(static_cast<bool>(xml_value));
00563 default:
00564 return 0;
00565 };
00566 }
00567
00568 template<> bool xml_cast(XmlRpc::XmlRpcValue xml_value)
00569 {
00570 using namespace XmlRpc;
00571 switch(xml_value.getType()) {
00572 case XmlRpcValue::TypeDouble:
00573 return static_cast<bool>(static_cast<double>(xml_value));
00574 case XmlRpcValue::TypeInt:
00575 return static_cast<bool>(static_cast<int>(xml_value));
00576 case XmlRpcValue::TypeBoolean:
00577 return static_cast<bool>(xml_value);
00578 default:
00579 return false;
00580 };
00581 }
00582
00583 template <class T>
00584 bool getImpl(const std::string& key, std::vector<T>& vec, bool cached)
00585 {
00586 XmlRpc::XmlRpcValue xml_array;
00587 if(!getImpl(key, xml_array, cached)) {
00588 return false;
00589 }
00590
00591
00592 if(xml_array.getType() != XmlRpc::XmlRpcValue::TypeArray) {
00593 return false;
00594 }
00595
00596
00597 vec.resize(xml_array.size());
00598
00599
00600 for (int i = 0; i < xml_array.size(); i++) {
00601 if(!xml_castable<T>(xml_array[i].getType())) {
00602 return false;
00603 }
00604
00605 vec[i] = xml_cast<T>(xml_array[i]);
00606 }
00607
00608 return true;
00609 }
00610
00611 bool get(const std::string& key, std::vector<std::string>& vec)
00612 {
00613 return getImpl(key, vec, false);
00614 }
00615 bool get(const std::string& key, std::vector<double>& vec)
00616 {
00617 return getImpl(key, vec, false);
00618 }
00619 bool get(const std::string& key, std::vector<float>& vec)
00620 {
00621 return getImpl(key, vec, false);
00622 }
00623 bool get(const std::string& key, std::vector<int>& vec)
00624 {
00625 return getImpl(key, vec, false);
00626 }
00627 bool get(const std::string& key, std::vector<bool>& vec)
00628 {
00629 return getImpl(key, vec, false);
00630 }
00631
00632 bool getCached(const std::string& key, std::vector<std::string>& vec)
00633 {
00634 return getImpl(key, vec, true);
00635 }
00636 bool getCached(const std::string& key, std::vector<double>& vec)
00637 {
00638 return getImpl(key, vec, true);
00639 }
00640 bool getCached(const std::string& key, std::vector<float>& vec)
00641 {
00642 return getImpl(key, vec, true);
00643 }
00644 bool getCached(const std::string& key, std::vector<int>& vec)
00645 {
00646 return getImpl(key, vec, true);
00647 }
00648 bool getCached(const std::string& key, std::vector<bool>& vec)
00649 {
00650 return getImpl(key, vec, true);
00651 }
00652
00653 template <class T>
00654 bool getImpl(const std::string& key, std::map<std::string, T>& map, bool cached)
00655 {
00656 XmlRpc::XmlRpcValue xml_value;
00657 if(!getImpl(key, xml_value, cached)) {
00658 return false;
00659 }
00660
00661
00662 if(xml_value.getType() != XmlRpc::XmlRpcValue::TypeStruct) {
00663 return false;
00664 }
00665
00666
00667 for (XmlRpc::XmlRpcValue::ValueStruct::const_iterator it = xml_value.begin();
00668 it != xml_value.end();
00669 ++it)
00670 {
00671
00672 if(!xml_castable<T>(it->second.getType())) {
00673 return false;
00674 }
00675
00676 map[it->first] = xml_cast<T>(it->second);
00677 }
00678
00679 return true;
00680 }
00681
00682 bool get(const std::string& key, std::map<std::string, std::string>& map)
00683 {
00684 return getImpl(key, map, false);
00685 }
00686 bool get(const std::string& key, std::map<std::string, double>& map)
00687 {
00688 return getImpl(key, map, false);
00689 }
00690 bool get(const std::string& key, std::map<std::string, float>& map)
00691 {
00692 return getImpl(key, map, false);
00693 }
00694 bool get(const std::string& key, std::map<std::string, int>& map)
00695 {
00696 return getImpl(key, map, false);
00697 }
00698 bool get(const std::string& key, std::map<std::string, bool>& map)
00699 {
00700 return getImpl(key, map, false);
00701 }
00702
00703 bool getCached(const std::string& key, std::map<std::string, std::string>& map)
00704 {
00705 return getImpl(key, map, true);
00706 }
00707 bool getCached(const std::string& key, std::map<std::string, double>& map)
00708 {
00709 return getImpl(key, map, true);
00710 }
00711 bool getCached(const std::string& key, std::map<std::string, float>& map)
00712 {
00713 return getImpl(key, map, true);
00714 }
00715 bool getCached(const std::string& key, std::map<std::string, int>& map)
00716 {
00717 return getImpl(key, map, true);
00718 }
00719 bool getCached(const std::string& key, std::map<std::string, bool>& map)
00720 {
00721 return getImpl(key, map, true);
00722 }
00723
00724 bool getParamNames(std::vector<std::string>& keys)
00725 {
00726 XmlRpc::XmlRpcValue params, result, payload;
00727 params[0] = this_node::getName();
00728 if (!master::execute("getParamNames", params, result, payload, false)) {
00729 return false;
00730 }
00731
00732 if (result.getType() != XmlRpc::XmlRpcValue::TypeArray) {
00733 return false;
00734 }
00735
00736 if (result.size() != 3) {
00737 return false;
00738 }
00739
00740 XmlRpc::XmlRpcValue parameters = result[2];
00741
00742 keys.resize(parameters.size());
00743
00744
00745 for (int i = 0; i < parameters.size(); ++i) {
00746 if (parameters[i].getType() != XmlRpc::XmlRpcValue::TypeString) {
00747 return false;
00748 }
00749 keys[i] = std::string(parameters[i]);
00750 }
00751 return true;
00752 }
00753
00754 bool search(const std::string& key, std::string& result_out)
00755 {
00756 return search(this_node::getName(), key, result_out);
00757 }
00758
00759 bool search(const std::string& ns, const std::string& key, std::string& result_out)
00760 {
00761 XmlRpc::XmlRpcValue params, result, payload;
00762 params[0] = ns;
00763
00764
00765
00766
00767 std::string remapped = key;
00768 M_string::const_iterator it = names::getUnresolvedRemappings().find(key);
00769 if (it != names::getUnresolvedRemappings().end())
00770 {
00771 remapped = it->second;
00772 }
00773
00774 params[1] = remapped;
00775
00776
00777
00778 if (!master::execute("searchParam", params, result, payload, false))
00779 {
00780 return false;
00781 }
00782
00783 result_out = (std::string)payload;
00784
00785 return true;
00786 }
00787
00788 void update(const std::string& key, const XmlRpc::XmlRpcValue& v)
00789 {
00790 std::string clean_key = names::clean(key);
00791 ROS_DEBUG_NAMED("cached_parameters", "Received parameter update for key [%s]", clean_key.c_str());
00792
00793 boost::mutex::scoped_lock lock(g_params_mutex);
00794
00795 if (g_subscribed_params.find(clean_key) != g_subscribed_params.end())
00796 {
00797 g_params[clean_key] = v;
00798 }
00799 invalidateParentParams(clean_key);
00800 }
00801
00802 void paramUpdateCallback(XmlRpc::XmlRpcValue& params, XmlRpc::XmlRpcValue& result)
00803 {
00804 result[0] = 1;
00805 result[1] = std::string("");
00806 result[2] = 0;
00807
00808 ros::param::update((std::string)params[1], params[2]);
00809 }
00810
00811 void init(const M_string& remappings)
00812 {
00813 M_string::const_iterator it = remappings.begin();
00814 M_string::const_iterator end = remappings.end();
00815 for (; it != end; ++it)
00816 {
00817 const std::string& name = it->first;
00818 const std::string& param = it->second;
00819
00820 if (name.size() < 2)
00821 {
00822 continue;
00823 }
00824
00825 if (name[0] == '_' && name[1] != '_')
00826 {
00827 std::string local_name = "~" + name.substr(1);
00828
00829 bool success = false;
00830
00831 try
00832 {
00833 int32_t i = boost::lexical_cast<int32_t>(param);
00834 ros::param::set(names::resolve(local_name), i);
00835 success = true;
00836 }
00837 catch (boost::bad_lexical_cast&)
00838 {
00839
00840 }
00841
00842 if (success)
00843 {
00844 continue;
00845 }
00846
00847 try
00848 {
00849 double d = boost::lexical_cast<double>(param);
00850 ros::param::set(names::resolve(local_name), d);
00851 success = true;
00852 }
00853 catch (boost::bad_lexical_cast&)
00854 {
00855
00856 }
00857
00858 if (success)
00859 {
00860 continue;
00861 }
00862
00863 if (param == "true" || param == "True" || param == "TRUE")
00864 {
00865 ros::param::set(names::resolve(local_name), true);
00866 }
00867 else if (param == "false" || param == "False" || param == "FALSE")
00868 {
00869 ros::param::set(names::resolve(local_name), false);
00870 }
00871 else
00872 {
00873 ros::param::set(names::resolve(local_name), param);
00874 }
00875 }
00876 }
00877
00878 XMLRPCManager::instance()->bind("paramUpdate", paramUpdateCallback);
00879 }
00880
00881 }
00882
00883 }