# Meta-model

### Module structure

We use XML to define our model's 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?) and would correlate to a node. It must indicate the represented component's type name (i.e. rangefinder), it's module category as per our categorization, and a short description.

• A module contains the mandatory and optional (which is, funnily enough, optional) tags.

• Each of those tags can contain topic, which would correlate to a topic or service, and/or param tags, which represent the node's 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*. It contains the definition of each of the values the topic's message would hold in the form of properties.

• 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 a message inside a message. In this case, said property containing the subproperties would have to define a fileName* as a topic would, indicating the file to be generated. 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 a message.

• Each param (parameter) tag must declare it's name and type (data type) and, optionally, it's unit and description, following the same logic as with the properties. A param correlates to a node parameter.

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), a development version of this model (rangefinder_clean.xml) which will disappear in time, 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 (rangefinder.xml).

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 topics 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. You can also take a look at the development rangefinder_clean.xml file to see how the complete file would look like after the references are processed.

Common structures, like the header (provides a timestamp), vectors, or the 7 common topics, are also separated for reusability and can be found in the complex and generic directories.

### Model composition

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. For this, you'd use the model composition:

First, you'd indicate to the tool that you want to generate a composite model and it's parts. Following the example above of an arm with an integrated camera:

python hrim.py compose composite/arm sensor/camera

This will generate an xml file (composition.xml by default, customizable using the -o or --output optional parameter followed by the desired file name) in the repository's root with a structure like the following, where each of those component's shows all it's optional capabilities (the mandatory ones are, well, mandatory, so the tool won't let you choose between those):

<composition>
<module type="composite" subType="arm">
<topic name="rc"/>
<topic name="reconfiguration"/>
</module>
<module type="sensor" subType="camera">
<topic name="compressed"/>
<topic name="image_mono"/>
<topic name="image_color"/>
<topic name="image_rect"/>
<topic name="image_rect_color"/>
<topic name="image_camera_info"/>
<topic name="set_camera_info"/>
<topic name="ptz"/>
<topic name="audio_raw"/>
<topic name="reconfiguration"/>
<param name="auto_brightness">
<param name="brightness">
<param name="auto_binning">
<param name="binning_x">
<param name="binning_y">
<param name="auto_contrast">
<param name="contrast">
<param name="auto_exposure">
<param name="exposure">
<param name="auto_focus">
<param name="focus">
<param name="auto_gain">
<param name="gain">
<param name="gain_red">
<param name="gain_green">
<param name="gain_blue">
<param name="auto_gamma">
<param name="gamma">
<param name="auto_hue">
<param name="hue">
<param name="auto_iris">
<param name="iris">
<param name="auto_iso">
<param name="iso">
<param name="auto_saturation">
<param name="saturation">
<param name="auto_sharpness">
<param name="sharpness  ">
<param name="auto_shutter">
<param name="shutter">
<param name="auto_white_balance">
<param name="white_balance_blue">
<param name="white_balance_red">
<param name="auto_zoom">
</module>
</composition>

Now, there's some optional parameters that might not get listed. For example, the parameters related to rc in the arm's model. This is because those parameters are related to a specific topic, they are mandatory if said topic is implemented and have no purpose without it. Including the rc topic will automatically also include those parameters.

Moving forward, now is when you remove the optional capabilities your component doesn't support. You might be left with something like:

<composition>
<module type="composite" subType="arm">
<topic name="rc"/>
</module>
<module type="sensor" subType="camera">
<topic name="image_color"/>
<topic name="image_rect_color"/>
<param name="auto_binning">
<param name="binning_x">
<param name="binning_y">
</module>
</composition>

After saving the changes you'd now "construct" the model of your composed component. That is to say, the tool will create an xml model based on the structure above. To do this just run (assuming the default file name):

python hrim.py construct composition.xml

This will in turn generate an xml model (model.xml by default, again customizable using the -o or --output parameter) of your component in the root of the repository, containing a composition of both models with their mandatory topics and parameters and the optional capabilities you indicated. This xml model can finally be used to generate your component's platform specific implementation by running (again, assuming the default file name):

python hrim.py generate model.xml

Which will generate the necessary packages containing the files needed to communicate with your component (now module!). The default platform of this implementation will be ROS 2, this can easily be modified by using the -p or --platform optional parameter followed by the desired platform.