Send Twist message on Ctrl.+C

asked 2019-07-09 02:01:07 -0500

Elric gravatar image

I'm working with ROS Melodic and Gazebo 9.9.0 on an Ubuntu 18.04.2 LTS.

I want to send a "stop" message to the robot when user kills a node.

To handle Ctrl.+C event, I use this:

 * Override the default ros sigint handler to stop the robot when user press
 * Ctrl.+C.
void sigintHandler(int sig)

  // All the default sigint handler does is call shutdown()

But this function doesn't allow to pass more parameters (I need to pass topic publisher, ros::Publisher cmd_vel_pub, to send the "stop" command).

I have declared this publisher on main function:

int main(int argc, char **argv)
  ros::init(argc, argv, "astar_controller");

  ros::NodeHandle n;

  // Override the default ros sigint handler.
  // This must be set after the first NodeHandle is created.
  std::signal(SIGINT, sigintHandler);

   * Topic where we are going to publish speed commands.
  ros::Publisher cmd_vel_pub = n.advertise<geometry_msgs::Twist>(cmdTopic, 1000);

  // More code...

What is the best option to get access to cmd_vel_pub?

I've thought to declared as global, but I don't think is a good option.

edit retag flag offensive close merge delete


Not an answer, but: are you trying to send an "all-zeros" Twist message to a mobile base driver?

Does that driver have a built-in command time-out?

gvdhoorn gravatar imagegvdhoorn ( 2019-07-09 02:11:31 -0500 )edit

The idea is to send an "all-zeros" Twist message but, I don't have and I don't know what is a built-in command time-out.

Elric gravatar imageElric ( 2019-07-09 02:13:24 -0500 )edit

A proper mobile base driver should have an internal timer running that automatically resets its outputs to "all-zeros" (or whatever makes sense for the particular robot) whenever it doesn't receive a new command (ie: a Twist) within a certain amount of time.

Having such a timeout is a simple precautionary measure that prevents "runaway robots", as the driver will command the robot to a stand-still when it doesn't receive a new command in time.

gvdhoorn gravatar imagegvdhoorn ( 2019-07-09 02:39:25 -0500 )edit

Thanks. How can I do that?

Elric gravatar imageElric ( 2019-07-09 02:40:50 -0500 )edit

Add a timer and in the callback check that current_time - time_of_last_cmd <= timeout, then override the "current command" to whatever would be appropriate if that is not true (ie: a timeout has occured).

In the cmd_vel subscription callback, update time_of_last_cmd to the time the cmd was received.

gvdhoorn gravatar imagegvdhoorn ( 2019-07-09 02:43:31 -0500 )edit