Giter VIP home page Giter VIP logo

jaxfg's Introduction

jaxfg

build lint mypy codecov

jaxfg is a factor graph-based nonlinear least squares library for JAX. Typical applications include sensor fusion, SLAM, bundle adjustment, optimal control.

The premise: we provide a high-level interface for defining probability densities as factor graphs. MAP inference reduces to nonlinear optimization, which we accelerate by analyzing the structure of the graph. Repeated factor and variable types have operations vectorized, and the sparsity of graph connections is translated into sparse matrix operations.

Features:

  • Autodiff-powered sparse Jacobians.
  • Automatic vectorization for repeated factor and variable types.
  • Manifold definition interface, with implementations provided for SO(2), SE(2), SO(3), and SE(3) Lie groups.
  • Support for standard JAX function transformations: jit, vmap, pmap, grad, etc.
  • Nonlinear optimizers: Gauss-Newton, Levenberg-Marquardt, Dogleg.
  • Sparse linear solvers: conjugate gradient (Jacobi-preconditioned), sparse Cholesky (via CHOLMOD).

This library is released as part of our IROS 2021 paper (more info in our core experiment repository here) and borrows heavily from a wide set of existing libraries, including GTSAM, Ceres Solver, minisam, SwiftFusion, and g2o. For technical background and concepts, GTSAM has a great set of tutorials.

Installation

scikit-sparse require SuiteSparse:

sudo apt update
sudo apt install -y libsuitesparse-dev

Then, from your environment of choice:

git clone https://github.com/brentyi/jaxfg.git
cd jaxfg
pip install -e .

Example scripts

Toy pose graph optimization:

python scripts/pose_graph_simple.py

Pose graph optimization from .g2o files:

python scripts/pose_graph_g2o.py  # For options, pass in a --help flag

Development

If you're interested in extending this library to define your own factor graphs, we'd recommend first familiarizing yourself with:

  1. Pytrees in JAX: https://jax.readthedocs.io/en/latest/jax-101/05.1-pytrees.html
  2. Python dataclasses: https://docs.python.org/3/library/dataclasses.html
    • We currently take a "make everything a dataclass" philosophy for software engineering in this library. This is convenient for several reasons, but notably makes it easy for objects to be registered as pytree nodes. See jax_dataclasses for details on this.
  3. Type annotations: https://docs.python.org/3/library/typing.html
    • We rely on generics (typing.Generic and typing.TypeVar) particularly heavily. If you're familiar with C++ this should come very naturally (~templates).
  4. Explicit decorators for overrides/inheritance: https://github.com/mkorpela/overrides
    • The @overrides and @final decorators signal which methods are being and/or shouldn't be overridden. The same goes for @abc.abstractmethod.

From there, we have a few references for defining your own factor graphs, factors, and manifolds:

Current limitations

  1. In XLA, JIT compilation needs to happen for each unique set of input shapes. Modifying graph structures can thus introduce significant re-compilation overheads; this can restrict applications that are dynamic or online.
  2. Our marginalization implementation is not very good.

To-do

This library's still in development mode! Here's our TODO list:

  • Preliminary graph, variable, factor interfaces
  • Real vector variable types
  • Refactor into package
  • Nonlinear optimization for MAP inference
    • Conjugate gradient linear solver
    • CHOLMOD linear solver
      • Basic implementation. JIT-able, but no vmap, pmap, or autodiff support.
      • Custom VJP rule? vmap support?
    • Gauss-Newton implementation
    • Termination criteria
    • Damped least squares
    • Dogleg
    • Inexact Newton steps
    • Revisit termination criteria
    • Reduce redundant code
    • Robust losses
  • Marginalization
    • Prototype using sksparse/CHOLMOD (works but fairly slow)
    • JAX implementation?
  • Validate g2o example
  • Performance
    • More intentional JIT compilation
    • Re-implement parallel factor computation
    • Vectorized linearization
    • Basic (Jacobi) CGLS preconditioning
  • Manifold optimization (mostly offloaded to jaxlie)
    • Basic interface
    • Manifold optimization on SO2
    • Manifold optimization on SE2
    • Manifold optimization on SO3
    • Manifold optimization on SE3
  • Usability + code health (low priority)
    • Basic cleanup/refactor
      • Better parallel factor interface
      • Separate out utils, lie group helpers
      • Put things in folders
    • Resolve typing errors
    • Cleanup/refactor (more)
    • Package cleanup: dependencies, etc
    • Add CI:
      • mypy
      • lint
      • build
      • coverage
    • More comprehensive tests
    • Clean up docstrings
    • New name

