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

extract double values with XmlRpc::XmlRpcValue from yaml file

asked 2020-04-19 14:37:59 -0500

zFnq9 gravatar image

updated 2020-04-20 02:38:17 -0500

Hi,

I want to extract some lists with double values.

Because it is a nested array, it is not readable with NodeHandle getParam?

ros::NodeHandle nh;
XmlRpc::XmlRpcValue box;
nh.getParam("test/values", box);

if(box.getType() == XmlRpc::XmlRpcValue::Type::TypeArray && box.size() > 0 )){
    if(box[0].getType() == XmlRpc::XmlRpcValue::Type::TypeArray && box[0].size() > 0){
        for(int i = 0; i < box[0].size(); i++) {
                  ROS_INFO("value %f ",box[0][i]);
        }
    }}

yaml file:

test: 
  values: 
  - [  0.0,  0.1,  0.2]
  - [  0.0,   -0.1,  -0.2]

At this point, how can I get the double value?

Error message:

warning: format ‘%f’ expects argument of type ‘double’, but argument 8 has type ‘XmlRpc::XmlRpcValue’ [-Wformat=]

box[0][i].getDoubleFormat() returned %.16g, so it should be correct.

But an assert failed with

ROS_ASSERT(box[0][i].getType() == XmlRpc::XmlRpcValue::TypeDouble);
edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted
2

answered 2020-04-20 03:34:02 -0500

The first thing that you need is to change the way you wrote the YAML file.

 test: 
  values0: [  0.0,  0.1,  0.2]
  values1: [  0.0,   -0.1,  -0.2]

To something like that, each array has a name.

1| ros::NodeHandle node;
 |
2| std::vector<double> vectorVar;
3| node.getParam("test/values0", vectorVar);

And for each array, you must repeat step 2 and 3, or create a vector of a vector.

Let me aware if it is working, I tried this solution here before, but we never know.

edit flag offensive delete link more

Comments

Thanks! With this method, do I need each name for getParam ("values0", "values1, ...") ? It should handle different length.

zFnq9 gravatar image zFnq9  ( 2020-04-20 05:56:33 -0500 )edit

Yes. however, the syntax isn't exactly this one. Should be this one: node.getParam(PARAM_NAME, VARIABLE)

So if you have more than one array in the YAML file. You should do something like this:

node.getParam("test/value0", value0Vector);
node.getParam("test/value1", value1Vector);
node.getParam("test/value2", value2Vector);

But you always can use loop statements to make this smart.

std::vector<std::vector<double>> vectorVar
for(int index = 0; ros::param::has("test/values" + std::to_string(index)); index++) {
    std::vector<double> tempVector;
    node.getParam("test/values" + std::to_string(index), tempVector);    
    vectorVar.push_back(tempVector);
}

Instead of using a tempVector you could resize your vector ( if the number of elements is known) and use vectorVar.at(index)

And there aren't problems arrays have a different number of elements.

Teo Cardoso gravatar image Teo Cardoso  ( 2020-04-20 14:14:55 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2020-04-19 14:20:41 -0500

Seen: 962 times

Last updated: Apr 20 '20