classic_bags
A ROS 2 interface in the style of ROS 1 for reading and writing bag files
README
classic_bags
Simplified ROS 2 interface in the style of ROS 1 for reading and writing bag files
Reading Python
ROS 1 Code
import rosbag
bag = rosbag.Bag('test.bag')
for topic, msg, t in bag.read_messages(topics=['chatter', 'numbers']):
print(msg)
bag.close()
ROS 2 Code
import classic_bags
bag = classic_bags.Bag('test.bag')
for topic, msg, t in bag.read_messages(topics=['chatter', 'numbers']):
print(msg)
# bag.close() Closing bag is not necessary
Writing Python
ROS 1 Code
import rosbag
from std_msgs.msg import Int32, String
bag = rosbag.Bag('test.bag', 'w')
try:
s = String()
s.data = 'foo'
i = Int32()
i.data = 42
bag.write('chatter', s)
bag.write('numbers', i)
finally:
bag.close()
ROS 2 Code
import classic_bags
from std_msgs.msg import Int32, String
bag = classic_bags.Bag('test.bag', 'w')
try:
s = String()
s.data = 'foo'
i = Int32()
i.data = 42
bag.write('chatter', s)
bag.write('numbers', i)
finally:
bag.close() # Closing is not strictly necessary
Alternate ROS 2 Code
import classic_bags
from std_msgs.msg import String
import rclpy.time
import builtin_interfaces.msg
with classic_bags.Bag('test.bag', 'w') as bag:
s = String()
s.data = 'foo'
# The third argument of the write method is the timestamp
# Floats are interpreted as seconds since epoch
bag.write('chatter', s, 456606000.5)
# Ints are interpreted as nanoseconds since epoch
bag.write('chatter', s, 456606000600000000)
# You can also use rclpy.time.Time
pytime = rclpy.time.Time(seconds=456606000, nanoseconds=700000000)
bag.write('chatter', s, pytime)
# Or a timestamp from a message
msgtime = builtin_interfaces.msg.Time()
msgtime.sec = 456606000
msgtime.nanosec = 800000000
bag.write('chatter', s, msgtime)
# If none is specified, the system time will be used
bag.write('chatter', s)
C++ Reading
ROS 1 Code
#include <rosbag/bag.h>
#include <rosbag/view.h>
#include <std_msgs/Int32.h>
#include <std_msgs/String.h>
#include <boost/foreach.hpp>
#define foreach BOOST_FOREACH
rosbag::Bag bag;
bag.open("test.bag", rosbag::bagmode::Read);
std::vector<std::string> topics;
topics.push_back(std::string("chatter"));
topics.push_back(std::string("numbers"));
rosbag::View view(bag, rosbag::TopicQuery(topics));
foreach(rosbag::MessageInstance const m, view)
{
std_msgs::String::ConstPtr s = m.instantiate<std_msgs::String>();
if (s != NULL)
std::cout << s->data << std::endl;
std_msgs::Int32::ConstPtr i = m.instantiate<std_msgs::Int32>();
if (i != NULL)
std::cout << i->data << std::endl;
}
bag.close();
ROS 2 Code
#include <classic_bags/bag.hpp>
#include <std_msgs/msg/string.hpp>
#include <std_msgs/msg/int32.hpp>
classic_bags::Bag bag
bag.open("test.bag", classic_bags::Read);
// Note: Topic filtering and iterator support not available yet
while (bag.hasNext())
{
auto m = bag.next();
std_msgs::msg::String::SharedPtr s = m->instantiate<std_msgs::msg::String>();
if (s != NULL)
std::cout << s->data << std::endl;
std_msgs::msg::Int32::SharedPtr i = m->instantiate<std_msgs::msg::Int32>();
if (i != NULL)
std::cout << i->data << std::endl;
}
bag.close();
C++ Writing
ROS 1 Code
#include <rosbag/bag.h>
#include <std_msgs/Int32.h>
#include <std_msgs/String.h>
rosbag::Bag bag;
bag.open("test.bag", rosbag::bagmode::Write);
std_msgs::String str;
str.data = std::string("foo");
std_msgs::Int32 i;
i.data = 42;
bag.write("chatter", ros::Time::now(), str);
bag.write("numbers", ros::Time::now(), i);
bag.close();
ROS 2 Code
#include <classic_bags/bag.hpp>
#include <std_msgs/msg/string.hpp>
#include <std_msgs/msg/int32.hpp>
classic_bags::Bag bag;
bag.open("test.bag", classic_bags::Write);
std_msgs::msg::String str;
str.data = std::string("foo");
std_msgs::msg::Int32 i;
i.data = 42;
// If not specified, timestamp is assumed to be system time
bag.write("chatter", str);
// Otherwise, timestamp must be rclcpp::Time
bag.write("numbers", rclcpp::Time(456606000600000000), i);
bag.close();