[英]Sampling keyboard input at a certain rate in C++
我想要做的是以一定的速率(例如 10-20 Hz)對鍵盤輸入進行采樣。 我使用從 stdin 讀取的 while 循環(我使用 read 是因為我想異步讀取,我不想每次都按 enter),然后在新循環開始之前暫停以保持采樣頻率穩定。
用戶按下左/右箭頭來發出命令(給機器人)。 如果沒有按下,output 為 0。
問題是,在暫停期間,標准輸入緩沖區被寫入(我想),因此讀取將返回一個舊的輸入。 最終結果是output延遲。 因此,如果我按下左鍵 output 立即變為 1,但當我松開時,它需要幾秒鍾才能返回 0。我想消除這個延遲。
我的目標是僅對最近按下的鍵進行采樣,以便無延遲地同步用戶輸入和 output 命令。 有辦法嗎? 先感謝您。
這是我正在使用的方法:
void key_reader::keyLoop()
{
char c;
bool dirty = false;
int read_flag;
// 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);
//FD_ZERO(&set); /* clear the set */
//FD_SET(kfd, &set); /* add our file descriptor to the set */
//timeout.tv_sec = 0;
//timeout.tv_usec = 10000;
if (fcntl(kfd, F_SETFL, O_NONBLOCK) == -1)
{
perror("fcntl:"); // an error accured
exit(-1);
}
puts("Reading from keyboard");
puts("---------------------------");
puts("Use arrow keys to move the turtle.");
ros::Rate r(10);
while (ros::ok())
{
read_flag = read(kfd, &c, 1);
switch (read_flag)
{
case -1:
// case -1: is empty and errono
// set EAGAIN
if (errno == EAGAIN)
{
//no input yet
direction = 0;
break;
}
else
{
perror("read:");
exit(2);
}
// case 0 means all bytes are read and EOF(end of conv.)
case 0:
//no input yet
direction = 0;
break;
default:
ROS_DEBUG("value: 0x%02X\n", c);
switch (c)
{
case KEYCODE_L:
ROS_DEBUG("LEFT");
direction = 1;
dirty = true;
break;
case KEYCODE_R:
ROS_DEBUG("RIGHT");
direction = -1;
dirty = true;
break;
}
}
continuos_input::input_command cmd;
cmd.type = "Keyboard";
cmd.command = direction;
cmd.stamp = ros::Time::now();
key_pub.publish(cmd);
r.sleep();
}
}
我覺得問題在於您的訂閱者而不是發布者。 我可以看到您已使用 rate 將發布速率限制為 10Hz。 使用 rqt 中的主題監視器確認發布率。 此外,為發布者設置較小的隊列大小可能會有所幫助。 如果不參考您的訂閱者節點,則無法給出更明確的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.