SymE3 is a small library built on top of SymPy for computing symbolic derivatives of functions that involve leveraging the exponential map from elements
A lot of problems in 3D machine perception use this "trick" to simplify calculation of jacobian matrices. Automatic computation of such derivatives is not supported in SymPy natively, which is where this library comes in. It defines a suite of specialized types which can be assembled together to form full function expressions and subsequently take derivatives. It is best described with a concrete example, point-to-plane ICP:
from SymE3.core import PointH, NormalH, LieAlgebra, LieGroup, TotalFunction, exp
n_ri = NormalH("{n_{r_i}}")
r_i = PointH("{r_i}")
l_i = PointH("{l_i}")
rhat_i = PointH("{\\hat{r}_i}")
That_rl = LieGroup("{\\hat{T}_{rl}}")
d = LieAlgebra("{\\delta}")
e = n_ri.transpose() * ((exp(d) * That_rl * l_i) - r_i)
print("Function:")
display(e)
e = e.subs(That_rl * l_i, rhat_i)
f = TotalFunction(e)
print("Substituted:")
display(f)
print("Expanded:")
fe = f.as_explicit()
display(fe)
print("Derivative w.r.t. delta:")
df_dd = f.diff(d)
display(df_dd)
Function:
Substituted:
Expanded:
Derivative w.r.t. delta:
As shown above, the function you want to take derivatives with respect to can be expressed in a natural symbolic form. From here, SymE3 takes care of all the hardwork involved in applying the python -m pytest test/*
.
The application of the generator matrices can seem sort of like an ad-hoc unnatural "hack" when done manually, almost as if it "wills" extra columns in the jacobian into existence. However, it can also be expressed as a tensor product operation followed by a tensor contraction, which is exactly what SymE3 does. Most of the code is concerned with intercepting / redefining calls to the diff
function to alter the expression in a way that applies the rules our special case needs before allowing the rest of the SymPy machinery to do its job.
Internally the code also verifies the derivative it provides by also computing the numerical derivative (using Sophus) and comparing the result using realistic variable values. This helps eliminate uncertainty in the result that may have otherwise been introduced by the hacking required to make this all work within SymPy.
Although there is a
Although extensively tested, this library is by no means rigorous. There are undoubtedly expressions which will break the logic; if you find one please send it on.
Here's a bunch of awesome material I found useful while working on this.
- Hauke Strasdat's PhD Thesis
- Joan Solà et al.'s A micro Lie theory for state estimation in robotics
- Tim Barfoot's SE(3) Identities
- Fan Zheng's Derivation of Jacobians in g2o::EdgeSE3Expmap
- Ethan Eade's Derivative of the Exponential Map
- Ethan Eade's Lie Groups for 2D and 3D Transformations
- Ethan Eade's Lie Groups for Computer Vision
- Tom Drummond's Lie groups, Lie algebras, projective geometry and optimization for 3D Geometry, Engineering and Computer Vision
- Ankur Handa's Simplified Jacobians in 6-DoF Camera Tracking