Skip to content

Latest commit

 

History

History
83 lines (57 loc) · 5 KB

DEVELOP.md

File metadata and controls

83 lines (57 loc) · 5 KB

Information for Developers

Coding Conventions

  • Classes and types use UpperCamelCase; methods and functions use lowerCamelCase.
  • Apart from those naming conventions, we adopt Google C++ style.
  • Use meaningful variable names, e.g. measurement not msm, avoid abbreviations.

Eigen Fixed-Size and Dynamic Storage

Use fixed-size types such as Matrix3, Matrix23, and Vector6 when dimensions are known at compile time, especially for OptionalJacobian outputs. Fixed-size types store their coefficients inline and avoid unnecessary dynamic allocation and fixed/dynamic conversions.

Use Matrix and Vector when dimensions are determined at runtime or when an existing API explicitly requires a dynamic type.

When assigning to a fixed-size Jacobian, prefer writing directly to it or using a fixed-size temporary:

if (H) {
  *H = Matrix3{{1.0, 0.0, 0.0},
               {0.0, 1.0, 0.0},
               {0.0, 0.0, 1.0}};
}

Use flat initializer lists for vectors and nested initializer lists for matrices:

Vector3 vector{1.0, 2.0, 3.0};
Matrix23 matrix{{1.0, 2.0, 3.0},
                {4.0, 5.0, 6.0}};

Header-Wrapper Parameter Name Matching

If you add a C++ function to a .i file to expose it to the wrapper, you must ensure that the parameter names match exactly between the declaration in the header file and the declaration in the .i. Similarly, if you change any parameter names in a wrapped function in a header file, or change any parameter names in a .i file, you must change the corresponding function in the other file to reflect those changes.

This includes inherited functions wrapped in .i files. If Pose2 inherits logmap from LieGroup (in Lie.h) and wraps logmap, Pose2.logmap in the .i needs to have the same parameter names as the function definition in Lie.h.

Important

The Doxygen documentation from the C++ will not carry over into the Python docstring if the parameter names do not match exactly!

If you encounter any functions that do not meet this criterion, please submit a PR to make them match.

Wrapper Maintenance: How to fix C++ GTSAM functions not showing up in Python

The GTSAM Python wrapper is created using the wrap library (docs). The following brief guide is intended to help users extend the GTSAM wrapper themselves if necessary.

The Python wrapper for a class is defined in the *.i interface file present in the same directory as the class. For example, the wrapper for gtsam/geometry/Pose3.h is defined in gtsam/geometry/geometry.i; for gtsam/navigation/ImuFactor.h, it's gtsam/navigation/navigation.i, etc. With that knowledge and following these steps, you can manipulate your local clone of GTSAM and rebuild the Python package with your custom extended bindings.

  1. Follow steps to clone, build, and install GTSAM with Python bindings on your OS, to be sure that you can do so before changing the source code. See INSTALL.md and the Python README.md.
  2. Identify which folder your problem class is in and the corresponding interface file.
  3. Edit the interface file to include your desired functions from C++. Largely, this consists of simply copying the function signature into the appropriate class of the .i, but you also must make sure that everything is explicitly referenced (e.g. with gtsam::, Eigen::). In some cases, such as with Vectors or Jacobians, you may have to change a return type or argument type. In such situations, let the similar code in the .i be your guide. Commonly, VectorN can be changed to gtsam::Vector.
  4. Rebuild GTSAM with Python bindings and reinstall the Python package.
  5. At this point, your function should be available after import gtsam.

Possible remaining issues

  • If the C++ library compiled before the interface change but generated wrapper code does not, first check the new declaration for missing namespaces, semicolons, and unsupported types. Also verify that CMake selected the intended Python interpreter and that stale generated output is not being reused. See the wrap docs for syntax guidelines.
  • If the new function won't show up in Python, make sure you have properly reinstalled the Python package. You might need to pip uninstall before reinstalling. On Windows, you might need to recopy the .pyd files and then rebuild as mentioned in the Windows installation instructions.

Windows

Windows shared-library builds require public symbols with out-of-line definitions to use the export macro for the library that owns them. Use GTSAM_EXPORT for the stable gtsam library and GTSAM_UNSTABLE_EXPORT for gtsam_unstable.

For example:

class GTSAM_EXPORT MyClass { ... };
GTSAM_EXPORT ReturnType myFunction();

class GTSAM_UNSTABLE_EXPORT MyUnstableClass { ... };

Header-only and template code has additional rules. See Using-GTSAM-EXPORT.md before adding an export macro.