Rosanswers logo

Hi everyone,

I found some code which is using 4 arguments to define a subscriber, such as in the following code:

#include "ros/ros.h"
#include <stdio.h>
#include <stdlib.h>
#include <sensor_msgs/Imu.h>
#include <vector>
#include <string>

using namespace std;

class ClassFoo
    ClassFoo(string rname){
        guest_name = rname;
        imu_sub = nm.subscribe("/imu", 1, &ClassFoo::imuCallback, this);

    void imuCallback(const sensor_msgs::Imu & msg)
        lowState.imu.quaternion[0] = msg.orientation.w;
        lowState.imu.quaternion[1] = msg.orientation.x;
        lowState.imu.quaternion[2] = msg.orientation.y;
        lowState.imu.quaternion[3] = msg.orientation.z;

        lowState.imu.gyroscope[0] = msg.angular_velocity.x;
        lowState.imu.gyroscope[1] = msg.angular_velocity.y;
        lowState.imu.gyroscope[2] = msg.angular_velocity.z;
        lowState.imu.accelerometer[0] = msg.linear_acceleration.x;
        lowState.imu.accelerometer[1] = msg.linear_acceleration.y;
        lowState.imu.accelerometer[2] = msg.linear_acceleration.z;

    ros::NodeHandle nm;
    ros::Subscriber imu_sub;
    string guest_name;

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

    string guest_name;
    ros::param::get("/guest_name", guest_name);

    ClassFoo listen_publish_obj(guest_name);
    ros::AsyncSpinner spinner(1); // one threads
    usleep(1000000); // must wait 1s

    ros::NodeHandle n;

    while (ros::ok()){
        // Do something
        cout << "I did nothing!" << endl;
    return 0;

The part I do not understand is the line: imu_sub = nm.subscribe("/imu", 1, &ClassFoo::imuCallback, this); : what is the fourth argument for? I know it's a pointer to the class ClassFoo, but I do not get what the purpose of this argument is. When I go to the documentation , it says:

\param tracked_object A shared pointer to an object to track for these callbacks. If set, the a weak_ptr will be created to this object, and if the reference count goes to 0 the subscriber callbacks will not get called. Note that setting this will cause a new reference to be added to the object before the callback, and for it to go out of scope (and potentially be deleted) in the code path (and therefore thread) that the callback is invoked from.

So does it mean that the fourth argument is some sort of "insurance" that if the ClassFoo object dies for any reason, the callback is not called? But if the object dies, the callback would be dead anyway, no?

Thank you in advance!

Originally posted by robotguy on ROS Answers with karma: 13 on 2023-03-10

Post score: 1


1 Answer 1


Rosanswers logo

You appear to be looking at the wrong overload.

The subscribe(..) call you show is the one for member functions, and the last argument is the object (not the class) on which the member function is defined (or: the instance of the class to pass to the member function when it is invoked).

As the subscriber is created for the current object, that reference would be this.

If it was some other object, it would not be this, but the name of the variable referring the object.

Originally posted by gvdhoorn with karma: 86574 on 2023-03-10

This answer was ACCEPTED on the original site

Post score: 2

Original comments

Comment by robotguy on 2023-03-10:
Ok thank you for the clarification! And can you please tell me what does this argument add compared to a call to subscribe() without the fourth argument? Is it an "insurance" as I wrote in my question?

Comment by Mike Scheutzow on 2023-03-11:
@robotguy No, not insurance. Calling the method of a class requires an actual object (instance of the class), and the 4th argument provides that. For your example, ros will call this->imuCallback(...).

Comment by robotguy on 2023-03-11:
Oh ok. I just realized with your comment that it's the equivalent of the self in python OOP. Somehow it didn't seem obvious at first but now, it is clear. Thank you guys!


Your Answer

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