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

Threading function - udp client integration to a Ros node

asked 2012-06-09 12:33:36 -0500

ajr_ gravatar image

updated 2014-01-28 17:12:37 -0500

ngrennan gravatar image

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?

edit retag flag offensive close merge delete

Comments

What's wrong with timers? If you want it to run as fast as possible, setting the timeout to 0 should work.

Dan Lazewatsky gravatar image Dan Lazewatsky  ( 2012-06-10 03:43:38 -0500 )edit

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.

ajr_ gravatar image ajr_  ( 2012-06-10 03:55:47 -0500 )edit

Timers will work, but they introduce extra latency for programs like this.

joq gravatar image joq  ( 2012-06-11 09:23:20 -0500 )edit

2 Answers

Sort by ยป oldest newest most voted
1

answered 2012-06-10 14:29:09 -0500

joq gravatar image

updated 2012-06-10 14:29:31 -0500

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.

edit flag offensive delete link more

Comments

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.

ajr_ gravatar image ajr_  ( 2012-06-10 22:53:21 -0500 )edit
1

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.

Lorenz gravatar image Lorenz  ( 2012-06-11 04:48:58 -0500 )edit

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.

joq gravatar image joq  ( 2012-06-11 07:26:57 -0500 )edit

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.

Lorenz gravatar image Lorenz  ( 2012-06-11 07:29:08 -0500 )edit

I expect it does if any data are exchanged between the callbacks and the main thread.

joq gravatar image joq  ( 2012-06-11 08:27:32 -0500 )edit

You are right of course. Never mind...

Lorenz gravatar image Lorenz  ( 2012-06-11 08:39:37 -0500 )edit

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.

ajr_ gravatar image ajr_  ( 2012-06-11 10:25:10 -0500 )edit

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.

joq gravatar image joq  ( 2012-06-11 10:31:59 -0500 )edit
0

answered 2012-06-10 06:05:12 -0500

Lorenz gravatar image

Timers are definitely a possibility but I'm not sure how accurate they are. They might not work in all cases.

Using threads (e.g. just posix threads or boost::thread) will work as well.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2012-06-09 12:33:36 -0500

Seen: 882 times

Last updated: Jun 14 '12