38 #include <boost/program_options.hpp> 43 namespace po = boost::program_options;
58 int cleaned_argc = cleaned_args.size();
59 char const* cleaned_argv[cleaned_argc];
60 for (
int i = 0; i < cleaned_argc; ++i)
61 cleaned_argv[i] = cleaned_args[i].c_str();
63 po::options_description desc(
"Options");
66 (
"help,h",
"produce help message")
67 (
"trigger-write,t",
"Write buffer of selected topcis to a bag file")
68 (
"pause,p",
"Stop buffering new messages until resumed or write is triggered")
69 (
"resume,r",
"Resume buffering new messages, writing over older messages as needed")
70 (
"all,a",
"Record all topics")
71 (
"size,s", po::value<double>()->default_value(-1),
72 "Maximum memory per topic to use in buffering in MB. Default: no limit")
73 (
"duration,d", po::value<double>()->default_value(30.0),
74 "Maximum difference between newest and oldest buffered message per topic in seconds. Default: 30")
75 (
"output-prefix,o", po::value<std::string>()->default_value(
""),
76 "When in trigger write mode, prepend PREFIX to name of writting bag file")
77 (
"output-filename,O", po::value<std::string>(),
"When in trigger write mode, exact name of written bag file")
78 (
"topic", po::value<std::vector<std::string> >(),
79 "Topic to buffer. If triggering write, write only these topics instead of all buffered topics.");
81 po::positional_options_description p;
86 po::store(po::command_line_parser(cleaned_argc, cleaned_argv).options(desc).positional(p).run(), vm);
89 catch (boost::program_options::error
const& e)
91 std::cout <<
"rosbag_snapshot: " << e.what() << std::endl;
97 std::cout <<
"Usage: rosrun rosbag_snapshot snapshot [options] [topic1 topic2 ...]" << std::endl
99 <<
"Buffer recent messages until triggered to write or trigger an already running instance." << std::endl
101 std::cout << desc << std::endl;
109 if (vm.count(
"topic"))
111 std::vector<std::string> topics = vm[
"topic"].as<std::vector<std::string> >();
112 for (
const std::string& str : topics)
125 if (vm.count(
"pause"))
126 opts.
action_ = SnapshotterClientOptions::PAUSE;
127 else if (vm.count(
"resume"))
128 opts.
action_ = SnapshotterClientOptions::RESUME;
129 else if (vm.count(
"trigger-write"))
131 opts.
action_ = SnapshotterClientOptions::TRIGGER_WRITE;
132 if (vm.count(
"topic"))
133 opts.
topics_ = vm[
"topic"].as<std::vector<std::string> >();
134 if (vm.count(
"output-prefix"))
135 opts.
prefix_ = vm[
"output-prefix"].as<std::string>();
136 if (vm.count(
"output-filename"))
137 opts.
filename_ = vm[
"output-filename"].as<std::string>();
153 if (nh.
getParam(
"default_memory_limit", tmp))
155 if (nh.
getParam(
"default_duration_limit", tmp))
163 ROS_ASSERT_MSG(topics.getType() == XmlRpcValue::TypeArray,
"topics param must be an array");
165 size_t size = topics.size();
166 for (
size_t i = 0; i < size; ++i)
168 XmlRpcValue topic_value = topics[i];
170 if (topic_value.getType() == XmlRpcValue::TypeString)
174 else if (topic_value.getType() == XmlRpcValue::TypeStruct)
176 ROS_ASSERT_MSG(topic_value.size() == 1,
"Paramater invalid for topic %lu", i);
177 std::string
const& topic = (*topic_value.begin()).first;
178 XmlRpcValue& topic_config = (*topic_value.begin()).second;
179 ROS_ASSERT_MSG(topic_config.getType() == XmlRpcValue::TypeStruct,
"Topic limits invalid for: '%s'",
182 ros::Duration dur = SnapshotterTopicOptions::INHERIT_DURATION_LIMIT;
183 int64_t mem = SnapshotterTopicOptions::INHERIT_MEMORY_LIMIT;
184 std::string duration =
"duration";
185 std::string memory =
"memory";
186 if (topic_config.hasMember(duration))
188 XmlRpcValue& dur_limit = topic_config[duration];
189 if (dur_limit.getType() == XmlRpcValue::TypeDouble)
191 double seconds = dur_limit;
194 else if (dur_limit.getType() == XmlRpcValue::TypeInt)
196 int seconds = dur_limit;
202 if (topic_config.hasMember(
"memory"))
204 XmlRpcValue& mem_limit = topic_config[memory];
205 if (mem_limit.getType() == XmlRpcValue::TypeDouble)
207 double mb = mem_limit;
210 else if (mem_limit.getType() == XmlRpcValue::TypeInt)
225 int main(
int argc,
char** argv)
227 po::variables_map vm;
232 if (vm.count(
"trigger-write") || vm.count(
"pause") || vm.count(
"resume"))
239 return client.
run(opts);
255 ROS_FATAL(
"No topics selected. Exiting.");
261 return snapshotter.
run();
int32_t default_memory_limit_
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void appendParamOptions(ros::NodeHandle &nh, SnapshotterOptions &opts)
bool parseVariablesMapClient(SnapshotterClientOptions &opts, po::variables_map const &vm)
bool parseOptions(po::variables_map &vm, int argc, char **argv)
bool addTopic(std::string const &topic, ros::Duration duration_limit=SnapshotterTopicOptions::INHERIT_DURATION_LIMIT, int32_t memory_limit=SnapshotterTopicOptions::INHERIT_MEMORY_LIMIT)
int main(int argc, char **argv)
std::vector< std::string > V_string
std::vector< std::string > topics_
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
#define ROS_ASSERT_MSG(cond,...)
ros::Duration default_duration_limit_
bool parseVariablesMap(SnapshotterOptions &opts, po::variables_map const &vm)
bool getParam(const std::string &key, std::string &s) const
ROSCPP_DECL void removeROSArgs(int argc, const char *const *argv, V_string &args_out)
class ROSBAG_DECL Snapshotter
int run(SnapshotterClientOptions const &opts)