Configuration¶
When you start a command line tool, you can supply it with one or more configuration destinations. The configuration is written in JSON.
Reading¶
Hierarchy¶
The configuration follows a hierarchy that is separated by dots (.
)
in the names of the keys. The hierarchy is inferred from the file system
and the structure of the JSON in the files.
For example, assume you supply the config destination config/local/
and there
is a file config/local/some/path/Test.json
and it contains the following
content:
{
"some_key": {
"other_key": {
"the_answer": 42,
"the_question": ["life", "universe", "everything"]
}
}
}
In this case, the config key some.path.Test.some_key.other_key.the_answer
will be read and set to 42
and the key some.path.Test.some_key.other_key.the_question
will contain a list of strings as shown.
A config destination can contain the special file called parent
.
It should consist of a single line giving a path (absolute or relative to the
current destination) to include. This means the contents of the given destination
will be treated as if they were present in the current destination.
Additionally, the parent destination will be read first which is important
for cascading (see below).
Cascading¶
The structure of the configuration makes it possible (and actually good and
common practice) to split a config object across multiple locations.
For example your config destination may have a file Test.json
that contains
{ "field_1": 42 }
but also reference a parent
directory that also has a file Test.json
that contains
{ "field_2": 23 }
In effect, both Test.field_1
and Test.field_2
are correctly read.
By default, we use this technique to separate
- configuration specific to an installation (in
config/local/
in the pilot home folder), which includes - configuration specific to a robot model (in
config/default/XXX/
in the installation folder), which includes - generic configuration (in
config/default/generic/
in the installation folder).
This makes the configuration easy to maintain.
Given the rules for the hierachy and for parent destinations, it is very much possible to specify the same key multiple times. In that case the key that is read last overwrites any previous one of the same name. In particular, a destination always overrides its parent.
Appending¶
It is also possible to append values to an array, by adding a +
to the variable name as such:
{ "array": [1, 2, 3] }
{ "array+": [4, 5, 6] }
The resulting array
config value will be [1, 2, 3, 4, 5, 6]
.
Command line¶
You can also supply configuration on the command line.
For example, to set MyModule.max_velocity
to 5
, append
--MyModule.max_velocity 5
to the command line.
Values are read as JSON objects. Make sure to use the correct quoting according
to the shell you use.
When setting a boolean value to true
, you can omit the value and just give
the key.
Arrays and objects can be provided on the command line as follows:
command --array [1, 2, 3, 4] --object {"field": 1234, "array": ["a", "b", "c"]}
Config keys given at the command line are read as the ultimate last ones, so they override any previous keys with the same names. This is useful for testing out certain values without constantly having to edit files.
Assignment¶
While some config keys are read explicitly by the application, most of the assignment happens automagically.
Modules¶
A module that is started with the name MyModule
will automatically be
assigned all configuration below the MyModule.
key.
From then on it behaves like a class (see below).
Classes¶
If a configuration key is applied to an instance of a VNX class, the members of the class are assigned the subkeys where the names match.
For example if you have an object of the class Test
below
class Test2 {
string what;
int over;
}
class Test {
string name;
int value;
vector<int> numbers;
Test2 other_one;
}
and you assign it the config
{
"name": "Picard",
"value": 1234,
"numbers": [1, 2, 3, 4],
"other_one": {
"what": "ever",
"over": 9000
}
}
then all the fields get assigned the config key with the matching name.
Notice that other_one
is another object which will get the same treatment
recursively with the embedded config object.
Fields without a matching config key are default initialized and spare keys without a matching field are silently ignored.