YARP
Yet Another Robot Platform
The ResourceFinder Class (basic)

Table of Contents

This tutorial shows how to use the yarp::os::ResourceFinder class to organize parameters passed to modules.

The ResourceFinder is a helper class that allows to find and read configuration files from YARP's installation directories or from directories that are user specific (see YARP data directories).

Introduction

Suppose we wish to write a module called 'rf_basic' that performs random movements of a single joint. The module is generic, so it can control any of the available joints of one of the limbs of a robot, either a real or a simulated one.

The module should receive the following parameters:

  • --robot <name> (the name of the robot)
  • --part <robotpart> (the limb of the robot)
  • --joint <jointnumber> (the joint we want to control)

In the module main function we add:

ResourceFinder rf;
rf.configure(argc, argv);

This creates an instance of the ResourceFinder, and configures it using data from the command line. We can query the value of the parameters:

std::string robotName=rf.find("robot").asString();
std::string partName=rf.find("part").asString();
int joint=rf.find("joint").asInt32();
std::cout << "Running with:\n";
std::cout << " robot: " << robotName.c_str() << '\n';
std::cout << " part: " << partName.c_str() << '\n';
std::cout << " joint: " << joint << '\n';

This achieves what we want. The program rf_basic can parse the parameters from the command line as desired. We here assume you are in the source directory of rf_basic and that you wrote a valid CMakeLists.txt. Compile with:

mkdir build
cd build
cmake ../
make

Finally run the newly created executable:

./rf_basic --robot robby --part head --joint 3
Running with:
 robot: robby
 part: head
 joint: 3

Now suppose we wish to place these configuration parameters in a file called config.ini. We can put this file together with the sources in a specific folder called randomMotion.

Create the file ./randomMotion/config.ini

Open it with your preferred editor and type:

robot icub
part head
joint 0

The code above already achieves what we wanted. The ResourceFinder automatically checks for a parameter --from that specifies from which file to read configuration parameters:

./rf_basic --from ../randomMotion/config.ini
Running with:
 robot: icub
 part: head
 joint: 0

Notice that we here assume you are in the build directory.

In many cases you don't want to bother about the exact path of the ini file. This happens for example if you are writing a script that executes the module and you don't know the exact configuration of the machine (it could even be running a different operating system!). This is the case for example when writing scripts for the yarpmanager: edit, run and manage multiple programs on a set of machines.

But first let's provide the ResourceFinder with a default configuration file so that the user does not have to specify it in the command line (notice that the parameter –from overwrites this setting):

ResourceFinder rf;
rf.setDefaultConfigFile("config.ini"); //specifies a default configuration file
rf.configure(argc, argv);

Now we can put config.ini in one of the data directories defined by YARP. A possible option is the directory .local/share/yarp/contexts inside the home of the user (in windows this is %APPDATA%/yarp/contexts, see YARP data directories for more details). By default this is the first place in which the ResourceFinder searches for files if not instructed with a precise path (like in this case).

To avoid confusions and clashes with other similar files we keep the file inside the directory randomMotion; we call this directory a context for the module rf_basic.

cp -r ../randomMotion/ $HOME/.local/share/yarp/contexts

Now from any working directory in the computer you can run your module and it will read parameters from $HOME/.local/share/yarp/contexts/randomMotion/config.ini and do its job.

To do this we can run rf_basic with the parameter --context:

./rf_basic --context randomMotion
[...]
|| found <home>/.local/share/yarp/contexts/randomMotion/config.ini
Running with:
 robot: robby
 part: head
 joint: 0

This is useful because:

  • the context directory can contain more than a single file, by changing only this directory we change the whole configuration of the module with a single command;
  • YARP defines a set of places that can contain context directories, in our example the randomMotion folder can be installed with the executable and located at runtime without the user providing its exact path (which is system dependent).

In fact we can now create another directory to store a different configuration file. This file could for example configure rf_basic to connect to a simulator and move joint number 2 of the arm.

We create a new directory and add there a new file:

mkdir $HOME/.local/share/yarp/contexts/randomMotionSim

Create with your preferred editor a file called config.ini that contains the following lines:

robot robbySim
part right_arm
joint 2

Put the file in the directory randomMotionSim you just created.

We run:

./rf_basic --context randomMotionSim
[...]
|| found <home>/.local/share/yarp/contexts/randomMotionSim/config.ini
Running with:
 robot: robbySim
 part: right_arm
 joint: 2

If you wish, you can specify a 'defaultContext' to be used when no parameters are given to the module.

Just add the following line after the call to setDefaultConfigFile():

rf.setDefaultContext("randomMotion");

Now running:

./rf_basic
[...]
|| found <home>/.local/share/yarp/contexts/randomMotion/config.ini
Running with:
 robot: robby
 part: head
 joint: 0

Before you move to the next tutorials it is better to cleanup your $HOME directory:

rm -rf $HOME/.local/share/yarp/contexts/randomMotion
rm -rf $HOME/.local/share/yarp/contexts/randomMotionSim

Discussion

We have seen how the ResourceFinder facilitates passing parameters to a module from a file. The ResourceFinder follows particular rules to locate configuration files that allow, for example, to switch the "initialization context" from which a module will be configured.

For simplicity, in the above example, we used specific Linux commands and directories. Adapting this tutorials to other operating systems should be strightforward.

Normally context directories are not copied manually to the home of the user, but they are installed together with other contexts in YARP's directories and managed with the yarp-config tool. The tutorial How to install files for the ResourceFinder describes how to use CMake to configure your build so that configuration files are automatically installed and it links to the yarp-config help page.

More insights on the ResourceFinder are given in a more advanced tutorial The ResourceFinder Class (advanced). See also the yarp::os::ResourceFinder class documentation.

Code

See code in: example/resourceFinder/tutorial_rf_basic.cpp