NCurses getch всегда возвращает ERR (-1) - PullRequest
0 голосов
/ 20 мая 2018

Я только начал работать с ROS и пытаюсь написать узел, который публикует ключи в теме.

Я создал узел в Linux Ubuntu 16.04.4 с помощью ncurses.

Это мой код:

#include <curses.h>

#include "ros/ros.h"
#include "std_msgs/String.h"

#include <sstream>

int main(int argc, char **argv)
{
    int ch;
    nodelay(stdscr, TRUE);

    ros::init(argc, argv, "keyboard_driver");

    ros::NodeHandle n;

    ros::Publisher key_pub = n.advertise<std_msgs::String>("keys", 1);

    ros::Rate loop_rate(100);

    while (ros::ok())
    {
        std_msgs::String msg;
        std::stringstream ss;

        if ((ch = getch()) != ERR)
        {
            ss << ch;
            std::cout << ch;
            msg.data = ss.str();

            ROS_INFO("%s", msg.data.c_str());

            key_pub.publish(msg);
        }

        ros::spinOnce();
        loop_rate.sleep();
    }

    return 0;
}

Я использую ncurses, чтобы избежать буфера терминала.

Тема появляется, но я ничего не получаю, если в другомтерминал, я запускаю эту команду:

rostopic echo /keys

Отладка я обнаружил, что getch () всегда возвращает -1.

Как мне сделать, чтобы это работало?

UPDATE

Я пробовал эту маленькую программу, и она ничего не печатает:

#include <iostream>
#include <curses.h>

int main(int argc, char **argv)
{
    int ch;
    cbreak();
    nodelay(stdscr, TRUE);

    for(;;)
    {
        if ((ch = getch()) != ERR)
        {
            std::cout << ch;
        }
    }

    return 0;
}

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

Чтобы использовать getch(), вы должны сделать следующее:

#include <iostream>
#include <curses.h>
#include <signal.h>
#include <stdlib.h>

void quit(int sig)
{
    endwin();
    exit(0);
}

int main(int argc, char **argv)
{
    int ch;

    signal(SIGINT,quit);

    initscr();
    cbreak();
    nodelay(stdscr, TRUE);

    for(;;)
    {
        if ((ch = getch()) != ERR)
        {
            std::cout << ch;
        }
    }

    return 0;
}

Я забыл добавить initscr(); вызов в начале и endwin(); в конце программы.

Подробнее о том, как использовать библиотеку ncurses здесь .

0 голосов
/ 20 мая 2018

Вы установили nodelay, поэтому getch немедленно вернется с ERR, если нет данных, готовых с терминала.Вот почему getch возвращает -1 (ERR).Вы не установили cbreak или raw, чтобы отключить буферизацию терминала, так что вы все еще получаете это - данные не будут поступать с терминала, пока не будет нажата Enter .

Поэтому добавьте вызов к cbreak() в начале (непосредственно перед или после вызова на nodelay()), и он должен работать так, как вы ожидаете.

...