jaxfg's People

Contributors

avandavad avatar brentyi avatar supern1ck avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jaxfg's Issues

Changing and indexing prior factors after making graph

Thanks for the library! I'm trying to update the mu of a prior factor based on the optimized pose of another graph's node. However I'm stuck figuring out how the rows of graph.factor_stacks[1].factor.mu.unit_complex_xy correspond to which nodes. Any help? Thanks

RealVectorVariable Class Issue

https://github.com/brentyi/jaxfg/blob/master/jaxfg/core/_variables.py#L151

I tried to use the RealVectorVariable[dim] to instantiate a real vector variable. But I got an TypeError: Parameter list is too short. I fixed error by changing the code from

        class _RealVectorVariable(VariableBase[hints.Array]):
            @staticmethod
            @overrides
            @final
            def get_default_value() -> hints.Array:
                return jnp.zeros(dim)

to

        class _RealVectorVariable(VariableBase[hints.Array]):
            @classmethod
            @overrides
            @final
            def get_default_value(cls) -> hints.Array:
                return jnp.zeros(dim)

A possible bug with the order in solution_assignments?

Hi Brent,

It seems that the solution_assignments is not consistent with the order of pose_variables in pose_graph_simple.py(https://github.com/brentyi/jaxfg/blob/f5204945bb6afa444810e6163e9a913bdbdd636b/scripts/pose_graph_simple.py). For the original code, the outputs of

# Grab and print a single variable value at a time.
print("First pose (jaxlie.SE2 object):")
print(solution_assignments.get_value(pose_variables[0]))
print()

print("Second pose (jaxlie.SE2 object):")
print(solution_assignments.get_value(pose_variables[1]))
print()

was

First pose (jaxlie.SE2 object): 
SE2(unit_complex=[1. 0.], xy=[0.33333 0.     ])

Second pose (jaxlie.SE2 object):
SE2(unit_complex=[1. 0.], xy=[1.66667 0.     ])

However, if I change the code of creating the factor graph to (switch the order of the two PriorFactors)

factors: List[jaxfg.core.FactorBase] = [
jaxfg.geometry.PriorFactor.make(
        variable=pose_variables[1],
        mu=jaxlie.SE2.from_xy_theta(2.0, 0.0, 0.0),
        noise_model=jaxfg.noises.DiagonalGaussian(jnp.ones(3)),
    ),
    jaxfg.geometry.PriorFactor.make(
        variable=pose_variables[0],
        mu=jaxlie.SE2.from_xy_theta(0.0, 0.0, 0.0),
        noise_model=jaxfg.noises.DiagonalGaussian(jnp.ones(3)),
    ),
    jaxfg.geometry.BetweenFactor.make(
        variable_T_world_a=pose_variables[0],
        variable_T_world_b=pose_variables[1],
        T_a_b=jaxlie.SE2.from_xy_theta(1.0, 0.0, 0.0),
        noise_model=jaxfg.noises.DiagonalGaussian(jnp.ones(3)),
    ),
]

Then, the outputs become

First pose (jaxlie.SE2 object):
SE2(unit_complex=[1. 0.], xy=[1.66667 0.     ])

Second pose (jaxlie.SE2 object):
SE2(unit_complex=[1. 0.], xy=[0.33333 0.     ])

It seems that the order in the solution_assignments is determined by the order of the factors?

SLAM example

Hello

This project seems very interesting, thanks for sharing it.

Could you please provide an example of a SLAM implementation using in the examples section using a popular dataset (KITTI or oxford dataset for example)?

This would be a very helpful example to learn how to use the library.

Thanks in advance

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.