fix: UnaryFactor Jacobian

release/4.3a0
Navid Mahabadi 2021-03-23 10:11:19 +01:00
parent 74e4fc392c
commit 554dd790d9
4 changed files with 34 additions and 26 deletions

View File

@ -8,7 +8,11 @@ public:
Vector evaluateError(const Pose2& q, Vector evaluateError(const Pose2& q,
boost::optional<Matrix&> H = boost::none) const boost::optional<Matrix&> H = boost::none) const
{ {
if (H) (*H) = (Matrix(2,3)<< 1.0,0.0,0.0, 0.0,1.0,0.0).finished(); const double cosTheta = cos(q.theta());
const double sinTheta = sin(q.theta());
if (H) (*H) = (gtsam::Matrix(2, 3) <<
cosTheta, -sinTheta, 0.0,
sinTheta, cosTheta, 0.0).finished();
return (Vector(2) << q.x() - mx_, q.y() - my_).finished(); return (Vector(2) << q.x() - mx_, q.y() - my_).finished();
} }
}; };

View File

@ -1,7 +1,9 @@
#LyX 2.1 created this file. For more info see http://www.lyx.org/ #LyX 2.2 created this file. For more info see http://www.lyx.org/
\lyxformat 474 \lyxformat 508
\begin_document \begin_document
\begin_header \begin_header
\save_transient_properties true
\origin unavailable
\textclass article \textclass article
\begin_preamble \begin_preamble
\usepackage{times} \usepackage{times}
@ -50,16 +52,16 @@
\language_package default \language_package default
\inputencoding auto \inputencoding auto
\fontencoding T1 \fontencoding T1
\font_roman ae \font_roman "ae" "default"
\font_sans default \font_sans "default" "default"
\font_typewriter default \font_typewriter "default" "default"
\font_math auto \font_math "auto" "auto"
\font_default_family rmdefault \font_default_family rmdefault
\use_non_tex_fonts false \use_non_tex_fonts false
\font_sc false \font_sc false
\font_osf false \font_osf false
\font_sf_scale 100 \font_sf_scale 100 100
\font_tt_scale 100 \font_tt_scale 100 100
\graphics default \graphics default
\default_output_format default \default_output_format default
\output_sync 0 \output_sync 0
@ -1061,7 +1063,7 @@ noindent
\begin_layout Subsection \begin_layout Subsection
\begin_inset CommandInset label \begin_inset CommandInset label
LatexCommand label LatexCommand label
name "sub:Full-Posterior-Inference" name "subsec:Full-Posterior-Inference"
\end_inset \end_inset
@ -1272,7 +1274,7 @@ ing to odometry measurements.
(see Section (see Section
\begin_inset CommandInset ref \begin_inset CommandInset ref
LatexCommand ref LatexCommand ref
reference "sub:Full-Posterior-Inference" reference "subsec:Full-Posterior-Inference"
\end_inset \end_inset
@ -1469,7 +1471,7 @@ GPS-like
\begin_inset CommandInset include \begin_inset CommandInset include
LatexCommand lstinputlisting LatexCommand lstinputlisting
filename "Code/LocalizationFactor.cpp" filename "Code/LocalizationFactor.cpp"
lstparams "aboveskip=10pt,basicstyle={\\ttfamily\\small},caption={Excerpt from examples/LocalizationExample.cpp},captionpos=b,frame=single,identifierstyle={\\bfseries},label={listing:LocalizationFactor},language={C++},numbers=left" lstparams "aboveskip=10pt,basicstyle={\\ttfamily\\small},captionpos=b,frame=single,identifierstyle={\\bfseries},language={C++},numbers=left,caption={Excerpt from examples/LocalizationExample.cpp},label={listing:LocalizationFactor}"
\end_inset \end_inset
@ -1590,15 +1592,15 @@ q_{y}
\begin_inset Formula $2\times3$ \begin_inset Formula $2\times3$
\end_inset \end_inset
matrix: matrix in tangent space which is the same the as the rotation matrix:
\end_layout \end_layout
\begin_layout Standard \begin_layout Standard
\begin_inset Formula \begin_inset Formula
\[ \[
H=\left[\begin{array}{ccc} H=\left[\begin{array}{ccc}
1 & 0 & 0\\ \cos(q_{\theta}) & -\sin(q_{\theta}) & 0\\
0 & 1 & 0 \sin(q_{\theta}) & \cos(q_{\theta}) & 0
\end{array}\right] \end{array}\right]
\] \]
@ -1750,7 +1752,7 @@ global
The marginals can be recovered exactly as in Section The marginals can be recovered exactly as in Section
\begin_inset CommandInset ref \begin_inset CommandInset ref
LatexCommand ref LatexCommand ref
reference "sub:Full-Posterior-Inference" reference "subsec:Full-Posterior-Inference"
\end_inset \end_inset
@ -1770,7 +1772,7 @@ filename "Code/LocalizationOutput5.txt"
Comparing this with the covariance matrices in Section Comparing this with the covariance matrices in Section
\begin_inset CommandInset ref \begin_inset CommandInset ref
LatexCommand ref LatexCommand ref
reference "sub:Full-Posterior-Inference" reference "subsec:Full-Posterior-Inference"
\end_inset \end_inset

Binary file not shown.

View File

@ -84,15 +84,17 @@ class UnaryFactor: public NoiseModelFactor1<Pose2> {
// The first is the 'evaluateError' function. This function implements the desired measurement // The first is the 'evaluateError' function. This function implements the desired measurement
// function, returning a vector of errors when evaluated at the provided variable value. It // function, returning a vector of errors when evaluated at the provided variable value. It
// must also calculate the Jacobians for this measurement function, if requested. // must also calculate the Jacobians for this measurement function, if requested.
Vector evaluateError(const Pose2& q, Vector evaluateError(const Pose2& q, boost::optional<Matrix&> H = boost::none) const override {
boost::optional<Matrix&> H = boost::none) const override { // The measurement function for a GPS-like measurement h(q) which predicts the measurement (m) is h(q) = q, q = [qx qy qtheta]
// The measurement function for a GPS-like measurement is simple: // The error is then simply calculated as E(q) = h(q) - m:
// error_x = pose.x - measurement.x // error_x = q.x - mx
// error_y = pose.y - measurement.y // error_y = q.y - my
// Consequently, the Jacobians are: // Node's orientation reflects in the Jacobian, in tangent space this is equal to the right-hand rule rotation matrix
// [ derror_x/dx derror_x/dy derror_x/dtheta ] = [1 0 0] // H = [ cos(q.theta) -sin(q.theta) 0 ]
// [ derror_y/dx derror_y/dy derror_y/dtheta ] = [0 1 0] // [ sin(q.theta) cos(q.theta) 0 ]
if (H) (*H) = (Matrix(2, 3) << 1.0, 0.0, 0.0, 0.0, 1.0, 0.0).finished(); const double cosTheta = cos(q.theta());
const double sinTheta = sin(q.theta());
if (H) (*H) = (gtsam::Matrix(2, 3) << cosTheta, -sinTheta, 0.0, sinTheta, cosTheta, 0.0).finished();
return (Vector(2) << q.x() - mx_, q.y() - my_).finished(); return (Vector(2) << q.x() - mx_, q.y() - my_).finished();
} }