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

read yaml parameter in C++

asked 2014-11-25 13:04:25 -0500

courrier gravatar image

updated 2014-11-26 06:06:36 -0500

Hi all,

I'm experiencing an issue in using the parameter server:

1) I start a roscore so that I get only one master on this machine. 2) I set a global param manually, say:

rosparam set /test/m '{"id0": 0, "id1": 1}'

3) I start one of my launchfile whose short version is:

    <node pkg="mypckg" name="mynode" type="mynode" output="screen"/>

I get:

roslaunch mypckg mylaunch.launch
... logging to /home/flowers/.ros/log/08d803da-74d2-11e4-9a51-a01d480daef0/roslaunch-zbook-4127.log
Checking log directory for disk usage. This may take awhile.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://zbook:55760/


 * /rosdistro
 * /rosversion

4) In the code of "mynode" I read this param:

                string m;
                if(!nh.getParam("/test/map", m))
                    ROS_ERROR("Failed to read 'map' on param server");

5) The above error is triggered, while rosparam get /thr/before still returns an existing value. It looks like I'm not reading params in the same namespace but I'm reading global parameters so I don't understand...

What are the PARAMETERS listed in the SUMMARY? Only parameters defined in the launch file or all available parameters on the server?

What am I missing? Thanks

edit retag flag offensive close merge delete



What is the output of rosparam list? You can try that at various points to see what the parameters are or how they're changing (using rosparam get)...

kramer gravatar image kramer  ( 2014-11-25 15:08:27 -0500 )edit

2 Answers

Sort by ยป oldest newest most voted

answered 2014-11-26 06:11:01 -0500

courrier gravatar image

updated 2014-11-26 06:15:17 -0500

I've modified my question to match the real problem and answer to it. Reading a yamlis quite heavy in C++, here's a way to read a map of arrays for instance:

                XmlRpc::XmlRpcValue symbols;

                if(!ros::param::get("/thr/symbols", symbols))
                    ROS_ERROR("Failed to read symbols on param server");

                for (XmlRpc::XmlRpcValue::iterator i=symbols.begin(); i!=symbols.end(); ++i) {
                    for(int j=0; j<i->second.size(); ++j) {

With YAML being:

object0: [0.1280805148444952, -0.2574350304851667]
table: [-0.019239830108468144]
object1: [-0.12373553201812965, -0.2581443366277866, 0.12297468008504482, 0.0405834453536516, 0.9474896873206372, -0.026972527372781926]
arm: [0.9303491449393159]
eye: [0.12397546355498722 -0.37202872219628474]

Sorry for editing 1000 times :)

edit flag offensive delete link more



Mmm, yaml-cpp makes yaml in C++ soooo much easier and less ugly!

Lorenzo Riano gravatar image Lorenzo Riano  ( 2014-11-26 12:11:30 -0500 )edit

Would it be really easier? This is not longer than the minimal code to iterate on two nested datastructures... the assert are for safety but obviously optional

courrier gravatar image courrier  ( 2014-11-26 12:40:50 -0500 )edit

That code looks terrible.

Tommi gravatar image Tommi  ( 2015-09-07 00:27:24 -0500 )edit

yaml-cpp is nice, but they've made horrible things with their versioning, so now we have ROS packages depending on 0.3, while other packages depend on 0.5, which can't be easily installed alongside... this is hell... guys from ETH tried to make it easier:

peci1 gravatar image peci1  ( 2017-05-26 08:31:58 -0500 )edit

answered 2014-11-25 14:32:34 -0500

updated 2014-11-26 16:42:45 -0500

How did you create nh in your code? If you declare it with

   ros:: NodeHandle nh("~")

then it'll be in the private namespace of your node. Honestly that's the only source of this problem that I can think of. Also make sure you're spelling the names correctly :)

To test the namespaces, you can use the NodeHandle method resolveName (see ).


Editing since the original question changed. I tried the following:

>> rosparam set /test/m '{"id0":0, "id1":1}'    
>> rosparam get /          
      m: {id0: 0, id1: 1}
>> rosparam get /test/m
     {id0: 0, id1: 1}
>> rosparam get /test/m/id0
>> rosparam get /test/m/id1

This is explained in , and it basically means that when you give a YAML string to rosparam set, it gets converted in a dictionary of parameters. You can see this behaviour if you do:

>> rosparam set -v /test/m '{"id0":0, "id1":1}'
set parameter [/test/m/id0] to [0]
set parameter [/test/m/id1] to [1]

Therefore the parameter you are looking for in your code (/test//m) doesn't exist as a string, but it's a dictionary! If you want to set a parameter to a string representing a YAML line, you can do something like:

>> rosparam set -v /test/m "\"{'id0':0, 'id1':1}\""
set parameter [/test/m] to [{'id0':0, 'id1':1}]

Even though it looks ugly :)

edit flag offensive delete link more


Yes I see. Well actually this is very useful to be able to read this as a dictionary. In my case I intended to ive the string to yaml-cpp so using the xml-rpc datastructures is also good, though heavy (as any C++ code :)

courrier gravatar image courrier  ( 2014-11-26 12:38:22 -0500 )edit

Question Tools



Asked: 2014-11-25 13:04:25 -0500

Seen: 13,792 times

Last updated: Nov 26 '14