Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
06acfac
Set mac_deployment_target variable
yambati03 Mar 10, 2025
3b0d4aa
Use clang if on MacOS
yambati03 Mar 12, 2025
bd73f77
Did not work, trying something else
yambati03 Mar 12, 2025
fe01f30
Potential fix for filesystem header issue
yambati03 Mar 12, 2025
3db3ed3
Change deployment target to 10.14
yambati03 Mar 12, 2025
a065a99
Fix
yambati03 Mar 12, 2025
47d3709
correctly fix script and record timing information
varunagrawal Mar 25, 2025
5c2e8d6
record timing information
varunagrawal Mar 25, 2025
d01bfba
implement DecisionTreeFactor::restrict
varunagrawal Mar 25, 2025
bbceb7a
optionally provide ordering for HybridSmoother::relinearize
varunagrawal Mar 25, 2025
2869a70
default argument for ordering in wrapper
varunagrawal Mar 25, 2025
e1d30ed
Merge branch 'borglab:develop' into develop
yambati03 Mar 27, 2025
a64e2a7
Merge remote-tracking branch 'upstream/pydocstrings-documentation' in…
yambati03 Mar 27, 2025
6fd467d
Generate doxygen XML and enable docstrings
yambati03 Mar 27, 2025
162e5d4
Reduce output from boost installation
yambati03 Mar 27, 2025
65ba500
Change MacOS min target to 10.15
yambati03 Mar 27, 2025
b5ac562
Forgot to install doxygen on mac. Oops
yambati03 Mar 27, 2025
6555466
Force boost build from source to respect MACOSX_DEPLOYMENT_TARGET option
yambati03 Mar 27, 2025
d0b364e
Forcing via --build-from-source did not work, trying something else
yambati03 Mar 27, 2025
4e5c07b
Merge branch 'borglab:develop' into develop
yambati03 Apr 3, 2025
a34c533
Install boost to the default location to suppress permissions errors
yambati03 Apr 3, 2025
8dda768
Add back prefix, local dir
yambati03 Apr 3, 2025
4b05994
Set BOOST_ROOT to local install dir
yambati03 Apr 3, 2025
3ef95a4
update Metis' cmake_minimum_required to 3.5
varunagrawal Apr 3, 2025
ef31675
Script to generate .ipynb doc files
p-zach Apr 3, 2025
f417171
First run of generating docs; most of nonlinear
p-zach Apr 3, 2025
9ab3e5b
Ensure runtime linker can dynamically load boost
yambati03 Apr 3, 2025
0715411
Usage example for script
p-zach Apr 3, 2025
6c22eae
Uninstall boost using brew
yambati03 Apr 3, 2025
91d23df
Merge pull request #2079 from borglab/fix/metis-cmake
varunagrawal Apr 3, 2025
9e902bb
Potential fix
yambati03 Apr 3, 2025
74fba4b
fix DiscreteBayesTree::marginalFactor return type
varunagrawal Apr 3, 2025
5ab2e3f
fix return type of DiscreteFactorGraoh::product
varunagrawal Apr 3, 2025
f4a7951
Merge pull request #2081 from borglab/fix/discrete-wrapping
varunagrawal Apr 4, 2025
cdbff87
Merge branch 'develop' into gpt-docs
dellaert Apr 4, 2025
b873550
Added comments
dellaert Apr 5, 2025
0078774
Moved BatchFixedLagSmoother in right spot
dellaert Apr 5, 2025
1fa20f5
Move optimizer docs to nonlinear
dellaert Apr 5, 2025
f2745c4
Better overview
dellaert Apr 5, 2025
8a0521b
NLO and Dogleg docs
dellaert Apr 5, 2025
bea6979
Explanatory text
p-zach Apr 5, 2025
fab57ee
Regenerated failed files
p-zach Apr 5, 2025
7c1a1e0
Nitpicking
p-zach Apr 5, 2025
159e185
Refine other optimizers' docs
p-zach Apr 5, 2025
dc08251
Files for nonlinearopt
p-zach Apr 5, 2025
50e40d0
Move remaining files
p-zach Apr 5, 2025
2ae55d7
Add PreintegratedRotation to wrapper
dellaert Apr 5, 2025
c14df87
Add docs for AHRS-related classes
dellaert Apr 5, 2025
796364d
Add navigation to docs
dellaert Apr 5, 2025
eb705c6
More details and code example
dellaert Apr 6, 2025
ed6038d
CustomFactor docs
dellaert Apr 6, 2025
3e8a29a
Added examples to site
dellaert Apr 6, 2025
02150a2
Moved stuff to notebook, Jacobian guidance
dellaert Apr 6, 2025
d31ab0f
Move and update expressions.md from BitBucket
dellaert Apr 6, 2025
0d6a8e2
Move incremental fls
p-zach Apr 6, 2025
d049592
Merge pull request #2082 from borglab/feature/ahrs_docs
dellaert Apr 6, 2025
a59b358
Fix ifls dependency
p-zach Apr 6, 2025
a832a52
Move bayes tree marg helper (no .i presence)
p-zach Apr 6, 2025
0e68480
Reviewed 3 more
dellaert Apr 6, 2025
f57c0a6
Fix wrapper interface error from typo
p-zach Apr 6, 2025
d3895d6
Moved example notebooks to examples
dellaert Apr 6, 2025
942750b
Reviewed all remaining notebooks
dellaert Apr 6, 2025
2991ce6
Merge branch 'develop' into gpt-docs
dellaert Apr 6, 2025
655ded3
Remove IncrementalFixedLagSmoother from gtsam_unstable wrapper
p-zach Apr 6, 2025
4226da3
Merge pull request #2080 from borglab/gpt-docs
dellaert Apr 6, 2025
c2f9c5e
Merge pull request #2083 from borglab/move-ifls
dellaert Apr 6, 2025
b29ca85
Mermaid diagram
dellaert Apr 7, 2025
12d74ad
Split AHRS and IMU overviews
dellaert Apr 7, 2025
f991a42
Split off params diagram
dellaert Apr 7, 2025
e84b1c4
Almost perfect Gemini 2.5 notebooks
dellaert Apr 7, 2025
13a74a4
AttitudeFactor
dellaert Apr 7, 2025
8757090
BarometricFactor
dellaert Apr 7, 2025
12104b7
ConstantVelocityFactor + wrapping
dellaert Apr 7, 2025
ae87ca6
GPSFactor + wrapping
dellaert Apr 7, 2025
f9c981d
MagFactor + wrapping
dellaert Apr 7, 2025
f4485db
MagPoseFactor + wrapping
dellaert Apr 7, 2025
a68d3ff
Scenario and ScenarioRunner
dellaert Apr 7, 2025
5eaba68
Add files and links
dellaert Apr 7, 2025
967c3ed
Merge pull request #2084 from borglab/feature/more_nav_docs
dellaert Apr 7, 2025
0570dea
Merge pull request #2073 from borglab/hybrid-relinearize
varunagrawal Apr 8, 2025
e7ff363
Fix the FixedLagSmootherExample and move it out of gtsam_unstable
jmackay2 Apr 9, 2025
48ffd93
Merge pull request #2085 from jmackay2/fix_example_build
varunagrawal Apr 9, 2025
8b0ade0
Dont pass rpath to cxxflags
yambati03 Apr 10, 2025
2afb78d
Pass DYLD_LIBRARY_PATH to delocate
yambati03 Apr 10, 2025
6b3a158
Merge branch 'borglab:develop' into develop
yambati03 Apr 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 38 additions & 12 deletions .github/scripts/python_wheels/cibw_before_all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,42 @@ export PYTHON="python${PYTHON_VERSION}"

