ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
1

Can't get dynamic reconfigure to spin when callback is a member of a class

asked 2016-12-27 02:33:55 -0500

Juan gravatar image

I am using ROS Indigo, Ubuntu 14.04. Get no compile errors. When I debug with GDB I can see I go into my callback once, but no more thereafter. This also happened when the callback was made global outside the class. I thought that perhaps this was why it was not being called. But it seems this is not the problem.

I have three other subscription callbacks in this code that work fine as well one publication.

Below I show the callback and the main function. Currently I use spinOnce() but I have tried other spin mechanisms like spin() AsyncSpinner, MultiThreadedSpinner to see if that made a difference.

The full file / ROS package can be found here: https://github.com/birlrobotics/birl_...

Any help would be greatly appreciated.

namespace force_controller
{
  //***********************************************************************************************************************************************
  // callback(...) for dynamic Reconfigure set as a global function. 
  // When the rqt_reconfigure gui is used and those parameters are changed, the config.param_name in this function will be updated. Then, these parameters need to be set to the private members of your code to record those changes. 
  //***********************************************************************************************************************************************
  //void callback(force_error_constants::force_error_constantsConfig &config, uint32_t level)
  void controller::callback(force_error_constants::force_error_constantsConfig &config, uint32_t level)
  {
    // Print the updated values
    ROS_INFO("Dynamic Reconfigure Prop gains: %f %f %f %f %f %f\nDerivative gains: %f", 

             // Proportional Gains
             config.k_fp0,
             config.k_fp1,
             config.k_fp2,

             config.k_mp0,
             config.k_mp1,
             config.k_mp2,

             // Derivative Gains
             config.k_fv0);

    // Save proportional gains  to the corresponding data members. 
    k_fp0=config.k_fp0;
    k_fp1=config.k_fp1;
    k_fp2=config.k_fp2;

    k_mp0=config.k_mp0;
    k_mp1=config.k_mp1;
    k_mp2=config.k_mp2;

    // Save derivative gains to the corresponding data members.
    k_fv0=config.k_fv0;

    // change the flag
    force_error_constantsFlag = true;

  }
...
----------------

 int main(int argc, char** argv)
{
  ros::init(argc, argv, "control_basis_controller");

  // Create a node namespace. Ie for service/publication: <node_name>/topic_name or for parameters: <name_name>/param_name 
  ros::NodeHandle node("~"); 

  // Instantiate the controller
  force_controller::controller myControl(node);

  // Set up the Dynamic Reconfigure Server to update controller gains: force, moment both proportional and derivative.
  if(myControl.dynamic_reconfigure_flag)
    {
     // (i) Set up the dynamic reconfigure server
      dynamic_reconfigure::Server<force_error_constants::force_error_constantsConfig> srv;

      // (ii) Create a callback object of type force_error_constantsConfig
      dynamic_reconfigure::Server<force_error_constants::force_error_constantsConfig>::CallbackType f;

      // (iii) Bind that object to the actual callback function
      //f=boost::bind(&force_controller::callback, _1, _2); // Used to pass two params to a callback.

      // Bind a new function f2 with the force_controller::controller::callback.
      // The left side of the command, tells boost that the callback returns void and has two input parameters. 
      // It also needs the address of the this pointer of our class, and the indication that it has the two parameters follow the order _1, _2. 
      boost::function<void (force_error_constants::force_error_constantsConfig &,int) > f2( boost::bind( &force_controller::controller::callback,&myControl, _1, _2 ) );

      // (iv) Set the callback to the service server. 
      f=f2; // Copy the functor data f2 to our dynamic_reconfigure::Server callback type
      srv.setCallback(f);

      // Update the rosCommunicationCtr
      myControl.rosCommunicationCtrUp();
    }

  if(!myControl.start())
    {
      ROS_ERROR("Could not start controller, exiting");
      ros::shutdown();
      return 1;
    }

  ros::Rate rate( myControl.get_fcLoopRate() );

  /*** Different Communication Modes ***/
  while(ros::ok())
    {

      // 1. Non ...
(more)
edit retag flag offensive close merge delete

Comments

Did you really change the values with the dynamic parameters? The Callback method is just called when one of the values change. Otherwise its just called one time at the beginning

chwimmer gravatar image chwimmer  ( 2017-05-22 04:28:48 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2017-05-21 23:41:31 -0500

lucasw gravatar image

Convert the rate while loop into a ros::Timer http://wiki.ros.org/roscpp/Overview/T... , and ros::spin() at the bottom.

edit flag offensive delete link more

Comments

I've had a similar problem. But since I need a while loop at that point, I've just added a "ros::spinOnce();" right before the sleep call for the loop happens. Thanks for your answer!

Zacryon gravatar image Zacryon  ( 2020-02-26 10:40:35 -0500 )edit

Question Tools

2 followers

Stats

Asked: 2016-12-27 02:33:55 -0500

Seen: 2,169 times

Last updated: May 21 '17