ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
1

Getting messages after an user input?

asked 2014-08-21 13:49:48 -0600

silentwf gravatar image

updated 2014-08-22 07:35:59 -0600

Hi all,

Right now my situation is that there is a node that publishes information, and I need to be able grab information from the publishing node and then print out (I need it for more than just "printing", but trying to keep it simple here) the information recieved when there is an user input.

Here's a snippet of the code

while(true)
{
  std::string inputString;
  std::cout << "Give input";
  std::getline(std::cin, inputString);

  if(inputString.compare("something") == 0)
  {
    //send a request to the node serving out the messages
    //print out recieved messages.
  }

  ros::spinOnce();
}

So I noticed that the received messages do not update on the first input of "something" (hence printing out the previous, un-updated message), but rather on the second time of input. To the best of my knowledge, it has to do something with how getline() is a blocking function, and hence the subscriber/publisher/service calls within this node are not being called, and is only called after there is a spin function invovled (be it spinOnce or spin). In this case, what is a good solution to get around this?

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
1

answered 2014-08-22 03:57:02 -0600

jorge gravatar image

mmm... all looks fine in your code and your explanation, so I cannot see what's your problem. For example, this simple program works as I suppose you expect:

#include <ros/ros.h>
#include <std_msgs/String.h>

int main(int argc, char** argv)
{
  ros::init(argc, argv, "test");

  ros::NodeHandle nh("~");
  ros::Publisher p = nh.advertise<std_msgs::String> ("msg", 1);
  while(true)
  {
    std::string inputString;
    std::cout << "Give input";
    std::getline(std::cin, inputString);
    std_msgs::String msg;

    if(inputString.compare("something") == 0)
    {
      //send a request to the node serving out the messages
      //print out recieved messages.
      msg.data = inputString;
      p.publish(msg);
    }

    ros::spinOnce();
  }

  return 0;
}

Or am I misunderstanding your goal?

edit flag offensive delete link more

Comments

Hi, I wonder if you've tried executing the program you have written? Lets assume that the message I am going to receive is an integer with value "1" and the default integer I have within the node is 0. If you run that program, the first "something" input will give you a 0, not a 1. It is only until you input "something" the second time does 1 print out. This is the problem I am facing. I wonder if this makes it more clear?

silentwf gravatar image silentwf  ( 2014-08-22 07:25:49 -0600 )edit

mmm... sorry, I'm not following what you say about integers. Yep, I run the program, and if you write "something" and type enter, it publish "something" in the /test/msg topic. If you write any other thing, it just ignores it

jorge gravatar image jorge  ( 2014-08-22 08:15:47 -0600 )edit

Sorry for not making it clear. Try this: In one node, have an integer that increases every half a second (so 0, 1, 2, 3...). In the same node, have a subscriber that listens to a second node. When the second node passes "something" to the first node, the first node publishes the current integer. In the second node, have a subscriber that listens to the integer that will be published by the first node when the user inputs "something" into the second node. (So the "something" will cause the second node to publish a message to the first node, and the first node will reply with an integer). See if running this gets you the correct integer. In my case it doesn't.

silentwf gravatar image silentwf  ( 2014-08-22 19:17:01 -0600 )edit

mmm... sorry, your explanation is quite confusing to me. Can you explain the practical use you pursue? Or post a file with your current, non-working implementation?

jorge gravatar image jorge  ( 2014-08-26 03:16:04 -0600 )edit

Hi, sorry for the confusion. To simplify, I have a node that is subscribing to a topic that is publishing at 100Hz. Now I want to allow user input to this node. When the user inputs a certain string, the contents of the topic will be outputted. I don't want the node to be constantly printing out the topic contents.

silentwf gravatar image silentwf  ( 2014-08-27 08:58:33 -0600 )edit

OK, it's more clear now. The important point to keep in mind is that your subscriber will receive nothing until you call spin or spinOnce. In your code, you block waiting for user input before calling spinOnce, so you receive nothing. Place the spinOnce before the std::getline.

jorge gravatar image jorge  ( 2014-08-27 09:23:22 -0600 )edit
1

answered 2014-08-22 06:36:40 -0600

Wolf gravatar image

You might want to flush the std::cin before reading:

std::cout << "Give input";
std::cin.clear(); 
std::cin.ignore(INT_MAX,'\n'); 
std::getline(std::cin, inputString);
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2014-08-21 13:49:48 -0600

Seen: 6,753 times

Last updated: Aug 22 '14