if [ "$(uname)" == "Linux" ]; then
# manylinux2014 is based on CentOS 7, so use yum to install dependencies
yum install -y wget

# Install Boost from source
wget https://archives.boost.io/release/1.87.0/source/boost_1_87_0.tar.gz --quiet
tar -xzf boost_1_87_0.tar.gz
cd boost_1_87_0
./bootstrap.sh --prefix=/opt/boost
./b2 install --prefix=/opt/boost --with=all
cd ..
yum install -y wget doxygen
elif [ "$(uname)" == "Darwin" ]; then
brew install wget cmake boost
brew install wget cmake doxygen
fi

# Install Boost from source
wget https://archives.boost.io/release/1.87.0/source/boost_1_87_0.tar.gz --quiet
tar -xzf boost_1_87_0.tar.gz
cd boost_1_87_0

BOOST_PREFIX="$HOME/opt/boost"
./bootstrap.sh --prefix=${BOOST_PREFIX}

if [ "$(uname)" == "Linux" ]; then
./b2 install --prefix=${BOOST_PREFIX} --with=all -d0
elif [ "$(uname)" == "Darwin" ]; then
# Default to macOS 10.15 if MACOSX_DEPLOYMENT_TARGET is not set
if [[ -z "${MACOSX_DEPLOYMENT_TARGET}" ]]; then
export MACOSX_DEPLOYMENT_TARGET="10.15"
fi

