Difference between revisions of "Cogniteam/CodeConvention"

From cogniteam
Jump to: navigation, search
 
Line 1: Line 1:
 
==Git==
 
==Git==
 
* Learn basic Git functionality, you must fully understand the following features:
 
* Learn basic Git functionality, you must fully understand the following features:
 +
** [https://www.atlassian.com/git/tutorials/using-branches Branching]
 
** [https://www.atlassian.com/git/tutorials/merging-vs-rebasing Merge vs. Rebase]
 
** [https://www.atlassian.com/git/tutorials/merging-vs-rebasing Merge vs. Rebase]
 
** [https://www.atlassian.com/git/tutorials/syncing Remote: push, pull]
 
** [https://www.atlassian.com/git/tutorials/syncing Remote: push, pull]

Latest revision as of 13:04, 31 December 2019

Git

Git Flow

  • Read this first if you are not familiar with git flow.
  • Main rules:
    • develop branch must be always in working state
    • master branch holds only stable releases

Feature branches

All development is made in feature branches, you can make any commit to this branch. Ideally, each feature should be related to an issue in GitLab. Once the feature is done, squash all commits on your feature branch into one commit with a message: feature x added, closes #111, and merge to develop using rebase

  • Feature branches are allowed to have not stable/compiling code
  • Use rebase instead of merge on develop branch
  • All feature branches should be branched from the latest develop branch and have the format feature/[ISSUE-REF]-[FEATURE-NAME].

Release

  • After all features have been integrated and version is ready to be realeased - create a release branch for it from latest develop branch. Name it with a release/v prefix, for example release/v1.0.0 or release/v0.9.9-rc
  • When in release branch, test your version in production environment, only bugfixes are allowed to be commited in release branch. After finishing all tests, update VERSION file with version to be released, commit it with version as a message, merge to master and develop branch and add a tag with a version number pointing to newly created commit on master branch, new version is released.

The code in the release branch is deployed onto a suitable test environment, tested, and any problems are fixed directly in the release branch. This deploy -> test -> fix -> redeploy -> retest cycle continues until you are happy that the release is good enough to release to customers.

Commits

  • Use lower case in commit message (except type/file names and first commit message - 'Initial commit')
  • Use 'bugfix: ' prefix for bugfix commits
  • Commit text should be short and precise, tell what feature this commit relates and what king of change you have made:
    • feature x added, closes #23
    • voxel map filtering added, closes #54 - Assumes there is an issue with id 54 (Voxel map filtering)
    • install instruction added to README.md
    • bugfix: segfault in MapBuilder fixed
    • XmlReader class added
  • Don't commit meaningless messages like:
    • tiny fixes
    • fix
    • crashing

Naming convention

Branch type Name format Description Examples
master master Latest stable released version
develop develop Latest development version
feature feature/[ISSUE-REF]-[FEATURE-NAME] Feature branch (including bugs) feature/1-organize-pleco-core-repository
hotfix hotfix/[HOTFIX-NAME] Hotfixes hotfix/3-brush-does-not-rotate
release release/v[MAJOR].[MINOR].[PATCH] Deploy & Test release/v0.9.1, release/v1.2.1-rc1, release/v1.2.2-alpha

ROS/ROS2

  • If your project contains custom messages/services/actions, consider creating separate package projectname_msgs containing all messages/services/actions, don't put code in this package
  • Create separate package for complex projects comprising many packages: projectname_launch, again, don't put code files here, it used for storing launch files/scripts and parameters/configuration files (see hamster_launch, lynx_launch)

Files and folders

Component Convention Example
Nodes Lower camel case
Add '_node' suffix
hamster_driver_node
cognitao_server_node
hector_mapping_node
Packages Lower camel case hamster_driver
demo_planner_ros
cognitao_msgs
Messages (actions, services and messages) Upper camel case Vector.msg
RunPlan.action
GetMap.srv

C++

  • Use C++14 standard <syntaxhighlight lang="cmake">
  1. CMake

add_compile_options(-std=c++14) </syntaxhighlight>

  • Use 4 spaces for tabbing
  • Avoid typing more than 80 characters per line
  • Prefer shared_ptr over pure pointers
  • Prefer full names over short:
    • worldModel instead of wm
    • task_ instead of t_
    • calculateDistance() instead of calcDist()
  • Use meaningful names for variables and methods (don't afraid to use long names):
    • distance not d
    • lastReceivedPosition_ not lastRP_
  • Don't use too much general names for classes:
    • Icp2dMapAligner instead of MapAligner
    • VoxelGridMap instead of Map3d

Object-Oriented Programming

Convention names description

Upper Camel Case Lower Camel Case Upper Snake Case Lower Snake Case
UpperCamelCase lowerCamelCase UPPER_SNAKE_CASE lower_snake_case

Naming conventions

Component Convention Example
Variables Lower camel case <syntaxhighlight lang="C++">

int state_;

MessageType messageType;

uint32_t countOfSomething;

ros::NodeHandle rosNodeHandle; </syntaxhighlight>

Methods Lower camel case <syntaxhighlight lang="C++">

void calculate();

int getCount();

int processIncomingMessages(); </syntaxhighlight>

Member variables Add '_' suffix to name, cannot be public <syntaxhighlight lang="C++">

int memberVariable_;

std::string name_;

ros::ServiceClient rosServiceClient_; </syntaxhighlight>

Class names Upper camel case <syntaxhighlight lang="C++">

class Vector3;

class AgentController;

class MapAligner; </syntaxhighlight>

Abstract classes Upper camel case
Prefix 'I' for interfaces - pure abstract classes without any implementations
Suffix 'Base' for abstract base classes with some implementations
<syntaxhighlight lang="C++">

class ITextParser; // Pure abstract class - defines only interfaces without any implementations

class IMapFilter;

class TaskBase; // Abstract class with some implementations common to all tasks

class MappingBase;

</syntaxhighlight>

Namespaces Lower camel case <syntaxhighlight lang="C++">

namespace cognitao_utils { }

namespace cogniteam { namespace tools {

} /* namespace tools */ } /* namespace cogniteam */ </syntaxhighlight>

Enums Upper camel case
Prefer enum class over regular enums
<syntaxhighlight lang="C++">

enum class MessageTypes {

   Single = 1,
   MultiPacket = 2,

};

enum class Colors {

   Red = 0x00,
   Green = 0x01,
   Blue = 0x02

}; </syntaxhighlight>

Template parameters Upper camel case <syntaxhighlight lang="C++">

template <typename MessageT>

template <typename DataT>

template <typename ObjectT> </syntaxhighlight>

Constants Upper snake case <syntaxhighlight lang="C++">

const double PI = 3.14159265359;

const double PI_HALF = 1.57079632679;

static const Color THEME_COLOR = Colors::Red; </syntaxhighlight>

Files and folders

Component Convention Example
Class files
Header and source file
Upper camel case MyClass.h
MyClass.cpp
AgentRosController.hpp
Main
File containint main() method, usually ROS node
Lower snake case cognitao_runner.cpp
my_app.cpp
agent_controller_node.cpp
Folders Lower snake case cognitao_ros
include/agent_controller
src/map_filters
Packages (pure cmake, ROS/ROS2 packages) Lower camel case hamster_driver
demo_planner
cognitao

Class template

Header file

<syntaxhighlight lang="C++"> /*

* CogniteamClass.h
* 
*  Created on: Jan 1, 2031
*      Author: John Doe <johndoe@cogniteam.com>
*
*
* Cogniteam LTD CONFIDENTIAL
*
* Unpublished Copyright (c) 2010-2020 Cogniteam,        All Rights Reserved.
*
* NOTICE:  All information contained  herein  is,  and  remains the property
* of Cogniteam.   The   intellectual   and   technical   concepts  contained
* herein are proprietary to Cogniteam and may  be  covered  by  Israeli  and
* Foreign Patents, patents in process,  and  are  protected  by trade secret
* or copyright law. Dissemination of  this  information  or  reproduction of
* this material is strictly forbidden unless  prior  written  permission  is
* obtained  from  Cogniteam.  Access  to  the  source  code contained herein
* is hereby   forbidden   to   anyone  except  current  Cogniteam employees,
* managers   or   contractors   who   have   executed   Confidentiality  and
* Non-disclosure    agreements    explicitly    covering     such     access
*
* The copyright notice  above  does  not  evidence  any  actual  or intended
* publication  or  disclosure    of    this  source  code,   which  includes
* information that is confidential  and/or  proprietary,  and  is  a   trade
* secret, of   Cogniteam.    ANY REPRODUCTION,  MODIFICATION,  DISTRIBUTION,
* PUBLIC   PERFORMANCE,  OR  PUBLIC  DISPLAY  OF  OR  THROUGH USE   OF  THIS
* SOURCE  CODE   WITHOUT   THE  EXPRESS  WRITTEN  CONSENT  OF  Cogniteam  IS
* STRICTLY PROHIBITED, AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL
* TREATIES.  THE RECEIPT OR POSSESSION OF  THIS SOURCE  CODE  AND/OR RELATED
* INFORMATION DOES  NOT CONVEY OR IMPLY ANY RIGHTS  TO  REPRODUCE,  DISCLOSE
* OR  DISTRIBUTE ITS CONTENTS, OR TO  MANUFACTURE,  USE,  OR  SELL  ANYTHING
* THAT      IT     MAY     DESCRIBE,     IN     WHOLE     OR     IN     PART
*
*/
                        // Maximum 80 characters per line        // new line  
                                                                 // new line

// // Always use header guards for header files //

  1. ifndef PATH_TO_FILE_AND_FILE_NAME_
  2. define PATH_TO_FILE_AND_FILE_NAME_
                                                                 // new line
                                                                 // new line

// // Group includes of the same library and separate it using a new line // Order your include files from low level to higher. // 1. libstd C headers: <printf.h>, <file.h>, <math.h> // 2. libstd C++ headers: <fstream>, <thread>, <mutex>, <cmath> // 4. Other 3rd party includes: <boost/mutex.hpp>, <Qt/QtCore>, <ros/ros.h>, // <pcl/pcl.h> // 4. Local includes: <cogniteam/project_name3/SomeClass.h> //

  1. include <printf.h>
                                                                 // new line
  1. include <iostream>
  2. include <fstream>
  3. include <mutex>
                                                                 // new line
  1. include <boost/bind.hpp>
  2. include <boost/thread.hpp>
  3. include <boost/thread/mutex.hpp>
  4. include <boost/asio.hpp>
  5. include <boost/asio/serial_port.hpp>
  6. include <boost/system/error_code.hpp>
                                                                 // new line
  1. include <ros/ros.h>
  2. include <std_msgs/String.h>
  3. include <ackermann_msgs/AckermannDriveStamped.h>
                                                                 // new line
  1. include <cogniteam/AwesomeClass.h>
  2. include <cogniteam/project_name3/JustSomeClass.h>
                                                                 // new line
                                                                 // new line

// // Always wrap your code with a namespace // namespace cogniteam { namespace project_name {

                                                                 // new line
                                                                 // new line

// Include other namespaces using namespace std; using namespace cogniteam::project_name2;

                                                                 // new line
                                                                 // new line

/**

* Custom color for...
*/

enum class CogniColor {

   Red = 1, 
   Blue = 2,
   Green

};

                                                                 // new line
                                                                 // new line

/**

* High level description of class purposes 
* @note Comment using Doxygen's 'Javadoc style' format
* @url http://www.doxygen.nl/manual/docblocks.html
*/

class CogniteamClass : public CogniteamBaseClass {

                                                                                  // Use separate public block for constructors and descructor

public:

   /**
    * Construct a new Cogniteam Class object
    */

CogniteamClass();

   /**
    * Construct a new Cogniteam Class object
    * @param obj1 
    */

CogniteamClass(const SomeClass& obj1);

   /**
    * Copy constructor
    * @note Don't forget to implement copy constructor & copy assignment operator
    *       if you have pointers in your class
    * @param obj1 
    */

CogniteamClass(const CogniteamClass& obj1);

   /**
    * Destroys the Cogniteam Class object
    * @note Always declare virtual desctrutor in your classes
    */

virtual ~CogniteamClass();

public:

   /**
    * Public type alias for convenient
    */
   using Ptr = shared_ptr<CogniteamClass>;
   using ConstPtr = shared_ptr<CogniteamClass const>;

public:

   //
   // Public member methods
   // NO PUBLIC VARIABLE ALLOWED - USE GETTERS AND SETTERS
   //
   // Getter & Setter example for member variable object_:
   //


   /**
    * Set the Var object
    * @note inline setters & getters
    * @note Use const methods for getters
    * @note Setters and getters must be as short as possible, ideally, 
    *       one copy assignment and one return: 
    * @param var 
    * @return int 
    */
   inline void setObject(Object& object) {
       object_ = object;
   }
   
   /**
    * Gets the Object object
    * @return Object 
    */
   inline Object getObject() const {
       return object_;
   }
   /**
    * Use prefix T for template parameters (MessageT, ServiceT, PacketT...)
    * @tparam ObjectT 
    * @param object 
    */
   template <typename ObjectT>
   void templateMethod(const ObjectT& object) {
       // ...
   }

protected:

   //
   // Protected member methods
   //
   /**
    * Protected method, visible by this and derived classes
    * @return int 
    */
   int protectedMethod();

protected:

   //
   // Protected member variables
   //
   /**
    * Protected member variable, visible by this and derived classes
    */
   int protectedMemberVariable_ = 0;

private:

   //
   // Private member methods
   //
   /**
    * Runs my algorithm 
    * @param param1 First parameter
    * @param param2 Second parameter
    * @param param3 Another parameter
    * @return true If success
    * @return false If failure
    */
   bool runAlgorithm(double param1, double param2, double param3);
   /**
    * Calculates a number such that...
    * @param param1 First param for calculationg
    * @return double Calculation result
    */
   double calculateNumber(double param1) const;

private:

   //
   // Private member methods
   //
   /**
    * Const member example, upper case with underscore, place const's first
    */

const string CONST_MEMBER_STRING = "monitor_red";

   /**
    * Private variable, visible by this class only
    */

Object object_;

};

                                                                 // new line
                                                                 // new line

} /* namespace project_name */ } /* namespace cogniteam */

                                                                 // new line
                                                                 // new line
  1. endif /* PATH_TO_FILE_AND_FILE_NAME_ */
                                                                 // new line

</syntaxhighlight>

Source file

<syntaxhighlight lang="C++"> /*

* CogniteamClass.cpp
* 
*  Created on: Jan 1, 2031
*      Author: John Doe <johndoe@cogniteam.com>
*
*
* Cogniteam LTD CONFIDENTIAL
*
* Unpublished Copyright (c) 2010-2020 Cogniteam,        All Rights Reserved.
*
* NOTICE:  All information contained  herein  is,  and  remains the property
* of Cogniteam.   The   intellectual   and   technical   concepts  contained
* herein are proprietary to Cogniteam and may  be  covered  by  Israeli  and
* Foreign Patents, patents in process,  and  are  protected  by trade secret
* or copyright law. Dissemination of  this  information  or  reproduction of
* this material is strictly forbidden unless  prior  written  permission  is
* obtained  from  Cogniteam.  Access  to  the  source  code contained herein
* is hereby   forbidden   to   anyone  except  current  Cogniteam employees,
* managers   or   contractors   who   have   executed   Confidentiality  and
* Non-disclosure    agreements    explicitly    covering     such     access
*
* The copyright notice  above  does  not  evidence  any  actual  or intended
* publication  or  disclosure    of    this  source  code,   which  includes
* information that is confidential  and/or  proprietary,  and  is  a   trade
* secret, of   Cogniteam.    ANY REPRODUCTION,  MODIFICATION,  DISTRIBUTION,
* PUBLIC   PERFORMANCE,  OR  PUBLIC  DISPLAY  OF  OR  THROUGH USE   OF  THIS
* SOURCE  CODE   WITHOUT   THE  EXPRESS  WRITTEN  CONSENT  OF  Cogniteam  IS
* STRICTLY PROHIBITED, AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL
* TREATIES.  THE RECEIPT OR POSSESSION OF  THIS SOURCE  CODE  AND/OR RELATED
* INFORMATION DOES  NOT CONVEY OR IMPLY ANY RIGHTS  TO  REPRODUCE,  DISCLOSE
* OR  DISTRIBUTE ITS CONTENTS, OR TO  MANUFACTURE,  USE,  OR  SELL  ANYTHING
* THAT      IT     MAY     DESCRIBE,     IN     WHOLE     OR     IN     PART
*
*/
                        // Maximum 80 characters per line        // new line  
                                                                 // new line
  1. include <cogniteam/CogniteamClass.h>
                                                                 // new line
                                                                 // new line

// // Always wrap your code with a namespace // namespace cogniteam { namespace project_name {

                                                                 // new line
                                                                 // new line

/**

* Construct a new Cogniteam Class object, more deatils about implementation
* can be added here
*/

CogniteamClass::CogniteamClass()

   : varToInit_(1), 
     varToinit2_(2.0) {
   // 
   // Other initialization...
   //

}

/**

* Construct a new Cogniteam Class object
* @param obj1 
*/

CogniteamClass::CogniteamClass(const SomeClass& obj1) {

}

/**

* Copy constructor
* @note Don't forget to implement copy constructor & copy assignment operator
*       if you have pointers in your class
* @param obj1 
*/

CogniteamClass::CogniteamClass(const CogniteamClass& obj1) {

}

/**

* Destroys the Cogniteam Class object
* @note Always declare virtual desctrutor in your classes
*/

CogniteamClass::~CogniteamClass() {

}

/**

* Describe the implementation 
* @param param1 First parameter
* @param param2 Second parameter
* @param param3 Another parameter
* @return true If success
* @return false If failure
*/

bool CogniteamClass::runAlgorithm(double param1, double param2, double param3) {

}

/**

* Describe the implementation
* @param param1 First param for calculationg
* @return double Calculation result
*/

double CogniteamClass::calculateNumber(double param1) const {

}

                                                                 // new line
                                                                 // new line

} /* namespace project_name */ } /* namespace cogniteam */

                                                                 // new line

</syntaxhighlight>

Read more