The Borg Lab

GTSAM 2.0.0 Changes


GTSAM is a high-performance, easy-to-use, and modern C++ library for SLAM, SAM, bundle adjustment, and general nonlinar optimization.

Changes in 2.0.0 from 1.0-beta

  • Large runtime speedup and less memory usage
  • Greatly simplified and cleaner API
  • New discrete optimization framework
  • Expanded MATLAB interface
  • Dogleg nonlinear optimization (in addition to Levenberg-Marquardt and Gauss-Newton algorithms)
  • iSAM2 algorithm for incremental nonlinear estimation (See project:  ISAM2)
  • Incremental nonlinear Dogleg optimization using ISAM2 (See Rosen et al, ICRA 2012)
  • CMake build system
  • BSD License

Main API changes affecting compiling against GTSAM

To make code using GTSAM cleaner and easier to write, we eliminated the need for most typedefs and specialized graph and values classes.  Previously, code using GTSAM needed a large body of typedefs and specialized classes, for example, PoseKey, OdometryFactor, ASPNGraph, ASPNValues, etc.  These are no longer necessary because of a move to dynamic value types.

NonlinearFactor{1-6} are now named NoiseModelFactor{1-6}:

  • This is because they are actually NoiseModelFactor's, not the more general NonlinearFactor.
  • Rename the base classes of any custom nonlinear factors as necessary.

Nonlinear keys are integers (but compatible with Symbol), and TypedSymbol is gone:

  • Values uses the type 'Key' (typedefed to size_t) as a nonlinear key, instead of TypedSymbol or Symbol.
  • The integer keys must be unique among all variable types, but you can still use Symbol with different letters for different variable types in order to keep convenient IDs, such as having both camera 1 (x1) and landmark 1 (l1).  Internally, Symbol will be transformed to a unique integer Key.
  • Symbol can be implicitly converted to Key, so you can continue to use Symbol to have nice 'x3'-style variables.

Required / recommended code changes:

  • Remove all TypedSymbol typedefs.
  • Remove typedefs to NonlinearFactorGraph<…> - it's no longer a template!
  • Use Symbol or Key (size_t) keys, instead of TypedSymbol, with Values, Ordering, and NonlinearFactor
  • For convenience, if you already have typedefs named e.g. PoseKey, you can define a function:

    Key PoseKey(size_t j) { return Symbol('x', j); }

    and analogously for PointKey, etc.  This reduces the amount of code changes you'll have to make.

Dynamic Value objects and Values:

  • Values is now a non-templated object that stores arbitrary objects derived from Value (e.g. Pose2, Point3, Rot3, etc…).
  • Values uses Key (typedefed from size_t) keys instead of TypedSymbol keys
  • When retrieving an object from Values, you must tell it the type, e.g. Pose3 pose =<Pose3>(j);
  • Other minor API changes in Values due to storing dynamic types.
  • To get all variables of a particular type, or whose Key matches a particular pattern, use the Values::filter() function.  This is similar to how we could say TupleValues::first() or TupleValues::second(), but more powerful.

Required / recommended code changes:

  • Remove all typedefs to Values<...> and TupleValues<…> - Values is no longer a template, and TupleValues is gone!
  • Anywhere you previously used the [] operator in TupleValues, change this to use Values::at<ValueType>(Key key)
  • Anywhere you used the first(), second(), etc, functions in TupleValues to view just the Pose3 Values part, etc, use instead:
    BOOST_FOREACH(Values::Filtered<Pose3>::value_type key_value, values.filter<Pose3>()) { … }
    to retrieve all key-value pairs with Value type Pose3,
    BOOST_FOREACH(Values::Filtered<Pose3>::value_type key_value, values.filter<Pose3>(Symbol::ChrTest('x')) { … }
    to retrieve all key-value pairs with Value type Pose3 AND key (interpreted as Symbol) whose character is 'x',
    BOOST_FOREACH(Values::Filtered<>::value_type key_value, values.filter(Symbol::ChrTest('x')) { … }
    to retrieve all key-value pairs with key whose character is 'x', but unlike the previous example, here the values could be any type, and will be returned as Value base class references.
  • Use ConstFiltered instead of Filtered to maintain const-correctness if you do not need to modify the values
  • If the Values object is const, Values::filter() will always return Values::ConstFiltered<…>.

Nonlinear factors are now templated on Value type, not key type:

  • This is because all keys are now integers (Key).
  • Change the template arguments of custom factors to take this into account.  For examples, see the factors in the slam directory.