Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error at line 0, column 0: bad conversion while loading YAML file

Below is the yaml sample file which I have already validated through YAMLint URL but while loading this file with yaml-cpp library function LoadFile, I am getting error:

"Error at line 0, column 0: bad conversion while loading YAML file"

sample yaml file:

%YAML 1.1
---
name: abcd_server_interface
spec_type: interface
spec_version: 1
description: 'Interface for capability ABCD Slam'
default_provider: abcd_server/abcd_server_provider
interface: {}
topics: {
     provides: {

       provide: {
       name: '/3d_pose_graph',
       type: '-',
       description: '-',
       },

       provide: {
       name: '/key_frame_msgs',
       type: '-',
       description: '-'
         }, 

       provide: {
       name: '/pc_map',
       type: 'sensor_msgs/PointCloud2',
       description: 'Point cloud'
         },

       provide: {
       name: '/3dOctomap',
       type: '-',
       description: '-'
         },

       provide: {
       name: '/poseOfRobots',
       type: '-',
       description: '-'
         },

       provide: {
       name: '/occupied_calls_vis_array',
       type: '-',
       description: '-'
         },
     },    
     requires: {

      require: {
       name: '/image_depth_throttled',
       type: 'sensor_msgs/Image',
       description: 'Sensor Image',
       },

       require: {
       name: '/image_color_throttled/compressed',
       type: 'sensor_msgs/CompressedImage',
       description: 'Sensor compressed image',
       },

      require: {
       name: '/statistics',
       type: '-',
       description: '-',
       },

       require: {
       name: '/initialpose',
       type: '-',
       description: '-',
       },

       require: {
       name: '/reset_rgbdserver',
       type: 'std_msgs/Bool',
       description: 'To reset server',
       },

       require: {
       name: '/scan',
       type: 'sensor_msgs/LaserScan',
       description: 'laser scan data',
       },

       require: {
       name: '/tf',
       type: 'tf2_msgs/TFMessage',
       description: 'tf',
       },

       require: {
       name: '/tf_static',
       type: 'tf2_msgs/TFMessage',
       description: 'tf static',
       },      

      }
   }

Parameter: {
       parameter: {
       name: 'max_delay',
       value: '100'
       },

       parameter: {
       name: 'rgb_hints',
       value: 'compressed'
       },

       parameter: {
       name: 'depth_hints',
       value: 'raw'
       },

       parameter: {
       name: 'bot_frame',
       value: '/base_link'
       },

       parameter: {
       name: 'kinect_frame',
       value: '/camera_depth_optical_frame'
       },

       parameter: {
       name: 'minZ',
       value: '-1.0'
       },

       parameter: {
       name: 'maxZ',
       value: '4.0'
       },    
}

Here is the code which I have written to replace param name's (max_delay) value in yaml file in Parameter section.

#include <fstream>
#include <iostream>
#include "yaml-cpp/yaml.h" 

using namespace std;

bool UpdateYAMLFile(const string& sYamlFile, const string& sParamName2Update, const string sValue)
{
    bool bRet = false;
    try
    {        
        //YAML::Node head_ = YAML::LoadFile(sYamlFile);
                YAML::Node head_ = YAML::LoadFile(sYamlFile);

                //YAML::Node head_ = YAML::Load(sYamlFile);
std::cout << head_.size();

                cout<<"ramesh"<<endl;
        for (YAML::iterator ith = head_.begin();ith != head_.end(); ++ith)
        {
            YAML::Node sub1_ = ith->second;
            for (YAML::iterator itc = sub1_.begin();itc != sub1_.end(); ++itc)
            {
                string sParam = itc->second["name"].as<std::string>(); //cout << sParam  << endl;
                if(sParam == sParamName2Update)
                {
                    itc->second["value"] = sValue;
                    bRet = true;
                }
            }
        }       
        ofstream fout(sYamlFile); 
        fout << head_;          //cout << head_ << "\n";
    }
    catch (const YAML::Exception& e)
    {
        cout << "ERROR: Updation of yaml file " << sYamlFile << "Failed: Exception: " << e.what() << "\n";
    }
    return bRet;
}
//driver
int main(int argc, char** argv) 
{

    int bRet = UpdateYAMLFile("sample.yaml", "max_delay","1150");

    if(bRet == true)
        cout << "SUCCESS: YAML file updated..\n";
    else
        cout << "ERROR: YAML file update FAILED...\n";

  return 0;
}

Basically UpdateYAMLFile API will update max_dealy param value in sample yaml file. using this API I should be able to update all the param ( max_delay, rgb_hints, depth_hints, minZ, maxZ) in parameter section of sample yaml file.

Command:

 g++ -std=c++0x yaml.cpp -o res /usr/lib/x86_64-linux-gnu/libyaml-cpp.a
like image 575
user2997518 Avatar asked Feb 05 '26 03:02

user2997518


1 Answers

It looks like you're off by one on your map accesses. Your maps are nested three-deep:

topics: {                      // first key/value pair
     provides: {               // second key/value pair
       provide: {              // third key/value pair
       name: '/3d_pose_graph', // now lookup the name attribute
       type: '-',
       description: '-',
       }
     }
}

You also have a problem with your third map: all of the keys are "provide". This isn't really a map, and it'll be parsed as a single key/value pair (each overwrites the previous). You can make it a list as follows:

topics: {
   provides: [               // this is now a list
     {
       name: '/3d_pose_graph',
       type: '-',
       description: '-',
     }, {
       name: '/key_frame_msgs',
       type: '-',
       description: '-'
     }, ...
   ]
}

Moreover, you don't have to iterate blindly through values of maps without knowing what's in it. Why not just access the keys directly:

for (YAML::Node provides : head_["topics"]["provides"]) {
  if (provides["name"].as<std::string>() == sParamName2Update) {
    provides["name"] = sValue;
  }
}
like image 54
Jesse Beder Avatar answered Feb 06 '26 17:02

Jesse Beder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!