- 3.0.2 Documentation
Developer Guidelines

We very much welcome external developers. Small changes and contributions can be made via pull requests. If you have a larger enhancement, bug fix or other contribution in mind, feel free to first create an issue to align the development with ongoing activities.

Formatting

We support clang-format and provide a style template to automatically format the source code. Please refer to the clang-format style sheet in the package root directory for our conventions.

Example command for running clang-format:

$ catkin build --no-deps <package_name> -v --make-args clang-format

Template Instantiation

CT relies on explicit template instantiation, that means precompilation of the library for user-specified state and control dimensions. While CT handles things slightly different, please see this post to learn more about the subject. The basic idea is that for all templated class there is

  • a header (.h) that defines the class and its methods
  • an (header) implementation (-impl.h) that implements all methods
  • a cpp template file (.cpp.in) that instantiates the template

The template file has the following placeholders

Placeholder Description
STATE_DIM_PRESPEC The state dimension
CONTROL_DIM_PRESPEC The control dimension
SCALAR_PRESPEC The scalar type
DOUBLE_OR_FLOAT "true" if the scalar type is double or float
POS_DIM_PRESPEC Position dimension for symplectic integrator (default: 0)
VEL_DIM_PRESPEC Velocity dimension for symplectic integrator (default: 0)

You can use these placeholders in the code

#if \@DOUBLE_OR_FLOAT\@
template class ct::coreMyClass<\@STATE_DIM_PRESPEC\@, \@CONTROL_DIM_PRESPEC\@>;
#endif

The parser in the CMakeLists.txt would then create the following code out of this (for STATE_DIM=3, CONTROL_DIM=2, SCALAR=double)

#if 1
template class ct::coreMyClass<3, 2>;
#endif
Note
The parameter DOUBLE_OR_FLOAT is optional but can be used if your class does not compile for Auto-Diff types which is often the case if no special care is taken.

Other guidelines

  • Headerguards: please use
    #pragma once
    as header guards, rather than
    #ifndef
    #define
    /*...*/
    #endif
  • never use std::make_shared and std::allocate_shared within the CT. They cause aligment issues, compare the following bugreport: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1049 Currently, the best option is to declare and define shared pointers using CT types as in the following example
    std::shared_ptr<ct::core::ControlledSystem<state_dim, control_dim>> nonlinearSystem( new SomeClass(...));