mirror of
https://github.com/AtsushiSakai/PythonRobotics.git
synced 2026-01-14 23:28:06 -05:00
* Rearchitecture document structure * Rearchitecture document structure * Rearchitecture document structure * Rearchitecture document structure * Rearchitecture document structure * Rearchitecture document structure * Rearchitecture document structure
219 lines
14 KiB
ReStructuredText
219 lines
14 KiB
ReStructuredText
.. _Graph SLAM Formulation:
|
||
|
||
Graph SLAM Formulation
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
Author Jeff Irion
|
||
|
||
Problem Formulation
|
||
^^^^^^^^^^^^^^^^^^^
|
||
|
||
Let a robot’s trajectory through its environment be represented by a
|
||
sequence of :math:`N` poses:
|
||
:math:`\mathbf{p}_1, \mathbf{p}_2, \ldots, \mathbf{p}_N`. Each pose lies
|
||
on a manifold: :math:`\mathbf{p}_i \in \mathcal{M}`. Simple examples of
|
||
manifolds used in Graph SLAM include 1-D, 2-D, and 3-D space, i.e.,
|
||
:math:`\mathbb{R}`, :math:`\mathbb{R}^2`, and :math:`\mathbb{R}^3`.
|
||
These environments are *rectilinear*, meaning that there is no concept
|
||
of orientation. By contrast, in :math:`SE(2)` problem settings a robot’s
|
||
pose consists of its location in :math:`\mathbb{R}^2` and its
|
||
orientation :math:`\theta`. Similarly, in :math:`SE(3)` a robot’s pose
|
||
consists of its location in :math:`\mathbb{R}^3` and its orientation,
|
||
which can be represented via Euler angles, quaternions, or :math:`SO(3)`
|
||
rotation matrices.
|
||
|
||
As the robot explores its environment, it collects a set of :math:`M`
|
||
measurements :math:`\mathcal{Z} = \{\mathbf{z}_j\}`. Examples of such
|
||
measurements include odometry, GPS, and IMU data. Given a set of poses
|
||
:math:`\mathbf{p}_1, \ldots, \mathbf{p}_N`, we can compute the estimated
|
||
measurement
|
||
:math:`\hat{\mathbf{z}}_j(\mathbf{p}_1, \ldots, \mathbf{p}_N)`. We can
|
||
then compute the *residual*
|
||
:math:`\mathbf{e}_j(\mathbf{z}_j, \hat{\mathbf{z}}_j)` for measurement
|
||
:math:`j`. The formula for the residual depends on the type of
|
||
measurement. As an example, let :math:`\mathbf{z}_1` be an odometry
|
||
measurement that was collected when the robot traveled from
|
||
:math:`\mathbf{p}_1` to :math:`\mathbf{p}_2`. The expected measurement
|
||
and the residual are computed as
|
||
|
||
.. math::
|
||
|
||
\begin{aligned}
|
||
\hat{\mathbf{z}}_1(\mathbf{p}_1, \mathbf{p}_2) &= \mathbf{p}_2 \ominus \mathbf{p}_1 \\
|
||
\mathbf{e}_1(\mathbf{z}_1, \hat{\mathbf{z}}_1) &= \mathbf{z}_1 \ominus \hat{\mathbf{z}}_1 = \mathbf{z}_1 \ominus (\mathbf{p}_2 \ominus \mathbf{p}_1),\end{aligned}
|
||
|
||
where the :math:`\ominus` operator indicates inverse pose composition.
|
||
We model measurement :math:`\mathbf{z}_j` as having independent Gaussian
|
||
noise with zero mean and covariance matrix :math:`\Omega_j^{-1}`; we
|
||
refer to :math:`\Omega_j` as the *information matrix* for measurement
|
||
:math:`j`. That is,
|
||
|
||
.. math::
|
||
p(\mathbf{z}_j \ | \ \mathbf{p}_1, \ldots, \mathbf{p}_N) = \eta_j \exp (-\mathbf{e}_j(\mathbf{z}_j, \hat{\mathbf{z}}_j))^{\mathsf{T}}\Omega_j \mathbf{e}_j(\mathbf{z}_j, \hat{\mathbf{z}}_j)
|
||
:label: infomat
|
||
|
||
where :math:`\eta_j` is the normalization constant.
|
||
|
||
The objective of Graph SLAM is to find the maximum likelihood set of
|
||
poses given the measurements :math:`\mathcal{Z} = \{\mathbf{z}_j\}`; in
|
||
other words, we want to find
|
||
|
||
.. math:: \mathop{\mathrm{arg\,max}}_{\mathbf{p}_1, \ldots, \mathbf{p}_N} \ p(\mathbf{p}_1, \ldots, \mathbf{p}_N \ | \ \mathcal{Z})
|
||
|
||
Using Bayes’ rule, we can write this probability as
|
||
|
||
.. math::
|
||
\begin{aligned}
|
||
p(\mathbf{p}_1, \ldots, \mathbf{p}_N \ | \ \mathcal{Z}) &= \frac{p( \mathcal{Z} \ | \ \mathbf{p}_1, \ldots, \mathbf{p}_N) p(\mathbf{p}_1, \ldots, \mathbf{p}_N) }{ p(\mathcal{Z}) } \notag \\
|
||
&\propto p( \mathcal{Z} \ | \ \mathbf{p}_1, \ldots, \mathbf{p}_N)
|
||
\end{aligned}
|
||
:label: bayes
|
||
|
||
since :math:`p(\mathcal{Z})` is a constant (albeit, an unknown constant)
|
||
and we assume that :math:`p(\mathbf{p}_1, \ldots, \mathbf{p}_N)` is
|
||
uniformly distributed. Therefore, we
|
||
can use Eq. :eq:`infomat` and and Eq. :eq:`bayes` to simplify the Graph SLAM
|
||
optimization as follows:
|
||
|
||
.. math::
|
||
|
||
\begin{aligned}
|
||
\mathop{\mathrm{arg\,max}}_{\mathbf{p}_1, \ldots, \mathbf{p}_N} \ p(\mathbf{p}_1, \ldots, \mathbf{p}_N \ | \ \mathcal{Z}) &= \mathop{\mathrm{arg\,max}}_{\mathbf{p}_1, \ldots, \mathbf{p}_N} \ p( \mathcal{Z} \ | \ \mathbf{p}_1, \ldots, \mathbf{p}_N) \\
|
||
&= \mathop{\mathrm{arg\,max}}_{\mathbf{p}_1, \ldots, \mathbf{p}_N} \prod_{j=1}^M p(\mathbf{z}_j \ | \ \mathbf{p}_1, \ldots, \mathbf{p}_N) \\
|
||
&= \mathop{\mathrm{arg\,max}}_{\mathbf{p}_1, \ldots, \mathbf{p}_N} \prod_{j=1}^M \exp \left( -(\mathbf{e}_j(\mathbf{z}_j, \hat{\mathbf{z}}_j))^{\scriptstyle{\mathsf{T}}}\Omega_j \mathbf{e}_j(\mathbf{z}_j, \hat{\mathbf{z}}_j) \right) \\
|
||
&= \mathop{\mathrm{arg\,min}}_{\mathbf{p}_1, \ldots, \mathbf{p}_N} \sum_{j=1}^M (\mathbf{e}_j(\mathbf{z}_j, \hat{\mathbf{z}}_j))^{\scriptstyle{\mathsf{T}}}\Omega_j \mathbf{e}_j(\mathbf{z}_j, \hat{\mathbf{z}}_j).\end{aligned}
|
||
|
||
We define
|
||
|
||
.. math:: \chi^2 := \sum_{j=1}^M (\mathbf{e}_j(\mathbf{z}_j, \hat{\mathbf{z}}_j))^{\scriptstyle{\mathsf{T}}}\Omega_j \mathbf{e}_j(\mathbf{z}_j, \hat{\mathbf{z}}_j),
|
||
|
||
and this is what we seek to minimize.
|
||
|
||
Dimensionality and Pose Representation
|
||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
Before proceeding further, it is helpful to discuss the dimensionality
|
||
of the problem. We have:
|
||
|
||
- A set of :math:`N` poses
|
||
:math:`\mathbf{p}_1, \mathbf{p}_2, \ldots, \mathbf{p}_N`, where each
|
||
pose lies on the manifold :math:`\mathcal{M}`
|
||
|
||
- Each pose :math:`\mathbf{p}_i` is represented as a vector in (a
|
||
subset of) :math:`\mathbb{R}^d`. For example:
|
||
|
||
- An :math:`SE(2)` pose is typically represented as
|
||
:math:`(x, y, \theta)`, and thus :math:`d = 3`.
|
||
|
||
- An :math:`SE(3)` pose is typically represented as
|
||
:math:`(x, y, z, q_x, q_y, q_z, q_w)`, where :math:`(x, y, z)`
|
||
is a point in :math:`\mathbb{R}^3` and
|
||
:math:`(q_x, q_y, q_z, q_w)` is a *quaternion*, and so
|
||
:math:`d = 7`. For more information about :math:`SE(3)`
|
||
parameterization and pose transformations, see
|
||
[blanco2010tutorial]_.
|
||
|
||
- We also need to be able to represent each pose compactly as a
|
||
vector in (a subset of) :math:`\mathbb{R}^c`.
|
||
|
||
- Since an :math:`SE(2)` pose has three degrees of freedom, the
|
||
:math:`(x, y, \theta)` representation is again sufficient and
|
||
:math:`c=3`.
|
||
|
||
- An :math:`SE(3)` pose only has six degrees of freedom, and we
|
||
can represent it compactly as :math:`(x, y, z, q_x, q_y, q_z)`,
|
||
and thus :math:`c=6`.
|
||
|
||
- We use the :math:`\boxplus` operator to indicate pose composition
|
||
when one or both of the poses are represented compactly. The
|
||
output can be a pose in :math:`\mathcal{M}` or a vector in
|
||
:math:`\mathbb{R}^c`, as required by context.
|
||
|
||
- A set of :math:`M` measurements
|
||
:math:`\mathcal{Z} = \{\mathbf{z}_1, \mathbf{z}_2, \ldots, \mathbf{z}_M\}`
|
||
|
||
- Each measurement’s dimensionality can be unique, and we will use
|
||
:math:`\bullet` to denote a “wildcard” variable.
|
||
|
||
- Measurement :math:`\mathbf{z}_j \in \mathbb{R}^\bullet` has an
|
||
associated information matrix
|
||
:math:`\Omega_j \in \mathbb{R}^{\bullet \times \bullet}` and
|
||
residual function
|
||
:math:`\mathbf{e}_j(\mathbf{z}_j, \hat{\mathbf{z}}_j) = \mathbf{e}_j(\mathbf{z}_j, \mathbf{p}_1, \ldots, \mathbf{p}_N) \in \mathbb{R}^\bullet`.
|
||
|
||
- A measurement could, in theory, constrain anywhere from 1 pose to
|
||
all :math:`N` poses. In practice, each measurement usually
|
||
constrains only 1 or 2 poses.
|
||
|
||
Graph SLAM Algorithm
|
||
^^^^^^^^^^^^^^^^^^^^
|
||
|
||
The “Graph” in Graph SLAM refers to the fact that we view the problem as
|
||
a graph. The graph has a set :math:`\mathcal{V}` of :math:`N` vertices,
|
||
where each vertex :math:`v_i` has an associated pose
|
||
:math:`\mathbf{p}_i`. Similarly, the graph has a set :math:`\mathcal{E}`
|
||
of :math:`M` edges, where each edge :math:`e_j` has an associated
|
||
measurement :math:`\mathbf{z}_j`. In practice, the edges in this graph
|
||
are either unary (i.e., a loop) or binary. (Note: :math:`e_j` refers to
|
||
the edge in the graph associated with measurement :math:`\mathbf{z}_j`,
|
||
whereas :math:`\mathbf{e}_j` refers to the residual function associated
|
||
with :math:`\mathbf{z}_j`.) For more information about the Graph SLAM
|
||
algorithm, see [grisetti2010tutorial]_.
|
||
|
||
We want to optimize
|
||
|
||
.. math:: \chi^2 = \sum_{e_j \in \mathcal{E}} \mathbf{e}_j^{\scriptstyle{\mathsf{T}}}\Omega_j \mathbf{e}_j.
|
||
|
||
Let :math:`\mathbf{x}_i \in \mathbb{R}^c` be the compact representation
|
||
of pose :math:`\mathbf{p}_i \in \mathcal{M}`, and let
|
||
|
||
.. math:: \mathbf{x} := \begin{bmatrix} \mathbf{x}_1 \\ \mathbf{x}_2 \\ \vdots \\ \mathbf{x}_N \end{bmatrix} \in \mathbb{R}^{cN}
|
||
|
||
We will solve this optimization problem iteratively. Let
|
||
|
||
.. math:: \mathbf{x}^{k+1} := \mathbf{x}^k \boxplus \Delta \mathbf{x}^k = \begin{bmatrix} \mathbf{x}_1 \boxplus \Delta \mathbf{x}_1 \\ \mathbf{x}_2 \boxplus \Delta \mathbf{x}_2 \\ \vdots \\ \mathbf{x}_N \boxplus \Delta \mathbf{x}_2 \end{bmatrix}
|
||
:label: update
|
||
|
||
The :math:`\chi^2` error at iteration :math:`k+1` is
|
||
|
||
.. math:: \chi_{k+1}^2 = \sum_{e_j \in \mathcal{E}} \underbrace{\left[ \mathbf{e}_j(\mathbf{x}^{k+1}) \right]^{\scriptstyle{\mathsf{T}}}}_{1 \times \bullet} \underbrace{\Omega_j}_{\bullet \times \bullet} \underbrace{\mathbf{e}_j(\mathbf{x}^{k+1})}_{\bullet \times 1}.
|
||
:label: chisq_at_kplusone
|
||
|
||
We will linearize the residuals as:
|
||
|
||
.. math::
|
||
\begin{aligned}
|
||
\mathbf{e}_j(\mathbf{x}^{k+1}) &= \mathbf{e}_j(\mathbf{x}^k \boxplus \Delta \mathbf{x}^k) \\
|
||
&\approx \mathbf{e}_j(\mathbf{x}^{k}) + \frac{\partial}{\partial \Delta \mathbf{x}^k} \left[ \mathbf{e}_j(\mathbf{x}^k \boxplus \Delta \mathbf{x}^k) \right] \Delta \mathbf{x}^k \\
|
||
&= \mathbf{e}_j(\mathbf{x}^{k}) + \left( \left. \frac{\partial \mathbf{e}_j(\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)}{\partial (\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)} \right|_{\Delta \mathbf{x}^k = \mathbf{0}} \right) \frac{\partial (\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)}{\partial \Delta \mathbf{x}^k} \Delta \mathbf{x}^k.
|
||
\end{aligned}
|
||
:label: linearization
|
||
|
||
Plugging :eq:`linearization` into :eq:`chisq_at_kplusone`, we get:
|
||
|
||
.. math::
|
||
|
||
\begin{aligned}
|
||
\chi_{k+1}^2 &\approx \ \ \ \ \ \sum_{e_j \in \mathcal{E}} \underbrace{[ \mathbf{e}_j(\mathbf{x}^k)]^{\scriptstyle{\mathsf{T}}}}_{1 \times \bullet} \underbrace{\Omega_j}_{\bullet \times \bullet} \underbrace{\mathbf{e}_j(\mathbf{x}^k)}_{\bullet \times 1} \notag \\
|
||
&\hphantom{\approx} \ \ \ + \sum_{e_j \in \mathcal{E}} \underbrace{[ \mathbf{e}_j(\mathbf{x^k}) ]^{\scriptstyle{\mathsf{T}}}}_{1 \times \bullet} \underbrace{\Omega_j}_{\bullet \times \bullet} \underbrace{\left( \left. \frac{\partial \mathbf{e}_j(\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)}{\partial (\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)} \right|_{\Delta \mathbf{x}^k = \mathbf{0}} \right)}_{\bullet \times dN} \underbrace{\frac{\partial (\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)}{\partial \Delta \mathbf{x}^k}}_{dN \times cN} \underbrace{\Delta \mathbf{x}^k}_{cN \times 1} \notag \\
|
||
&\hphantom{\approx} \ \ \ + \sum_{e_j \in \mathcal{E}} \underbrace{(\Delta \mathbf{x}^k)^{\scriptstyle{\mathsf{T}}}}_{1 \times cN} \underbrace{ \left( \frac{\partial (\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)}{\partial \Delta \mathbf{x}^k} \right)^{\scriptstyle{\mathsf{T}}}}_{cN \times dN} \underbrace{\left( \left. \frac{\partial \mathbf{e}_j(\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)}{\partial (\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)} \right|_{\Delta \mathbf{x}^k = \mathbf{0}} \right)^{\scriptstyle{\mathsf{T}}}}_{dN \times \bullet} \underbrace{\Omega_j}_{\bullet \times \bullet} \underbrace{\left( \left. \frac{\partial \mathbf{e}_j(\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)}{\partial (\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)} \right|_{\Delta \mathbf{x}^k = \mathbf{0}} \right)}_{\bullet \times dN} \underbrace{\frac{\partial (\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)}{\partial \Delta \mathbf{x}^k}}_{dN \times cN} \underbrace{\Delta \mathbf{x}^k}_{cN \times 1} \notag \\
|
||
&= \chi_k^2 + 2 \mathbf{b}^{\scriptstyle{\mathsf{T}}}\Delta \mathbf{x}^k + (\Delta \mathbf{x}^k)^{\scriptstyle{\mathsf{T}}}H \Delta \mathbf{x}^k, \notag\end{aligned}
|
||
|
||
where
|
||
|
||
.. math::
|
||
|
||
\begin{aligned}
|
||
\mathbf{b}^{\scriptstyle{\mathsf{T}}}&= \sum_{e_j \in \mathcal{E}} \underbrace{[ \mathbf{e}_j(\mathbf{x^k}) ]^{\scriptstyle{\mathsf{T}}}}_{1 \times \bullet} \underbrace{\Omega_j}_{\bullet \times \bullet} \underbrace{\left( \left. \frac{\partial \mathbf{e}_j(\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)}{\partial (\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)} \right|_{\Delta \mathbf{x}^k = \mathbf{0}} \right)}_{\bullet \times dN} \underbrace{\frac{\partial (\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)}{\partial \Delta \mathbf{x}^k}}_{dN \times cN} \\
|
||
H &= \sum_{e_j \in \mathcal{E}} \underbrace{ \left( \frac{\partial (\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)}{\partial \Delta \mathbf{x}^k} \right)^{\scriptstyle{\mathsf{T}}}}_{cN \times dN} \underbrace{\left( \left. \frac{\partial \mathbf{e}_j(\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)}{\partial (\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)} \right|_{\Delta \mathbf{x}^k = \mathbf{0}} \right)^{\scriptstyle{\mathsf{T}}}}_{dN \times \bullet} \underbrace{\Omega_j}_{\bullet \times \bullet} \underbrace{\left( \left. \frac{\partial \mathbf{e}_j(\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)}{\partial (\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)} \right|_{\Delta \mathbf{x}^k = \mathbf{0}} \right)}_{\bullet \times dN} \underbrace{\frac{\partial (\mathbf{x}^k \boxplus \Delta \mathbf{x}^k)}{\partial \Delta \mathbf{x}^k}}_{dN \times cN}.\end{aligned}
|
||
|
||
Using this notation, we obtain the optimal update as
|
||
|
||
.. math:: \Delta \mathbf{x}^k = -H^{-1} \mathbf{b}. \label{eq:deltax}
|
||
|
||
We apply this update to the poses via :eq:`update` and repeat until convergence.
|
||
|
||
|
||
.. [blanco2010tutorial] Blanco, J.-L.A tutorial onSE(3) transformation parameterization and on-manifold optimization.University of Malaga, Tech. Rep 3(2010)
|
||
.. [grisetti2010tutorial] Grisetti, G., Kummerle, R., Stachniss, C., and Burgard, W.A tutorial on graph-based SLAM.IEEE Intelligent Transportation Systems Magazine 2, 4 (2010), 31–43.
|
||
|