ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
3

Read or write message from/to file

asked 2011-09-22 23:08:59 -0500

Stephan gravatar image

updated 2014-01-28 17:10:25 -0500

ngrennan gravatar image

What is the easiest way to load/write a message from/to a file in C++? I want something like this:

void loadMessage(const std::string& filename, std_msgs::Image& image_msg)
{
    // open file and put it's content in img_msg
}
void saveMessage(std_msgs::Image& image_msg, const std::string& filename)
{
    // put message content in file
}

The file has YAML format, for example created by

rostopic pub -1 /image std_msgs/Image > file
edit retag flag offensive close merge delete

Comments

Is there some reason not to use `rosbag`? That is the normal ROS technique; it can be done with standard commands.
joq gravatar image joq  ( 2011-09-23 02:20:18 -0500 )edit
Do you mean that you want the output file to be in YAML format?
Mac gravatar image Mac  ( 2011-09-23 02:20:38 -0500 )edit
lucasw gravatar image lucasw  ( 2016-02-08 14:00:06 -0500 )edit

3 Answers

Sort by » oldest newest most voted
5

answered 2011-09-23 02:45:55 -0500

Lorenz gravatar image

updated 2011-09-23 02:46:42 -0500

The best way I see is to use rosbag. You can easily record messages from the command line by just executing

rosbag /topic1 /topic2

Rosbag also provides a C++ and a Python API for writing and reading streams of messages from your programs. Have a look at this page for more information on the API.

edit flag offensive delete link more
3

answered 2014-02-12 21:30:23 -0500

Markus Bader gravatar image

updated 2014-02-12 21:30:50 -0500

Hi

you can dump the message into a binary buffer. Attached you can see how I did it with a sensor_msgs::LaserScan.

void LaserLineFilterNode::callback (const sensor_msgs::LaserScan::ConstPtr& _msg) {

    {
        // Write to File
        std::ofstream ofs("/tmp/filename.txt", std::ios::out|std::ios::binary);

        uint32_t serial_size = ros::serialization::serializationLength(*_msg);
        boost::shared_array<uint8_t> obuffer(new uint8_t[serial_size]);

        ros::serialization::OStream ostream(obuffer.get(), serial_size);
        ros::serialization::serialize(ostream, *_msg);
        ofs.write((char*) obuffer.get(), serial_size);
        ofs.close();
    }
    {
        // Read from File to msg_scan_
        //sensor_msgs::LaserScan msg_scan_ --> is a class variable
        std::ifstream ifs("/tmp/filename.txt", std::ios::in|std::ios::binary);
        ifs.seekg (0, std::ios::end);
        std::streampos end = ifs.tellg();
        ifs.seekg (0, std::ios::beg);
        std::streampos begin = ifs.tellg();

        uint32_t file_size = end-begin;
        boost::shared_array<uint8_t> ibuffer(new uint8_t[file_size]);
        ifs.read((char*) ibuffer.get(), file_size);
        ros::serialization::IStream istream(ibuffer.get(), file_size);
        ros::serialization::deserialize(istream, msg_scan_);
        ifs.close();
    }
    ....

More details on http://wiki.ros.org/roscpp/Overview/M...

But I there is still an issue, I had to create a memory buffer fist, it would be nice to see how one can create a ros::serialization::OStream to stream directly into a file.

Hmm... I will post a separate question for that :-)

Greetings Markus

edit flag offensive delete link more

Comments

so did you find how to serialize directly to a file?

brice rebsamen gravatar image brice rebsamen  ( 2014-05-20 15:04:20 -0500 )edit

The ros bag C++ API provides this functionality. see here

Danfoa gravatar image Danfoa  ( 2019-05-24 02:01:38 -0500 )edit
0

answered 2011-09-23 02:11:31 -0500

DimitriProsser gravatar image

If the file is a yaml file, you could try using a yaml parser/emitter for C++. One example would be yaml-cpp. I believe that this is the library used as the backend for rosdep as well.

edit flag offensive delete link more

Question Tools

Stats

Asked: 2011-09-22 23:08:59 -0500

Seen: 11,027 times

Last updated: Feb 12 '14