00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "rosbag/player.h"
00036 #include "boost/program_options.hpp"
00037
00038 namespace po = boost::program_options;
00039
00040 rosbag::PlayerOptions parseOptions(int argc, char** argv) {
00041 rosbag::PlayerOptions opts;
00042
00043 po::options_description desc("Allowed options");
00044
00045 desc.add_options()
00046 ("help,h", "produce help message")
00047 ("prefix,p", po::value<std::string>()->default_value(""), "prefixes all output topics in replay")
00048 ("quiet,q", "suppress console output")
00049 ("immediate,i", "play back all messages without waiting")
00050 ("pause", "start in paused mode")
00051 ("queue", po::value<int>()->default_value(100), "use an outgoing queue of size SIZE")
00052 ("clock", "publish the clock time")
00053 ("hz", po::value<float>()->default_value(100.0f), "use a frequency of HZ when publishing clock time")
00054 ("delay,d", po::value<float>()->default_value(0.2f), "sleep SEC seconds after every advertise call (to allow subscribers to connect)")
00055 ("rate,r", po::value<float>()->default_value(1.0f), "multiply the publish rate by FACTOR")
00056 ("start,s", po::value<float>()->default_value(0.0f), "start SEC seconds into the bag files")
00057 ("duration,u", po::value<float>(), "play only SEC seconds from the bag files")
00058 ("skip-empty", po::value<float>(), "skip regions in the bag with no messages for more than SEC seconds")
00059 ("loop,l", "loop playback")
00060 ("keep-alive,k", "keep alive past end of bag (useful for publishing latched topics)")
00061 ("try-future-version", "still try to open a bag file, even if the version is not known to the player")
00062 ("topics", po::value< std::vector<std::string> >()->multitoken(), "topics to play back")
00063 ("pause-topics", po::value< std::vector<std::string> >()->multitoken(), "topics to pause playback on")
00064 ("bags", po::value< std::vector<std::string> >(), "bag files to play back from");
00065
00066 po::positional_options_description p;
00067 p.add("bags", -1);
00068
00069 po::variables_map vm;
00070
00071 try
00072 {
00073 po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
00074 } catch (boost::program_options::invalid_command_line_syntax& e)
00075 {
00076 throw ros::Exception(e.what());
00077 } catch (boost::program_options::unknown_option& e)
00078 {
00079 throw ros::Exception(e.what());
00080 }
00081
00082 if (vm.count("help")) {
00083 std::cout << desc << std::endl;
00084 exit(0);
00085 }
00086
00087 if (vm.count("prefix"))
00088 opts.prefix = vm["prefix"].as<std::string>();
00089 if (vm.count("quiet"))
00090 opts.quiet = true;
00091 if (vm.count("immediate"))
00092 opts.at_once = true;
00093 if (vm.count("pause"))
00094 opts.start_paused = true;
00095 if (vm.count("queue"))
00096 opts.queue_size = vm["queue"].as<int>();
00097 if (vm.count("hz"))
00098 opts.bag_time_frequency = vm["hz"].as<float>();
00099 if (vm.count("clock"))
00100 opts.bag_time = true;
00101 if (vm.count("delay"))
00102 opts.advertise_sleep = ros::WallDuration(vm["delay"].as<float>());
00103 if (vm.count("rate"))
00104 opts.time_scale = vm["rate"].as<float>();
00105 if (vm.count("start"))
00106 {
00107 opts.time = vm["start"].as<float>();
00108 opts.has_time = true;
00109 }
00110 if (vm.count("duration"))
00111 {
00112 opts.duration = vm["duration"].as<float>();
00113 opts.has_duration = true;
00114 }
00115 if (vm.count("skip-empty"))
00116 opts.skip_empty = ros::Duration(vm["skip-empty"].as<float>());
00117 if (vm.count("loop"))
00118 opts.loop = true;
00119 if (vm.count("keep-alive"))
00120 opts.keep_alive = true;
00121
00122 if (vm.count("topics"))
00123 {
00124 std::vector<std::string> topics = vm["topics"].as< std::vector<std::string> >();
00125 for (std::vector<std::string>::iterator i = topics.begin();
00126 i != topics.end();
00127 i++)
00128 opts.topics.push_back(*i);
00129 }
00130
00131 if (vm.count("pause-topics"))
00132 {
00133 std::vector<std::string> pause_topics = vm["pause-topics"].as< std::vector<std::string> >();
00134 for (std::vector<std::string>::iterator i = pause_topics.begin();
00135 i != pause_topics.end();
00136 i++)
00137 opts.pause_topics.push_back(*i);
00138 }
00139
00140 if (vm.count("bags"))
00141 {
00142 std::vector<std::string> bags = vm["bags"].as< std::vector<std::string> >();
00143 for (std::vector<std::string>::iterator i = bags.begin();
00144 i != bags.end();
00145 i++)
00146 opts.bags.push_back(*i);
00147 } else {
00148 if (vm.count("topics") || vm.count("pause-topics"))
00149 throw ros::Exception("When using --topics or --pause-topics, --bags "
00150 "should be specified to list bags.");
00151 throw ros::Exception("You must specify at least one bag to play back.");
00152 }
00153
00154 return opts;
00155 }
00156
00157 int main(int argc, char** argv) {
00158 ros::init(argc, argv, "play", ros::init_options::AnonymousName);
00159
00160
00161 rosbag::PlayerOptions opts;
00162 try {
00163 opts = parseOptions(argc, argv);
00164 }
00165 catch (ros::Exception const& ex) {
00166 ROS_ERROR("Error reading options: %s", ex.what());
00167 return 1;
00168 }
00169
00170 rosbag::Player player(opts);
00171
00172 try {
00173 player.publish();
00174 }
00175 catch (std::runtime_error& e) {
00176 ROS_FATAL("%s", e.what());
00177 return 1;
00178 }
00179
00180 return 0;
00181 }