6 #ifndef DYNAMIC_RECONFIGURE_MGR_H
7 #define DYNAMIC_RECONFIGURE_MGR_H
10 #include <dynamic_reconfigure/server.h>
13 #include <unordered_set>
16 #include <boost/any.hpp>
17 #include <Eigen/Dense>
39 template <
typename ConfigType>
43 using callback_t =
typename dynamic_reconfigure::Server<ConfigType>::CallbackType;
48 DynamicReconfigureMgr(
const ros::NodeHandle& nh = ros::NodeHandle(
"~"),
bool print_values =
true, std::string node_name = std::string(),
const callback_t& user_callback = {})
49 : m_not_initialized(
true),
50 m_loaded_invalid_default(
false),
51 m_print_values(print_values),
52 m_node_name(node_name),
53 m_server(m_server_mtx, nh),
54 m_usr_cbf(user_callback),
55 m_pl(nh, print_values, node_name)
71 void update_config(
const ConfigType& cfg)
73 m_server.updateConfig(cfg);
79 m_server.updateConfig(config);
82 void publish_descriptions()
85 m_server.getConfigDefault(dflt);
86 m_server.setConfigDefault(dflt);
89 bool loaded_successfully()
95 bool m_not_initialized, m_loaded_invalid_default, m_print_values;
96 std::string m_node_name;
98 boost::recursive_mutex m_server_mtx;
99 typename dynamic_reconfigure::Server<ConfigType> m_server;
100 callback_t m_usr_cbf;
103 std::unordered_set<std::string> m_to_init;
106 void dynamic_reconfigure_callback(ConfigType& new_config, uint32_t level)
110 if (m_node_name.empty())
111 ROS_INFO(
"Dynamic reconfigure request received");
113 ROS_INFO(
"[%s]: Dynamic reconfigure request received", m_node_name.c_str());
116 if (m_not_initialized)
118 load_defaults(new_config);
119 update_config(new_config);
123 print_changed_params(new_config);
125 m_not_initialized =
false;
128 m_usr_cbf(new_config, level);
131 template <
typename T>
132 void load_param(
const std::string& name,
typename ConfigType::AbstractParamDescriptionConstPtr& descr, ConfigType& config)
134 using param_descr_t =
typename ConfigType::template ParamDescription<T>;
135 boost::shared_ptr<const param_descr_t> cast_descr = boost::dynamic_pointer_cast<const param_descr_t>(descr);
136 m_pl.
loadParam(name, config.*(cast_descr->field));
139 void load_defaults(ConfigType& new_config)
142 std::vector<typename ConfigType::AbstractParamDescriptionConstPtr> descrs = new_config.__getParamDescriptions__();
143 for (
auto& descr : descrs)
145 std::string name = descr->name;
146 size_t pos = name.find(
"__");
147 while (pos != name.npos)
149 name.replace(pos, 2,
"/");
150 pos = name.find(
"__");
153 if (descr->type ==
"bool")
154 load_param<bool>(name, descr, new_config);
155 else if (descr->type ==
"int")
156 load_param<int>(name, descr, new_config);
157 else if (descr->type ==
"double")
158 load_param<double>(name, descr, new_config);
159 else if (descr->type ==
"str")
160 load_param<std::string>(name, descr, new_config);
163 ROS_ERROR(
"[%s]: Unknown parameter type: '%s'", m_node_name.c_str(), descr->type.c_str());
164 m_loaded_invalid_default =
true;
170 void print_changed_params(
const ConfigType& new_config)
173 std::vector<typename ConfigType::AbstractParamDescriptionConstPtr> descrs = new_config.__getParamDescriptions__();
174 for (
auto& descr : descrs)
176 boost::any val, old_val;
177 descr->getValue(new_config, val);
178 descr->getValue(config, old_val);
179 std::string name = descr->name;
180 const size_t pos = name.find(
"__");
181 if (pos != name.npos)
183 if (m_not_initialized)
188 name.replace(pos, 2,
"/");
196 std::string* stringval;
198 if (try_cast(val, intval))
200 if (m_not_initialized || !try_compare(old_val, intval))
201 print_value(name, *intval);
202 }
else if (try_cast(val, doubleval))
204 if (m_not_initialized || !try_compare(old_val, doubleval))
205 print_value(name, *doubleval);
206 }
else if (try_cast(val, boolval))
208 if (m_not_initialized || !try_compare(old_val, boolval))
209 print_value(name, *boolval);
210 }
else if (try_cast(val, stringval))
212 if (m_not_initialized || !try_compare(old_val, stringval))
213 print_value(name, *stringval);
216 print_value(name, std::string(
"unknown dynamic reconfigure type"));
223 template <
typename T>
224 inline void print_value(
const std::string& name,
const T& val)
226 if (m_node_name.empty())
227 std::cout <<
"\t" << name <<
":\t" << val << std::endl;
229 ROS_INFO_STREAM(
"[" << m_node_name <<
"]: parameter '" << name <<
"':\t" << val);
232 template <
typename T>
233 inline bool try_cast(boost::any& val, T*& out)
235 return (out = boost::any_cast<T>(&val));
237 template <
typename T>
238 inline bool try_compare(boost::any& val, T*& to_what)
241 if ((tmp = boost::any_cast<T>(&val)))
244 return *tmp == *to_what;
247 if (m_node_name.empty())
248 ROS_WARN(
"DynamicReconfigure value type has changed - this should not happen!");
250 ROS_WARN_STREAM(
"[" << m_node_name <<
"]: DynamicReconfigure value type has changed - this should not happen!");
259 #endif // DYNAMIC_RECONFIGURE_MGR_H