./b2 install --prefix=${BOOST_PREFIX} --with=all -d0 \
cxxflags="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET}" \
linkflags="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET}"
fi
cd ..

# Export paths so CMake or build system can find Boost
export BOOST_ROOT="${BOOST_PREFIX}"
export BOOST_INCLUDEDIR="${BOOST_PREFIX}/include"
export BOOST_LIBRARYDIR="${BOOST_PREFIX}/lib"

# Ensure runtime linker can find Boost libraries
export LD_LIBRARY_PATH="${BOOST_LIBRARYDIR}:$LD_LIBRARY_PATH" # For Linux
export REPAIR_LIBRARY_PATH="${BOOST_LIBRARYDIR}:$DYLD_LIBRARY_PATH" # For macOS

$(which $PYTHON) -m pip install -r $PROJECT_DIR/python/dev_requirements.txt

# Remove build/cache files that were generated on host
Expand All @@ -48,11 +71,14 @@ cmake $PROJECT_DIR \
-DGTSAM_PYTHON_VERSION=$PYTHON_VERSION \
-DPYTHON_EXECUTABLE:FILEPATH=$(which $PYTHON) \
-DGTSAM_ALLOW_DEPRECATED_SINCE_V43=OFF \
-DCMAKE_INSTALL_PREFIX=$PROJECT_DIR/gtsam_install
-DCMAKE_INSTALL_PREFIX=$PROJECT_DIR/gtsam_install \
-DGTSAM_GENERATE_DOC_XML=0

cd $PROJECT_DIR/build/python
# Generate Doxygen XML documentation
doxygen build/doc/Doxyfile

# Install the Python wrapper module and generate Python stubs
cd $PROJECT_DIR/build/python
if [ "$(uname)" == "Linux" ]; then
make -j $(nproc) install
make -j $(nproc) python-stubs
Expand Down
42 changes: 26 additions & 16 deletions .github/workflows/build-cibw.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,22 +76,22 @@ jobs:
manylinux_image: manylinux2014

# MacOS x86_64
# - os: macos-13
# python_version: "3.10"
# cibw_python_version: 310
# platform_id: macosx_x86_64
# - os: macos-13
# python_version: "3.11"
# cibw_python_version: 311
# platform_id: macosx_x86_64
# - os: macos-13
# python_version: "3.12"
# cibw_python_version: 312
# platform_id: macosx_x86_64
# - os: macos-13
# python_version: "3.13"
# cibw_python_version: 313
# platform_id: macosx_x86_64
- os: macos-13
python_version: "3.10"
cibw_python_version: 310
platform_id: macosx_x86_64
- os: macos-13
python_version: "3.11"
cibw_python_version: 311
platform_id: macosx_x86_64
- os: macos-13
python_version: "3.12"
cibw_python_version: 312
platform_id: macosx_x86_64
- os: macos-13
python_version: "3.13"
cibw_python_version: 313
platform_id: macosx_x86_64

