0

I'm trying to open and read a .conf file in my program using libconfig::readFile(), but it gives me always a FileIOException. I think that the program is unable to locate the file but I don't know where the problem is.

This is the .conf file code:

controlLoopPeriod = 100.0;  # ms

saturationMax = [10.0];
saturationMin = [-10.0];


task = {  Linear_Velocity = {
          type = 0;   # 0 equality, 1 inequality
          gain = 1.0;
          enable = true;
          saturation = 10.0; 
          };
        };


priorityLevels = ( { name = "PL_JPosition";
                     tasks = ["Joint_Position"];
                     lambda = 0.0001;
                     threshold = 0.01; 
                    } 
                  );


actions = ( { name = "jPosition";
              levels = ["PL_JPosition"]; 
            } 
          );


states = {  State_move = {
            minHeadingError = 0.05;
            maxHeadingError = 0.2; 
            };
          };

This is where I'm trying to open the file and read it:

bool RobotPositionController::LoadConfiguration() { 
        libconfig::Config confObj;

        // Inizialization
        std::string confPath = "home/nimblbot/tpik_ctr_algo/ctrl_rob_nimblbot";
        confPath.append("/conf/");
        confPath.append(fileName_);

        std::cout << "PATH TO CONF FILE : " << confPath << std::endl;

        // Read the file. If there is an error, report it and exit.
        try {
            confObj.readFile(confPath.c_str());
        } catch (const libconfig::FileIOException& fioex) {
            std::cerr << "I/O error while reading file: " << fioex.what() << std::endl;
            return -1;
        } catch (const libconfig::ParseException& pex) {
            std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine() << " - " << pex.getError() << std::endl;
            return -1;
        }

        conf_->ConfigureFromFile(confObj);

        ConfigureTaskFromFile(tasksMap_, confObj);
        ConfigurePriorityLevelsFromFile(actionManager_, tasksMap_, confObj);

        // Set Saturation values for the iCAT (read from conf file)
        iCat_->SetSaturation(conf_->saturationMin, conf_->saturationMax);

        ConfigureActionsFromFile(actionManager_, confObj);

        //insert states in the map
        statesMap_.insert({ states::ID::jPos, stateJPosition_ });
        
        ConfigureSatesFromFile(statesMap_, confObj);

        //insert command in the map
        commandsMap_.insert({ commands::ID::jPos, commandJPosition_ });
        
        return true;
    }

Thanks in advance for any type of help.

stark
  • 12,615
  • 3
  • 33
  • 50

1 Answers1

0

It looks to me you are missing a / at the beginning of your home path.

I.e., change:

std::string confPath = "home/nimblbot/tpik_ctr_algo/ctrl_rob_nimblbot";

For:

std::string confPath = "/home/nimblbot/tpik_ctr_algo/ctrl_rob_nimblbot";

I take it you have checked the .conf file exists at:

/home/nimblbot/tpik_ctr_algo/ctrl_rob_nimblbot/conf
rturrado
  • 7,699
  • 6
  • 42
  • 62
  • I've already tried with `/home/nimblbot/tpik_ctr_algo/ctrl_rob_nimblbot/conf` but it said me that there was a syntax error in the chosen path. – Angelica Ginnante Jul 14 '20 at 08:52
  • It gives me `I/O error while reading file: FileIOException` and `Aborted (core dumped)`. Instead, if I write `/home/nimblbot/tpik_ctr_algo/ctrl_rob_nimblbot/conf`, the error is `Segmentation fault (core dumped)` – Angelica Ginnante Jul 14 '20 at 12:12
  • Good. Definitely, you need the `/` at the beginning of the path. If you read your program, the `I/O error while reading file` happens because the path to your config file is wrong. You should deal with the `return -1` at the caller, so you avoid that `Aborted`; probably you are carrying on like if everything went well, and you try to access an object that you expect it exists but wasn't created, and your program ends up segfaulting. Anyway, you have now to use the `/home...` path and check why your program still segfaults. Any chance to debug it? – rturrado Jul 14 '20 at 12:46
  • Thanks you were right, the problem was in another part of the code. Can I ask you if you can suggest me a function to find the correct path and avoid writing the whole path `/home/nimblbot/tpik_ctr_algo/ctrl_rob_nimblbot/conf`? – Angelica Ginnante Jul 14 '20 at 14:01
  • Do you want to pass the name of a config file as a parameter to your program and let your program find it under a given folder? If so, have a look at this post: https://stackoverflow.com/a/612176/260313. – rturrado Jul 14 '20 at 14:52
  • Anyway, I would first have a thought at how you want your program to be used. Where will the binary live? E.g. at `/home/nimblbot/tpik_ctr_algo/ctrl_rob_nimblbot/`. Will there be a single config file or more? Will the config file always be under `conf` folder? Will the config file always be called the same or do you want to parameterize the config file name? – rturrado Jul 14 '20 at 15:01
  • A possible solution would be to implement a function receiving the config file name that would 1) get the binary folder (https://stackoverflow.com/q/1528298/260313), e.g. `/home/nimblbot/tpik_ctr_algo/ctrl_rob_nimblbot/`, 2) build the config file folder from that binary folder, e.g. `binFolder + "/conf"`, and, 3) search for a given config file name (see the post in the previous comment) under the config file folder to build the final config file path. – rturrado Jul 14 '20 at 15:11