No description, website, or topics provided.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
images
tutorial
.gitignore
LICENSE.md
README.md

README.md

Installation

Pre-requisites

  • Ubuntu 14.04 or above
  • ROS / DDS / ZMQ
  • Cmake 2.8+
  • gcc for C++11
  • Doxygen
  • Java 8+
  • Maven 3+
  • kpsr-core

Installation

Building and installing the code

CMake part

At the parent folder of kpsr-core:

git clone https://bitbucket.org/kpsr-devs/kpsr-code-generator.git
cd kpsr-code-generator
mkdir build
cd build
cmake ..
make
sudo make install

This will install two files in the main Klepsydra installation folder:

/opt/klepsydra/bin

These files are:

  • kpsr-code-generator-VERSION-jar-with-dependencies.jar which is executable for generation code.
  • cmake/KpsrCodeGen.cmake. a utility cmake script for running the code generator tool at cmake execution time.

The code generator tool guide

A note on Klepsydra Publishing and Subscription

This tool generates the code corresponding to events that can be published and subscribed in Klepsydra.

However, it is very important to notice that Klepsydra does not need to use the event generated with this tool, but any object with the following methods:

  • Copy constructor
  • Empty constructor
  • Clone method

Any object fitting into these requirements, can be used to publish and subscribe in Klepsydra.

Now, these requirements are for events sent within the same process (in-memory communication) for events that need to travel using ROS, DDS, or ZMQ, further requirements need to be met. For example for ROS, a MSG file is needed, for DDS, it is a IDL and for ZMQ a Cereal JSON or Binary serializer are needed.

Also, for all these middleware, Klepsydra also need a mapper class to convert from the middleware realm into the Klepsydra one and vice versa.

The advantage of using this code generation tool is that all these elements are automatically created and the developer only needs to worry about the application concern itself.

Introduction

Klepsydra generation code tool is driven by a file that contains all the information to generate an event class. This file is called KIDL (Klepsydra Interface Description Language).

The generated code is placed under a folder called gen placed in a location provided to the code generation tool. This folder should be included as is in your project to avoid mixing up different versions, etc.

This tool is written in Java and it is extensible and flexible to adapt to both new data types and new middleware.

The following sections will cover each of these elements in details.

A note on best practices

The use of native middleware message classes through the code is considered bad practice by many experts. For example, this link to Ros unit testing explains that you need to right your code 'sans ROS'. This allows you to perform testing without all the catkin system in ROS, but only with cmake, which is lightweight and easy to develop and test.

In general, best practices recommend the use of Plain Old C++ Objects or POCOs in your code rather than middleware classes and do object mapping between them. This is exactly what our tool does: we generate POCOs and the corresponding mappers to middleware.

Example

Lets start by showing an example of a KIDL file:

className: Temperature
middlewares:
relatedClasses:
enums:
    - name: Units
      exists: false
      values:
         - CELSIUS = 0
         - FAHRENHEIT
         - KELVIN
fields:
    - name   : value
      type   : float32
    - name   : units
      type   : Units

This KIDL describes a class Temperature that has two attributes. The first is value which is of standard type float32, which is translated into float in C++. A table with all the standard types and their conversion types is available in REF!!!.

The second attribute is units of the custom type Units. In this case, this type corresponds to an enumeration. Which is defined as well in this KIDL. All custom types in KIDL are either an enum or a class. In the former, the definition can be included in the same KIDL, but in the latter, it cannot. We will come back this second type later on in this document.

The output of the generator for this KIDL is the following:

/* Copyright (C) Klepsydra Robotics - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 */

// This code has been automatically generated, manual modification might be inadvertently overridden.

#ifndef TEMPERATURE_H_
#define TEMPERATURE_H_


// Include section.


// Klepsydra generated event class.
class Temperature {
public:
   // Autogenerated Enum.
   enum Units {
      CELSIUS = 0,
      FAHRENHEIT,
      KELVIN
   };

   // Default constructor.
   Temperature() {}

   // Main constructor.
   Temperature(
      float value,
      Units units)
      : value(value)
      , units(units)
   {}

