1

I got this following function with me working now. But what I need to improve is that it would read input from the keyboard (on the terminal) EVEN THOUGH IT IS NOT BEING PRESSED. I need to know when it is NOT pressed (idle) so that the switch case block will fall into the default section. At this point, the read() function waits until there's an input from the user. Can anyone give a suggestion just based on modifying this following code? NOTE: I'm a Java programmer, and still learning C/C++ so it might be hard to get in my head a little bit. Thanks guys..

EDIT: I found this link, and seems to have something related to what i'm looking for at the line of fcntl(STDIN_FILENO,F_SETFL,flags | O_NONBLOCK); . But since I barely know anything in C, I completely have no Idea what it's saying, yet.
http://www.codeguru.com/forum/showthread.php?t=367082

int kfd = 0;
struct termios cooked, raw;
char c;
bool dirty = false;

//get the console in raw mode
tcgetattr(kfd, &cooked);
memcpy(&raw, &cooked, sizeof(struct termios));
raw.c_lflag &=~ (ICANON | ECHO);
// Setting a new line, then end of file
raw.c_cc[VEOL] = 1;
raw.c_cc[VEOF] = 2;
tcsetattr(kfd, TCSANOW, &raw);

puts("Reading from keyboard");
puts("=====================");
puts("Use arrow keys to navigate");

while(true){
//get the next event from the keyboard
if(read(kfd, &c, 1) < 0)
{
  perror("read():");
  exit(-1);
}

linear_ = angular_ = 0;
ROS_DEBUG("value: 0x%02X\n", c);

switch(c)
{
  case KEYCODE_L:
    ROS_DEBUG("LEFT");
    angular_ = -1.0;
    dirty = true;
    break;
  case KEYCODE_R:
    ROS_DEBUG("RIGHT");
    angular_ = 1.0;
    dirty = true;
    break;
  case KEYCODE_U:
    ROS_DEBUG("UP");
    linear_ = 1.0;
    dirty = true;
    break;
  case KEYCODE_D:
    ROS_DEBUG("DOWN");
    linear_ = -1.0;
    dirty = true;
    break;
  default:
    ROS_DEBUG("RELEASE");
    linear_ = 0;
    angular_ = 0;
    dirty = true;
    break;
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
haikalpribadi
  • 424
  • 1
  • 7
  • 19
  • 2
    Instead of using termios directly, I recommend using something like [ncurses](http://en.wikipedia.org/wiki/Ncurses). [Here](http://hughm.cs.ukzn.ac.za/~murrellh/os/notes/ncurses.html) is a tutorial that shows how to get keys in a non-blocking fashion. – Some programmer dude Feb 24 '12 at 10:37
  • There's no way just to just to modify the above code is it? i'm just looking to read keyboard inputs from the terminal (forgot to mention that). Of course my last resort would be to learn ncurses but I'm already having a hard time learning C/C++. – haikalpribadi Feb 24 '12 at 10:47
  • @JoachimPileborg I've edited my question with (what i think is) a related link. Do you think you know what it's talking about? – haikalpribadi Feb 24 '12 at 10:53
  • @pst I've edited my question with (what i think is) a related link. Do you think you know what it's talking about? – haikalpribadi Feb 24 '12 at 10:53
  • 1
    You can make `STDIN_FILENO` non-blocking like that, but then remember that `read` will return an error when there is nothing to read. Check `errno` to see if it's a real error or if it would block (`errno == EWOULDBLOCK`). – Some programmer dude Feb 24 '12 at 10:57

1 Answers1

1

The OP seems to have answered their question:

I think I solved my problem. Please, anyone, verify and let me know if this is the right way to do it, or is it the complete way to do it (am I missing any other addition step e.g. resetting it back again -if that even makes sense) .

So what i found is to add this 3 lines before entering the while loop:

flags = fcntl(0, F_GETFL, 0); /* get current file status flags */
flags |= O_NONBLOCK;          /* turn off blocking flag */
fcntl(0, F_SETFL, flags);         /* set up non-blocking read */
Rakete1111
  • 47,013
  • 16
  • 123
  • 162
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129