210 lines
8.0 KiB
Markdown
210 lines
8.0 KiB
Markdown
|
# Coding style for RBDL
|
||
|
|
||
|
This documents gives an overview of the coding style used in RBDL and also
|
||
|
the general goals of RBDL.
|
||
|
|
||
|
If you are considering contributing to this library please read the whole
|
||
|
document.
|
||
|
|
||
|
## General Purpose of RBDL
|
||
|
|
||
|
RBDL implements large parts of the algorithms and methods described in
|
||
|
Featherstone's book Rigid Body Dynamics Algorithms. One of the main goals
|
||
|
of this library is to serve as an efficient implementation for the methods
|
||
|
described in Featherstone's book and to a lesser extent general multibody
|
||
|
dynamics and kinematics computations. A person who is familiar with
|
||
|
Featherstone's book should have an easy time to understand the code and
|
||
|
therefore the variable naming conventions used in the book should when
|
||
|
possible used in the code, e.g.:
|
||
|
|
||
|
- the joint space inertia matrix is denoted with H
|
||
|
- the coriolis forces are denoted with C
|
||
|
|
||
|
The algorithmic parts of RBDL's code try to follow the algorithmic or
|
||
|
mathematical notations instead of wrapping algorithms in elegant
|
||
|
programming patterns.
|
||
|
|
||
|
### Aims and Non-Aims of RBDL
|
||
|
|
||
|
This is what RBDL aims to be:
|
||
|
|
||
|
* RBDL aims to be lean
|
||
|
* RBDL aims to be easily integrated into other projects
|
||
|
* RBDL aims to be suitable as a foundation for sophisticated dynamics packages
|
||
|
* RBDL gives you access to its internals and provides only a thin abstraction layer over the actual computation
|
||
|
* RBDL aims to be self-contained and dependant on as few libraries as possible
|
||
|
|
||
|
And this is what RBDL is ***not*** about:
|
||
|
|
||
|
* RBDL is ***not*** a fully fledged simulator with collision detection or fancy graphics
|
||
|
* RBDL does not keep you from screwing up things.
|
||
|
|
||
|
Multibody dynamics is a complicated subject and in this codebase the
|
||
|
preference is mathematical and algorithmic clarity over elegant software
|
||
|
architecture.
|
||
|
|
||
|
## Licensing
|
||
|
|
||
|
RBDL is published under the very permissive zlib license that gives you a
|
||
|
lot of freedom in the use of full library or parts of it. The core part
|
||
|
of the library is solely using this license but addons may use different
|
||
|
licenses.
|
||
|
|
||
|
There is no formal contributor license agreement for this project. Instead
|
||
|
when you submit patches or create a pull request it is assumed that you
|
||
|
have the rights to transfer the corresponding code to the RBDL project and
|
||
|
that you are okay that the code will be published as part of RBDL.
|
||
|
|
||
|
## Data Storage
|
||
|
|
||
|
RBDL tries to avoid dynamic allocations and prefers contiguous memory
|
||
|
storage such as in ```std::vector```s over possibly fragmented memory as in
|
||
|
```std::list``` or heap allocated tree structures.
|
||
|
|
||
|
Where possible we use the Structure-of-Arrays (SOA) approach to store data,
|
||
|
e.g. the velocities v of all bodies is stored in an array (```std::vector```)
|
||
|
of ```SpatialVector```s in the ```Model``` structure.
|
||
|
|
||
|
## Naming Conventions
|
||
|
|
||
|
1. Structs and classes use CamelCase, e.g. ```ConstraintSet```
|
||
|
2. Struct and class members use the lowerCamelCase convention, e.g.
|
||
|
```Model::dofCount```.
|
||
|
Exceptions are:
|
||
|
1. The member variable is a mathematical symbol in an
|
||
|
algorithm reference, E.g. ```S``` is commonly used to denote the joint
|
||
|
motion subspace, then we use the algorithm notation. For mathematical
|
||
|
symbols we also allow the underscore ```_``` to denote a subscript.
|
||
|
2. Specializations of existing variables may be prefixed with an identifier,
|
||
|
followed by a underscore. E.g. ```Model::S``` is the default storage for
|
||
|
joint motion subspaces, however for the specialized 3-DOF joints it uses
|
||
|
the prefix ```multdof3_``` and are therefore stored in
|
||
|
```Model::multdof3_S```.
|
||
|
3. Only the first letter of an acronym is using a capital letter, e.g.
|
||
|
degree of freedom (DOF) would be used as ```jointDofCount```, or
|
||
|
```dofCount```.
|
||
|
4. Variables that are not member variables use the ```snake_case``` convention.
|
||
|
|
||
|
### Examples
|
||
|
|
||
|
struct Model {
|
||
|
std::vector<SpatialVector> v; // ok, v is an
|
||
|
std::vector<SpatialVector> S; // ok, S is commonly used in a reference algorithm
|
||
|
std::vector<double> u; // ok
|
||
|
std::vector<Vector3d> multdof3_u; // ok, 3-dof specialization of Model::u
|
||
|
|
||
|
std::vector<unsigned int> mJointIndex; // NOT OK: invalid prefix
|
||
|
unsigned int DOFCount; // NOT OK: only first letter of abbreviation should be in upper case
|
||
|
double error_tol; // NOT OK: use camelCase instead of snake_case
|
||
|
void CalcPositions(); // NOT OK: camelCase for member variables and function must start with lower-case name
|
||
|
|
||
|
};
|
||
|
|
||
|
## Spacing and Line Width
|
||
|
|
||
|
We use spaces to indent code and use two spaces to indent a block. Do not
|
||
|
use tabs. Namespaces should not be indented.
|
||
|
|
||
|
Lines should not exceed 80 characters in width.
|
||
|
|
||
|
Hint: in the root directory of the RBDL repository you find the file
|
||
|
.editorconfig which uses the correct spacing settings automatically for
|
||
|
many editors (see http://editorconfig.org/ for more details).
|
||
|
|
||
|
## Error Handling
|
||
|
|
||
|
RBDL will fail loudly and abort if an error occurs. This allows you to spot
|
||
|
errors early on. RBDL does not use exceptions.
|
||
|
|
||
|
Code must compile without warnings with all compiler warnings enabled.
|
||
|
Please also consider checking code with static code analyzers such as
|
||
|
clang-analyzer (http://clang-analyzer.llvm.org/).
|
||
|
|
||
|
## Const Correctness
|
||
|
|
||
|
This code uses const correctness, i.e. parameters that are not expected to
|
||
|
change must be specified as const. Use const references whenever possible.
|
||
|
For some optional variables we use pointers, but when possible use
|
||
|
references.
|
||
|
|
||
|
## Braces
|
||
|
|
||
|
Use braces whenever possible. E.g. even there is only a single line of code
|
||
|
after an if-statement wrap it with curly braces. The opening brace starts
|
||
|
in the same line as the ```if``` or the ```else``` statement.
|
||
|
|
||
|
## Documentation
|
||
|
|
||
|
Most importantly the code should be readable to someone who is familiar
|
||
|
with multibody dynamics, especially with Featherstone's notation. The
|
||
|
documentation should mainly serve to clarify the API in terms of doxygen
|
||
|
comments. Within the code itself comments may be used to emphasize on ideas
|
||
|
behind it or to clarify sections. But in general it is best to write
|
||
|
readable code in the first place as comments easily become deprecated.
|
||
|
|
||
|
The doxygen comments should be written in the header files and not in the
|
||
|
```.cc``` files.
|
||
|
|
||
|
## Testing
|
||
|
|
||
|
All code contributions must provide unit tests. RBDL uses UnitTest++
|
||
|
(https://github.com/unittest-cpp/unittest-cpp) as a testing framework. Many
|
||
|
small tests that check single features are preferred over large tests that
|
||
|
test multiple things simultaneously.
|
||
|
|
||
|
Bugfixes ideally come with a test case that reproduce the bug.
|
||
|
|
||
|
## Branching and Bookmarks
|
||
|
|
||
|
RBDL uses Mercurial (https://mercurial-scm.org) as version control system.
|
||
|
The branching concept of mercurial is different than in git. Git's
|
||
|
branching concept is captured in mercurial using bookmarks
|
||
|
(https://www.mercurial-scm.org/wiki/Bookmarks).
|
||
|
|
||
|
The ```default``` branch is reserved for releases. Bugfixes and
|
||
|
contributions happen in the ```dev``` branch but should have a bookmark
|
||
|
assigned to them.
|
||
|
|
||
|
Please do not create new branches, i.e. do not run ```hg branch
|
||
|
<branchname>```.
|
||
|
|
||
|
### Working on a new feature
|
||
|
|
||
|
The following steps are advised when working on a new feature for RBDL:
|
||
|
|
||
|
1. Clone the official repository.
|
||
|
2. Switch to the ```dev``` branch.
|
||
|
3. Create a bookmark that describes that feature preferably in a single
|
||
|
word.
|
||
|
4. Commit all changes to this bookmark in the ```dev``` branch.
|
||
|
5. Publish your work online and notify the RBDL maintainer(s).
|
||
|
|
||
|
Here are the commands to perform steps 1.-4.:
|
||
|
|
||
|
# Step 1: clone official repository
|
||
|
hg clone https://bitbucket.org/rbdl/rbdl <newfeature> && cd <newfeature>
|
||
|
|
||
|
# Step 2: switch to the dev branch
|
||
|
hg update dev
|
||
|
|
||
|
# Step 3: create a bookmark
|
||
|
hg bookmark newfeature
|
||
|
|
||
|
# ...
|
||
|
# Make changes
|
||
|
# ...
|
||
|
|
||
|
# Step 4: commit changes
|
||
|
hg commit
|
||
|
|
||
|
For step 5 the easiest would be to push your changes to a fork of the
|
||
|
official repository on bitbucket and create a pull request.
|
||
|
|
||
|
## Debugging
|
||
|
|
||
|
* Todo: mention logging facility
|
||
|
* Todo: mention SimpleMath as a fast-compiling (but slower runtime) linear
|
||
|
algebra package.
|
||
|
|
||
|
|