YARP  2.3.68+220-20170323.2+git4955ef0
Yet Another Robot Platform
The ResourceFinder Class (basic)
Author
Lorenzo Natale and Elena Ceseracciu

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 'random_motion' that performs random movements of a single joint. The module is generic in that 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 j (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 from data from the command line. We can query the value of the parameters:

ConstString robotName=rf.find("robot").asString();
ConstString partName=rf.find("part").asString();
int joint=rf.find("joint").asInt();
cout<<"Running with:"<<endl;
cout<<"robot: "<<robotName.c_str()<<endl;
cout<<"part: "<<partName.c_str()<<endl;
cout<<"joint: "<<joint<<endl;

This achieves what we want. The program random_motion can parse the parameters from the command line as desired. For example (we here assume you are in the source directory of random_motion and that you wrote a valid CMakeLists.txt):

mkdir build
cd build
cmake ../
make
./random_motion --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:

./random_motion --from ../randomMotion/config.ini
robot icub
part head
joint 0

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

Now in many cases you don't want to bother about the exact path to 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.

We will see you to do this. But first let's first 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.setVerbose(); //logs searched directories
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 random_motion.

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 random_motion with the parameter –context:

./random_motion --context randomMotion
[...]
|| found /home/nat/.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 random_motion 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 you 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:

./random_motion --context randomMotionSim
[...]
|| found /home/nat/.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:

./random_motion
[...]
|| found /home/nat/.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