Skip to content

Commit

Permalink
Merge pull request #729 from borglab/feature/wrapper-operator-overloa…
Browse files Browse the repository at this point in the history
…ding
  • Loading branch information
dellaert authored Apr 2, 2021
2 parents 8ffad01 + 38d867d commit 43e8f1e
Show file tree
Hide file tree
Showing 40 changed files with 1,127 additions and 391 deletions.
67 changes: 47 additions & 20 deletions gtsam/gtsam.i
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,6 @@ class Point2 {
};

// std::vector<gtsam::Point2>
#include <gtsam/geometry/Point2.h>
class Point2Vector
{
// Constructors
Expand Down Expand Up @@ -308,6 +307,12 @@ class StereoPoint2 {
gtsam::StereoPoint2 compose(const gtsam::StereoPoint2& p2) const;
gtsam::StereoPoint2 between(const gtsam::StereoPoint2& p2) const;

// Operator Overloads
gtsam::StereoPoint2 operator-() const;
// gtsam::StereoPoint2 operator+(Vector b) const; //TODO Mixed types not yet supported
gtsam::StereoPoint2 operator+(const gtsam::StereoPoint2& p2) const;
gtsam::StereoPoint2 operator-(const gtsam::StereoPoint2& p2) const;

// Manifold
gtsam::StereoPoint2 retract(Vector v) const;
Vector localCoordinates(const gtsam::StereoPoint2& p) const;
Expand Down Expand Up @@ -356,7 +361,6 @@ class Point3 {
void pickle() const;
};

#include <gtsam/geometry/Point3.h>
class Point3Pairs {
Point3Pairs();
size_t size() const;
Expand Down Expand Up @@ -384,6 +388,9 @@ class Rot2 {
gtsam::Rot2 compose(const gtsam::Rot2& p2) const;
gtsam::Rot2 between(const gtsam::Rot2& p2) const;

// Operator Overloads
gtsam::Rot2 operator*(const gtsam::Rot2& p2) const;

// Manifold
gtsam::Rot2 retract(Vector v) const;
Vector localCoordinates(const gtsam::Rot2& p) const;
Expand Down Expand Up @@ -432,6 +439,9 @@ class SO3 {
gtsam::SO3 between(const gtsam::SO3& R) const;
gtsam::SO3 compose(const gtsam::SO3& R) const;

// Operator Overloads
gtsam::SO3 operator*(const gtsam::SO3& R) const;

// Manifold
gtsam::SO3 retract(Vector v) const;
Vector localCoordinates(const gtsam::SO3& R) const;
Expand Down Expand Up @@ -459,6 +469,9 @@ class SO4 {
gtsam::SO4 between(const gtsam::SO4& Q) const;
gtsam::SO4 compose(const gtsam::SO4& Q) const;

// Operator Overloads
gtsam::SO4 operator*(const gtsam::SO4& Q) const;

// Manifold
gtsam::SO4 retract(Vector v) const;
Vector localCoordinates(const gtsam::SO4& Q) const;
Expand Down Expand Up @@ -486,6 +499,9 @@ class SOn {
gtsam::SOn between(const gtsam::SOn& Q) const;
gtsam::SOn compose(const gtsam::SOn& Q) const;

// Operator Overloads
gtsam::SOn operator*(const gtsam::SOn& Q) const;

// Manifold
gtsam::SOn retract(Vector v) const;
Vector localCoordinates(const gtsam::SOn& Q) const;
Expand Down Expand Up @@ -544,6 +560,9 @@ class Rot3 {
gtsam::Rot3 compose(const gtsam::Rot3& p2) const;
gtsam::Rot3 between(const gtsam::Rot3& p2) const;

// Operator Overloads
gtsam::Rot3 operator*(const gtsam::Rot3& p2) const;

// Manifold
//gtsam::Rot3 retractCayley(Vector v) const; // TODO, does not exist in both Matrix and Quaternion options
gtsam::Rot3 retract(Vector v) const;
Expand Down Expand Up @@ -598,6 +617,9 @@ class Pose2 {
gtsam::Pose2 compose(const gtsam::Pose2& p2) const;
gtsam::Pose2 between(const gtsam::Pose2& p2) const;

// Operator Overloads
gtsam::Pose2 operator*(const gtsam::Pose2& p2) const;

// Manifold
gtsam::Pose2 retract(Vector v) const;
Vector localCoordinates(const gtsam::Pose2& p) const;
Expand Down Expand Up @@ -655,6 +677,9 @@ class Pose3 {
gtsam::Pose3 compose(const gtsam::Pose3& pose) const;
gtsam::Pose3 between(const gtsam::Pose3& pose) const;

// Operator Overloads
gtsam::Pose3 operator*(const gtsam::Pose3& pose) const;

// Manifold
gtsam::Pose3 retract(Vector v) const;
Vector localCoordinates(const gtsam::Pose3& pose) const;
Expand Down Expand Up @@ -695,7 +720,6 @@ class Pose3 {
void pickle() const;
};

#include <gtsam/geometry/Pose3.h>
class Pose3Pairs {
Pose3Pairs();
size_t size() const;
Expand All @@ -704,8 +728,6 @@ class Pose3Pairs {
void push_back(const gtsam::Pose3Pair& pose_pair);
};

// std::vector<gtsam::Pose3>
#include <gtsam/geometry/Pose3.h>
class Pose3Vector
{
Pose3Vector();
Expand Down Expand Up @@ -976,7 +998,9 @@ class CalibratedCamera {

// Standard Interface
gtsam::Pose3 pose() const;
double range(const gtsam::Point3& p) const; // TODO: Other overloaded range methods
double range(const gtsam::Point3& point) const;
double range(const gtsam::Pose3& pose) const;
double range(const gtsam::CalibratedCamera& camera) const;

// enabling serialization functionality
void serialize() const;
Expand Down Expand Up @@ -1048,7 +1072,6 @@ class Similarity3 {
};



// Forward declaration of PinholeCameraCalX is defined here.
#include <gtsam/geometry/SimpleCamera.h>
// Some typedefs for common camera types
Expand Down Expand Up @@ -1251,9 +1274,9 @@ class SymbolicBayesTree {
};

// class SymbolicBayesTreeClique {
// BayesTreeClique();
// BayesTreeClique(CONDITIONAL* conditional);
// // BayesTreeClique(const pair<typename ConditionalType::shared_ptr, typename ConditionalType::FactorType::shared_ptr>& result) : Base(result) {}
// SymbolicBayesTreeClique();
// SymbolicBayesTreeClique(CONDITIONAL* conditional);
// SymbolicBayesTreeClique(const pair<typename ConditionalType::shared_ptr, typename ConditionalType::FactorType::shared_ptr>& result) : Base(result) {}
//
// bool equals(const This& other, double tol) const;
// void print(string s) const;
Expand All @@ -1264,13 +1287,13 @@ class SymbolicBayesTree {
// CONDITIONAL* conditional() const;
// bool isRoot() const;
// size_t treeSize() const;
// // const std::list<derived_ptr>& children() const { return children_; }
// // derived_ptr parent() const { return parent_.lock(); }
// const std::list<derived_ptr>& children() const { return children_; }
// derived_ptr parent() const { return parent_.lock(); }
//
// // TODO: need wrapped versions graphs, BayesNet
// // BayesNet<ConditionalType> shortcut(derived_ptr root, Eliminate function) const;
// // FactorGraph<FactorType> marginal(derived_ptr root, Eliminate function) const;
// // FactorGraph<FactorType> joint(derived_ptr C2, derived_ptr root, Eliminate function) const;
// BayesNet<ConditionalType> shortcut(derived_ptr root, Eliminate function) const;
// FactorGraph<FactorType> marginal(derived_ptr root, Eliminate function) const;
// FactorGraph<FactorType> joint(derived_ptr C2, derived_ptr root, Eliminate function) const;
//
// void deleteCachedShortcuts();
// };
Expand Down Expand Up @@ -2734,7 +2757,7 @@ virtual class SmartProjectionPoseFactor: gtsam::NonlinearFactor {
void add(const gtsam::Point2& measured_i, size_t poseKey_i);

// enabling serialization functionality
//void serialize() const;
void serialize() const;
};

typedef gtsam::SmartProjectionPoseFactor<gtsam::Cal3_S2> SmartProjectionPose3Factor;
Expand Down Expand Up @@ -3040,7 +3063,7 @@ class ShonanAveraging3 {
ShonanAveraging3(string g2oFile);
ShonanAveraging3(string g2oFile,
const gtsam::ShonanAveragingParameters3 &parameters);

// TODO(frank): deprecate once we land pybind wrapper
ShonanAveraging3(const gtsam::BetweenFactorPose3s &factors);
ShonanAveraging3(const gtsam::BetweenFactorPose3s &factors,
Expand Down Expand Up @@ -3132,6 +3155,11 @@ class ConstantBias {
gtsam::imuBias::ConstantBias compose(const gtsam::imuBias::ConstantBias& b) const;
gtsam::imuBias::ConstantBias between(const gtsam::imuBias::ConstantBias& b) const;

// Operator Overloads
gtsam::imuBias::ConstantBias operator-() const;
gtsam::imuBias::ConstantBias operator+(const gtsam::imuBias::ConstantBias& b) const;
gtsam::imuBias::ConstantBias operator-(const gtsam::imuBias::ConstantBias& b) const;

// Manifold
gtsam::imuBias::ConstantBias retract(Vector v) const;
Vector localCoordinates(const gtsam::imuBias::ConstantBias& b) const;
Expand Down Expand Up @@ -3182,9 +3210,8 @@ virtual class PreintegratedRotationParams {

Matrix getGyroscopeCovariance() const;

// TODO(frank): allow optional
// boost::optional<Vector> getOmegaCoriolis() const;
// boost::optional<Pose3> getBodyPSensor() const;
boost::optional<Vector> getOmegaCoriolis() const;
boost::optional<gtsam::Pose3> getBodyPSensor() const;
};

#include <gtsam/navigation/PreintegrationParams.h>
Expand Down
1 change: 1 addition & 0 deletions wrap/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
__pycache__/
.vscode/
*build*
*install*
*dist*
*.egg-info

Expand Down
83 changes: 56 additions & 27 deletions wrap/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,54 +1,83 @@
cmake_minimum_required(VERSION 3.9)

# Set the project name and version
project(GTwrap VERSION 1.0)
project(gtwrap VERSION 1.0)

# ##############################################################################
# General configuration

set(WRAP_PYTHON_VERSION
"Default"
CACHE STRING "The Python version to use for wrapping")

include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/GtwrapUtils.cmake)
gtwrap_get_python_version(${WRAP_PYTHON_VERSION})

# ##############################################################################
# Install the CMake file to be used by other projects
# Set the variables to be used for the cmake config file.
if(WIN32 AND NOT CYGWIN)
set(SCRIPT_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/CMake")
set(INSTALL_CMAKE_DIR CMake/${PROJECT_NAME})
else()
set(SCRIPT_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib/cmake")
set(INSTALL_CMAKE_DIR lib/cmake/${PROJECT_NAME})
endif()

# Configure the include directory for matlab.h
# This allows the #include to be either gtwrap/matlab.h, wrap/matlab.h or something custom.
if(NOT DEFINED GTWRAP_INCLUDE_NAME)
set(GTWRAP_INCLUDE_NAME "gtwrap" CACHE INTERNAL "Directory name for Matlab includes")
endif()
configure_file(${PROJECT_SOURCE_DIR}/templates/matlab_wrapper.tpl.in ${PROJECT_SOURCE_DIR}/gtwrap/matlab_wrapper.tpl)
set(INSTALL_LIB_DIR lib/${PROJECT_NAME})
set(INSTALL_BIN_DIR bin/${PROJECT_NAME})
set(INSTALL_INCLUDE_DIR include/${PROJECT_NAME})

# ##############################################################################
# Package Configuration

# Helper functions for generating the gtwrapConfig.cmake file correctly.
include(CMakePackageConfigHelpers)

# Configure the config file which is used for `find_package`.
configure_package_config_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/gtwrapConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/cmake/gtwrapConfig.cmake
INSTALL_DESTINATION "${INSTALL_CMAKE_DIR}"
PATH_VARS INSTALL_CMAKE_DIR INSTALL_LIB_DIR INSTALL_BIN_DIR
INSTALL_INCLUDE_DIR
INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})

message(STATUS "Package config : ${CMAKE_INSTALL_PREFIX}/${INSTALL_CMAKE_DIR}")

# ##############################################################################
# Install the package

message(STATUS "CMake : ${CMAKE_INSTALL_PREFIX}/${INSTALL_CMAKE_DIR}")
# Install CMake scripts to the standard CMake script directory.
install(FILES cmake/gtwrapConfig.cmake cmake/MatlabWrap.cmake
cmake/PybindWrap.cmake cmake/GtwrapUtils.cmake
DESTINATION "${SCRIPT_INSTALL_DIR}/gtwrap")
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/cmake/gtwrapConfig.cmake
cmake/MatlabWrap.cmake cmake/PybindWrap.cmake cmake/GtwrapUtils.cmake
DESTINATION "${CMAKE_INSTALL_PREFIX}/${INSTALL_CMAKE_DIR}")

# Needed for the CMAKE_INSTALL_X variables used below.
include(GNUInstallDirs)
# Configure the include directory for matlab.h This allows the #include to be
# either gtwrap/matlab.h, wrap/matlab.h or something custom.
if(NOT DEFINED GTWRAP_INCLUDE_NAME)
set(GTWRAP_INCLUDE_NAME
"gtwrap"
CACHE INTERNAL "Directory name for Matlab includes")
endif()

configure_file(${PROJECT_SOURCE_DIR}/templates/matlab_wrapper.tpl.in
${PROJECT_SOURCE_DIR}/gtwrap/matlab_wrapper.tpl)

# Install the gtwrap python package as a directory so it can be found by CMake
# for wrapping.
install(DIRECTORY gtwrap DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/gtwrap")
message(STATUS "Lib path : ${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB_DIR}")
install(DIRECTORY gtwrap
DESTINATION "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB_DIR}")

# Install pybind11 directory to `CMAKE_INSTALL_PREFIX/lib/gtwrap/pybind11` This
# will allow the gtwrapConfig.cmake file to load it later.
install(DIRECTORY pybind11
DESTINATION "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB_DIR}")

# Install wrapping scripts as binaries to `CMAKE_INSTALL_PREFIX/bin` so they can
# be invoked for wrapping. We use DESTINATION (instead of TYPE) so we can
# support older CMake versions.
message(STATUS "Bin path : ${CMAKE_INSTALL_PREFIX}/${INSTALL_BIN_DIR}")
install(PROGRAMS scripts/pybind_wrap.py scripts/matlab_wrap.py
DESTINATION ${CMAKE_INSTALL_FULL_BINDIR})

# Install pybind11 directory to `CMAKE_INSTALL_PREFIX/lib/gtwrap/pybind11` This
# will allow the gtwrapConfig.cmake file to load it later.
install(DIRECTORY pybind11 DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/gtwrap")
DESTINATION "${CMAKE_INSTALL_PREFIX}/${INSTALL_BIN_DIR}")

# Install the matlab.h file to `CMAKE_INSTALL_PREFIX/lib/gtwrap/matlab.h`.
install(FILES matlab.h DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}/gtwrap")
message(
STATUS "Header path : ${CMAKE_INSTALL_PREFIX}/${INSTALL_INCLUDE_DIR}")
install(FILES matlab.h
DESTINATION "${CMAKE_INSTALL_PREFIX}/${INSTALL_INCLUDE_DIR}")
32 changes: 28 additions & 4 deletions wrap/DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ The python wrapper supports keyword arguments for functions/methods. Hence, the

- Class variables are read-write so they can be updated directly in Python.

- Operator Overloading (Python only)
- You can overload operators just like in C++.

```cpp
class Overload {
Overload operator*(const Overload& other) const;
};
```
- Supported operators are the intersection of those supported in C++ and in Python.
- Operator overloading definitions have to be marked as `const` methods.

- Pointer types
- To declare a simple/raw pointer, simply add an `@` to the class name, e.g.`Pose3@`.
- To declare a shared pointer (e.g. `gtsam::noiseModel::Base::shared_ptr`), use an asterisk (i.e. `*`). E.g. `gtsam::noiseModel::Base*` to define the wrapping for the `Base` noise model shared pointer.
Expand Down Expand Up @@ -78,7 +89,7 @@ The python wrapper supports keyword arguments for functions/methods. Hence, the
- Can have multiple functions of the same name in different namespaces.
- Functions can be templated and have multiple template arguments, e.g.
```cpp
template<T, >
template<T, R, S>
```

- Using classes defined in other modules
Expand All @@ -99,7 +110,7 @@ The python wrapper supports keyword arguments for functions/methods. Hence, the
virtual boost::shared_ptr<CLASS_NAME> clone() const;
```

- Class Templates
- Templates
- Basic templates are supported either with an explicit list of types to instantiate,
e.g.

Expand All @@ -113,18 +124,31 @@ The python wrapper supports keyword arguments for functions/methods. Hence, the
template<T, U> class Class2 { ... };
typedef Class2<Type1, Type2> MyInstantiatedClass;
```

- Templates can also be defined for methods, properties and static methods.
- In the class definition, appearances of the template argument(s) will be replaced with their
instantiated types, e.g. `void setValue(const T& value);`.
- To refer to the instantiation of the template class itself, use `This`, i.e. `static This Create();`.
- To create new instantiations in other modules, you must copy-and-paste the whole class definition
into the new module, but use only your new instantiation types.
- When forward-declaring template instantiations, use the generated/typedefed name, e.g.
- When forward-declaring template instantiations, use the generated/typedef'd name, e.g.

```cpp
class gtsam::Class1Pose2;
class gtsam::MyInstantiatedClass;
```
- Template arguments can be templates themselves, e.g.

```cpp
// Typedef'd PinholeCamera
template<CALIBRATION>
class PinholeCamera { ... };
typedef gtsam::PinholeCamera<gtsam::Cal3_S2> PinholeCameraCal3_S2;

template<CAMERA>
class SfmFactor { ... };
// This is valid.
typedef gtsam::SfmFactor<gtsam::PinholeCamera<gtsam::Cal3_S2>> BasicSfmFactor;
```

- `Boost.serialization` within the wrapper:
- You need to mark classes as being serializable in the markup file (see `gtsam.i` for examples).
Expand Down
Loading

0 comments on commit 43e8f1e

Please sign in to comment.