簡體   English   中英

在C++中以一定的速率采樣鍵盤輸入

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM