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

How to use roscpp TimerEvent API in class

asked 2013-02-05 01:36:07 -0500

rikonor gravatar image

updated 2014-01-28 17:15:06 -0500

ngrennan gravatar image

Hi,

I am very new to ROS and quite rusty on my C++. Currently I'm on Fuerte and Ubuntu 12.04. I was following the roscpp tutorial which explains how to create a simple publisher and subscriber.

I think I understand the tutorial fairly ok so I wanted to try and generalize it a little bit and instead of creating the nodes inside their respective main() as done in the tutorial to try and create classes for them.

I tried rewriting the publisher part first and came up with the following code (Based on the roscpp overview pages and my own ideas.

#include <ros/ros.h>
#include <std_msgs/String.h>

class BasicNode
{
private:

public:
    BasicNode() {};
    void timerCallback(const ros::TimerEvent& event);

    //Utilities
    ros::NodeHandle nh;
    ros::Timer timer;
    ros::Publisher pub;
    std_msgs::String str;
};

void BasicNode::timerCallback(const ros::TimerEvent& event) {
    str.data = "hello world";
    pub.publish(str);
}

int main(int argc, char **argv) {
    BasicNode MyPubNode;
    ros::init(argc, argv, "BasicNode");
    MyPubNode.pub = MyPubNode.nh.advertise<std_msgs::String>("chatter",1000);
    MyPubNode.timer = MyPubNode.nh.createTimer(ros::Duration(0.1), &MyPubNode.timerCallback, &MyPubNode);

}

I try and compile the file but get the following error:

/home/rikonor/fuerte_workspace/sandbox/beginner_tutorials/src/BasicNode.cpp: In function ‘int main(int, char**)’:
/home/rikonor/fuerte_workspace/sandbox/beginner_tutorials/src/BasicNode.cpp:28:76: error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function.  Say ‘&BasicNode::timerCallback’ [-fpermissive]

I tried a different approach as well changing the following:

MyPubNode.timer = MyPubNode.nh.createTimer(ros::Duration(0.1), BasicNode::timerCallback);

and received the following error:

error: invalid use of non-static member function ‘void BasicNode::timerCallback(const ros::TimerEvent&)’

If anybody can direct me to what I am doing wrong I will appreciate it. Am I even going at it the right way? Is this the conventional way? In the meantime I'll keep trying and figure it out, if I find anything, I'll post it back here. Thank you, rikonor

--------EDIT--------

Hi,

I think I found out what I did wrong, I did call ros::spin(). I edited the code to add the following:

while(ros::ok())
    {
        ros::spinOnce();
    }

or

ros::spin();

Is this indeed enough or am I missing anything else? Also since I called ros::spin() inside of main(), would you recommend a class function that does it instead, and gets called from main? To be honest I don't see how it matters but I thought I'd ask.

Again, thank you. rikonor

edit retag flag offensive close merge delete

Comments

I personally prefer to do spinning from the main, but the problem is unrelated as you had a problem at compile-time. Forgetting to spin will result in missing functionality at run-time.

dornhege gravatar image dornhege  ( 2013-02-05 02:10:00 -0500 )edit

1 Answer

Sort by » oldest newest most voted
1

answered 2013-02-05 02:07:06 -0500

dornhege gravatar image

updated 2013-02-05 02:07:43 -0500

The notation for member functions is ::, not .. Use &MyPubNode::timerCallback instead of &MyPubNode.timerCallback.

Also it might be a good idea to do the initialization from the constructor instead of from the main.

edit flag offensive delete link more

Question Tools

Stats

Asked: 2013-02-05 01:36:07 -0500

Seen: 3,409 times

Last updated: Feb 05 '13