Giter Club home page Giter Club logo

ros_msg_parser's Introduction

Ros Message Parser

This is the successor of ros_type_introspection, just simpler and easier to use.

This C++ library extracts information from a ROS Message, even when its type is unknown at compilation time.

Have you ever wanted to build an app that can subscribe to any topic and extract its content, or can read data from any rosbag? What if the topic and/or the bag contains user defined ROS types ignored at compilation time?

The common solution in the ROS ecosystem is to use Python, that provides the needed introspection. Tools, for instance, like rqt_plot, rqt_bag and rosbridge took this approach. This library implements a C++ alternative.

This library is particularly useful to extract data from two type-erasing classes provided by ROS itself:

  1. topic_tools::ShapeShifter: a type used to subscribe to any topic, regardless of the original type.

  2. rosbag::MessageInstance: the generic type commonly used to read data from a ROS bag.

Examples

Generic Topic Subscriber

void topicCallback(const RosMsgParser::ShapeShifter& msg,
                   const std::string& topic_name,
                   RosMsgParser::ParsersCollection& parsers)
{
  // you must register the topic definition.
  //  Don't worry, it will not be done twice
  parsers.registerParser(topic_name, msg);

  auto deserialized_msg = parsers.deserialize(topic_name, msg);

  // Print the content of the message
  printf("--------- %s ----------\n", topic_name.c_str());
  for (auto it : deserialized_msg->renamed_vals)
  {
    const std::string& key = it.first;
    double value = it.second;
    std::cout << key << " = " << value << std::endl;
  }
  for (auto it : deserialized_msg->flat_msg.name)
  {
    const std::string& key = it.first.toStdString();
    const std::string& value = it.second;
    std::cout << key << " = " << value << std::endl;
  }
}

// usage: pass the name of the topic as command line argument
int main(int argc, char** argv)
{
  RosMsgParser::ParsersCollection parsers;

  if (argc != 2)
  {
    printf("Usage: rosbag_example topic_name\n");
    return 1;
  }
  const std::string topic_name = argv[1];

  ros::init(argc, argv, "universal_subscriber");
  ros::NodeHandle nh;

  // who is afraid of lambdas and boost::functions ?
  boost::function<void(const RosMsgParser::ShapeShifter::ConstPtr&)> callback;
  callback = [&parsers, topic_name](const RosMsgParser::ShapeShifter::ConstPtr& msg) -> void {
    topicCallback(*msg, topic_name, parsers);
  };
  ros::Subscriber subscriber = nh.subscribe(topic_name, 10, callback);

  ros::spin();
  return 0;
}

Generic rosbag reader

#include "ros_msg_parser/ros_parser.hpp"
#include <ros/ros.h>

// usage: pass the name of the file as command line argument
int main(int argc, char** argv)
{
  if (argc != 2)
  {
    printf("Usage: pass the name of a file as first argument\n");
    return 1;
  }

  RosMsgParser::ParsersCollection parsers;

  rosbag::Bag bag;
  try
  {
    bag.open(argv[1]);
  }
  catch (rosbag::BagException& ex)
  {
    printf("rosbag::open thrown an exception: %s\n", ex.what());
    return -1;
  }

  // this  rosbag::View will accept ALL the messages
  rosbag::View bag_view(bag);

  // register (only once at the beginning) the type of messages
  for (const rosbag::ConnectionInfo* connection : bag_view.getConnections())
  {
    const std::string& topic_name = connection->topic;
    parsers.registerParser(topic_name, *connection);
  }

  for (rosbag::MessageInstance msg_instance : bag_view)
  {
    const std::string& topic_name = msg_instance.getTopic();
    const auto deserialized_msg = parsers.deserialize(topic_name, msg_instance);

    // Print the content of the message
    printf("--------- %s ----------\n", topic_name.c_str());
    for (const auto& it : deserialized_msg->renamed_vals)
    {
      const std::string& key = it.first;
      const double value = it.second;
      std::cout << key << " = " << value << std::endl;
    }
    for (const auto& it : deserialized_msg->flat_msg.name)
    {
      const std::string& key = it.first.toStdString();
      const std::string& value = it.second;
      std::cout << key << " = " << value << std::endl;
    }
  }
  return 0;
}

Acknowledgements

This library is inspired by these other libraries matlab_rosbag and cpp_introspection.

You might want to have a look to ros_babel_fish.

ros_msg_parser's People

Contributors

facontidavide avatar efernandez avatar meyerj avatar samkhal avatar levavakian avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.