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

How to notify that a bag file has been completely played? [closed]

asked 2012-12-11 03:06:05 -0600

ubisum gravatar image

updated 2012-12-11 03:58:31 -0600

Hello everyone.
I built a bag file that, every time is played, sends messaged to two topics. I start bag playing from keyboard:

rosbag play -r 2 subset.bag

On the other side, there's a simple program receiving messages from both topics and calling right functions in a specified class to manage them according to their nature:

int main(int argc, char **argv){
    stage_listener sl;
    char buffer [1024];
    while(1){
        int i = fscanf(stdin,"%s",buffer);

        if(strcmp("exit",buffer) == 0)
            exit(0);

        else if(strcmp("num_nodes",buffer) == 0){
            printf("\nOdometry nodes: %i\nScan nodes: %i\n",sl.numOdom(),sl.numScan());
            //int b = (*sl).numOdom();
        }

        else if(strcmp("listen",buffer) == 0){
            ROS_INFO("Activating topics listening...\n");
            ros::init(argc,argv, "listener");
            ros::NodeHandle n_odom, n_scan;
            ros::Subscriber sub_odom = n_odom.subscribe("/odom", 1000, &stage_listener::addOdomNode, &sl);
            ros::Subscriber sub_scan = n_scan.subscribe("/base_scan", 1000, &stage_listener::addScanNode, &sl); 

            ros::spin();
            ROS_INFO("Listening activity completed");
        }

        else{
            ROS_INFO("Command not found\n");
        }
    }

}

The receiver stands waiting for messages after executing instruction

ros::spin();

The problem is that receiver doesn't know when all messages have been sent and keeps waiting, without regaining control and proceeding in executing subsequent instructions. I want, after the end of messages in bag file, main() function to regain control and print on screen by instruction

ROS_INFO("Listening activity completed");

Then, a new execution of while(1) must start, in such a way new commands can be inserted from keyboard through instruction

int i = fscanf(stdin,"%s",buffer);

Is there a way to break ros::spin() loop when there are no more messages to be received?

Thanks for help.

edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by SL Remy
close date 2016-09-08 12:37:35.320895

Comments

Can you more fully explain what you're trying to do? At the surface level it sounds like you need service calls if you care about control/sequence..

SL Remy gravatar image SL Remy  ( 2012-12-11 03:30:07 -0600 )edit

i edited file, i hope this will help to explain better my problem

ubisum gravatar image ubisum  ( 2012-12-11 04:01:43 -0600 )edit

If the program is called with "listen" then it subscribes to /odom and /base_scan.. and you'd like it to stop when the data is done?

SL Remy gravatar image SL Remy  ( 2012-12-11 04:12:31 -0600 )edit

yes, exactly

ubisum gravatar image ubisum  ( 2012-12-11 04:24:31 -0600 )edit

3 Answers

Sort by ยป oldest newest most voted
1

answered 2012-12-11 04:19:45 -0600

SL Remy gravatar image

Try using roslaunch. E.g.

<launch>
  <node pkg="rosbag" type="rosbag" name="rosbag" args="play -2 $(find NAME_OF_PACKAGE)/subset.bag" required = "true"/>
  <node pkg="stagelistener" type="stagelistener" name="stagelistener" args="listen"/>
</launch>

Not sure why you need the stdin stuff.. but I'm sure you have a good reason.

edit flag offensive delete link more

Comments

thanks for answer. i never used launch files, since i'm a ros newbie. could you explain to me how xml code states that ros::spin() loop has to be broken once all messages have been sent?

ubisum gravatar image ubisum  ( 2012-12-11 04:27:39 -0600 )edit

The parameter required="true" means that if that node stops (or terminate) then all the other nodes in the launch script also must be stopped. Assuming that the stagelistener code is processing the data as expected, when the rosbag node is done, it should be terminated by roslaunch housekeeping.

SL Remy gravatar image SL Remy  ( 2012-12-11 07:59:02 -0600 )edit
1

answered 2012-12-11 11:18:41 -0600

Bill Smart gravatar image

Another potential solution is to write the second part of your system (the part that takes input from the keyboard) as a separate ROS node that communicates with the original node. Then, you don't have to drop out of the spin(). This doesn't solve the problem of knowing when rosbag is done, though.

One hack that might work is to record a second bag file done.bag with a single message in it on a new topic (let's call it done). Then play the bags back-to-back: rosbag play subset.bag done.bag. When you see the message on the done topic, then you know that the first bag is finished, and that you can start listening for command-line input (using the method in the first part of this answer).

A bit kludgey, but it might work.

edit flag offensive delete link more
1

answered 2012-12-11 03:42:40 -0600

dornhege gravatar image

I'm not aware of such functionality in rosbag specifically.

rosbag quits once it is through, so you could just check if the rosbag node is still running. If one of the topics is only contained in the bagfile, you could also just see if there is a publisher for the topic left and if not, conclude that it has finished.

edit flag offensive delete link more

Question Tools

Stats

Asked: 2012-12-11 03:06:05 -0600

Seen: 1,871 times

Last updated: Dec 11 '12