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.
- rerun
rerun
- Conversion from fact.rs types to rerun types
- residuals
- Struct & traits for implementing residuals
- robust
- Robust kernels (M-Estimators) for robust estimation.
- serde
serde
- 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