From 758c2b7a496407473c55eb82996a4527eb073436 Mon Sep 17 00:00:00 2001 From: Sergi Hernandez Juan <shernand@iri.upc.edu> Date: Fri, 23 Oct 2020 13:30:47 +0200 Subject: [PATCH] Added the dynamic_reconfigure function to handle generic parameters to the module and module action classes. --- include/iri_ros_tools/module.h | 31 +++++ include/iri_ros_tools/module_action.h | 181 ++++++++++++++++++------- include/iri_ros_tools/module_service.h | 8 +- 3 files changed, 166 insertions(+), 54 deletions(-) diff --git a/include/iri_ros_tools/module.h b/include/iri_ros_tools/module.h index 0166c85..46b7d7f 100644 --- a/include/iri_ros_tools/module.h +++ b/include/iri_ros_tools/module.h @@ -160,6 +160,17 @@ class CModule * and can be ignored. */ virtual void reconfigure_callback(ModuleCfg &config, uint32_t level)=0; + /** + * \ brief Handles the dynamic reconfigure parameters of the module service + * + * This functions handles all generic module service parameters for each instance + * and updates the internal attributes accordingly. + * + * \param config data object with all the module parameters. + * \param name prefix given to the module servie variables in order to locate and + * handle them. + */ + void dynamic_reconfigure(ModuleCfg &config, const std::string &name); /** * \brief function to start the operation of the class * @@ -307,6 +318,26 @@ void *CModule<ModuleCfg>::module_thread(void *param) pthread_exit(NULL); } +template<class ModuleCfg> +void CModule<ModuleCfg>::dynamic_reconfigure(ModuleCfg &config, const std::string &name) +{ + std::vector<typename ModuleCfg::AbstractParamDescriptionConstPtr> params; + boost::any value; + + params=ModuleCfg::__getParamDescriptions__(); + + for(typename std::vector<typename ModuleCfg::AbstractParamDescriptionConstPtr>::iterator param=params.begin();param!=params.end();param++) + { + if((*param)->name==(name+"_rate_hz")) + { + + (*param)->getValue(config,value); + if(value.type()==typeid(double)) + this->set_rate(boost::any_cast<double &>(value)); + } + } +} + template<class ModuleCfg> void CModule<ModuleCfg>::start_operation(void) { diff --git a/include/iri_ros_tools/module_action.h b/include/iri_ros_tools/module_action.h index a34c7b3..4397ff5 100644 --- a/include/iri_ros_tools/module_action.h +++ b/include/iri_ros_tools/module_action.h @@ -56,7 +56,7 @@ typedef enum {ACTION_IDLE, * * <main node namespace>/<class namespace>/<class name> */ -template<class action_ros> +template<class action_ros,class dyn_reconf_config> class CModuleAction { private: @@ -279,6 +279,17 @@ class CModuleAction */ CModuleAction(const std::string &name,const std::string &name_space=std::string("")); + /** + * \ brief Handles the dynamic reconfigure parameters of the module service + * + * This functions handles all generic module service parameters for each instance + * and updates the internal attributes accordingly. + * + * \param config data object with all the module parameters. + * \param name prefix given to the module servie variables in order to locate and + * handle them. + */ + void dynamic_reconfigure(dyn_reconf_config &config, const std::string &name); /** * \brief Sets the maximum number of attempts to start the action * @@ -457,9 +468,9 @@ class CModuleAction ROS_DEBUG_STREAM("CModuleAction::make_request: Server " << this->name << " is Available!"); this->current_num_retries=0; this->action_client->sendGoal(msg, - boost::bind(&CModuleAction<action_ros>::action_done, this, _1, _2), - boost::bind(&CModuleAction<action_ros>::action_active, this), - boost::bind(&CModuleAction<action_ros>::action_feedback, this, _1)); + boost::bind(&CModuleAction<action_ros,dyn_reconf_config>::action_done, this, _1, _2), + boost::bind(&CModuleAction<action_ros,dyn_reconf_config>::action_active, this), + boost::bind(&CModuleAction<action_ros,dyn_reconf_config>::action_feedback, this, _1)); this->feedback_watchdog.reset(ros::Duration(this->watchdog_time)); this->status=ACTION_RUNNING; if(this->use_timeout) @@ -559,8 +570,8 @@ class CModuleAction ~CModuleAction(); }; -template<class action_ros> -CModuleAction<action_ros>::CModuleAction(const std::string &name,const std::string &name_space):nh(name_space) +template<class action_ros,class dyn_reconf_config> +CModuleAction<action_ros,dyn_reconf_config>::CModuleAction(const std::string &name,const std::string &name_space):nh(name_space) { this->name=this->nh.getNamespace()+"/"+name; this->status=ACTION_IDLE; @@ -582,28 +593,98 @@ CModuleAction<action_ros>::CModuleAction(const std::string &name,const std::stri this->enabled=true; } -template<class action_ros> -void CModuleAction<action_ros>::action_active(void) +template<class action_ros,class dyn_reconf_config> +void CModuleAction<action_ros,dyn_reconf_config>::dynamic_reconfigure(dyn_reconf_config &config, const std::string &name) +{ + std::vector<typename dyn_reconf_config::AbstractParamDescriptionConstPtr> params; + bool enable_timeout,enable_watchdog; + double timeout,watchdog; + boost::any value; + + params=dyn_reconf_config::__getParamDescriptions__(); + + for(typename std::vector<typename dyn_reconf_config::AbstractParamDescriptionConstPtr>::iterator param=params.begin();param!=params.end();param++) + { + if((*param)->name==(name+"_num_retries")) + { + (*param)->getValue(config,value); + if(value.type()==typeid(int)) + this->set_max_num_retries(boost::any_cast<int &>(value)); + } + else if((*param)->name==(name+"_enable_timeout")) + { + if(value.type()==typeid(bool)) + { + if(boost::any_cast<bool &>(value)) + enable_timeout=true; + else + enable_timeout=false; + } + } + if((*param)->name==(name+"_timeout_s")) + { + (*param)->getValue(config,value); + if(value.type()==typeid(double)) + timeout=boost::any_cast<double &>(value); + } + if((*param)->name==(name+"_feedback_watchdog_time_s")) + { + (*param)->getValue(config,value); + if(value.type()==typeid(double)) + watchdog=boost::any_cast<double &>(value); + } + else if((*param)->name==(name+"_enable_watchdog")) + { + if(value.type()==typeid(bool)) + { + if(boost::any_cast<bool &>(value)) + enable_watchdog=true; + else + enable_watchdog=false; + } + } + else if((*param)->name==(name+"_enabled")) + { + if(value.type()==typeid(bool)) + { + if(boost::any_cast<bool &>(value)) + this->enable(); + else + this->disable(); + } + } + } + if(enable_timeout) + this->enable_timeout(timeout); + else + this->disable_timeout(); + if(enable_watchdog) + this->enable_watchdog(watchdog); +} + + +template<class action_ros,class dyn_reconf_config> +void CModuleAction<action_ros,dyn_reconf_config>::action_active(void) { ROS_DEBUG_STREAM("CModuleAction::action_active: Goal on server " << this->name << " just went active!"); } -template<class action_ros> -void CModuleAction<action_ros>::set_max_num_retries(unsigned int max_retries) +template<class action_ros,class dyn_reconf_config> +void CModuleAction<action_ros,dyn_reconf_config>::set_max_num_retries(unsigned int max_retries) { this->action_access.enter(); this->max_num_retries=max_retries; this->action_access.exit(); } -template<class action_ros> -unsigned int CModuleAction<action_ros>::get_max_num_retries(void) +template<class action_ros,class dyn_reconf_config> +unsigned int CModuleAction<action_ros,dyn_reconf_config>::get_max_num_retries(void) { return this->max_num_retries; } -template<class action_ros> -void CModuleAction<action_ros>::enable_watchdog(double time_s) +template<class action_ros,class dyn_reconf_config> +void CModuleAction<action_ros,dyn_reconf_config>::enable_watchdog(double time_s) { this->action_access.enter(); if(time_s>0.0) @@ -620,28 +701,28 @@ void CModuleAction<action_ros>::enable_watchdog(double time_s) this->action_access.exit(); } -template<class action_ros> -void CModuleAction<action_ros>::disable_watchdog(void) +template<class action_ros,class dyn_reconf_config> +void CModuleAction<action_ros,dyn_reconf_config>::disable_watchdog(void) { this->action_access.enter(); this->use_watchdog=false; this->action_access.exit(); } -template<class action_ros> -bool CModuleAction<action_ros>::is_watchdog_enabled(void) +template<class action_ros,class dyn_reconf_config> +bool CModuleAction<action_ros,dyn_reconf_config>::is_watchdog_enabled(void) { return this->use_watchdog; } -template<class action_ros> -double CModuleAction<action_ros>::get_feedback_watchdog_time(void) +template<class action_ros,class dyn_reconf_config> +double CModuleAction<action_ros,dyn_reconf_config>::get_feedback_watchdog_time(void) { return this->watchdog_time; } -template<class action_ros> -bool CModuleAction<action_ros>::is_watchdog_active(void) +template<class action_ros,class dyn_reconf_config> +bool CModuleAction<action_ros,dyn_reconf_config>::is_watchdog_active(void) { this->action_access.enter(); if(this->enabled) @@ -662,8 +743,8 @@ bool CModuleAction<action_ros>::is_watchdog_active(void) return false; } -template<class action_ros> -void CModuleAction<action_ros>::enable_timeout(double time_s) +template<class action_ros,class dyn_reconf_config> +void CModuleAction<action_ros,dyn_reconf_config>::enable_timeout(double time_s) { this->action_access.enter(); if(time_s>0.0) @@ -679,16 +760,16 @@ void CModuleAction<action_ros>::enable_timeout(double time_s) this->action_access.exit(); } -template<class action_ros> -void CModuleAction<action_ros>::disable_timeout(void) +template<class action_ros,class dyn_reconf_config> +void CModuleAction<action_ros,dyn_reconf_config>::disable_timeout(void) { this->action_access.enter(); this->use_timeout=false; this->action_access.exit(); } -template<class action_ros> -void CModuleAction<action_ros>::update_timeout(double time_s) +template<class action_ros,class dyn_reconf_config> +void CModuleAction<action_ros,dyn_reconf_config>::update_timeout(double time_s) { this->action_access.enter(); if(this->use_timeout) @@ -707,22 +788,22 @@ void CModuleAction<action_ros>::update_timeout(double time_s) this->action_access.exit(); } -template<class action_ros> -void CModuleAction<action_ros>::stop_timeout(void) +template<class action_ros,class dyn_reconf_config> +void CModuleAction<action_ros,dyn_reconf_config>::stop_timeout(void) { this->action_access.enter(); this->action_timeout.stop(); this->action_access.exit(); } -template<class action_ros> -bool CModuleAction<action_ros>::is_timeout_enabled(void) +template<class action_ros,class dyn_reconf_config> +bool CModuleAction<action_ros,dyn_reconf_config>::is_timeout_enabled(void) { return this->use_timeout; } -template<class action_ros> -bool CModuleAction<action_ros>::is_timeout_active(void) +template<class action_ros,class dyn_reconf_config> +bool CModuleAction<action_ros,dyn_reconf_config>::is_timeout_active(void) { this->action_access.enter(); if(this->use_timeout && this->action_timeout.timed_out()) @@ -738,36 +819,36 @@ bool CModuleAction<action_ros>::is_timeout_active(void) } } -template<class action_ros> -void CModuleAction<action_ros>::enable(void) +template<class action_ros,class dyn_reconf_config> +void CModuleAction<action_ros,dyn_reconf_config>::enable(void) { this->action_access.enter(); this->enabled=true; this->action_access.exit(); } -template<class action_ros> -void CModuleAction<action_ros>::disable(void) +template<class action_ros,class dyn_reconf_config> +void CModuleAction<action_ros,dyn_reconf_config>::disable(void) { this->action_access.enter(); this->enabled=false; this->action_access.exit(); } -template<class action_ros> -bool CModuleAction<action_ros>::is_enabled(void) +template<class action_ros,class dyn_reconf_config> +bool CModuleAction<action_ros,dyn_reconf_config>::is_enabled(void) { return this->enabled; } -template<class action_ros> -std::string CModuleAction<action_ros>::get_name(void) +template<class action_ros,class dyn_reconf_config> +std::string CModuleAction<action_ros,dyn_reconf_config>::get_name(void) { return this->name; } -template<class action_ros> -void CModuleAction<action_ros>::cancel(void) +template<class action_ros,class dyn_reconf_config> +void CModuleAction<action_ros,dyn_reconf_config>::cancel(void) { actionlib::SimpleClientGoalState action_state(actionlib::SimpleClientGoalState::PENDING); @@ -779,8 +860,8 @@ void CModuleAction<action_ros>::cancel(void) } } -template<class action_ros> -bool CModuleAction<action_ros>::is_finished(void) +template<class action_ros,class dyn_reconf_config> +bool CModuleAction<action_ros,dyn_reconf_config>::is_finished(void) { actionlib::SimpleClientGoalState action_state(actionlib::SimpleClientGoalState::PENDING); @@ -796,8 +877,8 @@ bool CModuleAction<action_ros>::is_finished(void) return true; } -template<class action_ros> -action_status CModuleAction<action_ros>::get_state(void) +template<class action_ros,class dyn_reconf_config> +action_status CModuleAction<action_ros,dyn_reconf_config>::get_state(void) { if(this->enabled) { @@ -813,8 +894,8 @@ action_status CModuleAction<action_ros>::get_state(void) return this->status; } -template<class action_ros> -CModuleAction<action_ros>::~CModuleAction() +template<class action_ros,class dyn_reconf_config> +CModuleAction<action_ros,dyn_reconf_config>::~CModuleAction() { if(this->enabled) { diff --git a/include/iri_ros_tools/module_service.h b/include/iri_ros_tools/module_service.h index 61fe04b..4c1cc96 100644 --- a/include/iri_ros_tools/module_service.h +++ b/include/iri_ros_tools/module_service.h @@ -122,7 +122,7 @@ class CModuleService * \param name prefix given to the module servie variables in order to locate and * handle them. */ - void dynamice_reconfigure(dyn_reconf_config &config, std::string &name); + void dynamic_reconfigure(dyn_reconf_config &config, const std::string &name); /** * \brief Sets the maximum number of attempts to start the action @@ -217,7 +217,7 @@ CModuleService<service_msg,dyn_reconf_config>::CModuleService(const std::string } template<class service_msg,class dyn_reconf_config> -void CModuleService<service_msg,dyn_reconf_config>::dynamice_reconfigure(dyn_reconf_config &config, std::string &name) +void CModuleService<service_msg,dyn_reconf_config>::dynamic_reconfigure(dyn_reconf_config &config, const std::string &name) { std::vector<typename dyn_reconf_config::AbstractParamDescriptionConstPtr> params; boost::any value; @@ -226,13 +226,13 @@ void CModuleService<service_msg,dyn_reconf_config>::dynamice_reconfigure(dyn_rec for(typename std::vector<typename dyn_reconf_config::AbstractParamDescriptionConstPtr>::iterator param=params.begin();param!=params.end();param++) { - if((*param)->name==(name+"_max_num_retries")) + if((*param)->name==(name+"_num_retries")) { (*param)->getValue(config,value); if(value.type()==typeid(int)) this->set_max_num_retries(boost::any_cast<int &>(value)); } - if((*param)->name==(name+"_enable")) + else if((*param)->name==(name+"_enabled")) { if(value.type()==typeid(bool)) { -- GitLab