HRIM Tooling

Note: the paths/commands on this page assume a Linux distribution, but the HRIM tool is OS-independent through both Python2 and Python3.

Contains docker related files used for our continuous integration.

Contains templates for our issues.

Holds every XML model, following our module categorization. These models are structured in the following way:

├── camera
│   ├── camera.xml
│   └── topics
│       ├── audio.xml
│       ├── cameraInfo.xml
│       ├── compressed.xml
│       ├── image.xml
│       ├── ptz.xml
│       ├── reconfiguration.xml
│       ├── setCameraInfo.xml
│       └── specs.xml


  • camera: Contains the XML files defining a camera sensor module's own interfaces.

  • camera.xml: Defines every interface a camera module could make use of. It references both the generic and its own topics' XML files and defines the module's own parameters, both mandatory and optional. Said own topic definition files are the ones contained in the topics directory.

  • topics: Contains an XML representation of each of the modules' unique interfaces. Repeated interface definitions (e.g. the camera's model defines multiple messages with the same definition using image.xml) make use of a single interface definition file.

Additionally, the models directory also contains the generic and schemas directories, and a dataMapping.xml file, where:

  • generic: Contains an XML representation of the interfaces used by all modules (the 7 generic topics/services described at the HRIM component model section).

  • schemas: Contains the different (for now only) XSD schema files to validate the different complete XML module models.

  • dataMapping.xml: File defining dictionaries to map the different data types between platforms. This is done so that a single model definition is enough to later on generate an implementation in any platform, independently of type mismatches. As an example, ROS 2 doesn't accept Double as a data type and it should be mapped to a Float64.

Note: some of these files might change locations at some point, namely dataMapping.xml (which technically isn't a model).

Contains the files related to the tooling itself.

The directory holding the function-specific python scripts which are:

  • The main script, takes care of processing the passed arguments and makes use of the rest of the scripts.
  • scripts/ Defines the classes to be used across the tool. They are used to get an object representation of a module when parsing.
  • scripts/ Generates an HRIM implementation from the parsed models.
  • scripts/ Parses the passed XML models to their object representation.
  • scripts/ Defines multi-use methods used across the other scripts.

Contains the pylint-specific configuration file for automatic code reviews (checking for maximum line length, naming notation...). This is used on the continuous integration previously mentioned.

Contains .txt templates used for the generation of package files, like CMakeLists.txt and package.xml.

Our license.

Another configuration file (this one for travis) needed as part of our continuous integration.

A description file for GitHub.

The tooling is available as a pip3 package and installable executing:

pip3 install hrim

Alternatively (and necessary if modifying the scripts locally), execute the following while positioned at the repository's root:

pip3 install -e installator/

You'll need a ROS 2 environment to compile it's respective implementation, there's instructions on that at the official ros docs depending on your OS.

The command structure would be the following:

hrim [-h] [-p {ros2}] {generate,compose,compile,list,clear} filePath [filePath ...]


-h/--help shows script's help.

-p/--platform should be followed by which platform (e.g. ROS 2) to generate the implementation in. Current valid values are:

  • ros2

{generate,compose,compile,list,clear} is mandatory and signifies the action to take:

  • generate: parses the passed module file and generates the corresponding packages/files to use with the selected platform (ROS 2 by default). The generated files will be located inside a generated directory on the root of the repository. Also accepts the following shorthands:

    • all: generates the implementation of every existent model
    • actuators: generates the implementation of every existent actuator models
    • composites: generates the implementation of every existent composite models
    • powers: generates the implementation of every existent power models
    • sensors: generates the implementation of every existent sensor models
  • compose*: meta-model composition. Generates a composition of models from the passed models in the repository's root, named model.xml. Expects a list of models for the composition as arguments, in a type/subtype or type/subtype/model (without the file extension) format. You can get a list of all valid models by running hrim list models at the repository root.
  • compile: meta-model package generation. Generates the corresponding packages/files based on the passed model composition file. Expects the composition's XML file as an argument.
  • list: lists either generated implementations or existing models. Expects one of the following:
    • models: lists all existing models.
    • implementations: lists all existing generated implementations.
  • clear: deletes generated implementations. Expects the name of the implementation to delete from the generated directory (i.e. sensor/imu will delete generated/sensor/imu, sensor will delete generated/sensor). Alternatively, use all to delete all generated implementations (doesn't include compositions).

*NOTE: 3D cameras require a type/subtype/model format (i.e. sensor/3dcamera/3dcamera_depth).

This format is valid for every other model too (i.e. actuator/servo/servo)

Generated packages will be placed inside a generated directory on the root of the repository. These packages will be organized inside directories named after it's respective module, inside directories named by the component type (sensor, actuator...). If the module defines any parameters, a .yaml file will be generated for the mandatory and optional parameters, respectively called mandatory_parameters.yaml and optional_parameters.yaml. As an example of a ROS 2 implementation of a camera:

├── sensor
│   ├── camera
│   │   ├── hrim_sensor_camera_msgs
│   │   │   ├── CMakeLists.txt
│   │   │   ├── msg
│   │   │   │   ├── Audio.msg
│   │   │   │   ├── CameraInfo.msg
│   │   │   │   ├── CompressedImage.msg
│   │   │   │   ├── Image.msg
│   │   │   │   ├── PTZ.msg
│   │   │   │   └── Reconfiguration.msg
│   │   │   └── package.xml
│   │   ├── hrim_sensor_camera_srvs
│   │   │   ├── CMakeLists.txt
│   │   │   ├── package.xml
│   │   │   └── srv
│   │   │       ├── SetCameraInfo.srv
│   │   │       └── SpecsCamera.srv
│   │   ├── mandatory_parameters.yaml
│   │   └── optional_parameters.yaml

After generating the desired packages, you can colcon build them like any other ROS 2 package and source them for usage. For example (assuming you are positioned at the repository's root):

source ~/ros2_ws/install/setup.bash # You'll need to source your existing ROS 2 environment, the path might change
colcon build
source install/setup.bash

You might get an error when running colcon build because of duplicate package names that would look something like:

ERROR:colcon:colcon build: Duplicate package names not supported:
- hrim_actuator_electricmotor_msgs:
  - .../HRIM/composition/defaultName/hrim_actuator_electricmotor_msgs
  - .../HRIM/generated/electricmotor/hrim_actuator_electricmotor_msgs

This happens if the directory you are currently at (for example, the repository's root) contains multiple definitions of the same package (for example, two separate compositions sharing one of their components). This is easily solvable positioning yourself at a path that doesn't contain multiple definitions, following the example above it could either be composition/defaultName or generated. Retry the compilation after this.

For execution examples check out the tooling examples section