Configuration files are essential parts of framework applications.
In a configuration file, the user sets up several parameters of the framework, specifies what libraries are loaded and configures the units that are used together with their parameters. The format of configuration files is XML. An application configuration file must always contain a root node.
Configuration files will be parsed by a ConfigurationLoader. This loader supports preparer and loader plugins. The loader will pass the XML configuration document to all preparer plugins. Each preparer plugin will parse the XML document and can replace, insert or modify the content of this document in any possible way. In a second step, the loader will parse the configuration file and for each tag that is found it will ask each loader plugin if it "understands" the tag. The plugin concept allows developers to add new preparers and loaders to support modification of the document or interpreting own tags in configuration files. There are already basic preparer and loader plugins with their respective tags available that will be explained below.
Index (A-Z)
<root>
The root of the XML config file is the outermost node, e.g. the parent of all other nodes, that is required since all XML documents need a root node. No other tag can exist outside the root node.
Nested Tags
Since the root node is the parent node of all other nodes nearly all tags can be nested children.
<include>
<include
file=
"otherfile.xml"/>
<include
file=
"optionfile.xml" select=
"Options/SubOption" as=
"Option"/>
<include
file=
"tree.xml" select=
"Tree/SubTree1:Tree/SubTree2:Tree/SubTree3/SubSub/*" />
<welcometext>Hello, my name is <include
file=
"name.txt" parse=
"text"/></welcometext>
Includes the content of another xml or text file into the current file. For xml files it additionally allows to only include one or multiple subtrees of the file using the select attribute.
At any position (inside the root node) in the config file an tag can be used to include another XML or text file on that position. The content of this file is inserted at the tag position. The tag node is removed.
| The root node of an included xml file is ignored/removed when including the file in your document. Remember to always have a root node around the actual content if you want others/yourself to be able to include your xml file in other documents. |
Attributes
- file = "filename.xml" (required)
- Specifies the path to the file to be included at that position. The path can contain environment variables. It also can be relative to the file the include tag was found in as well as an absolute path.
- select = "path/to/subtree" (optional)
- Specifies paths to subtrees that should be selected as included content, multiple entries are separated by ':' (e.g. path/to/subtree1:path/to/subtree2). The nodes of the listed paths are included, if found (selection referring to non-existent nodes is ignored). The asterisk can be used as wildcard (only for the complete final part of the name), e.g. 'path/to/subtree/*' includes all child nodes of the subtree node. Selection precedes processing of nodes, so it is not possible to select a subnode that will result from resolving e.g. a conditional or include tag. 'select="*"' selects all nodes, just like omitting the 'select' attribute. There is no de-duplication on the selection list, so nothing prevents duplicating nodes by selecting them more than once!
- select_not = "path/to/subtree" (optional)
- Specifies paths to subtrees that should NOT be included, multiple entries are separated by ':' The same rules apply as for 'select', except 'select_not="*"' is not valid. If a path specified in 'select_not' is a parent of a path that is selected (by name or wildcard), it does not affect that selection (deselection must be on same or deeper tree level as selection to apply both in combination). Since selection precedes node processing, 'select_not' can be used to ensure not processing certain nodes (e.g. when processing would result in a failure to load the configuration).
- as = "newName" (optional)
- Specifies a name for included subnodes. Ignored if 'select' attribute is not set. If multiple nodes are selected (by list or wildcard), ALL of them will be named the same!
- parse = "xml|text" (optional)
- Specifies how the included file should be parsed. Either as xml document or text. Default is xml. The 'select' and 'as' attributes only work with xml parsing.
Example
--Item.xml--
<root>
<item>1</item>
</root>
--Options.xml--
<root>
<Options>
<Option1>
<Factor>3</Factor>
</Option1>
<Option2>
<Factor>10</Factor>
</Option2>
</Options>
</root>
--Tree.xml--
<root>
<Tree>
<Subtree1>
<Child>A</Child>
</Subtree1>
<Subtree2>
<Child>B</Child>
</Subtree2>
</Options>
</root>
--Counter.txt--
5000
--Config.xml--
<root>
<include
file=
"Item.xml"/>
<include
file=
"Item.xml"/>
<include
file=
"Options.xml" select=
"Options/Option2/Factor" />
<include
file=
"Tree.xml" select=
"Tree/Subtree1:Tree/Subtree2/*" />
<Text>The counter is now at <include
file=
"Counter.txt" parse=
"text" />.</Text>
</root>
--Result.xml--
<root>
<item>1</item> <!-- first include -->
<item>1</item> <!-- second include -->
<Factor>10</Factor> <!-- third include -->
<Subtree1> <!-- fourth include, first path -->
<Child>A</Child>
</Subtree1>
<Child>B</Child> <!-- fourth include, second path -->
<Text>The counter is now at 5000.</Text>
</root>
Splitting configuration files into multiple files has many advantages. For example, a parameter file for a unit can reside in the package path of the unit and will be maintained and updated by the package author. All applications using this unit will always use the newest and updated parameters without changing their configuration file. Notice that in order to include config files installed somewhere in your MIRA_PATHs, you can use the "find" or "findpkg" function to locate the config files.
--Config.xml--
<root>
<include
file=
"${find etc/domains/MyDomain/MyConfig.xml}"/>
</root>
<if>
<if variable="value">
...
</if>
At any position in the config file, an <if> tag can be used to include or exclude content of the document based on pre-defined variables. The <if> tag checks if a variable has a given value using the syntax <if var="value">. If the check evaluates to true, the <if> node is replaced by its content. Otherwise, the <if> node and its sub nodes are removed. The <else> tag can be used for specifying content that is used when the condition is not met.
Attributes
- The attribute is interpreted as variable name that is checked against the specified value. E.g. the attribute os="linux" will cause the <if> tag to check if the value in the variable os equals the string "linux".
Example
<root>
<if os="linux">
<Device>/dev/ttyUSB0</Device>
</if>
<if os="windows">
<Device>COM1</Device>
</if>
</root>
-- assuming os=linux, the resulting document would look as follows --
<root>
<Device>/dev/ttyUSB0</Device>
</root>
This is useful whenever configuration parameters depend on environmental settings or resources. In the above example, a device name in the configuration file depends on the operating system. The usage of the <if> tag allows using the same configuration file on different operating systems. There are several pre-defined defines:
- os=windows|linux (define based on operating system)
- severity=1|2|3|4|5 (define based on specified loglevel)
You can also add more variables on the command line by adding the variables parameter
--var MyVar=true,AnotherOne=3,AndSoOn=hello
or by defining them with a <var> tag in the configuration file, see <var>.
The <if_all> tag is like <if>, except that it can check multiple conditions. All conditions (expressed as attributes) must be met (result is determined using AND operator).
<if_all variable1="value1" variable2="value2">
...
</if_all>
The <if_any> tag is like <if>, except that it can check multiple conditions. At least one of the conditions (expressed as attributes) must be met (result is determined using OR operator).
<if_any variable1="value1" variable2="value2">
...
</if_any>
<if_not>
<if_not variable="value">
...
</if_not>
At any position in the config file, an <if_not> tag can be used to include or exclude content of the document based on pre-defined variables. In contrast to the <if> tag the <if_not> tag checks if the condition evaluates to false and in this case the <if_not> node is replaced by its content. Otherwise, the <if_not> node and its sub nodes are removed. The <else> tag can be used for specifying content that is used when the condition is not met.
Attributes
- The attribute is interpreted as variable name that is checked against the specified value. E.g. the attribute os="linux" will cause the <if_not> tag to check if the value in the variable os does not equal the string "linux".
Example
<root>
<if_not os="windows">
<Device>/dev/ttyUSB0</Device>
</if_not>
</root>
-- assuming os=linux, the resulting document would look as follows --
<root>
<Device>/dev/ttyUSB0</Device>
</root>
The <if_not_all> tag is like <if_not>, except that it can check multiple conditions. At least one of the conditions (expressed as attributes) must NOT be met (result is determined using AND operator, then negation).
<if_not_all variable1="value1" variable2="value2">
...
</if_not_all>
The <if_not_any> tag is like <if_not>, except that it can check multiple conditions. None of the conditions (expressed as attributes) must be met (result is determined using OR operator, then negation).
<if_not_any variable1="value1" variable2="value2">
...
</if_not_any>
<assert>
<assert variable="value">Error message</assert>
At any position in the config file, an <assert> tag can be used to make sure a variable has a given value using the syntax <assert var="value">. If the check evaluates to true, the <assert> node is removed. Otherwise, an exception with the error message contained in the tag is thrown.
Attributes
- The attribute is interpreted as variable name that is checked against the specified value. E.g. the attribute os="linux" will make sure the value os equals the string "linux".
Example
<root>
<assert os="linux">This config does only work on linux machines</assert>
</root>
The <assert_all> tag is like <assert>, except that it can check multiple conditions. All conditions (expressed as attributes) must be met (result is determined using AND operator).
<assert_all variable1="value1" variable2="value2"...>Error message</assert_all>
The <assert_any> tag is like <assert>, except that it can check multiple conditions. At least one of the conditions (expressed as attributes) must be met (result is determined using OR operator).
<assert_any variable1="value1" variable2="value2"...>Error message</assert_any>
<assert_not>
<assert_not variable="value">Error message</assert_not>
At any position in the config file, an <assert_not> tag can be used to make sure variables do not equal a given value based on pre-defined variables. In contrast to the <assert> tag, the <assert_not> tag checks if the conditions evaluates to false and in this case the <assert_not> node is removed. Otherwise, an exception with the error message contained in the tag is thrown.
Attributes
- The attributes are interpreted as variable names that are checked against the specified value. E.g. the attribute os="linux" will make sure the value os does not equal the string "linux".
Example
<root>
<assert_not os="windows">This config does not work on windows machines</assert_not>
</root>
The <assert_not_all> tag is like <assert_not>, except that it can check multiple conditions. At least one of the conditions (expressed as attributes) must NOT be met (result is determined by AND operation, then negation).
<assert_not_all variable1="value1" variable2="value2"...>Error message</assert_not_all>
The <assert_not_any> tag is like <assert_not>, except that it can check multiple conditions. None of the conditions (expressed as attributes) must be met (result is determined by OR operation, then negation).
<assert_not_any variable1="value1" variable2="value2"...>Error message</assert_not_any>
<if_exists>
<if_exists class="mira::MyClass">
...
</if_exists>
<if_exists
file=
"${find etc/MyFile.txt}">
...
</if_exists>
<if_exists var="myvar">
...
</if_exists>
<if_exists env="ENVIRONMENTAL_VARIABLE">
...
</if_exists>
<if_exists package="PackageName">
...
</if_exists>
At any position in the config file an <if_exists> tag can be used just like an <if> tag to include or exclude content of the document. The <if_exists> tag checks if a class is registered at the class factory using the 'class' attribute and the syntax <if_exists class="namespace::ClassName">, if a file exists using the 'file' attribute, if a variable is defined using the 'var' attribute, if an environmental variable is set via the 'env' attribute or a package is installed via the 'package' attribute. If the check evaluates to true, the <if_exists> node is replaced by its content. Otherwise, the <if_exists> node and its sub nodes are removed. The <else> tag can be used for specifying content that is used when the condition is not met.
Attributes
- class = "namespace::ClassName" (optional) - checks if a class with the given identifier is known by the class factory.
- file = "filename" (optional) - checks if a file with the specified name exists. The filename is resolved (so it can contain environmental variables as well as the ${find file} command).
- var = "varname" (optional) - checks if a variable with specified name is defined
- env = "ENVIRONMENTAL_VARIABLE" (optional) - checks if an environmental variable with specified name is defined
- package = "PackageName" (optional) - checks if a package with specified name is installed
Example
<root>
<if_exists class="mira::SpecialAlgorithm">
<Algorithm class="mira::SpecialAlgorithm">...params...</Algorithm>
</if_exists>
</root>
This is useful whenever plugins are used by a module and that module provides a basic configuration file for all known plugins but the user has only installed a few of them. The module would otherwise try to load all plugins specified in the config file and that would lead to errors during startup, since these plugins are not installed and can therefore not be instantiated.
The <if_exists_all> tag is like <if_exists>, except that it can check multiple conditions. All conditions (expressed as attributes) must be met (result is determined using AND operator).
<if_exists_all var="value" package="name">
...
</if_exists_all>
The <if_exists_any> tag is like <if_exists>, except that it can check multiple conditions. At least one of the conditions (expressed as attributes) must be met (result is determined using OR operator).
<if_exists_any var="value" package="name">
...
</if_exists_any>
Note: In order to facilitate checking of multiple variables, files, packages, etc. in one condition tag, <if_exists_all> and <if_exists_any> accept any attributes beginning with 'var', 'file', 'package', etc. (because multiple use of the same attribute name in one tag would violate XML specifications). That means attributes e.g. 'var1', 'var2', 'varX' and 'varAnyFurtherTextHere' are all interpreted as specifying the existence of a variable, whose name is the attribute value. The part of the attribute name after 'var', 'file', 'package', etc. has no relevance and is ignored.
<if_not_exists>
<if_not_exists class="mira::MyClass">
...
</if_not_exists>
<if_not_exists
file=
"${find etc/MyFile.txt}">
...
</if_not_exists>
<if_not_exists var="myvar">
...
</if_not_exists>
<if_not_exists env="ENVIRONMENTAL_VARIABLE">
...
</if_not_exists>
<if_not_exists package="PackageName">
...
</if_not_exists>
At any position in the config file an <if_not_exists> tag can be used just like an <if_not> tag to include or exclude content of the document. The <if_not_exists> tag checks if no class with the given identifier is registered at the class factory using the 'class' attribute and the syntax <if_not_exists class="namespace::ClassName">, if no file exists using the 'file' attribute, if no variable is defined using the 'var' attribute, if no environmental variable is set via the 'env' attribute or no package is installed via the 'package' attribute. If the check evaluates to true, the <if_not_exists> node is replaced by its content. Otherwise, the <if_not_exists> node and its sub nodes are removed. The <else> tag can be used for specifying content that is used when the condition is not met.
Attributes
- class = "namespace::ClassName" (optional) - checks if no class with the given identifier is known by the class factory.
- file = "filename" (optional) - checks if no file with the specified name exists. The filename is resolved (so it can contain environmental variables as well as the ${find file} command).
- var = "varname" (optional) - checks if no variable with specified name is defined
- env = "ENVIRONMENTAL_VARIABLE" (optional) - checks if no environmental variable with specified name is defined
- package = "PackageName" (optional) - checks if no package with specified name is installed
Example
<root>
<if_not_exists class="mira::SpecialAlgorithm">
<Algorithm class="mira::DefaultAlgorithm">...params...</Algorithm>
</if_not_exists>
</root>
The <if_not_exists_all> tag is like <if_not_exists>, except that it can check multiple conditions. At least one condition (expressed as attributes) must NOT be met (result is determined using AND operator, then negation).
<if_not_exists_all var="value" package="name">
...
</if_not_exists_all>
The <if_not_exists_any> tag is like <if_not_exists>, except that it can check multiple conditions. None of the conditions (expressed as attributes) must be met (result is determined using OR operator, then negation).
<if_not_exists_any var="value" package="name">
...
</if_not_exists_any>
As in <if_exists_all> and <if_exists_any>, only the begin of the attribute name must match 'var', 'file', etc.
<assert_exists>
<assert_exists class="mira::MyClass">Error message</assert_exists>
<assert_exists
file=
"${find etc/MyFile.txt}">Error message</assert_exists>
<assert_exists var="myvar">Error message</assert_exists>
<assert_exists env="ENVIRONMENTAL_VARIABLE">Error message</assert_exists>
<assert_exists package="PackageName">Error message</assert_exists>
At any position in the config file an <assert_exists> tag can be used just like an <assert> tag to make sure a class is registered at the class factory using the 'class' attribute and the syntax <assert_exists class="namespace::ClassName">, a file exists using the 'file' attribute, a variable is defined using the 'var' attribute, an environmental variable is set via the 'env' attribute or a package is installed via the 'package' attribute. If the check evaluates to true, the <assert_exists> node is removed. Otherwise, an exception with the message contained in the tag is thrown.
Attributes
- class = "namespace::ClassName" (optional) - makes sure a class with the given identifier is known by the class factory.
- file = "filename" (optional) - makes sure a file with the specified name exists. The filename is resolved (so it can contain environmental variables as well as the ${find file} command).
- var = "varname" (optional) - makes sure a variable with specified name is defined
- env = "ENVIRONMENTAL_VARIABLE" (optional) - makes sure an environmental variable with specified name is defined
- package = "PackageName" (optional) - makes sure a package with specified name is installed
Example
<root>
<assert_exists package="SpecialAlgorithms">This config will only work when the package 'SpecialAlgorithms' is installed on the system</assert_exists>
</root>
The <assert_exists_all> tag is like <assert_exists>, except that it can check multiple conditions. All conditions (expressed as attributes) must be met (result is determined using AND operator).
<assert_exists_all var="value" package="name">
...
</assert_exists_all>
The <assert_exists_any> tag is like <assert_exists>, except that it can check multiple conditions. At least one of the conditions (expressed as attributes) must be met (result is determined using OR operator).
<assert_exists_any var="value" package="name">
...
</assert_exists_any>
In both <assert_exists_all> and <assert_exists_any>, only the begin of the attribute name must match 'var', 'file', etc. (see Attributes tag).
<assert_not_exists>
<assert_not_exists class="mira::MyClass">Error message</assert_not_exists>
<assert_not_exists
file=
"${find etc/MyFile.txt}">Error message</assert_not_exists>
<assert_not_exists var="myvar">Error message</assert_not_exists>
<assert_not_exists env="ENVIRONMENTAL_VARIABLE">Error message</assert_not_exists>
<assert_not_exists package="PackageName">Error message</assert_not_exists>
At any position in the config file an <assert_not_exists> tag can be used just like an ConfigXMLRefTagAsserNot tag to make sure no class with the given identifier is registered at the class factory using the 'class' attribute and the syntax <assert_not_exists class="namespace::ClassName">, no file exists using the 'file' attribute, no variable is defined using the 'var' attribute, no environmental variable is set via the 'env' attribute or no package is installed via the 'package' attribute. If the check evaluates to true, the <assert_not_exists> node is removed. Otherwise, an exception with the message contained in the tag is thrown.
Attributes
- class = "namespace::ClassName" (optional) - makes sure no class with the given identifier is known by the class factory.
- file = "filename" (optional) - makes sure no file with the specified name exists. The filename is resolved (so it can contain environmental variables as well as the ${find file} command).
- var = "varname" (optional) - makes sure no variable with specified name is defined
- env = "ENVIRONMENTAL_VARIABLE" (optional) - makes sure no environmental variable with specified name is defined
- package = "PackageName" (optional) - makes sure no package with specified name is installed
Example
<root>
<assert_not_exists package="SpecialAlgorithms">This config will not work when package 'SpecialAlgorithms' is installed on the system</assert_not_exists>
</root>
The <assert_not_exists_all> tag is like <assert_not_exists>, except that it can check multiple conditions. At least one condition (expressed as attributes) must NOT be met (result is determined using AND operator, then negation).
<assert_not_exists_all var="value" package="name">
...
</assert_not_exists_all>
The <assert_not_exists_any> tag is like <assert_not_exists>, except that it can check multiple conditions. None of the conditions (expressed as attributes) must be met (result is determined using OR operator, then negation).
<assert_not_exists_any var="value" package="name">
...
</assert_not_exists_any>
In both <assert_not_exists_all> and <assert_not_exists_any>, only the begin of the attribute name must match 'var', 'file', etc. (see Attributes tag).
<else>
<if var="value">
...
</if>
<else>
...
</else>
<if_exists
file=
"${find etc/MyFile.txt}">
...
</if_exists>
<else>
...
</else>
After an <if>, <if_not>, <if_exists> or <if_not_exists> tag, an <else> tag can be used to specify content that should be used when the conditions in the <if((_not)_exists)> tags are not met. If the check in the <if((_not)_exists)> tag evaluates to false, the <else> node is replaced by its content. Otherwise the <else> node and its sub nodes are removed.
Attributes
No attributes.
Example
<root>
<if_exists class="mira::SpecialAlgorithm">
<Algorithm class="mira::SpecialAlgorithm">...params...</Algorithm>
</if_exists>
<else>
<Algorithm class="mira::DefaultAlgorithm">...params...</Algorithm>
</else>
</root>
<var>
<var person="Peter Griffin"/>
Defines a variable and assigns a value (variable "person", value "Peter Griffin" in the example). The value of the variable can be checked in an <if> tag. The value is only assigned if the variable was not already defined before (e.g. via command line or earlier in the config file). To explicitely overwrite an already defined variable you can use the syntax:
<var person="Homer Simpson" overwrite="true"/>
Additionally, all occurances of $name, ${name} or name% in attributes or content of xml tags are replaced by either the respective defined variable or if no variable is defined by the value of the respective environmental variable.
<warning>
<warning message="Warning message"/>
The <warning> tag can be used to show a warning on startup.
Attributes
- message = "Message" (required)
<notice>
<notice message="Notice message"/>
The <notice> tag can be used to show a notice on startup.
Attributes
- message = "Message" (required)
<error>
<error message="Error message"/>
The <error> tag can be used to show an error on startup.
Attributes
- message = "Message" (required)
<abort>
<abort message="Abort message"/>
The <abort> tag can be used to abort startup while showing an error message.
Attributes
- message = "Message" (required)
- The message that will be written by using the MIRA_LOG(CRITICAL) mechanism before aborting startup
<library>
<library directory="Path to directory"/>
or
<library
file=
"Path to library file"/>
The <library> tag can be used to explicitly load dynamic libraries and plugins on startup.
Attributes
- directory = "Path" (required)
- Specifies a path where all libraries located within that path should be loaded. The path can contain environment variables. It can be either relative to the file the library tag was found in or as an absolute path.
- file = "Path" (required)
- Can be used instead of the directory attribute to specify a single library file that should be loaded. The path can contain environment variables. Note that the filename of the library should be expressed without any library prefixes and suffixes. They will be attached automatically depending on the Operating System where the configuration file is used. E.g. "path/libMyUnit.so" should be specified as "path/MyUnit". This ensures platform independence for the configuration files.
<communication>
In the <communication> tag, the user can specify information and parameters of the communication between frameworks e.g. host and port information of other frameworks,...
If the <communication> tag is used, the framework will contain a network component, meaning it will start a server that listens to client connections. It will also try to connect to the specified remote frameworks. The following parameters can be set:
- Port specifies the port of the server that listens to remote connections.
- KnownFrameworks contains a list of entries for each framework we want to connect to, with these elements:
- Address hostName:port location identifier
- KeepConnected (optional, default=true) Whether to retry connecting when the connection is lost
- ForcePTP (optional, default=false) Whether to force PTP time synchronization (synchronization is automatically enabled if the remote framework runs on a different host, but can be forced e.g. when the remote host recognition fails due to port forwarding)
- BinaryFormatVersion (optional, default=<current_format_version>) Binary format version of the remote framework, to ensure the remote framework can deserialze the data sent to it
- ServiceLevels service level agreements for channels like the used codecs for exchanging data between frameworks. If not specified, no codecs will be used.
- Authentication used authentication settings between connected frameworks. If not specified, no authentication is used.
Authentication types
Each framework may belong to a certain workgroup. The framework will be able to connect to other frameworks within the same group only. Moreover, there are three modes for authentication:
- No additional authentication
- Weak authentication using a password
- Strong authentication using an RSA key pair
The following parameters can be set to enable each level of authentication:
- Group The group name that the framework belongs to. Only frameworks with the same group can connect to each other. Very weak authentication. Can be combined with Password or Key
- Password The password that must be used by all frameworks that want to connect. Weak authentication. Can be combined with Group
- Key The key file containing private and public RSA keys to be used by all frameworks that want to connect. When two frameworks connect, both will send encrypted messages that will be signed with the private key by the remote partner and sent back for verification. Strong authentication. Can be combined with Group
See Examples for how to use these settings.
Service level agreements
Service level agreements are set by channel or by channel type. Each channel can have its own communication settings. These settings are defined on the channel subscriber's side. A service level description can include a list of codecs. When the local framework subscribes on a channel published by a remote framework, the remote framework uses the specified codecs for encoding a channel message before sending it to the subscriber framework.
Some codecs can be found in the CommonCodecs toolbox, including codecs for image compression like
- mira::codec::JpegCodec encoding images as JPEG (Parameter "Quality" 0: highest compression, 100: best quality, default: 95)
- mira::codec::PngCodec encoding images as PNG (Parameter "Compression" 0: lowest but fastest, 9: best but slowest, default: 3)
- mira::codec::Z11Codec lossless compression of 11 bit depth images
- mira::codec::Z16TableCodec lossless compression of 16 bit depth images
Starting with MIRAFramework 1.9.0, channel update rates for remote connections can be limited, by specifying a minimum interval between updates.
See Examples for how to use these settings.
Parent Tags
Example
The following example starts a framework server that listens on port 1234 and connects to another framework at localhost port 1235.
<communication>
<version
type=
"mira::RemoteModule">2</version>
<Port>1234</Port>
<KnownFrameworks>
<item>
<Address>127.0.0.1:1235</Address>
<ForcePTP>true</ForcePTP>
</item>
</KnownFrameworks>
</communication>
The next example specifies a group and a password for authentication:
<communication>
<version
type=
"mira::RemoteModule">2</version>
<Port>1234</Port>
<KnownFrameworks>
<item>
<Address>127.0.0.1:1235</Address>
</item>
</KnownFrameworks>
<Authentication>
<Group>MyGroup</Group>
<Password>MyPassword</Password>
</Authentication>
</communication>
The next example shows how to request remote frameworks to encode messages in channel "/MyNamespace/Image" using a JPG codec before sending them to our framework:
<communication>
<version
type=
"mira::RemoteModule">2</version>
<Port>1234</Port>
<KnownFrameworks>
<item>
<Address>127.0.0.1:1235</Address>
</item>
</KnownFrameworks>
<ServiceLevels>
<item>
<Channel>/MyNamespace/Image</Channel>
<Codecs>
<item class="mira::codec::JpegCodec">
<Quality>50</Quality>
</item>
</Codecs>
</item>
</ServiceLevels>
</communication>
In this example, the update rate of channel "HighBandwidthData" is limited to 1/s:
<communication>
<ServiceLevels>
<item>
<Channel>/HighBandwidthData</Channel>
<Interval>1000</Interval>
</item>
</ServiceLevels>
</communication>
For convenience, service levels can be set by channel type:
<communication>
<ServiceLevelsByType>
<item>
<Codecs>
<item class="mira::codec::JpegCodec">
<Quality>50</Quality>
</item>
</Codecs>
<ChannelType>
mira::Img[
unsigned char,3]</ChannelType>
<Codecs>
<item class="mira::codec::PngCodec">
</item>
</Codecs>
</item>
</ServiceLevelsByType>
</communication>
This needs to use the fully qualified name. '<' and '>' in the typename either must be escaped in XML ('<', '>'), or can be simply replaced by any of '('/')', '['/']' or '{'/'}' for convenience. Channel types can e.g. be looked up in miracenter's Channels view.
If there is a service level configured for a specific channel's name, that channel will ignore the by-type definition.
<namespace>
<namespace name="NamespaceName">
...
</namespace>
The <namespace> tag defines a namespace for all content between the starting and end tag. Namespaces can be nested.
Attributes
- name = "NamespaceName" (required)
- Specifies the name of the namespace
Nested Tags
Parent Tags
Example
In the example below, the unit IntSubscriber resides in the namespace /OuterNamespace/InnerNamespace. This means that also all the channels accessed and published by this unit are regarded as part of this namespace. Assuming that in this example the unit subscribes to a channel Int, the framework will refer to it internally as /OuterNamespace/InnerNamespace/Int. If a second unit publishes this Int channel in a different namespace, we need the <using> functionality to import channel names.
<namespace name="OuterNamespace">
<namespace name="InnerNamespace">
<unit id="IntSubscriber" class="IntSubscriberUnit"/>
</namespace>
</namespace>
<unit>
<unit id="UnitName" class="namespace::UnitClassIdentifier">
...parameters
</unit>
Declares a unit.
The 'id' specifies the authority name of the unit. The 'class' attribute specifies the class identifier of the unit for the class factory. The <unit> tag contains the parameters of the unit as subnodes.
Attributes
- id = "UnitName" (required)
- class = "namespace::UnitClassIdentifier" (required)
- Specifies the class identifier of the Unit or MicroUnit that should be created
- start = "true" (optional)
- Specifies whether to start the unit initially or not. If set to "false", the unit will be paused. The default is "true".
Nested Tags
- The parameters for the unit as subnodes
Parent Tags
Example
<unit id="IntPublisher" class="mira::IntPublisherUnit">
<CycleTime>10</CycleTime>
<AnotherParam>1.5</AnotherParam>
</unit>
<using>
<using name="/NS/Name" />
The <using> tags allows to import channel names and service names into other namespaces. Additionally a mapping (aliasing) can be applied. This means mapping names from one namespace to others, or injecting channels and services into namespaces.
Attributes
- name = "NameToImport" (required)
- Specifies the name of the Channel / Service that should be imported. This name usually will be given fully qualified (i.e. starting with "/") It is also allowed to import names from parent namespace by using "../" or going up several levels at once "../../../".
- as = "MappedName" (optional)
- Specifies the name of the Channel / Service in THIS namespace. If not specified the leaf of the name is used (e.g. in <using name="/NS/MyChannel"> 'as' is automatically set to 'MyChannel'
Parent Tags
Example
The unit IntPublisher publishes a channel Int. Since this unit has no namespace, it resides in the root namespace. As the unit IntSubscriber wants to access the channel Int, but resides in a different namespace, it must import /Int.
<unit id="IntPublisher" class="IntPublisherUnit">
<CycleTime>10</CycleTime>
</unit>
<namespace name="OuterNamespace">
<namespace name="InnerNamespace">
<using name="/Int" />
<unit id="IntSubscriber" class="IntSubscriberUnit"/>
</namespace>
</namespace>
If the unit IntSubscriber wants to access a channel of the same type but under a different name (e.g. Integer), we can specify the optional 'as' attribute:
<unit id="IntPublisher" class="IntPublisherUnit">
<CycleTime>10</CycleTime>
</unit>
<namespace name="OuterNamespace">
<namespace name="InnerNamespace">
<using name="/Int" as="Integer" />
<unit id="IntSubscriber" class="IntSubscriberUnit"/>
</namespace>
</namespace>
In order to import names from parent namespaces, use "../":
<namespace name="OuterNamespace">
<unit id="IntPublisher" class="IntPublisherUnit">
<CycleTime>10</CycleTime>
</unit>
<namespace name="InnerNamespace">
<using name="../Int" />
<unit id="IntSubscriber" class="IntSubscriberUnit"/>
</namespace>
</namespace>
<channel>
<channel name="ChannelName" slots="10"/>
This tag allows to configure the settings and internals of channels.
Attributes
- name = "ChannelName" (required)
- Specifies the name of the channel that is configured
- slots = "<Int>" (optional)
- Specifies the maximum number of slots that are allowed for the channel
- maxSlots = "<Int>" (optional)
- Specifies the maximum number of slots that are allowed for the channel (same as "slots")
- minSlots = "<Int>" (optional)
- Specifies the minimum desired number of slots to be used for the channel history
- storageDuration = "<Float>" (optional)
- Specifies the desired minimum duration for storing the channels history in seconds. This provides another mechanism beside "minSlots" to specify the minimum size of the channel's history. (Max slot count overrules storage duration, so if you have many channel updates and want to keep them for an extended time, you need to set both maxSlots and storageDuration.)
- autoIncreaseStorageDuration = "true" (optional)
- If this is true, the channel will automatically increase the storage duration when a read access requests data older than the most recent update, in order to ensure future read access to past data can be served (default: true).
Note: The <channel> tag is meant to set these attributes on channels which are fully defined through their publishers/subscribers. Due to the nature of channel creation, declaring a channel in the config file without instantiating any publishers or subscribers for it will create a channel "dummy" with no type and without any real use.
Parent Tags
Example
<channel name="Namespace/MyChannel" slots="10"/>
This sets the maximum number of slots for channel MyChannel in namespace Namespace to 10. Note that this only affects the maximum slots of the local framework. Note that, if your local framework connects to other frameworks subscribing this channel, the other frameworks define their maximum slot numbers independently, so it can differ.
<link>
<link child=
"ChildFrame" parent=
"ParentFrame" type=
"moving"/
"fixed"/>
or
<link child=
"ChildFrame" parent=
"ParentFrame" type=
"moving"/
"fixed">
...
</link>
This tag allows to add links between transformation frames. It can also be used to specify transformations between two frames (static or initial value). Transforms are specified by providing the values for translation and rotation between the opening and closing <link> tag. See example below
Attributes
- child = "ChildFrame" (required)
- Specifies the name of the child frame that is attached to the parent frame
- parent = "ParentFrame" (required)
- Specifies the name of the parent frame
- type = "moving" or "fixed" (optional)
- Specifies the type of the transformation link node
Parent Tags
Examples
Specifying a dynamic transform (with value e.g. to be updated by a publisher or played back from a tape):
<link child=
"Venus/Orbit" parent=
"Sun/Orbit" type=
"moving">
Specifying a 2D transform:
<link child=
"Venus/Pose" parent=
"Venus/Orbit" type=
"fixed">
<X>7</X>
<Y>0</Y>
<Phi>0</Phi>
</link>
Specifying a 2D transform with covariance:
<link child=
"LocalizationFrame" parent=
"Root" type=
"fixed">
<X>7</X>
<Y>0</Y>
<Phi>0</Phi>
<Cov>
[0.1, 0.0, 0.0;
0.0, 0.1, 0.0;
0.0, 0.0, 0.1]
</Cov>
</link>
Specifying a 3D transform:
<link child=
"KinectFrame" parent=
"Root" type=
"fixed">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
<Yaw>0</Yaw>
<Pitch>90</Pitch>
<Roll>-90</Roll>
</link>
Specifying a 3D transform with covariance:
<link child=
"LocalizationFrame" parent=
"Root" type=
"fixed">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
<Yaw>0</Yaw>
<Pitch>0</Pitch>
<Roll>0</Roll>
<Cov>
[0.1, 0.0, 0.0, 0.0, 0.0, 0.0;
0.0, 0.1, 0.0, 0.0, 0.0, 0.0;
0.0, 0.0, 0.1, 0.0, 0.0, 0.0;
0.0, 0.0, 0.0, 0.1, 0.0, 0.0;
0.0, 0.0, 0.0, 0.0, 0.1, 0.0;
0.0, 0.0, 0.0, 0.0, 0.0, 0.1]
</Cov>
</link>
<parameter>
<parameter name="Namespace/UnitName">
...
</parameter>
Specifies, adds or overwrites parameters of a unit.
The name specifies the name of the unit or the parameter(s) of a unit in a namespace. The tags within the <parameter> tag will replace tags of the same name in the unit/parameter if they exist, or will be added to the unit/parameter otherwise. It supports accessing parameters in collections and maps and provides a search operator for searching parameters.
Attributes
- name = "/Namespace/Unit.Param" (required)
- The name specifies the name of the unit or the parameter of a unit in a namespace. The content of the parameter tag is added or overwrites existing content relative to the path in the name attribute.
- hasChild = "SubParam.SubSubParam" (optional)
- If a search operator [?] is contained in the name attribute this attribute specifies an additional search path.
Nested Tags
Parent Tags
Example
The parameters (childs) in the parameter tag are relative to the last child parameter given in the name attribute:
<unit id="MyUnit" class="MyUnit">
<P1><P2><P3>Hello</P3></P2></P1>
</unit>
<parameter name="/MyUnit.P1.P2.P3">World</parameter>
<parameter name="/MyUnit.P1.P2">
<P3>World</P3>
</parameter>
<unit id="MyUnit" class="MyUnit">
<P1><P2><P3>World</P3></P2></P3>
</unit>
All parameters of the unit in the name attribute will be created if they do not exist:
<unit id="MyUnit" class="MyUnit"/>
<parameter name="/MyUnit.P1.P2">
<P3>Hello<P3>
</parameter>
<parameter name="/MyUnit.P1.P2.P3">Hello</parameter>
<unit id="MyUnit" class="MyUnit">
<P1><P2><P3>Hello</P3></P2></P3>
</unit>
To modify parameters in a collection or map you can use the [index] or ['index'] operator. for collections inserting can be done at different positions using [+begin], [+end] or [+index]:
<unit id="MyUnit" class="MyUnit">
<Collection>
<item>0<item>
<item>1</item>
<item>2</item>
</Collection>
<Map>
<key>a</key>
<item>0<item>
<key>b</key>
<item>1</item>
<key>c</key>
<item>2</item>
</Map>
</unit>
<parameter name="/MyUnit.Collection[0].item">1</parameter>
<parameter name="/MyUnit.Collection[0]">
<item>1</item>
</parameter>
<parameter name="/MyUnit.Collection[+end]">
<item>3</item>
</parameter>
<parameter name="/MyUnit.Collection[+begin]">
<item>-1</item>
</parameter>
<parameter name="/MyUnit.Collection[+1]">
<item>0.5</item>
</parameter>
<parameter name="/MyUnit.Map['a'].item">1</parameter>
<parameter name="/MyUnit.Map['a']">
<item>1</item>
</parameter>
<parameter name="/MyUnit.Map['d'].item">3</parameter>
If you only know the parameters of an item in the collection but not the index of the item you can use the search operator [?]. All parameters specified after the operator will form a search path. If no such parameter is found an exception is raised. The items in a collection are searched from first to last and only the first match is modified.
<unit id="MyUnit" class="MyUnit">
<Collection>
<item><A>0</A><item>
<item><B>1</B></item>
<item><C>2</C></item>
</Collection>
</unit>
<parameter name="/MyUnit.Collection[?].item.B">111</parameter>
If you want to search for a polymorphic parameter (with a specific class) you can use the {className} operator
<unit id="MyUnit" class="MyUnit">
<Collection>
<item><Module class="mira::ModuleA">0</Module></item>
<item><Module class="mira::ModuleB">1</Module></item>
<item><Module class="mira::ModuleC">2</Module></item>
</Collection>
<NestedCollection>
<item class="mira::ClassA">
<item>0</item>
<item>1</item>
</item>
<item class="mira::ClassB">
<item>2</item>
<item>3</item>
</item>
</NestedCollection>
</unit>
<parameter name="/MyUnit.Collection[?].item.Module{mira::ModuleB}">111</parameter>
<parameter name="/MyUnit.NestedCollection[?].item{mira::ClassA}[0].item">-1</parameter>
Using the attribute hasChild you can also search for an item that has a given sub structure while still modifying parameters relative to the item:
<unit id="MyUnit" class="MyUnit">
<Collection>
<item>
<Weight>0.1</Weight>
<Module class="mira::ModuleA">0</Module>
<item>
<item>
<Weight>2.0</Weight>
<Module class="mira::ModuleB">0</Module>
<item>
<item>
<Weight>10.0</Weight>
<Module class="mira::ModuleC">0</Module>
<item>
</Collection>
</unit>
<parameter name="/MyUnit.Collection[?].item" hasChild="Module{mira::ModuleB}">
<Weight>2.5</Weight>
</parameter>
The following examples shows a general overview:
<unit id="MyUnit" class="MyUnit">
<Pose>
<X>10</X>
<Y>0</Y>
<Phi>360</Phi>
</Pose>
<Int>1</Int>
<Collection>
<item>0<item>
<item>1</item>
<item>2</item>
</Collection>
<CollectionClass>
<item>
<Weight>0.1</Weight>
<Module class="mira::ns::ModuleA"/>
</item>
<item>
<Weight>0.5</Weight>
<Module class="mira::ns::ModuleB"/>
</item>
<item>
<Weight>10.0</Weight>
<Module class="mira::ns::ModuleC"/>
</item>
</CollectionClass>
<Map>
<key>a</key>
<item>0<item>
<key>b</key>
<item>1</item>
<key>c</key>
<item>2</item>
</Map>
</unit>
<parameter name="MyUnit.Pose">
<Phi>135</Phi>
</parameter>
<parameter name="MyUnit.Pose.Phi">135</parameter>
<parameter name="MyUnit">
<Int>2</Int>
<Hidden>10.333</Hidden>
</parameter>
<parameter name="MyUnit">
<Pose>
<X>20</X>
<Y>10</Y>
<Phi>180</Phi>
</Pose>
</parameter>
<parameter name="MyUnit.Collection[0].item">1</parameter>
<parameter name="MyUnit.Collection[0]">
<item>1</item>
</parameter>
<parameter name="MyUnit.Map['a'].item">1</parameter>
<parameter name="MyUnit.Map['a']">
<item>1</item>
</parameter>
<parameter name="MyUnit.Map['d'].item">3</parameter>
<remove_parameter>
<remove_parameter name="Namespace/UnitName.ParamName" />
<remove_parameter name="Namespace/UnitName" />
Removes a parameter of a unit in order to force the unit to use the default value for this parameter or to remove items from collections. The syntax for the name attribute is exactly the same as for the <parameter> tag.
Attributes
- name = "/Namespace/Unit.Param" (required)
- The name specifies the name of the unit or the parameter of a unit in a namespace. The parameter is erased from the config. Note that you can also remove entire units from the config by just writing:
name="Namespace/Unit"
- hasChild = "SubParam.SubSubParam" (optional)
- If a search operator [?] is contained in the name attribute this attribute specifies an additional search path.
Nested Tags
Parent Tags
<process>
Launches all units that are specified between the tag and the corresponding closing tag in a separate process, by starting an own mira or miragui executable. The process can be spawned on the same or a different machine. When the process is spawned on a remote machine an SSH is established. Username and password for the login can be specified using the settings below. However, it is recommended to use a password free SSH connection via shared keys (for details read here).
Attributes
- name = "somename" (optional)
- Specify a name for the process, to split up its definition (see "Named Processes" below)
- gui = "true" (optional)
- Will start the new process as "miragui" process, that allows to use Qt within its units (default: false)
- args = "arg1 arg2 arg3" (optional)
- Arguments that will be passed to the spawned process when it is launched.
- respawn = "true" (optional)
- Restart the process if it terminates or crashes (default: false)
- required = "true" (optional)
- Will stop the parent process, if the required sub process terminates (default: false)
- shutdownRecursively = "true" (optional)
- Will try to also stop all spawned descendant processes when stopping the sub process (useful when starting scripts, default: false)
- machine = "other.machine.org" (optional)
- Specifies the IP or URL of the machine where the process is started (default: localhost) If this parameter is set to the special value "thisprocess", the units will be started within "this process", hence, the process tag has no effect.
- port = "1234" (optional)
- The port where the spawned process is listening for incoming connections if 'connect' is true (default: 1234)
- connect = "true" (optional)
- If set to true, the calling process will automatically connect to the spawned process (default: true)
- delayConnect = "1000" (optional)
- Delay before starting to try establishing connection to the spawned process, in milliseconds (default: 2000ms)
- legacy = "true" (optional)
- If set to true, the parent will know the spawned process runs a legacy framework (using binary serialization format v0, from an older installation of mira), and will make sure to connect properly (default: false)
- forcePTP = "true" (optional)
- If set to true, will force time synchronization on the connection to the spawned framework, even though automatic detection would not recognize it as remote (e.g. with forwarded local port, default: false)
- user = "username" (optional)
- The username for the SSH connection
- sshpass = "password" (optional)
- The password for the SSH connection (NOTE: the sshpass tool needs to be installed on the system)
- executable = "path_to_mira_executable" (optional)
- Allows the specify the full path of the mira executable manually (default: mira or miragui, depending on the gui parameter)
- isMira = "false" (optional)
- Extends the <process> tag functionality to non-mira processes. If false, 'connect' will default to false and no mira config string will be given to the spawned process as parameter (default: true)
(note: previously named 'is_mira', changed for consistency, old name still works for compatibility)
- env = "variable1=value1;variable2=value2;variable3=value3" (optional)
- Allows to specify additional environment variables, that are set before the process is spawned
Nested Tags
Parent Tags
Named Processes
Processes can be named. This allows to associate units to the same process at different locations within the configuration file:
<!-- At the first occurance, the process should be configured -->
<process name="myprocess" machine="192.168.1.1" respawn="true">
<unit id="FirstUnit" class="SomeUnit"/>
</process>
...
<!-- At later occurances, the process can be referred to via its name.
The unit "SecondUnit" will be placed to the same process as the
"FirstUnit" above -->
<process name="myprocess">
<unit id="SecondUnit" class="SomeUnit"/>
</process>
Example
<process respawn="true">
<unit id="MyUnit" class="MyUnit"/>
<unit id="AnotherUnit" class="AnotherUnit"/>
</process>
<namespace name="outer_ns">
<process respawn="true" machine="192.168.1.1">
<unit id="MyUnit" class="MyUnit"/>
<namespace name="inner_ns">
<unit id="AnotherUnit" class="AnotherUnit"/>
</namespace>
</process>
</namespace>
<spawn>
(Should be obsolete, use <process ismira="false" executable="executable" args="arg1 arg2 arg3"> instead.)
Starts (spawns) a new process while loading the configuration and executes the specified command. The specified "command line" must contain the executable of the application that should be launched. It may, moreover, contain additional arguments that must be separated by spaces or tabs.
Attributes
- command = "executable arg1 arg2 arg3" (required)
- Command / executable to start with all arguments.
- respawn = "true" (optional)
- Restart the process if it terminates or crashes.
- required = "true" (optional)
- Will stop the parent process, if the required sub process terminates.
- machine = "other.machine.org" (optional)
- Starts the process on the specified remote machine.
Example
<spawn command="command line to execute"/>
<spawn command="command line to execute" machine="192.168.1.1" respawn="true"/>
The executed process will be stopped, when the parent application (mira or miracenter is terminated).
<defer_resolve>
<defer_resolve>
...
</defer_resolve>
Prevents preprocessing all child nodes (i.e., assigning or resolving variables, checking conditions, including files, issuing errors/warnings/notices). This is useful e.g. in conjunction with a <process> tag in order to defer resolving environment variables or file locations to the spawned mira process (which can run on a different host with its own environment).
<!--
Make the spawned process load the content of Config.xml and include it as its config
(in contrast to loading it here and transferring the content to the spawned process).
The' env' attribute transfers the path variable, otherwise it cannot be resolved
in the spawned process!
-->
<process env="configPath=${configPath}">
<defer_resolve defer="true">
<include
file=
"${configPath}/Config.xml"/>
</defer_resolve>
</process>
Attributes
- defer = "true" (optional)
- Control whether to actually defer, default = "true". If "true", child nodes are left unchanged, attribute is changed to "defer"="false". Otherwise, the tag is completely transparent.
<thread>
Creates a thread group for all enclosed units. Units within a thread group share an authority and therefore a main dispatcher thread. This makes sense for MicroUnits that do not need a process method and have only little work to do. A thread group can be used for reducing the number of used threads and for synchronizing multiple units. The specified 'id' is used as an authority name of the thread group.
<thread id="MyThreadGroup">
<unit id="FirstUnit" class="Instance">
...
</unit>
<unit id="SecondUnit" class="Instance">
...
</unit>
</thread>
Attributes
- id = "Name" (required)
- Specifies the name of the Authority that acts as a parent for all enclosed Units.
Nested Tags
Parent Tags
<log>
In the <log> tag, the user can specify the log severity level of the MIRA logging system. The log level must be specified using the attribute level. It can be specified as an integer number or as a string.
or
The values are: 0 = CRITICAL, 1 = ERROR, 2 = WARNING, 3 = NOTICE, 4 = DEBUG, 5 = TRACE.
<workspace>
The <workspace> tag can be used to specify a workspace file to be loaded when the configuration is started in miracenter. It behaves like the '–workspace' command line option (see miracenter). The file path must be specified by the file attribute:
<workspace
file=
"./personal.workspace" />
Only one file can be specified, therefore only the last respective tag within the entire config file is effective.
<initial_workspace>
The <initial_workspace> tag can be used to specify a workspace file to be loaded when the configuration is started in miracenter. It behaves like the '–initial-workspace' command line option (see miracenter): in contrast to the above tag, changes in the workspace are not saved to the loaded file, but to the file specified in <workspace> (or the default workspace file). The file path must be specified by the file attribute:
<initial_workspace
file=
"./initial.workspace" />
Only one file can be specified, therefore only the last respective tag within the entire config file is effective.
Note: the tag was previously named <initial-workspace>, but was changed to using snake_case in favour of a consistent tag naming scheme. For backward compatibility, the old version still works.