forked from robotology/yarp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathresource_finder_basic.dox
196 lines (140 loc) · 7.08 KB
/
resource_finder_basic.dox
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/**
*
@page yarp_resource_finder_basic 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 \ref yarp_data_dirs).
\section sec_intro 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:
\code
--robot name (the name of the robot)
--part robotpart (the limb of the robot)
--joint j (the joint we want to control)
\endcode
In the module \e main function we add:
\code
ResourceFinder rf;
rf.configure(argc, argv);
\endcode
This creates an instance of the ResourceFinder, and configures it from data from the command line. We can query the value of the parameters:
\code
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;
\endcode
This achieves what we want. The program \e 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):
\code
mkdir build
cd build
cmake ../
make
./random_motion --robot robby --part head --joint 3
Running with:
robot:robby
part:head
joint:3
\endcode
Now suppose we wish to place these configuration parameters in a file called \e config.ini. We can put this file together with the sources in a specific folder called \e randomMotion.
Create the file:
\code
./randomMotion/config.ini
\endcode
Open it with your preferred editor and type:
\code
robot icub
part head
joint 0
\endcode
The code above already achieves what we wanted. The ResourceFinder automatically checks for a parameter \e --from that specifies from which file to read configuration parameters:
\code
./random_motion --from ../randomMotion/config.ini
robot icub
part head
joint 0
\endcode
Notice that we here assume you are in the \e 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 \ref yarpmanager.
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 \e --from overwrites this setting):
\code
ResourceFinder rf;
rf.setVerbose(); //logs searched directories
rf.setDefaultConfigFile("config.ini"); //specifies a default configuration file
rf.configure(argc, argv);
\endcode
Now we can put \e 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 \ref yarp_data_dirs 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 \e randomMotion; we call this directory a \e context for the module random_motion.
\code
cp -r ../randomMotion $HOME/.local/share/yarp/contexts
\endcode
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 \e --context:
\code
./random_motion --context randomMotion
[...]
|| found /home/nat/.local/share/yarp/contexts/randomMotion/config.ini
Running with:
robot: robby
part: head
joint: 0
\endcode
This is useful because:
\li 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;
\li YARP defines a set of places that can contain context directories, in our example the \e 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:
\code
mkdir $HOME/.local/share/yarp/contexts/randomMotionSim
\endcode
Create with you preferred editor a file called \e config.ini that contains the following lines:
\code
robot robbySim
part right_arm
joint 2
\endcode
Put the file in the directory \e randomMotionSim you just created.
We run:
\code
./random_motion --context randomMotionSim
[...]
|| found /home/nat/.local/share/yarp/contexts/randomMotionSim/config.ini
Running with:
robot: robbySim
part: right_arm
joint: 2
\endcode
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():
\code
rf.setDefaultContext("randomMotion");
\endcode
Now running:
\code
./random_motion
[...]
|| found /home/nat/.local/share/yarp/contexts/randomMotion/config.ini
Running with:
robot: robby
part: head
joint: 0
\endcode
Before you move to the next tutorials it is better to cleanup your $HOME directory:
\code
rm -rf $HOME/.local/share/yarp/contexts/randomMotion
rm -rf $HOME/.local/share/yarp/contexts/randomMotionSim
\endcode
\section sec_discussion 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 \ref yarp_resource_finder_installation 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 \ref yarp_resource_finder_advanced. See also the yarp::os::ResourceFinder class documentation.
\section sec_code Code
See code in: example/resourceFinder/tutorial_rf_basic.cpp
*
**/