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

how to add a timeout for a teleop node

asked 2012-12-11 12:21:15 -0600

mte2010 gravatar image

updated 2021-12-03 09:52:11 -0600

Evgeny gravatar image

I have a teleop node that connects with my ps3 controller wirelessly to run my robot.

I want to add a timeout feature to set all of the parameters to zero in case the joy commands stop being sent to the teleop node. I have had my robot run away on me already and don't want that to happen again.

Can someone help and provide sudo code? And would this timeout be in the main function or in the ps3 button handler?

Thanks.

edit retag flag offensive close merge delete

Comments

2

The general approach is to not add the timeout in the teleop node but in your robot's base node (examples: PR2, Turtlebot). The reason is that it also can happen that your network connection drops. In that case, the robot would still run away.

Lorenz gravatar image Lorenz  ( 2012-12-11 20:30:09 -0600 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2012-12-11 13:30:09 -0600

Thomas D gravatar image

I create a public class variable called double last_cmd_vel_received that gets initialized in my constructor to last_command_vel_received = 0. Then, in the main() function of my node I read in a ROS parameter called double watchdog_timeout. For the main while loop I use ros::spinOnce() and rate.sleep() (where rate is another ROS parameter value). In my class I have a public function called zeroVelocities() that just sets all the actuator outputs to safe values. So, my main while loop looks something like the following:

...
while (nh.ok())
{
    if (ros::WallTime::now().toSec() - my_class->last_cmd_vel_received > watchdog_timeout)
    {
        my_class->zeroVelocities();
    }
    ros::spinOnce();
    rate.sleep();
}
...

In my callback function for the cmd_vel topic (where the function is part of my class) I set last_cmd_vel_received = ros::WallTime::now().toSec(). You can play with timeout values however you want, but I have found that 0.3 or so works well with my robots.

edit flag offensive delete link more

Comments

2

A variation: save the last received message in the callback function. Then, in the loop: if (ros::Time::now() - last_msg_.header.stamp).toSec() > timeout_) { ... handle timeout ... }

Ivan Dryanovski gravatar image Ivan Dryanovski  ( 2012-12-11 16:15:43 -0600 )edit
1

That assumes the last received message has a header, which geometry_msgs::Twist does not (and that is what the standard cmd_vel topic publishes). But it is a viable alternative if that assumption holds.

Thomas D gravatar image Thomas D  ( 2012-12-11 17:23:44 -0600 )edit

@Thomas D: yes, good catch.

Ivan Dryanovski gravatar image Ivan Dryanovski  ( 2012-12-11 17:59:32 -0600 )edit

Question Tools

Stats

Asked: 2012-12-11 12:21:15 -0600

Seen: 2,089 times

Last updated: Dec 11 '12