If we only implement dynamic_reconfigure in server side, we have to manually calibrate parameters in GUI. Calibrating parameters is tedious if we have a lot of parameters. I'm using ros kinetic to implement a client node in c++ that can subscribe to a topic error and dynamically calibrate parameters in server node based on the data from the subscription of the topic error. However, there is no c++ client API tutorial in official document. I can only look at the header file in Github for implementation, and I got the error for creating a client in my class. I want to implement a class Calibration to define my client node. The following is my implementation of client node and error message.
//in calibration.h
#include <ros/ros.h>
#include <string>
#include <vector>
#include <std_msgs/Float32.h>
#include <dynamic_reconfigure/client.h>
#include <calibration/HcNodeConfig.h>
using namespace std;
class Calibration {
hc::HcNodeConfig config;
ros::NodeHandle n;
ros::Subscriber listener;
//dynamic_reconfigure::Client<hc::HcNodeConfig> adjuster("adjuster", &Calibration::adjuster_callback);
public:
Calibration();
void callback(const std_msgs::Float32ConstPtr& msg);
void adjuster_callback(hc::HcNodeConfig& params);
};
//in calibration.cpp
#include "calibration.h"
void Calibration::adjuster_callback(hc::HcNodeConfig& params) {
cout << "this is a dynamic_reconfigure callback" << endl;
}
void Calibration::callback(const std_msgs::Float32ConstPtr& msg) {
float error = msg->data;
dynamic_reconfigure::Client<hc::HcNodeConfig> client("hc", &Calibration::adjuster_callback, NULL);
if (error <= 0.0) {
config.direction = 0.0;
client.setConfiguration(config);
}
}
Calibration::Calibration() {
listener = n.subscribe("/error", 100, &Calibration::callback, this);
ros::spin();
}
int main(int argc, char ** argv) {
ros::init(argc, argv, "adjuster");
Calibration cal();
return 0;
}
I got the following error.
/opt/ros/kinetic/include/dynamic_reconfigure/client.h: In instantiation of ‘dynamic_reconfigure::Client<ConfigType>::Client(const string&, boost::function<void(const ConfigType&)>, boost::function<void(const dynamic_reconfigure::ConfigDescription_<std::allocator<void> >&)>) [with ConfigType = hc::HcNodeConfig; std::__cxx11::string = std::__cxx11::basic_string<char>]’:
/home/david-dev/workspace/lidar/src/calibration/src/online/calibration.cpp:11:100: required from here
/opt/ros/kinetic/include/dynamic_reconfigure/client.h:332:19: warning: ‘dynamic_reconfigure::Client<hc::HcNodeConfig>::nh_’ will be initialized after [-Wreorder]
ros::NodeHandle nh_;
^
/opt/ros/kinetic/include/dynamic_reconfigure/client.h:326:8: warning: ‘bool dynamic_reconfigure::Client<hc::HcNodeConfig>::received_configuration_’ [-Wreorder]
bool received_configuration_;
^
In file included from /home/david-dev/workspace/lidar/src/calibration/src/online/calibration.h:5:0,
from /home/david-dev/workspace/lidar/src/calibration/src/online/calibration.cpp:1:
/opt/ros/kinetic/include/dynamic_reconfigure/client.h:68:3: warning: when initialized here [-Wreorder]
Client(
^
In file included from /usr/include/boost/function/detail/maybe_include.hpp:18:0,
from /usr/include/boost/function/detail/function_iterate.hpp:14,
from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52,
from /usr/include/boost/function.hpp:64,
from /opt/ros/kinetic/include/ros/forwards.h:40,
from /opt/ros/kinetic/include/ros/common.h:37,
from /opt/ros/kinetic/include/ros/ros.h:43,
from /home/david-dev/workspace/lidar/src/calibration/src/online/calibration.h:1,
from /home/david-dev/workspace/lidar/src/calibration/src/online/calibration.cpp:1:
/usr/include/boost/function/function_template.hpp: In instantiation of ‘static void boost::detail::function::function_void_mem_invoker1<MemberPtr, R, T0>::invoke(boost::detail::function::function_buffer&, T0) [with MemberPtr = void (Calibration::*)(hc::HcNodeConfig&); R = void; T0 = const hc::HcNodeConfig&]’:
/usr/include/boost/function/function_template.hpp:940:38: required from ‘void boost::function1<R, T1>::assign_to(Functor) [with Functor = void (Calibration::*)(hc::HcNodeConfig&); R = void; T0 = const hc::HcNodeConfig&]’
/usr/include/boost/function/function_template.hpp:728:7: required from ‘boost::function1<R, T1>::function1(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = void (Calibration::*)(hc::HcNodeConfig&); R = void; T0 = const hc::HcNodeConfig&; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
/usr/include/boost/function/function_template.hpp:1077:16: required from ‘boost::function<R(T0)>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = void (Calibration::*)(hc::HcNodeConfig&); R = void; T0 = const hc::HcNodeConfig&; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
/home/david-dev/workspace/lidar/src/calibration/src/online/calibration.cpp:11:100: required from here
/usr/include/boost/function/function_template.hpp:231:28: error: no match for call to ‘(boost::_mfi::mf1<void, Calibration, hc::HcNodeConfig&>) (const hc::HcNodeConfig&)’
BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
^
In file included from /usr/include/boost/bind/mem_fn.hpp:215:0,
from /usr/include/boost/mem_fn.hpp:22,
from /usr/include/boost/function/detail/prologue.hpp:18,
from /usr/include/boost/function.hpp:24,
from /opt/ros/kinetic/include/ros/forwards.h:40,
from /opt/ros/kinetic/include/ros/common.h:37,
from /opt/ros/kinetic/include/ros/ros.h:43,
from /home/david-dev/workspace/lidar/src/calibration/src/online/calibration.h:1,
from /home/david-dev/workspace/lidar/src/calibration/src/online/calibration.cpp:1:
/usr/include/boost/bind/mem_fn_template.hpp:163:7: note: candidate: R boost::_mfi::mf1<R, T, A1>::operator()(T*, A1) const [with R = void; T = Calibration; A1 = hc::HcNodeConfig&]
R operator()(T * p, A1 a1) const
^
/usr/include/boost/bind/mem_fn_template.hpp:163:7: note: candidate expects 2 arguments, 1 provided
/usr/include/boost/bind/mem_fn_template.hpp:168:25: note: candidate: template<class U> R boost::_mfi::mf1<R, T, A1>::operator()(U&, A1) const [with U = U; R = void; T = Calibration; A1 = hc::HcNodeConfig&]
template<class U> R operator()(U & u, A1 a1) const
^
/usr/include/boost/bind/mem_fn_template.hpp:168:25: note: template argument deduction/substitution failed:
In file included from /usr/include/boost/function/detail/maybe_include.hpp:18:0,
from /usr/include/boost/function/detail/function_iterate.hpp:14,
from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52,
from /usr/include/boost/function.hpp:64,
from /opt/ros/kinetic/include/ros/forwards.h:40,
from /opt/ros/kinetic/include/ros/common.h:37,
from /opt/ros/kinetic/include/ros/ros.h:43,
from /home/david-dev/workspace/lidar/src/calibration/src/online/calibration.h:1,
from /home/david-dev/workspace/lidar/src/calibration/src/online/calibration.cpp:1:
/usr/include/boost/function/function_template.hpp:231:28: note: candidate expects 2 arguments, 1 provided
BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
^
In file included from /usr/include/boost/bind/mem_fn.hpp:215:0,
from /usr/include/boost/mem_fn.hpp:22,
from /usr/include/boost/function/detail/prologue.hpp:18,
from /usr/include/boost/function.hpp:24,
from /opt/ros/kinetic/include/ros/forwards.h:40,
from /opt/ros/kinetic/include/ros/common.h:37,
from /opt/ros/kinetic/include/ros/ros.h:43,
from /home/david-dev/workspace/lidar/src/calibration/src/online/calibration.h:1,
from /home/david-dev/workspace/lidar/src/calibration/src/online/calibration.cpp:1:
/usr/include/boost/bind/mem_fn_template.hpp:176:25: note: candidate: template<class U> R boost::_mfi::mf1<R, T, A1>::operator()(const U&, A1) const [with U = U; R = void; T = Calibration; A1 = hc::HcNodeConfig&]
template<class U> R operator()(U const & u, A1 a1) const
^
/usr/include/boost/bind/mem_fn_template.hpp:176:25: note: template argument deduction/substitution failed:
In file included from /usr/include/boost/function/detail/maybe_include.hpp:18:0,
from /usr/include/boost/function/detail/function_iterate.hpp:14,
from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52,
from /usr/include/boost/function.hpp:64,
from /opt/ros/kinetic/include/ros/forwards.h:40,
from /opt/ros/kinetic/include/ros/common.h:37,
from /opt/ros/kinetic/include/ros/ros.h:43,
from /home/david-dev/workspace/lidar/src/calibration/src/online/calibration.h:1,
from /home/david-dev/workspace/lidar/src/calibration/src/online/calibration.cpp:1:
/usr/include/boost/function/function_template.hpp:231:28: note: candidate expects 2 arguments, 1 provided
BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
^
In file included from /usr/include/boost/bind/mem_fn.hpp:215:0,
from /usr/include/boost/mem_fn.hpp:22,
from /usr/include/boost/function/detail/prologue.hpp:18,
from /usr/include/boost/function.hpp:24,
from /opt/ros/kinetic/include/ros/forwards.h:40,
from /opt/ros/kinetic/include/ros/common.h:37,
from /opt/ros/kinetic/include/ros/ros.h:43,
from /home/david-dev/workspace/lidar/src/calibration/src/online/calibration.h:1,
from /home/david-dev/workspace/lidar/src/calibration/src/online/calibration.cpp:1:
/usr/include/boost/bind/mem_fn_template.hpp:184:7: note: candidate: R boost::_mfi::mf1<R, T, A1>::operator()(T&, A1) const [with R = void; T = Calibration; A1 = hc::HcNodeConfig&]
R operator()(T & t, A1 a1) const
^
/usr/include/boost/bind/mem_fn_template.hpp:184:7: note: candidate expects 2 arguments, 1 provided
make[2]: *** [CMakeFiles/calibration_calibration_node.dir/src/online/calibration.cpp.o] Error 1
make[1]: *** [CMakeFiles/calibration_calibration_node.dir/all] Error 2
make: *** [all] Error 2
I think I pass wrong parameters to the dynamic_reconfigure::Client constructor. Any fix and improvement to my code? Thank you so much.