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. ![]()
The table below provides you with a quick reference.
Summary
| Item | Examples | Description |
| Module Name | wheel_locomotor |
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 |
same rules as module names for hardware, drop hw prefix and the dash suffix |
| Binary File Name | utest_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 |
leading caps, underscore separated, specific to general descriptors prefix name |
| Function Name | function_name(int arg) |
lowercase, underscore separated |
get_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,...} |
enumerations name and content and template types are uppercase, underscore separated |
| Pointer and Reference | int * ptr
|
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
libprefix. For example:libtrajectory_generator - Use only singular (not plural) names. For example:
matrixand notmatrices - 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 calledjpl_stereo_vision - Place reusable hardware drivers in separate modules.
- Use this format for hardware drivers:
hw_[<backplane>]_<name>-<function>. Start all hardware module names withhw_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
.hsuffix for all C++ and C header files - Use
.ccsuffix for all C++ source files - Use
.csuffix all C source files
- Use
- 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
.hfiles and implementations in.ippfiles. Include the.ippfile in the.hfile. List the.ippfile in theINC_LINKSof theMakefileif the file needs to be externally visible.
- Do not use the word
claratyorclin 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_locomotorhas files two primary filesfd_locomotor.handfd_locomotor.cc
- Module
- 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>.ccto show how to use<file>.cc. If multiple demo scenarios are appropriate spanning simple to complex usages, add additional files. Usedemo_<file>_simple.ccto show the simple cases. In some cases, it makes sense to have onedemo_file.ccfor a number of.ccfiles.utest_<file>.ccto 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 return0, 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.
- Name Spaces
- All CLARAty classes should be under the
claratynamespace. Generally, classes from third party deliveries are not considered CLARAty classes and may use their own namespace.
- Do not use
using namespace blah;in any.hfile. Usestd::prefix in all.hfiles as appropriate forcout, cerr, endl,etc. - Use
using namespace std;in.ccfile as appropriate and avoid usingstd:: prefixforcout, cerr,andendl;. Usestd::prefix in .cc for clarification only (e.g. std::max(), etc)
- All CLARAty classes should be under the
- Class Names
- Start every word an uppercase letter with words separated by underscores. Make all abbreviations letters uppercase; so use
JPLand notJpl - For robot specific classes, use above table. For example, module names such as:
r7_mastandfd_locomotorshould have corresponding class namesR7_MastandFD_Locomotorrespectively - 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 theN_prefix since classes cannot start with a number (e.g.N_2D_PointandN_3D_Object)
- Start every word an uppercase letter with words separated by underscores. Make all abbreviations letters uppercase; so use
- Function Names
- Use lowercase with words separated by underscores (e.g.
set_cmd_velocity()) - Use
get_num_xx()for instead ofget_number_of_xx()
- Use lowercase with words separated by underscores (e.g.
- Template Types
- Use either uppercase single letter or follow enumeration/define name convention (e.g.
template<class T>ortemplate<typename TYPE_NAME>)
- Use either uppercase single letter or follow enumeration/define name convention (e.g.
- 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)
- Use lowercase with words separated by underscores (e.g.
- 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; })
- Capitalize the first letter of each subsequent word (e.g.
- #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}
- All defines and enumerations contents should be in uppercase with underscore separated words (e.g.
Code Standards
- Multiple inclusion protection:
- Use the following mechanism to avoid multiple header file inclusions. While the
#definefor 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
- Use the following mechanism to avoid multiple header file inclusions. While the
- Header file includes:
- Place all definitions global to all modules inside the common definition file
common_defs.hwhich can be found in thesharemodule. 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
claratydirectory per above table. For example,#include "claraty/image.h" - Prefix hardware and adaptation includes with appropriate directories per above table
- Make
common_defs.hthe first header file you include. - Use double quotes "" delimiters for all CLARAty and user defined header files.
- Where possible, use <> delimiters without a
.hextension 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
- Place all definitions global to all modules inside the common definition file
- Inline functions
- Unless necessary for efficiency or clarity, implement all method definitions in
.ccfiles 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
inlinekeyword. For example:
class Foo { int func1(); }; inline int Foo:func1() { // more than a single code line }
- Unless necessary for efficiency or clarity, implement all method definitions in
- Pointerts and References
- Use pointers and references closer to typename. For example:
Object& objandint* ptr(C++ style, not C; be careful about declaring "int* ptr, non_ptr, *ptr2;" on one line)
- Use pointers and references closer to typename. For example:
- #defines and Enumerations
- Avoid use of
#defines to define constants. Useenumtypes embedded in appropriate classes (scoped) to avoid polluting the namespace.
- Avoid use of
- Library source files:
- Make either the corresponding header file or the
common_defs.hthe first include - The remaining includes should follow the same order as described for the header file includes order.
- Make either the corresponding header file or the
- Binary source files:
- Always declare main as:
int main(int argc, char* argv[])orint main()for all targets.
- Always declare main as:
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> * * © 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.mkfile in the module to specify appropriate target. Here is a complete target list. - List
Target OSas shown in this header file. Otherwise, you may omit theTarget OSline.
- Update the
- 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
.ccfiles - Target software documentation for both developers and users
- See following Doxygen Links
- See quick reference
- Files
- Use
@fileand a file description - Use
@author - Use
@date - Put the copyright notice
- Use
- Groups
- Use
@defgroupto create a group if you need one - Use
@ingroupfor all classes and examples
- Use
- Classes
- Use
@nameto label constructors/destructors, obsevers, mutators, etc. - Use
/**<to document class variables
- Use
- Methods
- Use
@paramfor parameters - Use
@returnfor return values
- Use
- Example/test code
- Use
@exampleto 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> * @} */ - Use
- Files