ROS Compatibility

Ark supplies a few helper classes and systems for interacting with ROS data. At the moment, the best way to interact with ROS data is to open a ROS bag file (with the ark::ros::BagReader class), iterate through the objects within, and convert those into equivalent Ark types.

The BagReader class will produce BaggedObject structures, which contain the raw bytes of a rosmsg file. Because bag files contain the schemas of the rosgmsg types, we can deserialize them on the fly and you can use the Ark reflection APIs (Object) to access their contents.

Reading Bags

You can programmatically read through bag files with the ark::ros::BagReader API:

#include "ark/ros/rosbag_reader.hh"

ark::ros::BagReader reader("path/to/log.bag");

while (auto object = reader.step())
{
    std::cout << object->topic_name << std::endl;
}

Each BaggedObject structure contains the system time that the object was logged at, the topic name, and the raw bytes. To deserialize data, you must parse the definitions. A convenient helper class exists with ark::ros::RosmsgRegistry. To load the registry with messages from a bag, you can do something like this:

#include "ark/ros/rosmsg_registry.hh"

ark::ros::RosmsgRegistry registry;

for (const auto &topic : reader.topics())
{
    registry.add_type(topic.type, topic.definition);
}

From there, you can deserialize the object (and print it as JSON):

#include "ark/serialization/object.hh"

auto decoded = registry.deserialize(object->type, object->payload);

std::cout << decoded->json().str << std::endl;

Under the hood, this is using an rbuf backend to decode all of the objects, so you can use the same ark::serialization::Object APIs to inspect all of the data.

Tooling

You can use the ark-rosbag-tool command to inspect ROS bag files, list topics, message definitions, and even deserialize the data in the bag files, using the Ark APIs. This can allow you to inspect ROS data without having ROS installed on your local system.

For example, to list the topics:

./build/ark-rosbag-tool ./cartographer_paper_deutsches_museum.bag -l
TYPE                                     TOPIC
sensor_msgs/MultiEchoLaserScan           vertical_laser_2d
sensor_msgs/Imu                          imu
sensor_msgs/MultiEchoLaserScan           horizontal_laser_2d

You can also list the rosmsg definition for a particular topic:

./build/ark-rosbag-tool ./cartographer_paper_deutsches_museum.bag --definition imu
# This is a message to hold data from an IMU (Inertial Measurement Unit)
# ...

Header header

geometry_msgs/Quaternion orientation
float64[9] orientation_covariance # Row major about x, y, z axes

geometry_msgs/Vector3 angular_velocity
float64[9] angular_velocity_covariance # Row major about x, y, z axes

geometry_msgs/Vector3 linear_acceleration
float64[9] linear_acceleration_covariance # Row major x, y z

Finally, you can dump the messages inside the bag file:

./build/ark-rosbag-tool ./cartographer_paper_deutsches_museum.bag -d -t imu
{
  "angular_velocity": {
    "x": 0.010483813472092152,
    "y": -0.004174433648586273,
    "z": 0.0037074105348438038
  },
  "header": {
    "frame_id": "imu_link",
    "seq": 0,
    "stamp": 1432647016483952200
  },
  ...
}

rosmsg Support

There is a rosmsg frontend for rbuf that you can make use of (with some effort), through the ark::ros::RosmsgParser class. This allows you to parse a msg definition (with all of its dependents in the same file) and will produce an ark::serialization::SchemaRegistry object.

From there, you could produce C++ (or JavaScript/Python) code to read in the rosmsg content. If you are just using reflection, it is probably better to just use the ark::ros::RosmsgRegistry class instead (see above).