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

How to publish a dictionary with other dictionary inside in a topic?

asked 2018-11-04 10:02:51 -0600

Ivan_Sanchez gravatar image

Hi all,

I'm trying to publish in a topic a dictionary with other dictionary inside so other ROS node is able to access to that information, but I do not know how can I do it. Anyone has any idea?

Thanks for your help!

edit retag flag offensive close merge delete


Which language are you using?

NEngelhard gravatar image NEngelhard  ( 2018-11-04 11:08:01 -0600 )edit

2 Answers

Sort by ยป oldest newest most voted

answered 2021-07-15 07:14:45 -0600

moooeeeep gravatar image

updated 2021-07-15 07:16:21 -0600

I'm trying to publish in a topic a dictionary with other dictionary inside

As there are no direct dictionaries available in the message format, you have these options:

  • serialize the dictionary (as suggested in the other answer) and write it into a string variable (or uint8[] if it's a binary blob).
  • Flatten the dictionary to non-nested key-value pairs ({"key1": {"key2": {"key3": "value"}}} turns to [("key1.key2.key3": "value")]). Then you can use something like diagnostic_msgs/KeyValue[] to hold your data.
  • If you have one level of nesting, you can create a custom KeyDictValue message, in which you store the KeyValue[] "dictionaries" for each "top level" key.
edit flag offensive delete link more

answered 2018-11-04 12:57:56 -0600

A dictionary is a concept supported by Python but not by C++ or ROS so you cannot add a dictionary directly to a message. However you can use a standard data definition language such as JSON and transport that data using a std_msgs/String message. This would have the advantage of being human readable if you need to debug the messages in transit too.

In python you could pack or unpack the JSON as below:

import json

encoded_data_string = json.dumps({... your dictionary ...})

loaded_dictionary = json.loads(encoded_data_string)

In a C++ node you could use the boost JSON module to read, store and write the data. The example below fills a boost::property tree object with JSON from a file, but could be adapted to read JSON from a std_msgs/String message.

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

// Short alias for this namespace
namespace pt = boost::property_tree;

// Create a root
pt::ptree root;

// Load the json file in this ptree
pt::read_json("filename.json", root);

Hope this helps.

edit flag offensive delete link more


While this solves the question that the OP asks, using string and serialise JSON into it is really not something I would recommend: the msg has no semantics and is opaque to nodes that don't "know" how to interprete the string.

ROS msgs and services are supposed to make up a ROS API, so something that can be used to interface with a (set of) node(s) without any knowledge of the implementation details.

Setting something up like that (ie: the ROS API) takes some effort, and plunking dictionaries into string fields is not something that should be done lightly.

gvdhoorn gravatar image gvdhoorn  ( 2018-11-05 02:12:31 -0600 )edit

Why not create your own ROS msg? In this way you could code the informations as you whish

Kappa95 gravatar image Kappa95  ( 2021-03-08 12:57:58 -0600 )edit

Question Tools

1 follower


Asked: 2018-11-04 10:02:51 -0600

Seen: 7,287 times

Last updated: Jul 15 '21