Follow this link to skip to the main content

Naming Conventions and Coding Standards

The Naming Standards and Coding Conventions are kept to a minimum and made as simple as possible. All CLARAty code should use these conventions as well as the ANSI C++ Standard. In rare cases, deviations are acceptable only if they provide an improvement to code clarity, efficiency, or address limitations in compilers and operating systems.

For modules to reach Integration Level 4, they need to be fully compliant with these conventions. new

The table below provides you with a quick reference.

Summary

Item Examples Description
Module Name wheel_locomotor
morphin_navigator
r8_motor
hw_pxc200-framegrabber
singular (with rare exceptions - e.g. bits), lowercase, underscore separated
Use specific to general specific_general or descriptor before name
robot specific start w/ robot prefix
hw_[bkplane]_name-func. Use dash to define hw functionality
Module Library Name libwheel_locomotor module name with lib prefix
File Name wheel_locomotor.h
morphin_navigator.cc
r8_motor.cc
pxc200.h
same rules as module names
for hardware, drop hw prefix and the dash suffix
Binary File Name utest_class_name.cc
btest_class_name.cc
demo_class_name.cc
regression test program returns 0 for success or number of failures
regression test program that needs to be compared to canned data
demonstrates simple usage and interactive functionality
File Extenstion .cc, .h, .c
Header file protection #ifndef  (FILE_NAME_H) uppercase filename with underscore separations
Class Name Morphin_Navigator
Camera_Image
leading caps, underscore separated, specific to general
descriptors prefix name
Function Name function_name(int arg)
lowercase, underscore separated
get_x()
set_x()
use get prefix to retrieve value (for non-data structure types)
use set prefix to set value (for non-data structure types)
Public Member Function / Variable foo_bar()/ foo_bar lower case, underscore separated
Private/Protected Function / Variable _foo_bar() / _foo_bar leading underscore, lower case, underscore separated
Enumeration / Define enum TYPE_NAME { ELEMENT_NAME,...}
#define MAX_VARS
enumerations name and content and template types are uppercase,
underscore separated
Pointer and Reference int * ptr
int * * ptrPtr

int * p1, * p2
Object & reference

pointers and references separated from variable and typename and lined up to for clarity (C++ style, not C).
Coding Standards
Documentation and Formatting Doxygen

Naming Conventions

Module Names

  • Send email to claraty-help if you need to create a new module.
  • Make module names lowercase with underscores '_' to separate words. For example: trajectory_generator
  • Match library name of a module to module name with the lib prefix. For example: libtrajectory_generator
  • Use only singular (not plural) names. For example: matrix and not matrices
  • Use descriptor before generic name. For example, the GESTALT navigation algorithm can be found a in module called: gestalt_navigator, and the JPL stereo algorithm can be found in a module called jpl_stereo_vision
  • Place reusable hardware drivers in separate modules.
  • Use this format for hardware drivers: hw_[<backplane>]_<name>-<function>. Start all hardware module names with hw_ followed by backplane name, if applicable (e.g. vme_, pci_, i2c_, isa_, etc.), followed by the hardware board name with a trailing dash (e.g. vpar10-, s720-, lm629- , etc.), followed by the definition of the board functionality (e.g. framegrabber, digital_io, analog_io, etc.). The dash separates the name of the board from the definition of its functionality. For example, a compact PCI driver for the PX610 framegrabber from Imagenation is: hw_pci_px610-framegrabber
  • Do not use the word "claraty" with any module name
  • Use the following standard prefixes and include directory conventions:
Name Module name Include Directory Comments
Task or Project project_<name> project/ For tasks supported by the MTP, IS, or other programs. No modules should depend on these
Hardware drivers hw_[<backplane>]_<name>-<function> hw/ For reusable hw drivers. Use backplane if applicable
User module user_<username> user/ Users' own private modules. No modules should depend on these
Rover or robot specific <robot_prefix>_<name> see below See table below
Science analysis analysis_<name> claraty/ Science analysis software
Utility modules <name>_utils claraty/ For 3rd or misc utilities, e.g. qt_utils, gl_utils, etc.,
All other modules see above claraty/ Core modules

