Tooling

This page describes HRIM tool's meta-development branch usage as per January 9 2019.

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

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

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

Where:

  • camera: Contains the model files defining a camera sensor module's communication.

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

  • camera.xml: Defines every communication 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.

  • camera_clean.xml: An alternate definition file for the module; has the same contents as camera.xml but without references to other files, a standalone model if you will. These are development files, so they will disappear in time. These files ares used both for readability (although they can get quite verbose) and schema verification.

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

  • generic: Contains an xml representation of the topics/structures used by all modules. This includes the 7 generic topics described at the HRIM component model section, as well as the Header and Time structures' definition, used to timestamp every published message.

  • geometry: Contains geometry-related common data structures used by multiple models, like quaternions or vectors.

  • 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).

The directory holding the function-specific python scripts. It's contents are:

  • classes.py: Defines the classes to be used across the tool. They are used to get an object representation of a module when parsing.
  • compiling.py: Generates an HRIM implementation from the parsed models.
  • parsing.py: Parses the passed XML models to their object representation.
  • printing.py: Shows a visualization of a parsed model.
  • utils.py: Defines multi-use methods used across the other scripts.

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

The main script, takes care of processing the passed arguments and makes use of the rest of the scripts.

The tooling itself depends on python's lxml library:

sudo apt-get install python-lxml

or

sudo apt-get install python3-lxml

Alternatively, the OS-independent pip command would be:

pip install lxml

or

pip3 install lxml

Additionally, 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:

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

Where:

-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

-e/--extend indicates whether already shown definitions should be shown again or not when printing the module's model (only shown once by default).

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

  • show: parses the passed module file and prints it's processed contents.
  • 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.
  • compose: meta-model composition. Generates a composition of models from the passed models in the repository's root, named model.xml.
  • compile: meta-model package generation. Generates the corresponding packages/files based on the passed model composition file.
  • list: lists either generated implementations or existing models.
  • clear: deletes generated implementations.

filePath is mandatory and what it signifies depends on the action to take:

  • show: path to the xml model file to show a definition of.
  • generate: path to the xml model to generate an implementation from. Alternatively, one of the following shorthands:
    • all: generates the implementation of all models.
    • allClean: generates the implementation of all development models.
  • compose: one or more models to make a composition from, in a type/subtype or type/subtype/model (without the file extension) format. You can get a list of all valid models making use of the list function.

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)

  • compile: the path to the model composition xml file (by default model.xml)
  • list: what you want to list:
    • models: lists all existing models.
    • implementations: lists all existing generated implementations.
  • clear: name of the implementation to delete from the generated directory (i.e. imu will delete generated/imu). Alternatively, use all to delete all generated implementations (doesn't include compositions).

Alternatively, shorthands are provided to generate the files for every existing module:

  • all: will generate the files for every existing (non-development) module file.
  • allClean: will generate the files for every existing development module file (module xml files ending with _clean).

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. 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:

generated/
...
├── camera
│   ├── hrim_sensor_camera_msgs
│   │   ├── msg
│   │   │   ├── Audio.msg
│   │   │   ├── CompressedImage.msg
│   │   │   ├── PTZ.msg
│   │   │   ├── Reconfiguration.msg
│   │   │   ├── CameraInfo.msg
│   │   │   ├── Image.msg
│   │   │   └── SpecsCamera.msg
│   │   ├── CMakeLists.txt
│   │   └── package.xml
│   ├── hrim_sensor_camera_srvs
│   │   ├── srv
│   │   │   └── SetCameraInfo.srv
│   │   ├── CMakeLists.txt
│   │   └── package.xml
│   ├── 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.

While positioned at the repository's root all of the following are valid command executions:

  • python hrim.py show $(pwd)/models/sensor/torque/torque.xml
  • python hrim.py show ./models/sensor/torque/torque.xml
  • python hrim.py -e show /models/sensor/torque/torque.xml
  • python hrim.py show --extend models/sensor/torque/torque.xml
  • python hrim.py show models/sensor/torque/torque.xml
  • python hrim.py generate $(pwd)/models/sensor/torque/torque.xml
  • python hrim.py generate ./models/sensor/torque/torque.xml
  • python hrim.py -p ros2 generate /models/sensor/torque/torque.xml
  • python hrim.py generate models/sensor/torque/torque.xml
  • python hrim.py generate --platform ros2 all
  • python hrim.py generate allClean
  • python hrim.py list models
  • python hrim.py clear all
  • python hrim.py clear imu
  • python hrim.py compose composite/arm sensor/imu actuator/gripper/gripper sensor/3dcamera/3dcamera_stereo
  • python hrim.py compile model.xml
  • python hrim.py compile validComposition.xml