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

subscriber callback not running (c++)

asked 2018-07-03 03:58:30 -0600

conect gravatar image

updated 2018-07-03 04:08:38 -0600

so I've been stuck on this for a while now and have come to realize that the issue with my code is that for some reason the callback function for my subscriber never seems to run and I can't understand why for the life of me.

I'm using 3 files to run my code in order to make sure that in the future everything will be as modular as possible and I can simply swap 1 or 2 lines in my main function file to make my turtlebot do different things based on the functions in the function file.

To make sure the callback was running I added a cout << "test" << endl; to the function just to see if anything prints, and it doesn't. So I assume that's where my major problem lies.

Any help would be greatly appreciated.

The files are:

#include <iostream>
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <nav_msgs/Odometry.h>
#include <std_msgs/Empty.h>
#include "TurtleFunction.cpp"
#include "TurtleFunction.h"

#include <sstream>
#include <string>
#include <cmath>
#include <math.h>

using namespace std;

int main(int argc, char** argv){

    // Initialize ROS
    ros::init(argc, argv, "test3");
    ros::NodeHandle nh;

    // Define Global Variables for use
    cmd_pub = nh.advertise<geometry_msgs::Twist>("/cmd_vel_mux/input/teleop", 50);
    reset_pub = nh.advertise<std_msgs::Empty>("/mobile_base/commands/reset_odometry", 1);
    OdomSub = nh.subscribe<nav_msgs::Odometry>("/odom",50,processodom);
    resetOdom(); // Reset the Odometry of the Turtlebot
    ros::Rate r(50);

    // Define Initial Velocity Variables for TurtleBot
    double v = 0.1;
    double theta = 0.01;

    int i = 0;

     * Begin Infinite Loop.
     * First Function is our method of identifying other TurtleBots (if applicable)
     * Second Function is our chosen Control Law (if applicable)
     * Third Function is how we drive the TurtleBot
        cout << "this is working" << i << endl;

    return 0;

The function file:


#include <iostream>
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <nav_msgs/Odometry.h>
#include <std_msgs/Empty.h>
#include "TurtleFunction.h"

#include <sstream>
#include <string>
#include <cmath>
#include <math.h>

using namespace std;

 * The Movement Function allows us to test that our Turtlebot can be controlled usings a
 * separate function file. It's also the "block" we use to make the movement modules for the
 * Turtlebot (i.e.- Unicycle Model or Feedback Linearization) work.
 * It takes three (3) inputs;
 * 1) the ros::Publisher that we will use to publish to the Turtlebot
 * 2) the desired linear velocity
 * 3) the desired rotational velocity
 * Using these three (3) inputs, it publishes a command to the Turtlebot telling it how to move
void Movement(double v,double theta){

    // geometry_msgs::Twist cmd_msg;

    cmd_msg.linear.x  = v;
    cout << "v = " << cmd_msg.linear.x << endl;
    cmd_msg.angular.z  = theta;
    cout << "theta = " << cmd_msg.angular.z << endl;
    cmd_pub.publish(cmd_msg); //send


 * The Unicycle Model is the classic model used for describing the dynamics
 * of the Turtlebot. The Unicycle Model Function allows us to find the desired linear velocity
 * and rotational velocity which we can ...
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2018-07-03 09:17:34 -0600

Okay, there are quite a few things wrong here so I'll go over them one at a time. Firstly I recommend learning some more C++ programming before diving into ROS. It should not be considered a way to learn C++ because we it uses some very complex features of the language.

Which node is producing the /odom messages? Are you sure this topic is being published because if not then you wouldn't expect the callback to be called. Can you describe what you're expecting this code to do?

You should never include a cpp file! That's not how multiple file C++ projects work, your header should define globals, function prototypes and class declarations. The C++ file then defines these function and classes, this article describes the reasoning behind this and shows you how it should be done.

Finally, you do not need to call ros::spinOnce() everywhere, a single call in your main loop is fine. I'm not sure how well protected it is but calling spinOnce within a callback could potentially cause strange recursive behaviour.

edit flag offensive delete link more


So I know usually I shouldn't include the cpp file, but at this point I've been trying to get this to work for over a week to no avail, so I took to the "throw everything at the wall and see what sticks approach" which also included added lots of ros::spinOnce()'s to the code.

conect gravatar image conect  ( 2018-07-04 02:47:43 -0600 )edit

I've now reverted everything back to how it was, including removing the extra ros::spinOnce lines and only have the single one in the while loop of my main function, and have moved the functions back to the header and only included that in my main as well.

conect gravatar image conect  ( 2018-07-04 02:48:59 -0600 )edit

using the rostopic echo /odom I can see that the /odom topic is publishing the expected messages, but my callback function still isn't running for some reason. essentially what I want this code to do is allow me to write a PID controller for my robot, so I need to get the odom information to do so

conect gravatar image conect  ( 2018-07-04 02:49:42 -0600 )edit

Managed to get it working, it seems the callback was being called, just not often enough so the data was being obscured by the other tests I had. I still couldn't use it to define a pointer to the odom messages, but I just set variables for each one and now it all works.

conect gravatar image conect  ( 2018-07-04 05:40:52 -0600 )edit

Question Tools



Asked: 2018-07-03 03:58:30 -0600

Seen: 1,817 times

Last updated: Jul 03 '18