   // Clone constructor. Needed by klepsydra core APIs.
   Temperature(const Temperature & that)
      : value(that.value)
      , units(that.units)
   {}

   // Clone method. Needed by klepsydra core APIs.
   void clone(const Temperature * that) {
      this->value = that->value;
      this->units = that->units;
   }

   // List of fields.
   float value;
   Units units;
};
#endif

This C++ class has two very important features:

  • This class is a POCO (plain old C++ object). In other words, it has no includes. Meaning that there are no dependencies whatsoever to anything other than C++11 standard. This is one of the key points in the Klepsydra philosophy: non-intrusive and lightweight.
  • The second important thing, is that the constructors are already created to fit the needs of Klepsydra publishers and subscribers.

The KIDL file

As explained in the introduction, this file in the YAML format and contains all the information needed to create the event class and, if specified, the middleware mapper and corresponding classes, files, etc.

Each KIDL contain four sections, some of them being optional:

  • Header. Where the class details are defined (class name, namespace, etc)
  • Middlewares. All the list of middlewares that this class will be used for. Optional section.
  • Related class and enums. All related elements to this class that will be used. Optional section.
  • Fields. List of all class fields.

Each of these sections will be explained in the remaining of this chapter.

Header

The header contains the following attributes, some of them being optional:

  • className. Name of the class event. This should be in the form of C++11 class naming spec.
  • namespace. Optional attribute in case we want to provide a namespace for the class. It should in the C++11 composed namespace form: nm1::nm2::nmx.
  • parentClass. Optional attribute to specify the presence of a parent class. If so, the constructors and clone methods will invoke the parent versions.
  • builder. Optional attribute that specify wether we want to create a builder for this class. This builder is generated as per the traditional builder pattern.

Middleware

The middleware section is the one in the lead of the definition of how will the conversion between Klepsydra and the middleware will be done. It has the following fields:

  • type. The type of middleware: ROS, DDS, ZMQ. This one of the main extension points of this tool as new middlwares are relatively easy to add.
  • namespace. The namespace to be used when naming the classes in the middleware. In the ROS case, it is only used when the class has to be generated.
  • exists. Boolean value to determine if the middleware specific files and classes have to be generated (e.g. MSG or IDL, etc). Useful in the case of ROS when reusing existing messages (geometry, sensors, etc.)
  • classNamespace. Namespace of the class message, in case it exists. This is an optional value, but quite useful when using existing classes in ROS. In the ROS specific tutorial, we will explain this in more detail.

Tool Usage

The tool works as a command line tool. It also integrates quite well with CMAKE. See tutorial examples in this repository for further information.

To use the tool as command line:

java -jar ${KPSR_CODEGEN_JAR} -f ${KIDL_FILE} -o ${genDir} -t event

Where:

  • KPSR_CODEGEN_JAR is the jar file created by the tool.
  • KIDL_FILE is the user provided KIDL
  • genDir is the output directory for the generated files.

CMAKE Script

The tool can be also be invoked at the cmake running time using the following blocks of cmake code:

First, we copy the cmake script from the Klepsydra installation and then we include it:

file(COPY ${KPSR_INSTALL}/bin/cmake/KpsrCodeGen.cmake
        DESTINATION ${CMAKE_SOURCE_DIR}/cmake/)

include(KpsrCodeGen)

Now, the tool can be invoked like this:

KpsrEventGenerator("${CMAKE_CURRENT_SOURCE_DIR}/kidl"
                   "${CMAKE_CURRENT_SOURCE_DIR}/gen")

Output dir structure.

The structure of the output folder is quite simple. The following tree shows the structure in the case of ROS. For DDS and ZMQ, the structure is quite similar:

.
+-- gen
|   +-- core
|       +-- include
|           +-- generated_event.h
|   +-- stages
|       +-- rosstg
|           +-- namespace
|               +-- include
|                   +-- event_ros_mapper.h
|               +-- msg
|                   +-- event.msg
|               +-- node
|                   +-- event_node_handler.js

License

© Copyright 2016-2017, Klepsydra Robotics, all rights reserved. Licensed under the terms in LICENSE.md