This section assumes previous knowledge of the concepts of nodes, topics and parameters. It's also recommended to read through the HRIM component model section before moving forward.
For instructions on installation and usage of the HRIM tooling go to the Tooling section.
We use XML to define our models in a machine-readable language.
Our module models will always contain a minimum of 9 mandatory topics (7 common ones, 1 defining it's specs and at least 1 purpose-specific one) and can contain mandatory parameters and optional topics and parameters. This model defines anything said module type could need to work communication wise, both as input or output.
Not all components will make use of every option defined inside a model, for example a motor would not be able to broadcast it's temperature if it doesn't have that capability, i.e. doesn't have an integrated thermometer. That's where the mandatory and optional topics and parameters come in: every communication/parameter deemed necessary for the module's integration in the system is mandatory and every module of that type will always make use of them, extra capabilities that not every module of that type would have are therefore optional.
As a (maybe not so) quick explanation:
A module is represented by a module tag (descriptive, right?). It must indicate the represented component's type as a name (i.e. rangefinder), it's module category as per our categorization as a type, and a short description, all as attributes.
A module contains the mandatory and optional (which is, funnily enough, optional) tags.
Each of those tags can contain topics, which would correlate to a topic, service or action, and/or param tags, which represent node parameters (so far so good).
Each topic tag must declare the represented topic's name, it's communication pattern type (publish if the module publishes that information, subscribe if it waits for it, service or action), a description of what that topic is for and a fileName*. A topic may also specify the package from which it originates through a package attribute (this is used to indicate the interface it represents wouldn't be generated for the current model, but comes from another one). The topic tag contains the definition of each of the values the topic's interface would hold in the form of properties. In the case of services and actions, their response and feedback (actions only) are declared as properties inside tags by that name.
As a quick example of this:
<topic type="service" ...> <property...>...</property> <property...>...</property> <response> <property name="result" type="boolean">...</property> </response> </topic>
Each property tag must declare it's name and type (data type), and can optionally declare a unit and a description to provide meta-data on that information piece. The property's type attribute can also be used to define it being a list using common notation (i.e. string for an unbounded list or string[n] for a bounded one). A property tag also either contains a value tag to declare a value for that field or other subproperties, indicating an submessage inside an interface. In this case, said property containing the subproperties would have to define a fileName* as a topic would, indicating the name of the interface to be generated, and may also declare a package of origin, following the same logic as with topics. Also, the type attribute of that topic would have no value other than indicating if it'd be a list, following the same notation as usual. A property correlates to a single value inside an interface.
*fileName indicates the name of the message file to be generated for the implementation. It also acts as a way for multiple topics to use the same message definition without each having it's own file. For an example on this, our camera module would use the same message file, with the same definition, for it's mandatory image_raw and optional image_mono, image_color, image_rect, and image_rect_color topics.
Phew! Finally got through that one! Don't worry, it all makes more sense when looking at a complete model. You can take a look at all the models we've developed so far inside the Models section.
You can also take a look at said models at our github repository inside the actuator, composite, power and sensor folders. If you do, you'll see how each module has it's own folder (i.e. sensor/rangefinder) and each of them has it's XML model (rangefinder.xml) and a topics folder that contains multiple XML files. Each of these files are related to the module's own topics, which are then referenced from the main model file.
Taking a look at said file you'll see the main structure defined above, some parameters, and some xi:include tags pointing to a generic/base.xml, topics/specs.xml, topics/distance.xml and topics/reconfiguration.xml, those having other references of their own. The first one references the 7 common interfaces mentioned initially and each of the others references a topic of the rangefinder, you can probably see some similarities between this and it's model page.
In the previous subsection we defined how a module's model is structured. However, they describe all the capabilities a module of that type could have, but not what a specific one might necessarily have. Not only that, but a module's capabilities might be composed of multiple models, e.g. a robotic arm with an integrated camera at the end. These wouldn't be two separated modules, but a single one with multiple capabilities, as the camera would be integrated, and therefore it would be a single component that would take from multiple models. For this, you'd use the model composition.
You can check out how this process works at our tooling examples section.