0
$\begingroup$

Rosanswers logo

Hi,

I have working ROS node with callBacks for subscriptions, and also with timers like this:

timer= nh.createTimer(ros::Duration(0.050), &Control::spin,this); // 20Hz
void Control::spin(const ros::TimerEvent & e)

But I would like to create additional function which connects to a UDP server and ask data. For this I need to create own function which would run as separate loop alongside other node callBacks. How should i create this, with help of what kind of tools? I guess timer is not the best solution because of constant Hz in loop.

My control node current structure:


int main(int argc, char **argv)
{
    printf("*************************************\n");

    ros::init(argc, argv, "control");
    ros::NodeHandle n;
    Control Mcontrol(n);
   
    ros::spin();
    return 0;
}

Control class requires itself quite fast response time to its tasks. It subscribes to IMU data ~20Hz and camera coordinate data would be obtained with help of UDP. UDP should be as fast as possible.

All tips are highly appreciated. Thanks.

EDIT: At the moment too busy to try solve this problem this way. Made separate node for UDP-client. Maybe later try to integrate them in to one node. I'm unsure will this make any difference latency wise?


Originally posted by ajr_ on ROS Answers with karma: 97 on 2012-06-09

Post score: 1


Original comments

Comment by Dan Lazewatsky on 2012-06-10:
What's wrong with timers? If you want it to run as fast as possible, setting the timeout to 0 should work.

Comment by ajr_ on 2012-06-10:
sure, of course i can do that too. I'm just wondering about possible solutions, if timers are the correct way then i'm happy to use them.

Comment by joq on 2012-06-11:
Timers will work, but they introduce extra latency for programs like this.

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

For a node, you don't need an extra thread. Within your main() thread, in place of ros::spin(), invoke ros::spinOnce() in a loop. The rest of that loop can read UDP requests, or whatever you want.

while (ros::ok()) {
    ros:spinOnce();
    // process UDP requests
}

Nodelets do need and extra thread for logic like this. I can explain how to do that too, if you are interested.


Originally posted by joq with karma: 25443 on 2012-06-10

This answer was ACCEPTED on the original site

Post score: 1


Original comments

Comment by ajr_ on 2012-06-10:
this could be a good solution. And it should keep the Control class fast enough to response and calculate control values(control toolbox pid) send back to robot.

Comment by Lorenz on 2012-06-11:
That actually depends on your message callbacks. spinOnce will execute all message/service callbacks in the current thread and block until they are done so if you do a lot of work there, it might take too long.

Comment by joq on 2012-06-11:
True. If it is a problem, there are ways to run the callbacks in separate threads at the cost of adding mutex logic to the code.

Comment by Lorenz on 2012-06-11:
To just run the callbacks in a separate thread, you could also use a ros::AsyncSpinner with just one thread. I think that shouldn't require any locking.

Comment by joq on 2012-06-11:
I expect it does if any data are exchanged between the callbacks and the main thread.

Comment by Lorenz on 2012-06-11:
You are right of course. Never mind...

Comment by ajr_ on 2012-06-11:
I have limited experience of threads, is there maybe some similar examples which would solve same kind of situation? To point me into right direction.

Comment by joq on 2012-06-11:
I recommend avoiding threads entirely until you are convinced that the simple spinOnce() solution causes excessive latency. Try that and measure the latency. Most likely, it will work fine.

$\endgroup$

Your Answer

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