20 #include "gflags/gflags.h" 21 #include "nav_msgs/Odometry.h" 26 #include "sensor_msgs/Imu.h" 27 #include "sensor_msgs/LaserScan.h" 28 #include "sensor_msgs/MultiEchoLaserScan.h" 29 #include "sensor_msgs/PointCloud2.h" 30 #include "tf2_msgs/TFMessage.h" 36 template <
typename MessagePtrType>
41 stamp += bag_to_current;
46 void PublishWithModifiedTimestamp<tf2_msgs::TFMessage::Ptr>(
49 for (
const auto& transform : message->transforms) {
51 stamp += bag_to_current;
53 publisher.publish(message);
56 int main(
int argc,
char** argv) {
57 google::InitGoogleLogging(argv[0]);
58 google::SetUsageMessage(
60 "This replays and publishes messages from a given bag file, modifying " 61 "their header timestamps to match current ROS time.\n\n" 62 "Messages are published in the same sequence and with the same delay " 64 "Contrary to rosbag play, it does not publish a clock, so time is" 65 "hopefully smoother and it should be possible to reproduce timing" 67 "It only plays message types related to Cartographer.\n");
68 google::ParseCommandLineFlags(&argc, &argv,
true);
69 CHECK(!FLAGS_bag_filename.empty()) <<
"-bag_filename is missing.";
71 ros::init(argc, argv,
"rosbag_publisher");
81 node_handle.
getParam(
"/use_sim_time", use_sim_time);
83 LOG(ERROR) <<
"use_sim_time is true but not supported. Expect conflicting " 84 "ros::Time and message header times or weird behavior.";
86 std::map<std::string, ros::Publisher> topic_to_publisher;
88 const std::string&
topic = c->topic;
89 if (topic_to_publisher.count(topic) == 0) {
91 c->datatype, c->msg_def);
102 ros::Duration after_bag_start = message.getTime() - bag_start;
106 ros::Time planned_publish_time = current_start + after_bag_start;
109 ros::Publisher& publisher = topic_to_publisher.at(message.getTopic());
110 if (message.isType<sensor_msgs::PointCloud2>()) {
112 message.instantiate<sensor_msgs::PointCloud2>(), publisher,
114 }
else if (message.isType<sensor_msgs::MultiEchoLaserScan>()) {
116 message.instantiate<sensor_msgs::MultiEchoLaserScan>(), publisher,
118 }
else if (message.isType<sensor_msgs::LaserScan>()) {
120 message.instantiate<sensor_msgs::LaserScan>(), publisher,
122 }
else if (message.isType<sensor_msgs::Imu>()) {
124 publisher, bag_to_current);
125 }
else if (message.isType<nav_msgs::Odometry>()) {
127 publisher, bag_to_current);
128 }
else if (message.isType<tf2_msgs::TFMessage>()) {
130 publisher, bag_to_current);
132 LOG(WARNING) <<
"Skipping message with type " << message.getDataType();
139 if (std::abs(simulation_delay) > 0.001) {
140 LOG(WARNING) <<
"Playback delayed by " << simulation_delay
141 <<
" s. planned_publish_time: " << planned_publish_time
142 <<
" current_time: " << current_time;
std::vector< const ConnectionInfo *> getConnections()
void open(std::string const &filename, uint32_t mode=bagmode::Read)
static bool sleepUntil(const Time &end)
DEFINE_string(bag_filename, "", "Bag to publish.")
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void publish(const boost::shared_ptr< M > &message) const
void PublishWithModifiedTimestamp(MessagePtrType message, const ros::Publisher &publisher, ros::Duration bag_to_current)
bool getParam(const std::string &key, std::string &s) const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
double ToSeconds(const Duration duration)
::cartographer::common::Time FromRos(const ::ros::Time &time)
ROSCPP_DECL void shutdown()
int main(int argc, char **argv)