Contributing
Contributions to moro are welcome.
moro is primarily an educational and research-oriented robotics library, so contributions should aim to preserve a clear API, readable symbolic formulations, and behavior that is useful for teaching and analysis.
This page summarizes the recommended development workflow for contributing code, documentation, tests, or examples.
Development setup
Clone the repository:
git clone https://github.com/JorgeDeLosSantos/moro.git
cd moro
The active development branch is:
develop
Switch to it before starting new work:
git checkout develop
git pull
It is recommended to create a dedicated branch for each change:
git checkout -b feature/my-change
or, for documentation-only work:
git checkout -b docs/my-change
Python environment
moro requires Python 3.9 or newer.
Creating a virtual environment is recommended.
For example:
python -m venv .venv
Activate it using the appropriate command for your operating system.
On Windows:
.venv\Scripts\activate
On Linux or macOS:
source .venv/bin/activate
Upgrade pip:
python -m pip install --upgrade pip
Then install the project in editable mode:
pip install -e .
Editable installation allows changes made to the local source code to become immediately available when importing moro.
The main runtime dependencies are installed automatically with the package.
Installing development tools
The test suite uses pytest:
pip install pytest
To build the documentation locally, install the documentation dependencies:
pip install sphinx myst-parser sphinx-rtd-theme numpydoc
Repository structure
The main project directories are:
moro/
├── moro/
├── tests/
├── examples/
└── docs/
The moro/ package contains the library source code.
The tests/ directory contains the automated test suite.
The examples/ directory contains example notebooks and related material.
The docs/ directory contains the Sphinx documentation.
The current documentation sources live in:
docs/source/
and generated HTML files are written to:
docs/build/html/
Generated documentation should not be committed to the repository.
Running the tests
Run the complete test suite from the repository root:
pytest
The current tests cover the main library areas, including:
tests/
├── test_core.py
├── test_transformations.py
├── test_inverse_kinematics.py
└── test_visualization.py
A specific test module can be executed independently.
For example:
pytest tests/test_transformations.py
or:
pytest tests/test_inverse_kinematics.py
When adding a new feature or fixing a bug, add or update tests whenever the behavior can be verified automatically.
Before submitting a contribution, the complete test suite should pass.
Writing tests
Tests should focus on observable behavior rather than implementation details whenever possible.
For symbolic robotics functionality, useful checks may include:
exact symbolic equality;
simplified symbolic equality;
matrix dimensions;
numerical evaluation at known configurations;
validation of input errors;
convergence behavior for numerical algorithms;
preservation of documented invariants.
Bug fixes should ideally include a regression test that fails before the fix and passes afterward.
When testing numerical algorithms, avoid relying unnecessarily on a single exact iteration count or floating-point representation unless that behavior is explicitly part of the API.
Building the documentation
The documentation uses Sphinx with both reStructuredText and MyST Markdown sources.
Build the HTML documentation from the repository root with:
sphinx-build -b html docs/source docs/build/html
The generated site can then be opened from:
docs/build/html/index.html
For a stricter validation before merging documentation changes, use:
sphinx-build -W -b html docs/source docs/build/html
The -W option treats warnings as errors and helps detect problems such as:
broken references;
missing documents;
invalid directives;
autodoc failures;
malformed MyST content.
Documentation structure
The documentation is organized into several layers:
Getting Started
User Guide
Examples
API Reference
Theory
Development
These sections serve different purposes.
Getting Started should help a new user install moro and perform a first analysis quickly.
User Guide pages should explain how to use specific parts of the library in practice.
Examples should present complete robotics workflows rather than isolated API calls.
API Reference is generated primarily from public docstrings using Sphinx autodoc.
Theory explains the mathematical concepts and conventions behind the implementation.
Development contains information intended for contributors.
When adding documentation, prefer extending the appropriate existing layer instead of duplicating the same explanation in several places.
Documentation style
The documentation is written in English.
Narrative documentation is primarily written in Markdown using MyST:
*.md
Sphinx structural pages and API Reference pages may use reStructuredText:
*.rst
Examples should favor readable symbolic models and small, reproducible numerical cases.
Code shown in the documentation should reflect the current public API.
Whenever possible, documentation examples should be simple enough to execute independently.
Naming conventions
Contributors should follow the naming and notation conventions adopted by the project.
See:
Development → Naming Conventions
These conventions are especially important because robotics notation can become ambiguous when frame indices, coordinate systems, transformations, positions, and joint variables are mixed.
New APIs should remain consistent with the existing conventions unless there is a strong reason to introduce a new one.
Any intentional deviation should be clearly documented.
Public API
Changes to the public API should be made carefully.
Public functionality currently includes the main robot model, transformation utilities, inverse-kinematics tools, and visualization interfaces.
When modifying public behavior:
preserve backward compatibility when practical;
update the corresponding docstrings;
update User Guide or Examples when behavior changes materially;
add or update tests;
record user-visible changes in the changelog when appropriate.
Internal implementation details should not become public API accidentally.
Docstrings
Public classes, methods, and functions should have clear docstrings.
Docstrings should explain at least:
purpose;
parameters;
return values;
important assumptions;
possible exceptions;
relevant conventions.
For mathematical functions, document frame conventions, coordinate representations, sequence conventions, or numerical assumptions whenever they affect interpretation.
The API Reference is generated from these docstrings, so incomplete docstrings directly affect the published documentation.
Symbolic computations
moro relies heavily on SymPy.
When contributing symbolic algorithms, consider both mathematical correctness and expression complexity.
Avoid unnecessary expansion or simplification when it introduces substantial computational cost without improving the result.
Prefer formulations that preserve readable expressions and reuse already-computed kinematic quantities when possible.
Changes that alter symbolic output should be tested carefully because mathematically equivalent expressions may have different computational costs.
Numerical algorithms
Numerical algorithms should expose convergence information when appropriate.
For iterative methods, consider:
tolerance;
iteration limits;
initialization;
reproducibility;
stagnation;
numerical singularities;
joint limits;
failure diagnostics.
A numerical method should not silently report success when its convergence condition has not been satisfied.
When randomness is involved, provide a reproducible mechanism whenever practical.
Visualization
Visualization changes should preserve the separation between:
robot model
↓
numerical scene evaluation
↓
rendering backend
Backend-specific behavior should remain isolated whenever practical.
Changes to Matplotlib or Three.js rendering should be checked with representative planar and spatial manipulators.
Animations should also be checked for configurations whose geometric scale changes substantially across the sequence.
Adding dependencies
moro intentionally has a small dependency set.
Before introducing a new mandatory dependency, consider whether the same functionality can reasonably be implemented using the existing stack.
A new dependency should provide a clear benefit to the library and should not significantly complicate installation for educational users.
Optional functionality should remain optional whenever practical.
Changelog
User-visible changes should be recorded in:
CHANGELOG.md
Examples include:
new public features;
changes in behavior;
bug fixes;
deprecated functionality;
compatibility changes;
important documentation additions.
Small internal refactors that do not affect users generally do not require a changelog entry.
Submitting changes
Before submitting a contribution:
update your branch with the latest
develop;run the complete test suite;
build the documentation if the change affects public behavior or docs;
review the diff for unrelated modifications;
ensure new public behavior is documented;
update
CHANGELOG.mdwhen appropriate.
A typical final verification may include:
pytest
and:
sphinx-build -W -b html docs/source docs/build/html
Commits should be focused and use concise messages describing the change.
Examples:
Add stagnation detection to CCD solver
Fix frame scaling in Three.js animation
Document position IK trajectory solver
Pull requests
Pull requests should target the develop branch unless a different target has been explicitly agreed upon.
A pull request should explain:
what was changed;
why the change is useful or necessary;
any important implementation decisions;
how the change was tested;
whether documentation or public behavior changed.
Large contributions are easier to review when they are divided into logically coherent changes.
When introducing a substantial feature, discussing the design before implementing a large patch is encouraged.
Reporting issues
Bug reports should include enough information to reproduce the problem.
Useful information includes:
moroversion;Python version;
operating system when relevant;
minimal robot definition;
minimal code reproducing the issue;
expected behavior;
actual behavior;
traceback or error message.
For numerical or symbolic problems, include the specific parameter values and configuration whenever possible.
Scope of contributions
moro is primarily focused on serial robot manipulators and on educationally useful tools for their analysis.
Contributions that fit naturally within this scope include:
kinematic modeling;
transformations;
Jacobians;
inverse kinematics;
dynamics;
visualization;
examples;
tests;
documentation.
Larger features should preserve the project’s educational character and avoid adding complexity without a clear robotics use case.