Crate factrs

Source
Expand description

fact.rs (pronounced factors) is a nonlinear least squares optimization library over factor graphs written in Rust.

It is specifically geared toward sensor fusion in robotics. It aims to be fast, easy to use, and safe. The fact.rs API takes heavy inspiration from the gtsam library.

Currently, it supports the following features

  • Gauss-Newton & Levenberg-Marquadt Optimizers
  • Common Lie Groups supported (SO2, SO3, SE2, SE3) with optimization in Lie Algebras
  • Automatic differentiation via dual numbers
  • Serialization of graphs & variables via optional serde support
  • Easy conversion to rerun types for straightforward visualization

§Background

Specifically, we solve the following problem,

$$ \blue{\Theta^*} = \red{\argmin_{\Theta}} \sum_{i} \green{\rho_i(||r_i(\Theta)||_{\Sigma_i} )} $$

The fact.rs API takes heavy inspiration from the gtsam library, and is loosely structured as follows,

  • Variables: These are the unknowns in the optimization problem. They are all lie-group based (even if trivially so). See the variable module for details on custom implementations. A collection of variables is stored in a Values container.
  • Optimizers: The optimizer is responsible for finding the optimal variables that minimize the factors. More info on factor graph optimizers in Optimizers.
  • Factors: Each factor represents a probabilistic constraint in the optimization. More info in Factor. A collection of factors is stored in a Graph container.

§Example

use factrs::{
    assign_symbols,
    core::{BetweenResidual, GaussNewton, Graph, Huber, PriorResidual, Values, SO2},
    fac,
    traits::*,
};

// Assign symbols to variable types
assign_symbols!(X: SO2);

// Make all the values
let mut values = Values::new();

let x = SO2::from_theta(1.0);
let y = SO2::from_theta(2.0);
values.insert(X(0), SO2::identity());
values.insert(X(1), SO2::identity());

// Make the factors & insert into graph
let mut graph = Graph::new();
let res = PriorResidual::new(x.clone());
let factor = fac![res, X(0)];
graph.add_factor(factor);

let res = BetweenResidual::new(y.minus(&x));
let factor = fac![res, (X(0), X(1)), 0.1 as std, Huber::default()];
graph.add_factor(factor);

// Optimize!
let mut opt: GaussNewton = GaussNewton::new(graph);
let result = opt.optimize(values).unwrap();
println!("Results {:#}", result);

Modules§

containers
Various containers for storing variables, residuals, factors, etc.
core
Helper module to group together most commonly used types
linalg
Various helpers for linear algebra structures.
linear
Structs & traits for solving linear factor graphs
noise
Noise model representations
optimizers
Optimizers for solving non-linear least squares problems.
rerunrerun
Conversion from fact.rs types to rerun types
residuals
Struct & traits for implementing residuals
robust
Robust kernels (M-Estimators) for robust estimation.
serdeserde
Macros to help with serde serialization
symbols
Untagged symbols if unchecked API is desired.
traits
Helper module to import common traits
utils
Misc utilities
variables
Variables to optimize

Macros§

assert_variable_eq
Variable wrapper around assert_matrix_eq
assign_symbols
Creates and assigns Symbols to Variables
fac
Easiest way to create a factor
test_lie
Test (most of) the matrix lie group rules
test_optimizer
Test optimizers
test_robust
Test robust kernels
test_variable
Test (most of) the lie group rules

Type Aliases§

dtype
The default floating point type used in the library

Attribute Macros§

mark
Mark an implementation of Variable, Residual, Noise, or Robust.