Robotics StackExchange | Archived questions

How to structure code inside a node

Hi, I'm learning ROS and I was wondering how should I write the code inside my nodes.

Let's take this example: The node should control the movement of a robot (publishing a velocity command) but at the same time check received messages from a sensor.

I also need to set the velocity gradually I can easily achieve this using a loop. But this avoid my node from calling the ros::Spin() and so the callback updating my global variables (or class members) is never called, right?

So I think I am supposed to make the code inside an infinite loop which calls ros::spinOnce() and write the code to control the robot in such a way that it doesn't block the loop?

I'm not sure I have been very clear, but I hope someone can point me in the right direction, thanks.

EDIT = I thought about something that could be smart in my case (mainly for readibility reasons) The switch/case. (I need to perform multiple action and I can't execute the next until i finished the previous or the sensor detect something. See:

 while(nh.ok())
    {
        switch(STATUS)
        {
        case 1:
            inc_vel();
            if (object detected) //global variable updated by the sensor callback
            {
                stop();
                STATUS++;
            }
            break;
        case 2:
            //do something else, for example turn around and change path
            break;
        }
        ros::spinOnce();
    }

Asked by Vendra on 2016-04-11 13:29:32 UTC

Comments

Answers

I think I get what you are asking, but if you could edit your question to be more clear that would be nice. It sounds like you want a node that checks a sensor, increases the robot's velocity, and then publishes that velocity. I would use 2 separate functions for this. You need a callback function to read the sensor data, and a second function to increment the velocity and publish it. Then in your main function have something like

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

That's a really basic idea of how to do this. More complex systems require other things like using multiple threads with synchronous or asynchronous spinners. Check out the callbacks page on the wiki.

Asked by Icehawk101 on 2016-04-11 14:24:11 UTC

Comments

The only thing I would add to this is a ros::Rate object to the loop, to make sure that each iteration runs in the correct amount of time. Otherwise it will spin as fast as possible, running at an undefined rate and using 100% CPU.

Asked by ahendrix on 2016-04-11 14:26:35 UTC

Okay, basically that is how I shaped my code. The thing is: when I call the inc_vel() function and I'm running the code inside it, I am not able to check the sensor, right? That is my problem. I'll edit the question and try to be more clear anyway

Asked by Vendra on 2016-04-11 14:32:37 UTC

I think you could call the callback function from inside the inc_vel function, but I am not positive. What sensor is it you are checking, encoders?

Asked by Icehawk101 on 2016-04-11 14:50:17 UTC

thanks @ahendrix for the tip, I thought about that multiple times but never really found a reason to put it unless strictly neccessary. This was helpful

Asked by Vendra on 2016-04-11 14:50:51 UTC

@Icehawk101 I'm checking an infrared line sensor so I can tolerate little delay between sensor readings. What I do care about is my code periodically checks that sensor.

Asked by Vendra on 2016-04-11 14:52:32 UTC