Consistent code style improves readability, debuggability, and maintainability. These guidelines describe best practice for Basilisk contributors. They are guidelines, not absolute rules — deviations are acceptable when carefully reasoned and documented in the code.
Foundational references:
Where this document is silent, the relevant foundational guidelines apply.
Before contributing, read CONTRIBUTING.md for pull request requirements, branch naming, and pre-commit setup.
Some Basilisk code predates this guide. When working with it:
- All new code must conform to this guide.
- For minor edits to non-conforming code, follow the existing local style — do not mix styles.
- For major work on non-conforming code, take the opportunity to re-style it to conform.
- Unless you have significant spare time, do not undertake wholesale conversion of the existing codebase.
Naming conventions
The following notation schemes are used throughout this document:
| Scheme | Description | Example |
|---|
CamelCase | Starts with capital; capital letter per word; no underscores | SpacecraftDynamics |
camelCase | Like CamelCase but lowercase first letter | spacecraftDynamics |
under_scored | Lowercase only; words separated by underscores | spacecraft_dynamics |
ALL_CAPITALS | All uppercase; words separated by underscores | MAX_ITERATION_COUNT |
Variables
No single-letter variable names. The only exceptions are i as an iteration index and a select set of conventional mathematical symbols.
Mathematical variables and reference frames
Naming follows the textbook Analytical Mechanics of Space Systems by Schaub and Junkins.
A vector v expressed in frame B is written vector_B.
An angular rate of frame B with respect to frame R, with components in B, is written omega_BR_B.
A direction cosine matrix mapping from N to B is written dcm_BN. The corresponding MRP attitude σ_B/N is written sigma_BN.
The Intel Eigen library’s .toRotationMatrix() returns [NB], not [BN]. Account for this when converting quaternions or MRPs to a DCM.
Common examples:
| Quantity | Variable name |
|---|
| Position of B relative to N in N frame components | r_BN_N |
Inertial time derivative of r_BN_N | rDot_BN_N |
| Unit direction vector from B to S in B frame | sHat_SB_B |
| Inertial time derivative of body angular rate in B frame | omegaDot_BN_B |
| First derivative with respect to x | xPrime |
| Second derivative with respect to x | xDPrime |
| Inertia tensor of hub about point C in B frame | IHubPntC_B |
Module and message naming
Message variables
Message variable names follow this pattern:
// C interface
SomeMsg_C descriptionInMsg; // input message
SomeMsg_C descriptionOutMsg; // output message
// C++ interface
ReadFunctor<SomeMsgPayload> descriptionInMsg; // input message
Message<SomeMsgPayload> descriptionOutMsg; // output message
// Buffer variable for read data
SomeMsgPayload descriptionInBuffer;
SomeMsgPayload — the message structure type.
In / Out — the direction relative to the module.
Msg — explicitly marks the variable as a message.
Buffer — explicitly marks the variable as holding read data.
Message definitions
C message payloads live in src/architecture/msgPayloadDefC/ as *.h files.
C++ message payloads live in src/architecture/msgPayloadDefCpp/ as *.h files.
- File names use UpperCamelCase and must match the message name inside the file.
- File names end with
MsgPayload (for example, SpecialSensorMsgPayload.h).
#ifndef SPECIAL_SENSOR_MESSAGE2_H
#define SPECIAL_SENSOR_MESSAGE2_H
/*! @brief Describe the purpose of the message */
typedef struct {
double sensorOutput_B[3]; //!< sensor vector in B frame components
double sensorSignal; //!< raw sensor signal
int status; //!< sensor status flag
} SpecialSensorMsgPayload;
#endif
After adding a message definition, run python3 conanfile.py to regenerate the SWIG interface files.
C/C++ conventions
Follow the Stroustrup/Sutter Core Guidelines. Key Basilisk-specific points:
- Format all C/C++ files with
clang-format before committing. The repository ships a .clang-format file (based on Mozilla style).
- Use
pre-commit hooks to automate formatting on commit.
- Wrap sections that must not be reformatted with:
// clang-format off
// ... manually formatted code ...
// clang-format on
- Document each struct member with a Doxygen
//!< comment:
double thrustForce_N; //!< [N] thrust force magnitude in the inertial frame
- Include unit comments on every numeric literal or variable with physical meaning:
double simTime = 100.0; // [s]
double altitude = 400e3; // [m]
Python conventions
Follow PEP 8 with these Basilisk-specific additions:
- Variables use lowerCamelCase (not
snake_case) to maintain consistency with the C/C++ interface exposed via SWIG.
- Inline comments are acceptable when brief.
- No spaces around math operators (
*, /, +, -) inside expressions:
# Correct
x = (4*9/2)-1
# Incorrect
x = (4 * 9 / 2) - 1
- Annotate physical quantities with unit comments on the same line:
simTime = 500.0 # [s]
orbitRadius = 7000e3 # [m]
angularRate = 0.01 # [rad/s]
thrust = 1.5 # [N]
- Write docstrings as valid reStructuredText (RST) so they render correctly with Sphinx:
def computeOrbit(semiMajorAxis, eccentricity):
"""
Compute the orbital period from Keplerian elements.
:param semiMajorAxis: semi-major axis of the orbit # [m]
:type semiMajorAxis: float
:param eccentricity: orbital eccentricity (dimensionless)
:type eccentricity: float
:return: orbital period # [s]
:rtype: float
"""
Running tests
All unit and integrated tests must pass before pushing code to the repository.
# Run the full test suite (pytest + gtest)
python run_all_test.py
# Run pytest with parallel execution across 8 processes
python3 -m pytest -n 8
# Generate an HTML validation report
python3 -m pytest --report
The pytest-xdist package (installed by requirements_dev.txt) enables the -n flag for parallel test execution. The pytest-html package enables the --report flag.
pre-commit
Install and enable pre-commit inside the repository to automatically format code on each commit:
pip install pre-commit
pre-commit install --hook-type pre-commit --hook-type commit-msg
To run pre-commit manually on a specific file:
pre-commit run --files <file>
When pre-commit modifies files, stage the changes and commit again.
Install via pip and run from the command line:
pip install clang-format
clang-format -i {filename} -style=file
In CLion, enable ClangFormat under Settings → Editor → Code Style, then reformat with Ctrl+Alt+L.
For Xcode, set up an Automator quick action pointing to your clang-format binary.
Contribution workflow
- Create a branch named
feature/bsk-XXX--short-desc (linked to a GitHub ticket) or hotfix/short-desc.
- Keep commits focused — each commit should represent one logical change.
- Rebase onto
develop before opening a pull request: git rebase develop.
- Open a PR against
develop using the repository PR template.
- Include a release-note snippet in
docs/source/Support/bskReleaseNotesSnippets/.
- Ensure at least one reviewer approves and CI passes before merging.
- Use the Merge strategy only — do not use “Squash and merge” or “Rebase and merge”.