chinese-hershey-font
Convert Chinese Characters to Single-Line Fonts using Computer Vision
A small C++11 header-only library for Lie theory.
manif is a Lie theory library for state-estimation targeted at robotics applications. It is developed as a header-only C++11 library with Python 3 wrappers.
At the moment, it provides the groups:
Other Lie groups can and will be added, contributions are welcome.
manif is based on the mathematical presentation of the Lie theory available in this paper. We recommend every user of manif to read the paper (17 pages) before starting to use the library. The paper offers a comprehensive yet accessible introduction to Lie theory, tailored specifically for roboticists. By presenting the material in a simplified manner, it lowers the barrier to entry for those interested in developing rigorous and elegant algorithms for state estimation, control, learning, and possibly more. This approach ensures that even readers without an advanced mathematical background can grasp the foundational concepts and apply them effectively in robotics.
You may also find the following video online, 'Lie theory for the roboticist', a lecture given at IRI-UPC.
In a rush? Check out our Lie group cheat sheet.
manif provides analytic computation of Jacobians for all the operations listed below.
Get quickly started with manif following our 'quick start' guides for both C++ and Python.
| Operation | Code | |
|---|---|---|
| Base Operation | ||
| Inverse | $\bf\mathcal{X}^{-1}$ | X.inverse() |
| Composition | $\bf\mathcal{X}\circ\bf\mathcal{Y}$ |
X * YX.compose(Y)
|
| Hat | $\boldsymbol\varphi^\wedge$ | w.hat() |
| Act on vector | $\bf\mathcal{X}\circ{\bf v}$ | X.act(v) |
| Retract to group element | $\exp(\boldsymbol\varphi^\wedge)$ | w.exp() |
| Lift to tangent space | $\log(\bf\mathcal{X})^\vee$ | X.log() |
| Manifold Adjoint | $\mathrm{Adj}(\bf\mathcal{X})$ | X.adj() |
| Tangent adjoint | $\mathrm{adj}(\boldsymbol\varphi^\wedge)$ | w.smallAdj() |
| Composed Operation | ||
| Manifold right plus | ${\bf\mathcal{X}}\circ\exp(\boldsymbol\varphi^\wedge)$ |
X + wX.plus(w)X.rplus(w)
|
| Manifold left plus | $\exp(\boldsymbol\varphi^\wedge)\circ\bf\mathcal{X}$ |
w + Xw.plus(X)w.lplus(X)
|
| Manifold right minus | $\log(\bf\mathcal{Y}^{-1}\circ\bf\mathcal{X})^\vee$ |
X - YX.minus(Y)X.rminus(Y)
|
| Manifold left minus | $\log(\bf\mathcal{X}\circ\bf\mathcal{Y}^{-1})^\vee$ | X.lminus(Y) |
| Between | ${\bf\mathcal{X}^{-1}}\circ{\bf\mathcal{Y}}$ | X.between(Y) |
| Inner Product | $\langle\boldsymbol\varphi,\boldsymbol\tau\rangle$ | w.inner(t) |
| Norm | $\left\lVert\boldsymbol\varphi\right\rVert$ |
w.weightedNorm()w.squaredWeightedNorm()
|
Above, ${\bf\mathcal{X}}$ & ${\bf\mathcal{Y}}$ (X & Y) represent group elements,
${\boldsymbol\varphi^\wedge}$ & ${\boldsymbol\tau^\wedge}$ represent elements in the Lie algebra of the Lie group,
${\boldsymbol\varphi}$ & ${\boldsymbol\tau}$ (w & t) represent the same elements of the tangent space
but expressed in Cartesian coordinates in $\mathbb{R}^n$,
and $\mathbf{v}$ (v) represents any element of $\mathbb{R}^n$.
manif favors Cartesian representations of the tangent spaces. This means that the tangent elements are regular vectors in $\mathbb{R}^n$, 'n' being the dimension of the Lie group.
The ordering of the elements in such vectors matters to correctly interpret them. It impacts the form of all Jacobian matrices and covariances matrices that will be defined on those tangent spaces.
As a reference, this is the way tangent spaces are defined in manif
| group | dimension | group elements | tangent elements (in order) |
|---|---|---|---|
| Rn | n | $\bf p$ | $\bf p$ |
| SO(2) | 1 | $\bf R$ | $\theta$ |
| SO(3) | 3 | $\bf R$ | $\boldsymbol\theta$ |
| SE(2) | 3 | $\bf p$, $\bf R$ | $\boldsymbol\rho$, $\theta$ |
| SE(3) | 6 | $\bf p$, $\bf R$ | $\boldsymbol\rho$, $\boldsymbol\theta$ |
| SE_2(3) | 9 | $\bf p$, $\bf R$, $\bf v$ | $\boldsymbol\rho$, $\boldsymbol\theta$, $\boldsymbol\nu$ |
| SGal(3) | 10 | $\bf p$, $\bf R$, $\bf v$, $t$ | $\boldsymbol\rho$, $\boldsymbol\nu$, $\boldsymbol\theta$, $s$ |
NOTE: the unfortunate order mismatch between the tangent elements in SE_2(3) and SGal(3).
As an example, in SE_2(3) the tangent vector ${\boldsymbol\tau}$ is defined by
$$ {\boldsymbol\tau} = \begin{bmatrix} {\boldsymbol\rho} \\ {\boldsymbol\theta} \\ {\boldsymbol\nu} \end{bmatrix} \in \mathbb{R}^9 $$
where $\boldsymbol\rho$, $\boldsymbol\theta$ and $\boldsymbol\nu$ are $\in \mathbb{R}^3$ and typically correspond respectively to changes in position, orientation and velocity.
A covariances matrix $\bf Q$ of an element of SE_2(3) can be block-partitioned as follows
$$ {\bf Q} = \begin{bmatrix} {\bf Q}_ {\boldsymbol\rho\boldsymbol\rho} & {\bf Q}_ {\boldsymbol\rho\boldsymbol\theta} & {\bf Q}_ {\boldsymbol\rho\boldsymbol\nu} \\ {\bf Q}_ {\boldsymbol\theta\boldsymbol\rho} & {\bf Q}_ {\boldsymbol\theta\boldsymbol\theta} & {\bf Q}_ {\boldsymbol\theta\boldsymbol\nu} \\ {\bf Q}_ {\boldsymbol\nu\boldsymbol\rho} & {\bf Q}_ {\boldsymbol\nu\boldsymbol\theta} & {\bf Q}_ {\boldsymbol\nu\boldsymbol\nu} \end{bmatrix} \in \mathbb{R}^{9\times 9} $$
All blocks ${\bf Q}_{\bf ij}$ are $3\times3$ and ${\bf Q}$ is $9\times9$.
All operations come with their respective analytical Jacobian matrices. Throughout manif, Jacobians are differentiated with respect to a perturbation on the local tangent space. These Jacobians map tangent spaces, as described in this paper. Please consider the order of elements in the tangent spaces when manipulating Jacobians.
Currently, manif implements the right Jacobian, whose definition reads:
$$ \frac{\delta f(\bf\mathcal{X})}{\delta\bf\mathcal{X}}\triangleq \lim_{\boldsymbol\varphi\to\bf0}\frac{f(\bf\mathcal{X}\oplus\boldsymbol\varphi)\ominus f(\bf\mathcal{X})}{\boldsymbol\varphi}\triangleq \lim_{\boldsymbol\varphi\to\bf0}\frac{\log(f({\bf\mathcal{X}})^{-1} f({\bf\mathcal{X}}\exp(\boldsymbol\varphi^\wedge)))^\vee}{\boldsymbol\varphi} $$
The Jacobians of any of the aforementioned operations can then be evaluated:
in C++,
SE3d X = SE3d::Random(); SE3Tangentd w = SE3Tangentd::Random(); SE3d::Jacobian J_o_x, J_o_w; auto X_plus_w = X.plus(w, J_o_x, J_o_w);
in Python,
X = SE3.Random() w = SE3Tangentd.Random() J_o_x = np.zeros((SE3.DoF, SE3.DoF)) J_o_w = np.zeros((SE3.DoF, SE3.DoF)) X_plus_w = X.plus(w, J_o_x, J_o_w)
While Jacobians in manif are differentiated with respect to a
local perturbation on the tangent space, many non-linear solvers
(e.g. Ceres) expect functions to be differentiated with respect to
the underlying representation vector of the group element
(e.g. with respect to quaternion vector for SO3).
For this reason, manif is compliant with the auto-differentiation libraries
ceres::Jet, autodiff::Dual & autodiff::Real.
The documentation is available online at the accompanying website. Both the C++ and the Python APIs are documented.
Do you want to build it locally? Find out how on the dedicated page.
Note: throughout the code documentation we refer to 'the paper' which you can find on the dedicated page.
We provide some self-contained and self-explained C++ examples to help you get started.
You prefer Python? The same examples are also available in Python.
Check out our related publications and how to cite them.
Find out who's already using manif.
Want to contribute? Great! Check out our contribution guidelines.
more like this
Convert Chinese Characters to Single-Line Fonts using Computer Vision
🎥🤟 8 minimalistic templates for tfjs mediapipe handpose and facemesh
search projects, people, and tags