0
$\begingroup$

Rosanswers logo

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_baxter_controllers/blob/master/force_controller/src/force_controller_topic.cpp

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 Blocking spin
      ros::spinOnce();
      myControl.force_controller();
      rate.sleep();
    }

  return 0;
}  

Originally posted by Juan on ROS Answers with karma: 208 on 2016-12-27

Post score: 1


Original comments

Comment by chwimmer on 2017-05-22:
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

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

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


Originally posted by lucasw with karma: 8729 on 2017-05-21

This answer was ACCEPTED on the original site

Post score: 1


Original comments

Comment by Zacryon on 2020-02-26:
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!

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.