sequenceplanner/r2r

Public `from_serialized_bytes` and Untyped support

tfoldi opened this issue · 4 comments

I am working on a project where I am reading data with the mcap rust library. In short, I get the messages' schema as string and data as u8[], and I need to convert it to some generic data types (or JSON). Ideally

Ideally, I could use the from_serailized_bytes function from msg_types but that module is private and the function is not accessible from outside. The same goes for the Untyped traits which I believe would be helpful to deserialize messages with known but not hard coded schema names.

So my questions are:

  • What do you suggest, what would be the best approach for my use case?
  • If it requires to make a few of the libraries functions/traits public, would you open to do that?

Thanks!

Hi,

If you know what you need I am open to exposing more functionality. I am not 100% clear on your usecase though. What will you do with the data eventually? Since you are using r2r I assume that eventually you want to publish some data as ros messages? If so I think the untyped set of functions would work, populate a serde_json::Object given the schema you have and publish the data that way. But the message type must exist and be built on the ros side for this to work, so you cannot for example create a bridge that supports an artibrary schema on the fly.

Thank you for your answer, let me add a quick clarification:

  • I have a few mcap files (ros bags) stored on file system
  • I want to make the data available for post processing (running ML models, etc.). Think about reshaping the messages in the rosbag to align multiple camera images to the same frequency/timestamps, experimenting with different model parameters, etc. on the collected data.
  • I want to execute this post processing inside the ROS2 environment (libraries can be/will be preloaded/linked), but not as a node. To do this, I need the from_serialized_bytes function to be available. See the code below:
    for message in mcap::MessageStream::new(&mapped)? {
        let message = message?;

        let schema_name = message
            .channel
            .schema
            .as_ref()
            .map(|schema| schema.name.as_str())
            .unwrap_or_default();

        if schema_name == "sensor_msgs/msg/Imu" {
            // message.data is [u8] 
            let data = from_serialized_bytes::<sensor_msgs::msg::Imu>(&message.data)?;
        }
    }

Now my challenge is that the from_serialized_bytes is not publicly available. Making it public will unlock this use case.

In addition to this, it would be great to access data from messages without hardcoding schema types, just by type names. As you mentioned, the messages must be defined at compilation time (which is ok). Imagine something like:

        let native =
            WrappedNativeMsgUntyped::new_from("sensor_msgs/msg/Imu").unwrap();
        native.from_serialized_bytes(&message.data).unwrap();

It will help me to create tools like topic_tools where I can cat the contents of files, downsample, etc. without hardcode each and every type. If you can help point me to the right direction I can try to implement myself.

Hope this makes a bit more sense.

Yes now I understand better, thanks. I agree that it would be nice to have. I just pushed a quick fix (d5f2ef0) that should enable your usecase. Let me know if it works.

This was quick! Thank you, I will a give a try but based on the example it is exactly what I needed.

Thanks again!