38 #include "boost/program_options.hpp" 42 namespace po = boost::program_options;
48 po::options_description desc(
"Allowed options");
51 (
"help,h",
"produce help message")
52 (
"all,a",
"record all topics")
53 (
"regex,e",
"match topics using regular expressions")
54 (
"exclude,x", po::value<std::string>(),
"exclude topics matching regular expressions")
55 (
"quiet,q",
"suppress console output")
56 (
"output-prefix,o", po::value<std::string>(),
"prepend PREFIX to beginning of bag name")
57 (
"output-name,O", po::value<std::string>(),
"record bagnamed NAME.bag")
58 (
"buffsize,b", po::value<int>()->
default_value(256),
"Use an internal buffer of SIZE MB (Default: 256)")
59 (
"chunksize", po::value<int>()->default_value(768),
"Set chunk size of message data, in KB (Default: 768. Advanced)")
60 (
"limit,l", po::value<int>()->default_value(0),
"Only record NUM messages on each topic")
61 (
"min-space,L", po::value<std::string>()->default_value(
"1G"),
"Minimum allowed space on recording device (use G,M,k multipliers)")
62 (
"bz2,j",
"use BZ2 compression")
63 (
"lz4",
"use LZ4 compression")
64 (
"split", po::value<int>()->implicit_value(0),
"Split the bag file and continue recording when maximum size or maximum duration reached.")
65 (
"max-splits", po::value<int>(),
"Keep a maximum of N bag files, when reaching the maximum erase the oldest one to keep a constant number of files.")
66 (
"topic", po::value< std::vector<std::string> >(),
"topic to record")
67 (
"size", po::value<uint64_t>(),
"The maximum size of the bag to record in MB.")
68 (
"duration", po::value<std::string>(),
"Record a bag of maximum duration in seconds, unless 'm', or 'h' is appended.")
69 (
"node", po::value<std::string>(),
"Record all topics subscribed to by a specific node.")
70 (
"tcpnodelay",
"Use the TCP_NODELAY transport hint when subscribing to topics.")
71 (
"udp",
"Use the UDP transport hint when subscribing to topics.");
74 po::positional_options_description p;
81 po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
82 }
catch (boost::program_options::invalid_command_line_syntax& e)
85 }
catch (boost::program_options::unknown_option& e)
90 if (vm.count(
"help")) {
91 std::cout << desc << std::endl;
97 if (vm.count(
"regex"))
99 if (vm.count(
"exclude"))
104 if (vm.count(
"quiet"))
106 if (vm.count(
"output-prefix"))
108 opts.
prefix = vm[
"output-prefix"].as<std::string>();
111 if (vm.count(
"output-name"))
113 opts.
prefix = vm[
"output-name"].as<std::string>();
116 if (vm.count(
"split"))
120 int S = vm[
"split"].as<
int>();
123 ROS_WARN(
"Use of \"--split <MAX_SIZE>\" has been deprecated. Please use --split --size <MAX_SIZE> or --split --duration <MAX_DURATION>");
129 if(vm.count(
"max-splits"))
133 ROS_WARN(
"--max-splits is ignored without --split");
140 if (vm.count(
"buffsize"))
142 int m = vm[
"buffsize"].as<
int>();
147 if (vm.count(
"chunksize"))
149 int chnk_sz = vm[
"chunksize"].as<
int>();
154 if (vm.count(
"limit"))
156 opts.
limit = vm[
"limit"].as<
int>();
158 if (vm.count(
"min-space"))
160 std::string ms = vm[
"min-space"].as<std::string>();
161 long long int value = 1073741824ull;
166 if (sscanf(ms.c_str(),
" %lld%c", &value, &mul) > 0) {
188 if (vm.count(
"bz2") && vm.count(
"lz4"))
200 if (vm.count(
"duration"))
202 std::string duration_str = vm[
"duration"].as<std::string>();
205 double multiplier = 1.0;
206 std::string unit(
"");
208 std::istringstream iss(duration_str);
209 if ((iss >> duration).fail())
210 throw ros::Exception(
"Duration must start with a floating point number.");
212 if ( (!iss.eof() && ((iss >> unit).fail())) )
216 if (unit == std::string(
""))
218 else if (unit == std::string(
"s"))
220 else if (unit == std::string(
"m"))
222 else if (unit == std::string(
"h"))
232 if (vm.count(
"size"))
234 opts.
max_size = vm[
"size"].as<uint64_t>() * 1048576;
238 if (vm.count(
"node"))
240 opts.
node = vm[
"node"].as<std::string>();
241 std::cout <<
"Recording from: " << opts.
node << std::endl;
243 if (vm.count(
"tcpnodelay"))
253 if (vm.count(
"topic"))
255 std::vector<std::string> bags = vm[
"topic"].as< std::vector<std::string> >();
256 std::sort(bags.begin(), bags.end());
257 bags.erase(std::unique(bags.begin(), bags.end()), bags.end());
258 for (std::vector<std::string>::iterator i = bags.begin();
261 opts.
topics.push_back(*i);
268 fprintf(stderr,
"Warning: Exclusion regex given, but no topics to subscribe to.\n" 269 "Adding implicit 'record all'.");
276 int main(
int argc,
char** argv) {
285 ROS_ERROR(
"Error reading options: %s", ex.what());
288 catch(boost::regex_error
const& ex) {
289 ROS_ERROR(
"Error reading options: %s\n", ex.what());
295 int result = recorder.
run();
ros::TransportHints transport_hints
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
boost::regex exclude_regex
ros::Duration max_duration
TransportHints & tcpNoDelay(bool nodelay=true)
rosbag::RecorderOptions parseOptions(int argc, char **argv)
Parse the command-line arguments for recorder options.
unsigned long long min_space
int main(int argc, char **argv)
CompressionType compression
std::vector< std::string > topics
std::string min_space_str