Robot Name Module/Filename Prefix Class Name Prefix Include Directory Comments
Rocky 8 r8_ R8_ rocky8/ Six wheel Rocker Bogie Rover
FIDO fd_ FD_ fido/ Six wheel Rocker Bogie Rover
Athena athena_ Athena_ athena/ Six wheel Rocker Bogie Rover
K9 (ARC) k9_ K9_ k9/ Six wheel Rocker Bogie Rover
Pluto pl_ PL_ pl/ Six wheel Rover / Progammable Logic
Rocky 7 r7_ R7_ rocky7/ Six wheel Rocker Bogie Rover
ROAMS rs_ RS_ roams/ Rover Simulator
ATRV Jr aj_ AJ_ atrv_jr/ COTS All terrain rover from IRobot
Axel axel_ Axel_ axel/ Two wheel minimal Rover
LEMUR lemur_ LEMUR_ lemur/ Legged Robot

File Names

  • File Extensions
    • Use .h suffix for all C++ and C header files
    • Use .cc suffix for all C++ source files
    • Use .c suffix all C source files
  • Use all lower case for filenames with underscores '_' to separate words (e.g. trajectory_generator.cc)
  • Start module and file names with a number as appropriate (e.g. 2d_point, 1d_solver, 3d_object). For corresponding class names, see below.
  • For C++ templates, separate class/function declaration from their implementation. Place declarations in .h files and implementations in .ipp files. Include the .ipp file in the .h file. List the .ipp file in the INC_LINKS of the Makefile if the file needs to be externally visible.new
  • Do not use the word claraty or cl in any filenames
  • Use short prefix per above table for robot adaptation filenames
  • Whenever possible, match the primary header and source filenames with the module name. For example:
    • Module fd_locomotor has files two primary files fd_locomotor.h and fd_locomotor.cc
  • Use one class per file unless the classes are nested (within the scope of the encompassing class)
  • For each module, create appropriate demo and test file(s) as follows:
    • demo_<file>.cc to show how to use <file>.cc. If multiple demo scenarios are appropriate spanning simple to complex usages, add additional files. Use demo_<file>_simple.cc to show the simple cases. In some cases, it makes sense to have one demo_file.cc for a number of .cc files.
    • utest_<file>.cc to carry out the unit regression tests. Use CPPUnit to build this test. The return of the executable should follow the Unix convention. If the test succeeds, the program should return 0, otherwise it should return the number of failed tests. The output should provide an executive summary on how many tests succeeded/failed and which tests failed. Specific format for output TBD.

  • Class / Function / Variable Names
    • Name Spaces
      • All CLARAty classes should be under the claraty namespace. Generally, classes from third party deliveries are not considered CLARAty classes and may use their own namespace.new
      • Do not use using namespace blah; in any .h file. Use std:: prefix in all .h files as appropriate for cout, cerr, endl, etc.
      • Use using namespace std; in .cc file as appropriate and avoid using std:: prefix for cout, cerr, and endl;. Use std:: prefix in .cc for clarification only (e.g. std::max(), etc)
    • Class Names
      • Start every word an uppercase letter with words separated by underscores. Make all abbreviations letters uppercase; so use JPL and not Jpl
      • For robot specific classes, use above table. For example, module names such as: r7_mast and fd_locomotor should have corresponding class names R7_Mast and FD_Locomotor respectively
      • Use intuitive classname: e.g. Color_Image, RGB_Image, Linux1394_Camera, DIO_Port
      • For classes that start with a number. e.g. 2d_point, 3d_object, etc, use the N_ prefix since classes cannot start with a number (e.g. N_2D_Point and N_3D_Object)
    • Function Names
      • Use lowercase with words separated by underscores (e.g. set_cmd_velocity())
      • Use get_num_xx() for instead of get_number_of_xx()
    • Template Types
      • Use either uppercase single letter or follow enumeration/define name convention (e.g. template<class T> or template<typename TYPE_NAME>)
    • Member Variable Names
      • Use lowercase with words separated by underscores (e.g. current_velocity)
      • Start private/protected variables with an underscore (e.g. _last_velocity)
    • Argument Names and Automatic Variables
      • Capitalize the first letter of each subsequent word (e.g. currentVelocity)
      • Use leading catch-strings to function arguments to make them easier to spot during maintenance (e.g. _set_foo( theFoo) {foo = theFoo; })
    • #defines and Enumerations
      • All defines and enumerations contents should be in uppercase with underscore separated words (e.g. enum MOTOR_CONTROL_MODE {VELOCITY, TRAPEZOIDAL_TRAJECTORY}

    Code Standards

    • Multiple inclusion protection:
      • Use the following mechanism to avoid multiple header file inclusions. While the #define for the header file can be arbitrary but unique, use the following convention:
        Filename: matrix_operators.h
        #ifndef  MATRIX_OPERATORS_H
        #define  MATRIX_OPERATORS_H
        ...
        // code goes here
        ...
        #endif // MATRIX_OPERATORS_H
    • Header file includes:
      • Place all definitions global to all modules inside the common definition file common_defs.h which can be found in the share module. These should be rare and need to be coordinated with the rest of the team.
      • Place all definitions that need be accessible to other modules (externally global) in the module's primary header file module_name.h
      • Prefix all generic includes with claraty directory per above table. For example, #include "claraty/image.h"
      • Prefix hardware and adaptation includes with appropriate directories per above table
      • Make common_defs.h the first header file you include.
      • Use double quotes "" delimiters for all CLARAty and user defined header files.
      • Where possible, use <> delimiters without a .h extension for system level includes (e.g. #include <iostream>)
      • Include only files that are needed in the header file itself unless there is a good reason to add other files (e.g. resolving circular dependencies). If a source file including that header needs additional include files, include them in the source file but not in the header file.
      • If it is not obvious from the header file name why a header file is included, add a comment, e.g.:
        #include <unistd.h>      // for read()
        #include <iostream>
      • The order in which header files are included should be as follows unless there is a good reason to change that order. Resolving circular dependency loops in header file definitions remains one of the C++ language's biggest stumbling blocks. Care should be taken not to exacerbate this problem.
        // Must be the first header
        #include "claraty/common_defs.h"
        
        // C system includes, e.g.:
        #include <math.h>
        
        // C++ system includes / STL includes, e.g.
        #include <string>
        #include <iostream>
        
        // ACE includes, e.g:
        #include <ace/Thread.h>
        
        // CLARAty/project includes, ideally ordered general to specific, e.g.
        #include "claraty/periodic_task.h"
        #include "claraty/rocky8/r8_mast.h"
        
      • Do not use using namespace <blah>; in the header file
    • Inline functions
      • Unless necessary for efficiency or clarity, implement all method definitions in .cc files and not with class declarations in header files
      • Place inline methods with multiple lines of code after the class declaration to keep the class declaration clear and readable. Remember to use the inline keyword. For example:
        class Foo {
        int func1();
        };
        
        inline int
        Foo:func1()
        {
        // more than a single code line
        }
    • Pointerts and References
      • Use pointers and references closer to typename. For example: Object& obj and int* ptr (C++ style, not C; be careful about declaring "int* ptr, non_ptr, *ptr2;" on one line)
    • #defines and Enumerations
      • Avoid use of #defines to define constants. Use enum types embedded in appropriate classes (scoped) to avoid polluting the namespace.
    • Library source files:
      • Make either the corresponding header file or the common_defs.h the first include
      • The remaining includes should follow the same order as described for the header file includes order.
    • Binary source files:
      • Always declare main as: int main(int argc, char* argv[]) or int main() for all targets.

    File Formatting and Documentation

    It may be easiest to see the following examples: example.h, example.cc, and test_example.cc

    Formatting

    • Place the following header information also shown below in all files (.h, .cc, .c). For your convenience, use the following emacs/xemacs lisp macro (save this emacs file in your home directory and add the following line to your ~/.emacs file or the .xemacs-options file (for xemacs): (load-library "~/.emacs_claraty.el") ). This macro creates complete header file templates, banner information, ifdef blocks, class blocks, and comments blocks for files and functions.
      //-*-c++-*- 
      //---------------------------< /-/ CLARAty /-/ >------------------------------
      /** 
       * @file  foo.h
       *
       * [short description]
       *
       * <br>@b Designer(s):  John Doe, Jane Lane
       * <br>@b Author(s):    John Doe
       * <br>@b Date:         June 9, 2006
       *
       * <b>Software License</b><br>
       * <code>http://claraty.jpl.nasa.gov/license/open_src/  or
       *       file: license/open_src.txt </code>
       *
       * &copy; 2006, Jet Propulsion Laboratory, California Institute of Technology<br>
       * [your institution copyright if applicable]
       *
       * $Revision: $
      **/ 
      //-----------------------------------------------------------------------------
      
    • For code designed for a specific target:
      • Update the .supported.mk file in the module to specify appropriate target. Here is a complete target list.
      • List Target OS as shown in this header file. Otherwise, you may omit the Target OS line.
    • In function definitions, place return types on a separate line as shown
      Image<unsigned char>
      Stereo_Processor::acquire(double duration)
      {
        // Braces on separate lines
      }
      
    • Use spaces instead of tabs. Many editors, such as emacs will automatically fill the tabs with their equivalent number of spaces. This is important to make the code readable from multiple editors with different tab settings and to avoid the mixing of spaces and tabs. Do not assume that everyone uses emacs, vi or VC++
    • Use two space indentations
    • Use line separators between function definitions, followed by the Doxygen documentation
      //------------------------------------------------------------------------
      /**
       * Sets the example id.
       * This sets the example id so it can be queried later.
       *
       * @param example_id the id number that this Example will be set to.
       * @return the boolean status of success or fail
       */
      
    • Try to keep all lines less than 80 columns
    • Properly align functions to improve code readability
    • Group class member functions by operation type. Organize the functions into sections for constructors, observers, and mutators
    • Pay attention to spacing. For example
      class Foo {
      
      /** @{ @name Constructors / Destructors */
      Foo();                   /**< with no parameters */
      Foo(int a);              /**< with one param */
      Foo(int a, float b)      /**< and so on */
      
      /** @{ @name Observers */
      int   get_value();
      float get_interval();
      };
    • is more readable than
      class Foo {
      /** @{ @name Constructors / Destructors */
      Foo(); /**< with no parameters */
      Foo(int a); /**< with one param */
      Foo(int a, float b) /**< and so on */
      /** @{ @name Observers */
      int get_value();
      float get_interval();
      };
      

    Inline Documentation

    • Use Doxygen style comments
    • Use hints and comments help other programmers understand a subtle piece of code. For example, a programmer might indicate that, to get data out of a container class efficiently, one should use the rc(row,column) /* row = Y, column = X */ method inherited from the Array_2D base class. Real simple hints that will save developers much time and head scratching!
    • Use only "method grouping" documentation comments in class declaration. Below is an example of method grouping
        /** @{ @name Example constructors/destructors */
        Example();
        Example(int example_id);
        Example(const Example<T>& rhs)
        virtual ~Example();
        /** @} */
      
        /** @{ @name Observers */
        int get_id() const;
        /** @} */
      
        /** @{ @name Mutators */
        inline void set_id(int example_id);
        /** @} */
    • Put all method documentation with the method definition in .cc files
    • Target software documentation for both developers and users
    • See following Doxygen Links
    • See quick reference
      • Files
        • Use @file and a file description
        • Use @author
        • Use @date
        • Put the copyright notice
      • Groups
        • Use @defgroup to create a group if you need one
        • Use @ingroup for all classes and examples
      • Classes
        • Use @name to label constructors/destructors, obsevers, mutators, etc.
        • Use /**< to document class variables
      • Methods
        • Use @param for parameters
        • Use @return for return values
      • Example/test code
        • Use @example to document example files
        • Document command line arguments for main
          /** * Short description.
          * Long description.
          *
          * @author <author>
          * @version <version>
          *
          * @ingroup <group-name>
          * @defgroup <group-name> <description>
          *
          * @param <param-name> <description>
          * @return <description>
          * @throws <class-name> <description>
          * @see <reference [(package)#function]>
          * @since <text> * @serial <field-description>
          * @deprecated <text>
          *
          * @{ @name <grouping> <description> * @} */