steps:
- name: Checkout
Expand Down Expand Up @@ -130,6 +130,14 @@ jobs:
run: |
cmake . -B build -DGTSAM_BUILD_PYTHON=1 -DGTSAM_PYTHON_VERSION=${{ matrix.python_version }}

# If on macOS, we previously installed boost using homebrew for the first build.
# We need to uninstall it before building the wheels with cibuildwheel, which will
# install boost from source.
- name: Uninstall Boost (MacOS)
if: runner.os == 'macOS'
run: |
brew uninstall boost

- name: Build and test wheels
env:
# Generate the platform identifier. See https://cibuildwheel.pypa.io/en/stable/options/#build-skip.
Expand All @@ -138,6 +146,8 @@ jobs:
CIBW_MANYLINUX_AARCH64_IMAGE: ${{ matrix.manylinux_image }}
CIBW_ARCHS: all
CIBW_ENVIRONMENT_PASS_LINUX: DEVELOP TIMESTAMP
MACOSX_DEPLOYMENT_TARGET: 10.15
CIBW_REPAIR_WHEEL_COMMAND_MACOS: DYLD_LIBRARY_PATH=$REPAIR_LIBRARY_PATH delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}

# Use build instead of pip wheel to build the wheels. This is recommended by PyPA.
# See https://cibuildwheel.pypa.io/en/stable/options/#build-frontend.
Expand Down
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ if(GTSAM_BUILD_PYTHON OR GTSAM_INSTALL_MATLAB_TOOLBOX)
# Set the include directory for matlab.h
set(GTWRAP_INCLUDE_NAME "wrap")

if (GTSAM_GENERATE_DOC_XML)
set(GTWRAP_ADD_DOCSTRINGS ON)
endif()

