As far as I know, there's no ROS (or Boost) built-in function for this.
You can look at the method used in the turtlesim teleop_turtle_key. This node is used in the Understanding Topics tutorial.
All the default built-in functions (cin >>
, getchar
, etc.) block until the user presses "enter". Which is probably not the behavior you want. So, you'll need to use some sort of OS-specific hack to read the keys as they are pressed.
See this thread for suggestions on how to implement a non-blocking getchar()
in linux. It boils down to modifying the terminal settings to disable input buffering. You'll want to make sure and restore the original settings when your program exits, or else the terminal will behave oddly. Basically, you need something like:
int getch()
{
static struct termios oldt, newt;
tcgetattr( STDIN_FILENO, &oldt); // save old settings
newt = oldt;
newt.c_lflag &= ~(ICANON); // disable buffering
tcsetattr( STDIN_FILENO, TCSANOW, &newt); // apply new settings
int c = getchar(); // read character (non-blocking)
tcsetattr( STDIN_FILENO, TCSANOW, &oldt); // restore old settings
return c;
}
Once you've got that function written, you can do something like:
while (ros::ok())
{
int c = getch(); // call your non-blocking input function
if (c == 'a')
send message 'A'
else if (c == 'b')
send message 'B'
<< do other processing >>
}
Originally posted by Jeremy Zoss with karma: 4976 on 2013-05-25
This answer was ACCEPTED on the original site
Post score: 16
Original comments
Comment by s_bot on 2013-05-25:
I tried your suggestion and it works very well. Thank you :)
Comment by Equanox on 2014-02-21:
Don't forget to add #include <termios.h>
Comment by einrob on 2014-11-21:
This didn't worked for me till I set the following:
newt.c_cc[VMIN] = 0;
newt.c_cc[VTIME] = 0;
See http://www.unixwiz.net/techtips/termios-vmin-vtime.html for more details.
This is a nice and easy way catching some basic Inputs! Thank you!
Comment by Adnan Munawar on 2016-06-17:
Very helpful. I wanted to handle the program termination using ctrl-c and it wasn't clean. Using your method and suggestion the edit by @einrob I can.
Comment by ROS_user on 2021-09-17:
Note that if you don't want your input to be displayed in the terminal, then you have to modify the line newt.c_lflag &= ~(ICANON);
to newt.c_lflag &= ~(ICANON | ECHO);
.
It is written in one of the link provided in the main answer, but maybe it is worth to highlight that.