# Copy matlab.h to the correct folder.
configure_file(${PROJECT_SOURCE_DIR}/wrap/matlab.h
${PROJECT_BINARY_DIR}/wrap/matlab.h COPYONLY)
Expand Down
7 changes: 7 additions & 0 deletions doc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ option(GTSAM_BUILD_DOCS "Enable/Disable building of doxygen doc
# configure doxygen
option(GTSAM_BUILD_DOC_HTML "Enable/Disable doxygen HTML output" ON)
option(GTSAM_BUILD_DOC_LATEX "Enable/Disable doxygen LaTeX output" OFF)
option(GTSAM_GENERATE_DOC_XML "Enable/Disable doxygen XML output" OFF)

# add a target to generate API documentation with Doxygen
if (GTSAM_BUILD_DOCS)
Expand All @@ -20,6 +21,12 @@ if (GTSAM_BUILD_DOCS)
set(GTSAM_BUILD_DOC_LATEX_YN "NO")
endif()

if (GTSAM_GENERATE_DOC_XML)
set(GTSAM_GENERATE_XML_YN "YES")
else()
set(GTSAM_GENERATE_XML_YN "NO")
endif()

# GTSAM core subfolders
set(gtsam_doc_subdirs
gtsam/base
Expand Down
2 changes: 1 addition & 1 deletion doc/Doxyfile.in
Original file line number Diff line number Diff line change
Expand Up @@ -2120,7 +2120,7 @@ MAN_LINKS = NO
# captures the structure of the code including all documentation.
# The default value is: NO.

GENERATE_XML = NO
GENERATE_XML = @GTSAM_GENERATE_XML_YN@

# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
Expand Down
3 changes: 3 additions & 0 deletions doc/examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Examples

This section contains python examples in interactive Python notebooks (`*.ipynb`). Python notebooks with an <img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/> button near the top can be opened in your browser, where you can run the files yourself and make edits to play with and understand GTSAM.
113 changes: 113 additions & 0 deletions doc/expressions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Expressions
## Motivation
GTSAM is an optimization library for objective functions expressed as a factor graph over a set of unknown variables. In the continuous case, the variables are typically vectors or elements on a manifold (such as the 3D rotation manifold). The factors compute vector-valued errors that need to be minimized, and are typically only connected to a handful of unknowns.

In the continuous case, the main optimization methods we have implemented are variants of Gauss-Newton non-linear optimization or conjugate gradient methods. Let us assume there are m factors over n unknowns. For either optimization method, we need to evaluate the sparse Jacobian matrix of the entire factor graph, which is a sparse block-matrix of m block-rows and n-block columns.

The sparse Jacobian is built up factor by factor, corresponding to the block-rows. A typical non-linear least-square term is $|h(x)-z|^2$ where $h(x)$ is a measurement function, which we need to be able to linearize as
$$
h(x) \approx h(x_0+dx)+H(x_0)dx
$$
Note the above is for vector unknowns, for Lie groups and manifold variables, see [doc/math.pdf](https://github.com/borglab/gtsam/blob/develop/doc/math.pdf) for details.

## Expressions
In many cases one can use GTSAM 4 Expressions to implement factors. Expressions are objects of type Expression<T>, and there are three main expression flavors:

- constants, e.g., `Expression<Point2> kExpr(Point2(3,4))`
- unknowns, e.g., `Expression<Point3> pExpr(123)` where 123 is a key.
- functions, e.g., `Expression<double> sumExpr(h, kexpr, pExpr)`

The latter case is an example of wrapping a binary measurement function `h`. To be able to wrap `h`, it needs to be able to compute its local derivatives, i.e., it has to have the signature
```c++
double h(const Point2& a, const Point3& b,
OptionalJacobian<1, 2> Ha, OptionalJacobian<1, 3> Hb)
```
In this case the output type 'T' is 'double', the two arguments have type Point2 and Point3 respectively, and the two remaining arguments provide a way to compute the function Jacobians, if needed. The templated type `OptionalJacobian<M,N>` behaves very much like `std::optional<Eigen::Matrix<double,M,N>`. If an actual matrix is passed in, the function is expected to treat it as an output argument in which to write the Jacobian for the result wrp. the corresponding input argument. *The matrix to write in will be allocated before the call.*

Expression constructors exist for both methods and functions with different arities. Note that an expression is templated with the output type T, not with the argument types. However, the constructor will infer the argument types from inspecting the signature of the function f, and will in this example expect two additional arguments of type Expression<Point2> and Expression<Point3>, respectively.

As an example, here is the constructor declaration for wrapping unary functions:
```c++
template<typename A>
Expression(typename UnaryFunction<A>::type function,
const Expression<A>& expression);
```
where (in this case) the function type is defined by
```c++
template<class A1>
struct UnaryFunction {
typedef boost::function<
T(const A1&, typename MakeOptionalJacobian<T, A1>::type)> type;
};
```
## Some measurement function examples
An example of a simple unary function is `gtsam::norm3` in [Point3.cpp](https://github.com/borglab/gtsam/blob/develop/gtsam/geometry/Point3.cpp#L41):
```c++
double norm3(const Point3 & p, OptionalJacobian<1, 3> H = {}) {
double r = sqrt(p.x() * p.x() + p.y() * p.y() + p.z() * p.z());
if (H) *H << p.x() / r, p.y() / r, p.z() / r;
return r;
}
```
The key new concept here is OptionalJacobian, which acts like a std::optional: if it evaluates to true, you should write the Jacobian of the function in it. It acts as a fixed-size Eigen matrix.

As we said above, expressions also support binary functions, ternary functions, and methods. An example of a binary function is 'Point3::cross':

```c++
Point3 cross(const Point3 &p, const Point3 & q,
OptionalJacobian<3, 3> H1 = {}, OptionalJacobian<3, 3> H2 = {}) {
if (H1) *H1 << skewSymmetric(-q.x(), -q.y(), -q.z());
if (H2) *H2 << skewSymmetric(p.x(), p.y(), p.z());
return Point3(p.y() * q.z() - p.z() * q.y(), p.z() * q.x() - p.x() * q.z(), p.x() * q.y() - p.y() * q.x());
}
```
Example of using cross:
```c++
using namespace gtsam;
Matrix3 H1, H2;
Point3 p(1,2,3), q(4,5,6), r = cross(p,q,H1,H2);
```
## Using Expressions for Inference
The way expressions are used is by creating unknown Expressions for the unknown variables we are optimizing for:
```c++
Expression<Point3> x(‘x’,1);
auto h = Expression<Point3>(& norm3, x);
```
For convenient creation of factors with expressions, we provide a new factor graph type `ExpressionFactorGraph`, which is just a `NonlinearFactorGraph` with an extra method addExpressionFactor(h, z, n) that takes a measurement expression h, an actual measurement z, and a measurement noise model R. With this, we can add a GTSAM nonlinear factor $|h(x)-z|^2$ to a `NonlinearFactorGraph` by
```c++
graph.addExpressionFactor(h, z, R)
```
In the above, the unknown in the example can be retrieved by the `gtsam::Symbol(‘x’,1)`, which evaluates to a uint64 identifier.

## Composing Expressions
The key coolness behind expressions, however, is that you can compose them into expression trees, as long as the leaves know how to do their own derivatives:
```c++
Expression<Point3> x1(‘x’1), x2(‘x’,2);
auto h = Expression<Point3>(& cross, x1, x2);
auto g = Expression<Point3>(& norm3, h);
```
Because we typedef Point3_ to Expression<Point3>, we can write this very concisely as
```c++
auto g = Point3_(& norm3, Point3_(& cross, x1(‘x’1), x2(‘x’,2)));
```
## PoseSLAM Example
Using expressions, it is simple to quickly create a factor graph corresponding to a PoseSLAM problem, where our only measurements are relative poses between a series of unknown 2D or 3D poses. The following code snippet from [Pose2SLAMExampleExpressions.cpp](https://github.com/borglab/gtsam/blob/develop/examples/Pose2SLAMExampleExpressions.cpp) is used to create a simple Pose2 example (where the robot is moving on a plane):
```c++
1 ExpressionFactorGraph graph;
2 Expression<Pose2> x1(1), x2(2), x3(3), x4(4), x5(5);
3 graph.addExpressionFactor(x1, Pose2(0, 0, 0), priorNoise);
4 graph.addExpressionFactor(between(x1,x2), Pose2(2, 0, 0 ), model);
5 graph.addExpressionFactor(between(x2,x3), Pose2(2, 0, M_PI_2), model);
6 graph.addExpressionFactor(between(x3,x4), Pose2(2, 0, M_PI_2), model);
7 graph.addExpressionFactor(between(x4,x5), Pose2(2, 0, M_PI_2), model);
8 graph.addExpressionFactor(between(x5,x2), Pose2(2, 0, M_PI_2), model);
```
This is what is going on:
- In line 1, we create an empty factor graph.
- In line 2 we create the 5 unknown poses, of type `Expression<Pose2>`, with keys 1 to 5. These are what we will optimize over.
- Line 3 then creates a simple factor that gives a prior on `x1` (the first argument), namely that it is at the origin `Pose2(0, 0, 0)` (the second argument), with a particular probability density given by `priorNoise` (the third argument).
- Lines 4-7 adds factors for the odometry constraints, i.e., the movement between successive poses of the robot. The function `between(t1,t2)` is implemented in [nonlinear/expressions.h](https://github.com/borglab/gtsam/blob/develop/gtsam/nonlinear/expressions.h) and is equivalent to calling the constructor Expression<T>(traits<T>::Between, t1, t2).
- Finally, line 8 creates a loop closure constraint between poses x2 and x5.

Another good example of its use is in
[SFMExampleExpressions.cpp](https://github.com/borglab/gtsam/blob/develop/examples/SFMExampleExpressions.cpp).
Loading
Loading