Sophie

Sophie

distrib > Fedora > 16 > i386 > by-pkgid > 4bc66056a634db26a1f4d0845dc41ca6 > files > 824

mrpt-doc-0.9.5-0.1.20110925svn2670.fc16.i686.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>CKalmanFilterCapable.h Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="tabs.css" rel="stylesheet" type="text/css">
</head><body>
<div align="left"><a href="http://www.mrpt.org/">Main MRPT website</a> &gt; <b>C++ reference</b> </div>
<div align="right">
<a href="index.html"><img border="0" src="mrpt_logo.png" alt="MRPT logo"></a>
</div>
<!-- Generated by Doxygen 1.7.5 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li><a href="pages.html"><span>Related&#160;Pages</span></a></li>
      <li><a href="modules.html"><span>Modules</span></a></li>
      <li><a href="namespaces.html"><span>Namespaces</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li class="current"><a href="files.html"><span>Files</span></a></li>
      <li>
        <div id="MSearchBox" class="MSearchBoxInactive">
          <div class="left">
            <form id="FSearchBox" action="search.php" method="get">
              <img id="MSearchSelect" src="search/mag.png" alt=""/>
              <input type="text" id="MSearchField" name="query" value="Search" size="20" accesskey="S" 
                     onfocus="searchBox.OnSearchFieldFocus(true)" 
                     onblur="searchBox.OnSearchFieldFocus(false)"/>
            </form>
          </div><div class="right"></div>
        </div>
      </li>
    </ul>
  </div>
  <div id="navrow2" class="tabs2">
    <ul class="tablist">
      <li><a href="files.html"><span>File&#160;List</span></a></li>
      <li><a href="globals.html"><span>File&#160;Members</span></a></li>
    </ul>
  </div>
<div class="header">
  <div class="headertitle">
<div class="title">CKalmanFilterCapable.h</div>  </div>
</div>
<div class="contents">
<a href="_c_kalman_filter_capable_8h.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/* +---------------------------------------------------------------------------+</span>
<a name="l00002"></a>00002 <span class="comment">   |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |</span>
<a name="l00003"></a>00003 <span class="comment">   |                                                                           |</span>
<a name="l00004"></a>00004 <span class="comment">   |                       http://www.mrpt.org/                                |</span>
<a name="l00005"></a>00005 <span class="comment">   |                                                                           |</span>
<a name="l00006"></a>00006 <span class="comment">   |   Copyright (C) 2005-2011  University of Malaga                           |</span>
<a name="l00007"></a>00007 <span class="comment">   |                                                                           |</span>
<a name="l00008"></a>00008 <span class="comment">   |    This software was written by the Machine Perception and Intelligent    |</span>
<a name="l00009"></a>00009 <span class="comment">   |      Robotics Lab, University of Malaga (Spain).                          |</span>
<a name="l00010"></a>00010 <span class="comment">   |    Contact: Jose-Luis Blanco  &lt;jlblanco@ctima.uma.es&gt;                     |</span>
<a name="l00011"></a>00011 <span class="comment">   |                                                                           |</span>
<a name="l00012"></a>00012 <span class="comment">   |  This file is part of the MRPT project.                                   |</span>
<a name="l00013"></a>00013 <span class="comment">   |                                                                           |</span>
<a name="l00014"></a>00014 <span class="comment">   |     MRPT is free software: you can redistribute it and/or modify          |</span>
<a name="l00015"></a>00015 <span class="comment">   |     it under the terms of the GNU General Public License as published by  |</span>
<a name="l00016"></a>00016 <span class="comment">   |     the Free Software Foundation, either version 3 of the License, or     |</span>
<a name="l00017"></a>00017 <span class="comment">   |     (at your option) any later version.                                   |</span>
<a name="l00018"></a>00018 <span class="comment">   |                                                                           |</span>
<a name="l00019"></a>00019 <span class="comment">   |   MRPT is distributed in the hope that it will be useful,                 |</span>
<a name="l00020"></a>00020 <span class="comment">   |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |</span>
<a name="l00021"></a>00021 <span class="comment">   |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |</span>
<a name="l00022"></a>00022 <span class="comment">   |     GNU General Public License for more details.                          |</span>
<a name="l00023"></a>00023 <span class="comment">   |                                                                           |</span>
<a name="l00024"></a>00024 <span class="comment">   |     You should have received a copy of the GNU General Public License     |</span>
<a name="l00025"></a>00025 <span class="comment">   |     along with MRPT.  If not, see &lt;http://www.gnu.org/licenses/&gt;.         |</span>
<a name="l00026"></a>00026 <span class="comment">   |                                                                           |</span>
<a name="l00027"></a>00027 <span class="comment">   +---------------------------------------------------------------------------+ */</span>
<a name="l00028"></a>00028 <span class="preprocessor">#ifndef CKalmanFilterCapable_H</span>
<a name="l00029"></a>00029 <span class="preprocessor"></span><span class="preprocessor">#define CKalmanFilterCapable_H</span>
<a name="l00030"></a>00030 <span class="preprocessor"></span>
<a name="l00031"></a>00031 <span class="preprocessor">#include &lt;<a class="code" href="_c_matrix_fixed_numeric_8h.html">mrpt/math/CMatrixFixedNumeric.h</a>&gt;</span>
<a name="l00032"></a>00032 <span class="preprocessor">#include &lt;<a class="code" href="_c_matrix_template_numeric_8h.html">mrpt/math/CMatrixTemplateNumeric.h</a>&gt;</span>
<a name="l00033"></a>00033 <span class="preprocessor">#include &lt;<a class="code" href="_c_array_8h.html">mrpt/math/CArray.h</a>&gt;</span>
<a name="l00034"></a>00034 <span class="preprocessor">#include &lt;<a class="code" href="base_2include_2mrpt_2math_2utils_8h.html">mrpt/math/utils.h</a>&gt;</span>
<a name="l00035"></a>00035 
<a name="l00036"></a>00036 <span class="preprocessor">#include &lt;<a class="code" href="_c_time_logger_8h.html">mrpt/utils/CTimeLogger.h</a>&gt;</span>
<a name="l00037"></a>00037 <span class="preprocessor">#include &lt;<a class="code" href="_c_loadable_options_8h.html">mrpt/utils/CLoadableOptions.h</a>&gt;</span>
<a name="l00038"></a>00038 <span class="preprocessor">#include &lt;<a class="code" href="_c_debug_output_capable_8h.html">mrpt/utils/CDebugOutputCapable.h</a>&gt;</span>
<a name="l00039"></a>00039 <span class="preprocessor">#include &lt;<a class="code" href="stl__extensions_8h.html">mrpt/utils/stl_extensions.h</a>&gt;</span>
<a name="l00040"></a>00040 <span class="preprocessor">#include &lt;<a class="code" href="os_8h.html">mrpt/system/os.h</a>&gt;</span>
<a name="l00041"></a>00041 <span class="preprocessor">#include &lt;<a class="code" href="_c_tic_tac_8h.html">mrpt/utils/CTicTac.h</a>&gt;</span>
<a name="l00042"></a>00042 <span class="preprocessor">#include &lt;<a class="code" href="_c_file_output_stream_8h.html">mrpt/utils/CFileOutputStream.h</a>&gt;</span>
<a name="l00043"></a>00043 <span class="preprocessor">#include &lt;<a class="code" href="_t_enum_type_8h.html">mrpt/utils/TEnumType.h</a>&gt;</span>
<a name="l00044"></a>00044 
<a name="l00045"></a>00045 <span class="preprocessor">#include &lt;<a class="code" href="bayes_2include_2mrpt_2bayes_2link__pragmas_8h.html">mrpt/bayes/link_pragmas.h</a>&gt;</span>
<a name="l00046"></a>00046 
<a name="l00047"></a>00047 
<a name="l00048"></a>00048 <span class="keyword">namespace </span>mrpt
<a name="l00049"></a>00049 {
<a name="l00050"></a>00050         <span class="keyword">namespace </span>bayes
<a name="l00051"></a>00051         {
<a name="l00052"></a>00052                 <span class="keyword">using namespace </span>mrpt::utils;
<a name="l00053"></a>00053                 <span class="keyword">using namespace </span>mrpt::math;
<a name="l00054"></a>00054                 <span class="keyword">using namespace </span>mrpt;
<a name="l00055"></a>00055                 <span class="keyword">using namespace </span>std;
<a name="l00056"></a>00056 <span class="comment"></span>
<a name="l00057"></a>00057 <span class="comment">                /** The Kalman Filter algorithm to employ in bayes::CKalmanFilterCapable</span>
<a name="l00058"></a>00058 <span class="comment">                  *  For further details on each algorithm see the tutorial: http://www.mrpt.org/Kalman_Filters</span>
<a name="l00059"></a>00059 <span class="comment">                  * \sa bayes::CKalmanFilterCapable::KF_options</span>
<a name="l00060"></a>00060 <span class="comment">                  * \ingroup mrpt_bayes_grp</span>
<a name="l00061"></a>00061 <span class="comment">                  */</span>
<a name="l00062"></a><a class="code" href="group__mrpt__bayes__grp.html#ga93ff73c3a01619f01d97fd80dff40d14">00062</a>                 <span class="keyword">enum</span> <a class="code" href="group__mrpt__bayes__grp.html#ga93ff73c3a01619f01d97fd80dff40d14" title="The Kalman Filter algorithm to employ in bayes::CKalmanFilterCapable For further details on each algo...">TKFMethod</a> {
<a name="l00063"></a><a class="code" href="group__mrpt__bayes__grp.html#gga93ff73c3a01619f01d97fd80dff40d14a5ad91d60187b5cca61d25994f7827dc0">00063</a>                         <a class="code" href="group__mrpt__bayes__grp.html#gga93ff73c3a01619f01d97fd80dff40d14a5ad91d60187b5cca61d25994f7827dc0">kfEKFNaive</a> = 0,
<a name="l00064"></a><a class="code" href="group__mrpt__bayes__grp.html#gga93ff73c3a01619f01d97fd80dff40d14acb25ab5d45035eb456de1c7250dbcf5a">00064</a>                         <a class="code" href="group__mrpt__bayes__grp.html#gga93ff73c3a01619f01d97fd80dff40d14acb25ab5d45035eb456de1c7250dbcf5a">kfEKFAlaDavison</a>,
<a name="l00065"></a><a class="code" href="group__mrpt__bayes__grp.html#gga93ff73c3a01619f01d97fd80dff40d14ac5aee4885e69b59edf793342e96acab3">00065</a>                         <a class="code" href="group__mrpt__bayes__grp.html#gga93ff73c3a01619f01d97fd80dff40d14ac5aee4885e69b59edf793342e96acab3">kfIKFFull</a>,
<a name="l00066"></a><a class="code" href="group__mrpt__bayes__grp.html#gga93ff73c3a01619f01d97fd80dff40d14a0c3af1381c1d9b4b4ebb04370dc59ba9">00066</a>                         <a class="code" href="group__mrpt__bayes__grp.html#gga93ff73c3a01619f01d97fd80dff40d14a0c3af1381c1d9b4b4ebb04370dc59ba9">kfIKF</a>
<a name="l00067"></a>00067                 };
<a name="l00068"></a>00068 
<a name="l00069"></a>00069                 <span class="comment">// Forward declaration:</span>
<a name="l00070"></a>00070                 <span class="keyword">template</span> &lt;<span class="keywordtype">size_t</span> VEH_SIZE, <span class="keywordtype">size_t</span> OBS_SIZE, <span class="keywordtype">size_t</span> FEAT_SIZE, <span class="keywordtype">size_t</span> ACT_SIZE, <span class="keyword">typename</span> KFTYPE&gt; <span class="keyword">class </span>CKalmanFilterCapable;
<a name="l00071"></a>00071 
<a name="l00072"></a><a class="code" href="namespacemrpt_1_1bayes_1_1detail.html">00072</a>                 <span class="keyword">namespace </span>detail {
<a name="l00073"></a>00073                 <span class="keyword">struct </span><a class="code" href="structmrpt_1_1bayes_1_1detail_1_1_c_run_one_kalman_iteration__add_new_landmarks.html">CRunOneKalmanIteration_addNewLandmarks</a>;
<a name="l00074"></a>00074                 }
<a name="l00075"></a>00075 <span class="comment"></span>
<a name="l00076"></a>00076 <span class="comment">                /** Generic options for the Kalman Filter algorithm in itself.</span>
<a name="l00077"></a>00077 <span class="comment">                  * \ingroup mrpt_bayes_grp</span>
<a name="l00078"></a>00078 <span class="comment">                  */</span>
<a name="l00079"></a>00079                 <span class="keyword">struct </span><a class="code" href="bayes_2include_2mrpt_2bayes_2link__pragmas_8h.html#a7ae1d44be57c866339914ce9f771ff5a">BAYES_IMPEXP</a> <a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html" title="Generic options for the Kalman Filter algorithm in itself.">TKF_options</a> : <span class="keyword">public</span> utils::<a class="code" href="classmrpt_1_1utils_1_1_c_loadable_options.html" title="This is a virtual base class for sets of options than can be loaded from and/or saved to configuratio...">CLoadableOptions</a>
<a name="l00080"></a>00080                 {
<a name="l00081"></a>00081                         <a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html" title="Generic options for the Kalman Filter algorithm in itself.">TKF_options</a>();
<a name="l00082"></a>00082 
<a name="l00083"></a>00083                         <span class="keywordtype">void</span>  loadFromConfigFile(
<a name="l00084"></a>00084                                 <span class="keyword">const</span> <a class="code" href="classmrpt_1_1utils_1_1_c_config_file_base.html" title="This class allows loading and storing values and vectors of different types from a configuration text...">mrpt::utils::CConfigFileBase</a>      &amp;source,
<a name="l00085"></a>00085                                 <span class="keyword">const</span> <a class="code" href="classstd_1_1string.html" title="STL class.">std::string</a>               &amp;section);
<a name="l00086"></a>00086 <span class="comment"></span>
<a name="l00087"></a>00087 <span class="comment">                        /** This method must display clearly all the contents of the structure in textual form, sending it to a CStream. */</span>
<a name="l00088"></a>00088                         <span class="keywordtype">void</span>  dumpToTextStream(<a class="code" href="classmrpt_1_1utils_1_1_c_stream.html" title="This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...">CStream</a>  &amp;out) <span class="keyword">const</span>;
<a name="l00089"></a>00089 
<a name="l00090"></a><a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html#a136e211bf1136d8437ad907782c2967d">00090</a>                         <a class="code" href="group__mrpt__bayes__grp.html#ga93ff73c3a01619f01d97fd80dff40d14" title="The Kalman Filter algorithm to employ in bayes::CKalmanFilterCapable For further details on each algo...">TKFMethod</a>       <a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html#a136e211bf1136d8437ad907782c2967d" title="The method to employ (default: kfEKFNaive)">method</a>;                         <span class="comment">//!&lt; The method to employ (default: kfEKFNaive)</span>
<a name="l00091"></a><a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html#a79d277e2e9ac720106e7665883aeb81d">00091</a> <span class="comment"></span>                        <span class="keywordtype">bool</span>            <a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html#a79d277e2e9ac720106e7665883aeb81d" title="If set to true timing and other information will be dumped during the execution (default=false)">verbose</a>;                <span class="comment">//!&lt; If set to true timing and other information will be dumped during the execution (default=false)</span>
<a name="l00092"></a><a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html#a512bf4ff5350affab3d5e94c03b7da1a">00092</a> <span class="comment"></span>                        <span class="keywordtype">int</span>             <a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html#a512bf4ff5350affab3d5e94c03b7da1a" title="Number of refinement iterations, only for the IKF method.">IKF_iterations</a>; <span class="comment">//!&lt; Number of refinement iterations, only for the IKF method.</span>
<a name="l00093"></a><a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html#a57b4a351be8de935f8c2c2357b3d8b5c">00093</a> <span class="comment"></span>                        <span class="keywordtype">bool</span>            <a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html#a57b4a351be8de935f8c2c2357b3d8b5c" title="If enabled (default=false), detailed timing information will be dumped to the console thru a CTimerLo...">enable_profiler</a>;<span class="comment">//!&lt; If enabled (default=false), detailed timing information will be dumped to the console thru a CTimerLog at the end of the execution.</span>
<a name="l00094"></a><a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html#aa628121a80c83a8e7a75363df9536048">00094</a> <span class="comment"></span>                        <span class="keywordtype">bool</span>            <a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html#aa628121a80c83a8e7a75363df9536048" title="(default=true) If true, OnTransitionJacobian will be called; otherwise, the Jacobian will be estimate...">use_analytic_transition_jacobian</a>;       <span class="comment">//!&lt; (default=true) If true, OnTransitionJacobian will be called; otherwise, the Jacobian will be estimated from a numeric approximation by calling several times to OnTransitionModel.</span>
<a name="l00095"></a><a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html#abe0d010c6e68f8270175362293fbcc17">00095</a> <span class="comment"></span>                        <span class="keywordtype">bool</span>            <a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html#abe0d010c6e68f8270175362293fbcc17" title="(default=true) If true, OnObservationJacobians will be called; otherwise, the Jacobian will be estima...">use_analytic_observation_jacobian</a>;      <span class="comment">//!&lt; (default=true) If true, OnObservationJacobians will be called; otherwise, the Jacobian will be estimated from a numeric approximation by calling several times to OnObservationModel.</span>
<a name="l00096"></a><a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html#a00d30cee24c38bfc6ec470a573646675">00096</a> <span class="comment"></span>                        <span class="keywordtype">bool</span>            <a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html#a00d30cee24c38bfc6ec470a573646675" title="(default=false) If true, will compute all the Jacobians numerically and compare them to the analytica...">debug_verify_analytic_jacobians</a>; <span class="comment">//!&lt; (default=false) If true, will compute all the Jacobians numerically and compare them to the analytical ones, throwing an exception on mismatch.</span>
<a name="l00097"></a><a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html#a5239885ee4c9ed75c1c3d6966226cae2">00097</a> <span class="comment"></span>                        <span class="keywordtype">double</span>          <a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html#a5239885ee4c9ed75c1c3d6966226cae2" title="(default-1e-2) Sets the threshold for the difference between the analytic and the numerical jacobians...">debug_verify_analytic_jacobians_threshold</a>; <span class="comment">//!&lt; (default-1e-2) Sets the threshold for the difference between the analytic and the numerical jacobians</span>
<a name="l00098"></a>00098 <span class="comment"></span>                };
<a name="l00099"></a>00099 <span class="comment"></span>
<a name="l00100"></a>00100 <span class="comment">                /** Auxiliary functions, for internal usage of MRPT classes */</span>
<a name="l00101"></a>00101                 <span class="keyword">namespace </span>detail
<a name="l00102"></a>00102                 {
<a name="l00103"></a>00103                         <span class="comment">// Auxiliary functions.</span>
<a name="l00104"></a>00104                         <span class="keyword">template</span> &lt;<span class="keywordtype">size_t</span> VEH_SIZE, <span class="keywordtype">size_t</span> OBS_SIZE, <span class="keywordtype">size_t</span> FEAT_SIZE, <span class="keywordtype">size_t</span> ACT_SIZE, <span class="keyword">typename</span> KFTYPE&gt;
<a name="l00105"></a>00105                         <span class="keyword">inline</span> <span class="keywordtype">size_t</span> <a class="code" href="namespacemrpt_1_1bayes_1_1detail.html#aeec894a458a3e7175e707871cd796f34">getNumberOfLandmarksInMap</a>(<span class="keyword">const</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html" title="Virtual base for Kalman Filter (EKF,IEKF,UKF) implementations.">CKalmanFilterCapable&lt;VEH_SIZE,OBS_SIZE,FEAT_SIZE,ACT_SIZE,KFTYPE&gt;</a> &amp;obj);
<a name="l00106"></a>00106                         <span class="comment">// Specialization:</span>
<a name="l00107"></a>00107                         <span class="keyword">template</span> &lt;<span class="keywordtype">size_t</span> VEH_SIZE, <span class="keywordtype">size_t</span> OBS_SIZE, <span class="keywordtype">size_t</span> ACT_SIZE, <span class="keyword">typename</span> KFTYPE&gt;
<a name="l00108"></a>00108                         <span class="keyword">inline</span> <span class="keywordtype">size_t</span> <a class="code" href="namespacemrpt_1_1bayes_1_1detail.html#aeec894a458a3e7175e707871cd796f34">getNumberOfLandmarksInMap</a>(<span class="keyword">const</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html" title="Virtual base for Kalman Filter (EKF,IEKF,UKF) implementations.">CKalmanFilterCapable&lt;VEH_SIZE,OBS_SIZE,0 /*FEAT_SIZE*/,ACT_SIZE,KFTYPE&gt;</a> &amp;obj);
<a name="l00109"></a>00109 
<a name="l00110"></a>00110                         <span class="keyword">template</span> &lt;<span class="keywordtype">size_t</span> VEH_SIZE, <span class="keywordtype">size_t</span> OBS_SIZE, <span class="keywordtype">size_t</span> FEAT_SIZE, <span class="keywordtype">size_t</span> ACT_SIZE, <span class="keyword">typename</span> KFTYPE&gt;
<a name="l00111"></a>00111                         <span class="keyword">inline</span> <span class="keywordtype">bool</span> <a class="code" href="namespacemrpt_1_1bayes_1_1detail.html#aafff1b2b519f6fb209de6ebde0830c19">isMapEmpty</a>(<span class="keyword">const</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html" title="Virtual base for Kalman Filter (EKF,IEKF,UKF) implementations.">CKalmanFilterCapable&lt;VEH_SIZE,OBS_SIZE,FEAT_SIZE,ACT_SIZE,KFTYPE&gt;</a> &amp;obj);
<a name="l00112"></a>00112                         <span class="comment">// Specialization:</span>
<a name="l00113"></a>00113                         <span class="keyword">template</span> &lt;<span class="keywordtype">size_t</span> VEH_SIZE, <span class="keywordtype">size_t</span> OBS_SIZE, <span class="keywordtype">size_t</span> ACT_SIZE, <span class="keyword">typename</span> KFTYPE&gt;
<a name="l00114"></a>00114                         <span class="keyword">inline</span> <span class="keywordtype">bool</span> <a class="code" href="namespacemrpt_1_1bayes_1_1detail.html#aafff1b2b519f6fb209de6ebde0830c19">isMapEmpty</a>(<span class="keyword">const</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html" title="Virtual base for Kalman Filter (EKF,IEKF,UKF) implementations.">CKalmanFilterCapable&lt;VEH_SIZE,OBS_SIZE,0 /*FEAT_SIZE*/,ACT_SIZE,KFTYPE&gt;</a> &amp;obj);
<a name="l00115"></a>00115                 }
<a name="l00116"></a>00116 
<a name="l00117"></a>00117 <span class="comment"></span>
<a name="l00118"></a>00118 <span class="comment">                /** Virtual base for Kalman Filter (EKF,IEKF,UKF) implementations.</span>
<a name="l00119"></a>00119 <span class="comment">                 *   This base class stores the state vector and covariance matrix of the system. It has virtual methods that must be completed</span>
<a name="l00120"></a>00120 <span class="comment">                 *    by derived classes to address a given filtering problem. The main entry point of the algorithm is CKalmanFilterCapable::runOneKalmanIteration, which</span>
<a name="l00121"></a>00121 <span class="comment">                 *    should be called AFTER setting the desired filter options in KF_options, as well as any options in the derived class.</span>
<a name="l00122"></a>00122 <span class="comment">                 *   Note that the main entry point is protected, so derived classes must offer another method more specific to a given problem which, internally, calls runOneKalmanIteration.</span>
<a name="l00123"></a>00123 <span class="comment">                 *</span>
<a name="l00124"></a>00124 <span class="comment">                 *  For further details and examples, check out the tutorial: http://www.mrpt.org/Kalman_Filters</span>
<a name="l00125"></a>00125 <span class="comment">                 *</span>
<a name="l00126"></a>00126 <span class="comment">                 *  The Kalman filter algorithms are generic, but this implementation is biased to ease the implementation</span>
<a name="l00127"></a>00127 <span class="comment">                 *  of SLAM-like problems. However, it can be also applied to many generic problems not related to robotics or SLAM.</span>
<a name="l00128"></a>00128 <span class="comment">                 *</span>
<a name="l00129"></a>00129 <span class="comment">                 *  The meaning of the template parameters is:</span>
<a name="l00130"></a>00130 <span class="comment">                 *      - VEH_SIZE: The dimension of the &quot;vehicle state&quot;: either the full state vector or the &quot;vehicle&quot; part if applicable.</span>
<a name="l00131"></a>00131 <span class="comment">                 *      - OBS_SIZE: The dimension of each observation (eg, 2 for pixel coordinates, 3 for 3D coordinates,etc).</span>
<a name="l00132"></a>00132 <span class="comment">                 *      - FEAT_SIZE: The dimension of the features in the system state (the &quot;map&quot;), or 0 if not applicable (the default if not implemented).</span>
<a name="l00133"></a>00133 <span class="comment">                 *      - ACT_SIZE: The dimension of each &quot;action&quot; u_k (or 0 if not applicable).</span>
<a name="l00134"></a>00134 <span class="comment">                 *      - KFTYPE: The numeric type of the matrices (default: double)</span>
<a name="l00135"></a>00135 <span class="comment">                 *</span>
<a name="l00136"></a>00136 <span class="comment">                 * Revisions:</span>
<a name="l00137"></a>00137 <span class="comment">                 *      - 2007: Antonio J. Ortiz de Galisteo (AJOGD)</span>
<a name="l00138"></a>00138 <span class="comment">                 *      - 2008/FEB: All KF classes corrected, reorganized, and rewritten (JLBC).</span>
<a name="l00139"></a>00139 <span class="comment">                 *      - 2008/MAR: Implemented IKF (JLBC).</span>
<a name="l00140"></a>00140 <span class="comment">                 *      - 2009/DEC: Totally rewritten as a generic template using fixed-size matrices where possible (JLBC).</span>
<a name="l00141"></a>00141 <span class="comment">                 *</span>
<a name="l00142"></a>00142 <span class="comment">                 *  \sa mrpt::slam::CRangeBearingKFSLAM, mrpt::slam::CRangeBearingKFSLAM2D</span>
<a name="l00143"></a>00143 <span class="comment">                 * \ingroup mrpt_bayes_grp</span>
<a name="l00144"></a>00144 <span class="comment">                 */</span>
<a name="l00145"></a>00145                 <span class="keyword">template</span> &lt;<span class="keywordtype">size_t</span> VEH_SIZE, <span class="keywordtype">size_t</span> OBS_SIZE, <span class="keywordtype">size_t</span> FEAT_SIZE, <span class="keywordtype">size_t</span> ACT_SIZE, <span class="keyword">typename</span> KFTYPE = <span class="keywordtype">double</span>&gt;
<a name="l00146"></a>00146                 <span class="keyword">class </span>CKalmanFilterCapable : <span class="keyword">public</span> mrpt::utils::<a class="code" href="classmrpt_1_1utils_1_1_c_debug_output_capable.html" title="This base class provides a common printf-like method to send debug information to std::cout...">CDebugOutputCapable</a>
<a name="l00147"></a>00147                 {
<a name="l00148"></a>00148                 <span class="keyword">public</span>:
<a name="l00149"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a6229386413a59a767a5197fca67e56cf">00149</a>                         <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">size_t</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a6229386413a59a767a5197fca67e56cf">get_vehicle_size</a>() { <span class="keywordflow">return</span> VEH_SIZE; }
<a name="l00150"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ae1bc73d658a9a0e1ca3615a523624434">00150</a>                         <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">size_t</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ae1bc73d658a9a0e1ca3615a523624434">get_observation_size</a>() { <span class="keywordflow">return</span> OBS_SIZE; }
<a name="l00151"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ad19146ca0b12bed3c2aace9329ece0fd">00151</a>                         <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">size_t</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ad19146ca0b12bed3c2aace9329ece0fd">get_feature_size</a>() { <span class="keywordflow">return</span> FEAT_SIZE; }
<a name="l00152"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#abaeadbd68b3a68d35e530a29b7c193b2">00152</a>                         <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">size_t</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#abaeadbd68b3a68d35e530a29b7c193b2">get_action_size</a>() { <span class="keywordflow">return</span> ACT_SIZE; }
<a name="l00153"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a1ac5b0adbbd3a0e5122ebb148ff3e7ad">00153</a>                         <span class="keyword">inline</span> <span class="keywordtype">size_t</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a1ac5b0adbbd3a0e5122ebb148ff3e7ad">getNumberOfLandmarksInTheMap</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="namespacemrpt_1_1bayes_1_1detail.html#aeec894a458a3e7175e707871cd796f34">detail::getNumberOfLandmarksInMap</a>(*<span class="keyword">this</span>); }
<a name="l00154"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a48adbb9852e76624b16e7fa115c19e65">00154</a>                         <span class="keyword">inline</span> <span class="keywordtype">bool</span>   <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a48adbb9852e76624b16e7fa115c19e65">isMapEmpty</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="namespacemrpt_1_1bayes_1_1detail.html#aafff1b2b519f6fb209de6ebde0830c19">detail::isMapEmpty</a>(*<span class="keyword">this</span>); }
<a name="l00155"></a>00155 
<a name="l00156"></a>00156 
<a name="l00157"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ad66228d2cc13705900669ccbab41f3d9">00157</a>                         <span class="keyword">typedef</span> KFTYPE <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ad66228d2cc13705900669ccbab41f3d9" title="The numeric type used in the Kalman Filter (default=double)">kftype</a>; <span class="comment">//!&lt; The numeric type used in the Kalman Filter (default=double)</span>
<a name="l00158"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a6195a8efec17869133a1fd31105d6a64">00158</a> <span class="comment"></span>                        <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html" title="Virtual base for Kalman Filter (EKF,IEKF,UKF) implementations.">CKalmanFilterCapable&lt;VEH_SIZE,OBS_SIZE,FEAT_SIZE,ACT_SIZE,KFTYPE&gt;</a>  <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a6195a8efec17869133a1fd31105d6a64" title="My class, in a shorter name!">KFCLASS</a>;  <span class="comment">//!&lt; My class, in a shorter name!</span>
<a name="l00159"></a>00159 <span class="comment"></span>
<a name="l00160"></a>00160                         <span class="comment">// ---------- Many useful typedefs to short the notation a bit... --------</span>
<a name="l00161"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a9a120b286d286048985b059aa721e0c1">00161</a>                         <span class="keyword">typedef</span> mrpt<a class="code" href="structmrpt_1_1dynamicsize__vector.html">::dynamicsize_vector&lt;KFTYPE&gt;</a> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a9a120b286d286048985b059aa721e0c1">KFVector</a>;
<a name="l00162"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ad214112622ea8531c9a7c052f93600bd">00162</a>                         <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">CMatrixTemplateNumeric&lt;KFTYPE&gt;</a>   <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ad214112622ea8531c9a7c052f93600bd">KFMatrix</a>;
<a name="l00163"></a>00163 
<a name="l00164"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a8dd3e63dd847fd98ef59b472e46cad2c">00164</a>                         <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">CMatrixFixedNumeric&lt;KFTYPE,VEH_SIZE,VEH_SIZE&gt;</a>   <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a8dd3e63dd847fd98ef59b472e46cad2c">KFMatrix_VxV</a>;
<a name="l00165"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a521a75ae040b78365ebf57f97967bc84">00165</a>                         <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">CMatrixFixedNumeric&lt;KFTYPE,OBS_SIZE,OBS_SIZE&gt;</a>   <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a521a75ae040b78365ebf57f97967bc84">KFMatrix_OxO</a>;
<a name="l00166"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ad8a2b4b92969f736bf6c147804b50614">00166</a>                         <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">CMatrixFixedNumeric&lt;KFTYPE,FEAT_SIZE,FEAT_SIZE&gt;</a> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ad8a2b4b92969f736bf6c147804b50614">KFMatrix_FxF</a>;
<a name="l00167"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#af20d435cc094724e00949ea137aa832b">00167</a>                         <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">CMatrixFixedNumeric&lt;KFTYPE,ACT_SIZE,ACT_SIZE&gt;</a>   <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#af20d435cc094724e00949ea137aa832b">KFMatrix_AxA</a>;
<a name="l00168"></a>00168 
<a name="l00169"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a60912a7a33cd8e77605e4761848609b2">00169</a>                         <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">CMatrixFixedNumeric&lt;KFTYPE,VEH_SIZE,OBS_SIZE&gt;</a>   <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a60912a7a33cd8e77605e4761848609b2">KFMatrix_VxO</a>;
<a name="l00170"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a7277a24dd3aae42b96708b4669e74a12">00170</a>                         <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">CMatrixFixedNumeric&lt;KFTYPE,VEH_SIZE,FEAT_SIZE&gt;</a>  <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a7277a24dd3aae42b96708b4669e74a12">KFMatrix_VxF</a>;
<a name="l00171"></a>00171 
<a name="l00172"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#affb2aa897e6434f6572d48ff1be1988e">00172</a>                         <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">CMatrixFixedNumeric&lt;KFTYPE,FEAT_SIZE,VEH_SIZE&gt;</a>  <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#affb2aa897e6434f6572d48ff1be1988e">KFMatrix_FxV</a>;
<a name="l00173"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a253bf3d53d25e20ec0592868efdba607">00173</a>                         <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">CMatrixFixedNumeric&lt;KFTYPE,FEAT_SIZE,OBS_SIZE&gt;</a>  <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a253bf3d53d25e20ec0592868efdba607">KFMatrix_FxO</a>;
<a name="l00174"></a>00174 
<a name="l00175"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ada78f649a58aa64c3db6c8b436b5ceba">00175</a>                         <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">CMatrixFixedNumeric&lt;KFTYPE,OBS_SIZE,FEAT_SIZE&gt;</a>  <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ada78f649a58aa64c3db6c8b436b5ceba">KFMatrix_OxF</a>;
<a name="l00176"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ab0ddb67c05616e7fc1fcabe9cc04c753">00176</a>                         <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">CMatrixFixedNumeric&lt;KFTYPE,OBS_SIZE,VEH_SIZE&gt;</a>   <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ab0ddb67c05616e7fc1fcabe9cc04c753">KFMatrix_OxV</a>;
<a name="l00177"></a>00177 
<a name="l00178"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ad4f1667845ca7553925160142821cff0">00178</a>                         <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">CArrayNumeric&lt;KFTYPE,VEH_SIZE&gt;</a>  <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ad4f1667845ca7553925160142821cff0">KFArray_VEH</a>;
<a name="l00179"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a6454c68e3c45da92e2bbb3e8aa8f6f70">00179</a>                         <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">CArrayNumeric&lt;KFTYPE,ACT_SIZE&gt;</a>  <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a6454c68e3c45da92e2bbb3e8aa8f6f70">KFArray_ACT</a>;
<a name="l00180"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a6c1b24a2c7b35e77411888a06de4e59d">00180</a>                         <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">CArrayNumeric&lt;KFTYPE,OBS_SIZE&gt;</a>  <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a6c1b24a2c7b35e77411888a06de4e59d">KFArray_OBS</a>;
<a name="l00181"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#aa0e71d2a45e5d935eba18d817bb31cf9">00181</a>                         <span class="keyword">typedef</span> <span class="keyword">typename</span> mrpt<a class="code" href="classstd_1_1vector.html" title="STL class.">::aligned_containers&lt;KFArray_OBS&gt;::vector_t</a>  <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#aa0e71d2a45e5d935eba18d817bb31cf9">vector_KFArray_OBS</a>;
<a name="l00182"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a0b5b72d68126a91918ce085789da06bd">00182</a>                         <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">CArrayNumeric&lt;KFTYPE,FEAT_SIZE&gt;</a> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a0b5b72d68126a91918ce085789da06bd">KFArray_FEAT</a>;
<a name="l00183"></a>00183 
<a name="l00184"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#aabe244779fd4694bc5e6d336874396de">00184</a>                         <span class="keyword">inline</span> <span class="keywordtype">size_t</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#aabe244779fd4694bc5e6d336874396de">getStateVectorLength</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> m_xkk.size(); }
<a name="l00185"></a>00185 <span class="comment"></span>
<a name="l00186"></a>00186 <span class="comment">                        /** Returns the mean of the estimated value of the idx&#39;th landmark (not applicable to non-SLAM problems).</span>
<a name="l00187"></a>00187 <span class="comment">                          * \exception std::exception On idx&gt;= getNumberOfLandmarksInTheMap()</span>
<a name="l00188"></a>00188 <span class="comment">                          */</span>
<a name="l00189"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a4cc933fc0dacdd126b08b08591c617f4">00189</a>                         <span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a4cc933fc0dacdd126b08b08591c617f4" title="Returns the mean of the estimated value of the idx&#39;th landmark (not applicable to non-SLAM problems)...">getLandmarkMean</a>(<span class="keywordtype">size_t</span> idx, <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_FEAT</a> &amp;feat )<span class="keyword"> const </span>{
<a name="l00190"></a>00190                                 <a class="code" href="mrpt__macros_8h.html#a47eb5a445c2bf3d9190396510ea9683e">ASSERT_</a>(idx&lt;getNumberOfLandmarksInTheMap())
<a name="l00191"></a>00191                                 ::<a class="code" href="group__mrpt__system__os.html#gae1184cfb1f617787dc4c9da98becbe3a" title="An OS and compiler independent version of &quot;memcpy&quot;.">memcpy</a>(&amp;feat[0], &amp;m_xkk[VEH_SIZE+idx*FEAT_SIZE], FEAT_SIZE*<span class="keyword">sizeof</span>(m_xkk[0]));
<a name="l00192"></a>00192                         }<span class="comment"></span>
<a name="l00193"></a>00193 <span class="comment">                        /** Returns the covariance of the idx&#39;th landmark (not applicable to non-SLAM problems).</span>
<a name="l00194"></a>00194 <span class="comment">                          * \exception std::exception On idx&gt;= getNumberOfLandmarksInTheMap()</span>
<a name="l00195"></a>00195 <span class="comment">                          */</span>
<a name="l00196"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ae32eeb6c71cb7ea1acf21ae09ac19827">00196</a>                         <span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ae32eeb6c71cb7ea1acf21ae09ac19827" title="Returns the covariance of the idx&#39;th landmark (not applicable to non-SLAM problems).">getLandmarkCov</a>(<span class="keywordtype">size_t</span> idx, <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_FxF</a> &amp;feat_cov )<span class="keyword"> const </span>{
<a name="l00197"></a>00197                                 m_pkk.extractMatrix(VEH_SIZE+idx*FEAT_SIZE,VEH_SIZE+idx*FEAT_SIZE,feat_cov);
<a name="l00198"></a>00198                         }
<a name="l00199"></a>00199 
<a name="l00200"></a>00200                 <span class="keyword">protected</span>:<span class="comment"></span>
<a name="l00201"></a>00201 <span class="comment">                        /** @name Kalman filter state</span>
<a name="l00202"></a>00202 <span class="comment">                                @{ */</span>
<a name="l00203"></a>00203 
<a name="l00204"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a7e8948c9d209c23517c45c6494b46147">00204</a>                         <a class="code" href="structmrpt_1_1dynamicsize__vector.html">KFVector</a>  <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a7e8948c9d209c23517c45c6494b46147" title="The system state vector.">m_xkk</a>;  <span class="comment">//!&lt; The system state vector.</span>
<a name="l00205"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a15c291ca9eb40996381dc0e60f01d533">00205</a> <span class="comment"></span>                        <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a>  <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a15c291ca9eb40996381dc0e60f01d533" title="The system full covariance matrix.">m_pkk</a>;  <span class="comment">//!&lt; The system full covariance matrix.</span>
<a name="l00206"></a>00206 <span class="comment"></span><span class="comment"></span>
<a name="l00207"></a>00207 <span class="comment">                        /** @} */</span>
<a name="l00208"></a>00208 
<a name="l00209"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a3eff55c428065c52bd2f9418e3944e48">00209</a>                         mrpt<a class="code" href="classmrpt_1_1utils_1_1_c_time_logger.html" title="A versatile &quot;profiler&quot; that logs the time spent within each pair of calls to enter(X)-leave(X), among other stats.">::utils::CTimeLogger</a>  <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a3eff55c428065c52bd2f9418e3944e48">m_timLogger</a>;
<a name="l00210"></a>00210 <span class="comment"></span>
<a name="l00211"></a>00211 <span class="comment">                        /** @name Virtual methods for Kalman Filter implementation</span>
<a name="l00212"></a>00212 <span class="comment">                                @{</span>
<a name="l00213"></a>00213 <span class="comment">                         */</span>
<a name="l00214"></a>00214 <span class="comment"></span>
<a name="l00215"></a>00215 <span class="comment">                        /** Must return the action vector u.</span>
<a name="l00216"></a>00216 <span class="comment">                          * \param out_u The action vector which will be passed to OnTransitionModel</span>
<a name="l00217"></a>00217 <span class="comment">                          */</span>
<a name="l00218"></a>00218                         <span class="keyword">virtual</span> <span class="keywordtype">void</span> OnGetAction( <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_ACT</a> &amp;out_u ) <span class="keyword">const</span> = 0;
<a name="l00219"></a>00219 <span class="comment"></span>
<a name="l00220"></a>00220 <span class="comment">                        /** Implements the transition model \f$ \hat{x}_{k|k-1} = f( \hat{x}_{k-1|k-1}, u_k ) \f$</span>
<a name="l00221"></a>00221 <span class="comment">                          * \param in_u The vector returned by OnGetAction.</span>
<a name="l00222"></a>00222 <span class="comment">                          * \param inout_x At input has \f[ \hat{x}_{k-1|k-1} \f] , at output must have \f$ \hat{x}_{k|k-1} \f$ .</span>
<a name="l00223"></a>00223 <span class="comment">                          * \param out_skip Set this to true if for some reason you want to skip the prediction step (to do not modify either the vector or the covariance). Default:false</span>
<a name="l00224"></a>00224 <span class="comment">                          * \note Even if you return &quot;out_skip=true&quot;, the value of &quot;inout_x&quot; MUST be updated as usual (this is to allow numeric approximation of Jacobians).</span>
<a name="l00225"></a>00225 <span class="comment">                          */</span>
<a name="l00226"></a>00226                         <span class="keyword">virtual</span> <span class="keywordtype">void</span> OnTransitionModel(
<a name="l00227"></a>00227                                 <span class="keyword">const</span> <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_ACT</a> &amp;in_u,
<a name="l00228"></a>00228                                 <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_VEH</a>       &amp;inout_x,
<a name="l00229"></a>00229                                 <span class="keywordtype">bool</span> &amp;out_skipPrediction
<a name="l00230"></a>00230                                 )  <span class="keyword">const</span> = 0;
<a name="l00231"></a>00231 <span class="comment"></span>
<a name="l00232"></a>00232 <span class="comment">                        /** Implements the transition Jacobian \f$ \frac{\partial f}{\partial x} \f$</span>
<a name="l00233"></a>00233 <span class="comment">                          * \param out_F Must return the Jacobian.</span>
<a name="l00234"></a>00234 <span class="comment">                          *  The returned matrix must be \f$V \times V\f$ with V being either the size of the whole state vector (for non-SLAM problems) or VEH_SIZE (for SLAM problems).</span>
<a name="l00235"></a>00235 <span class="comment">                          */</span>
<a name="l00236"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a9102af2605891c4b76ef1216013da46d">00236</a>                         <span class="keyword">virtual</span> <span class="keywordtype">void</span> OnTransitionJacobian( <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_VxV</a>  &amp;out_F )<span class="keyword"> const</span>
<a name="l00237"></a>00237 <span class="keyword">                        </span>{
<a name="l00238"></a>00238                                 m_user_didnt_implement_jacobian=<span class="keyword">true</span>;
<a name="l00239"></a>00239                         }
<a name="l00240"></a>00240 <span class="comment"></span>
<a name="l00241"></a>00241 <span class="comment">                        /** Only called if using a numeric approximation of the transition Jacobian, this method must return the increments in each dimension of the vehicle state vector while estimating the Jacobian.</span>
<a name="l00242"></a>00242 <span class="comment">                          */</span>
<a name="l00243"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a6546398d63e8298f0b0a59a86e2395a7">00243</a>                         <span class="keyword">virtual</span> <span class="keywordtype">void</span> OnTransitionJacobianNumericGetIncrements(<a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_VEH</a> &amp;out_increments)<span class="keyword"> const</span>
<a name="l00244"></a>00244 <span class="keyword">                        </span>{
<a name="l00245"></a>00245                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i=0;i&lt;VEH_SIZE;i++) out_increments[i] = 1e-6;
<a name="l00246"></a>00246                         }
<a name="l00247"></a>00247 <span class="comment"></span>
<a name="l00248"></a>00248 <span class="comment">                        /** Implements the transition noise covariance \f$ Q_k \f$</span>
<a name="l00249"></a>00249 <span class="comment">                          * \param out_Q Must return the covariance matrix.</span>
<a name="l00250"></a>00250 <span class="comment">                          *  The returned matrix must be of the same size than the jacobian from OnTransitionJacobian</span>
<a name="l00251"></a>00251 <span class="comment">                          */</span>
<a name="l00252"></a>00252                         <span class="keyword">virtual</span> <span class="keywordtype">void</span> OnTransitionNoise( KFMatrix_VxV &amp;out_Q )  <span class="keyword">const</span> = 0;
<a name="l00253"></a>00253 <span class="comment"></span>
<a name="l00254"></a>00254 <span class="comment">                        /** This will be called before OnGetObservationsAndDataAssociation to allow the application to reduce the number of covariance landmark predictions to be made.</span>
<a name="l00255"></a>00255 <span class="comment">                          *  For example, features which are known to be &quot;out of sight&quot; shouldn&#39;t be added to the output list to speed up the calculations.</span>
<a name="l00256"></a>00256 <span class="comment">                          * \param in_all_prediction_means The mean of each landmark predictions; the computation or not of the corresponding covariances is what we&#39;re trying to determined with this method.</span>
<a name="l00257"></a>00257 <span class="comment">                          * \param out_LM_indices_to_predict The list of landmark indices in the map [0,getNumberOfLandmarksInTheMap()-1] that should be predicted.</span>
<a name="l00258"></a>00258 <span class="comment">                          * \note This is not a pure virtual method, so it should be implemented only if desired. The default implementation returns a vector with all the landmarks in the map.</span>
<a name="l00259"></a>00259 <span class="comment">                          * \sa OnGetObservations, OnDataAssociation</span>
<a name="l00260"></a>00260 <span class="comment">                          */</span>
<a name="l00261"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a505fa1e6eb8a300e0e1171a26b4f5b15">00261</a>                         <span class="keyword">virtual</span> <span class="keywordtype">void</span> OnPreComputingPredictions(
<a name="l00262"></a>00262                                 <span class="keyword">const</span> <a class="code" href="classstd_1_1vector.html" title="STL class.">vector_KFArray_OBS</a> &amp;in_all_prediction_means,
<a name="l00263"></a>00263                                 <a class="code" href="classstd_1_1vector.html">mrpt::vector_size_t</a>                             &amp;out_LM_indices_to_predict )<span class="keyword"> const</span>
<a name="l00264"></a>00264 <span class="keyword">                        </span>{
<a name="l00265"></a>00265                                 <span class="comment">// Default: all of them:</span>
<a name="l00266"></a>00266                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> N = this-&gt;getNumberOfLandmarksInTheMap();
<a name="l00267"></a>00267                                 out_LM_indices_to_predict.resize(N);
<a name="l00268"></a>00268                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i=0;i&lt;N;i++) out_LM_indices_to_predict[i]=i;
<a name="l00269"></a>00269                         }
<a name="l00270"></a>00270 <span class="comment"></span>
<a name="l00271"></a>00271 <span class="comment">                        /** Return the observation NOISE covariance matrix, that is, the model of the Gaussian additive noise of the sensor.</span>
<a name="l00272"></a>00272 <span class="comment">                          * \param out_R The noise covariance matrix. It might be non diagonal, but it&#39;ll usually be.</span>
<a name="l00273"></a>00273 <span class="comment">                          * \note Upon call, it can be assumed that the previous contents of out_R are all zeros.</span>
<a name="l00274"></a>00274 <span class="comment">                          */</span>
<a name="l00275"></a>00275                         <span class="keyword">virtual</span> <span class="keywordtype">void</span> OnGetObservationNoise(KFMatrix_OxO &amp;out_R)  <span class="keyword">const</span> = 0;
<a name="l00276"></a>00276 <span class="comment"></span>
<a name="l00277"></a>00277 <span class="comment">                        /** This is called between the KF prediction step and the update step, and the application must return the observations and, when applicable, the data association between these observations and the current map.</span>
<a name="l00278"></a>00278 <span class="comment">                          *</span>
<a name="l00279"></a>00279 <span class="comment">                          * \param out_z N vectors, each for one &quot;observation&quot; of length OBS_SIZE, N being the number of &quot;observations&quot;: how many observed landmarks for a map, or just one if not applicable.</span>
<a name="l00280"></a>00280 <span class="comment">                          * \param out_data_association An empty vector or, where applicable, a vector where the i&#39;th element corresponds to the position of the observation in the i&#39;th row of out_z within the system state vector (in the range [0,getNumberOfLandmarksInTheMap()-1]), or -1 if it is a new map element and we want to insert it at the end of this KF iteration.</span>
<a name="l00281"></a>00281 <span class="comment">                          * \param in_all_predictions A vector with the prediction of ALL the landmarks in the map. Note that, in contrast, in_S only comprises a subset of all the landmarks.</span>
<a name="l00282"></a>00282 <span class="comment">                          * \param in_S The full covariance matrix of the observation predictions (i.e. the &quot;innovation covariance matrix&quot;). This is a M·O x M·O matrix with M=length of &quot;in_lm_indices_in_S&quot;.</span>
<a name="l00283"></a>00283 <span class="comment">                          * \param in_lm_indices_in_S The indices of the map landmarks (range [0,getNumberOfLandmarksInTheMap()-1]) that can be found in the matrix in_S.</span>
<a name="l00284"></a>00284 <span class="comment">                          *</span>
<a name="l00285"></a>00285 <span class="comment">                          *  This method will be called just once for each complete KF iteration.</span>
<a name="l00286"></a>00286 <span class="comment">                          * \note It is assumed that the observations are independent, i.e. there are NO cross-covariances between them.</span>
<a name="l00287"></a>00287 <span class="comment">                          */</span>
<a name="l00288"></a>00288                         <span class="keyword">virtual</span> <span class="keywordtype">void</span> OnGetObservationsAndDataAssociation(
<a name="l00289"></a>00289                                 vector_KFArray_OBS                      &amp;out_z,
<a name="l00290"></a>00290                                 <a class="code" href="classstd_1_1vector.html" title="STL class.">mrpt::vector_int</a>            &amp;out_data_association,
<a name="l00291"></a>00291                                 <span class="keyword">const</span> vector_KFArray_OBS        &amp;in_all_predictions,
<a name="l00292"></a>00292                                 <span class="keyword">const</span> KFMatrix              &amp;in_S,
<a name="l00293"></a>00293                                 <span class="keyword">const</span> <a class="code" href="classstd_1_1vector.html">vector_size_t</a>         &amp;in_lm_indices_in_S,
<a name="l00294"></a>00294                                 <span class="keyword">const</span> KFMatrix_OxO          &amp;in_R
<a name="l00295"></a>00295                                 ) = 0;
<a name="l00296"></a>00296 <span class="comment"></span>
<a name="l00297"></a>00297 <span class="comment">                        /** Implements the observation prediction \f$ h_i(x) \f$.</span>
<a name="l00298"></a>00298 <span class="comment">                          * \param idx_landmark_to_predict The indices of the landmarks in the map whose predictions are expected as output. For non SLAM-like problems, this input value is undefined and the application should just generate one observation for the given problem.</span>
<a name="l00299"></a>00299 <span class="comment">                          * \param out_predictions The predicted observations.</span>
<a name="l00300"></a>00300 <span class="comment">                          */</span>
<a name="l00301"></a>00301                         <span class="keyword">virtual</span> <span class="keywordtype">void</span> OnObservationModel(
<a name="l00302"></a>00302                                 <span class="keyword">const</span> <a class="code" href="classstd_1_1vector.html">mrpt::vector_size_t</a>       &amp;idx_landmarks_to_predict,
<a name="l00303"></a>00303                                 vector_KFArray_OBS  &amp;out_predictions
<a name="l00304"></a>00304                                 ) <span class="keyword">const</span> = 0;
<a name="l00305"></a>00305 <span class="comment"></span>
<a name="l00306"></a>00306 <span class="comment">                        /** Implements the observation Jacobians \f$ \frac{\partial h_i}{\partial x} \f$ and (when applicable) \f$ \frac{\partial h_i}{\partial y_i} \f$.</span>
<a name="l00307"></a>00307 <span class="comment">                          * \param idx_landmark_to_predict The index of the landmark in the map whose prediction is expected as output. For non SLAM-like problems, this will be zero and the expected output is for the whole state vector.</span>
<a name="l00308"></a>00308 <span class="comment">                          * \param Hx  The output Jacobian \f$ \frac{\partial h_i}{\partial x} \f$.</span>
<a name="l00309"></a>00309 <span class="comment">                          * \param Hy  The output Jacobian \f$ \frac{\partial h_i}{\partial y_i} \f$.</span>
<a name="l00310"></a>00310 <span class="comment">                          */</span>
<a name="l00311"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a45e3d11533732ae6fdc6f0d8a0c6a16e">00311</a>                         <span class="keyword">virtual</span> <span class="keywordtype">void</span> OnObservationJacobians(
<a name="l00312"></a>00312                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> &amp;idx_landmark_to_predict,
<a name="l00313"></a>00313                                 <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_OxV</a> &amp;Hx,
<a name="l00314"></a>00314                                 <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_OxF</a> &amp;Hy
<a name="l00315"></a>00315                                 )<span class="keyword"> const</span>
<a name="l00316"></a>00316 <span class="keyword">                        </span>{
<a name="l00317"></a>00317                                 m_user_didnt_implement_jacobian=<span class="keyword">true</span>;
<a name="l00318"></a>00318                         }
<a name="l00319"></a>00319 <span class="comment"></span>
<a name="l00320"></a>00320 <span class="comment">                        /** Only called if using a numeric approximation of the observation Jacobians, this method must return the increments in each dimension of the vehicle state vector while estimating the Jacobian.</span>
<a name="l00321"></a>00321 <span class="comment">                          */</span>
<a name="l00322"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#acbba7768aa0513f67e30628787e429c2">00322</a>                         <span class="keyword">virtual</span> <span class="keywordtype">void</span> OnObservationJacobiansNumericGetIncrements(
<a name="l00323"></a>00323                                         <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_VEH</a>  &amp;out_veh_increments,
<a name="l00324"></a>00324                                         <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_FEAT</a> &amp;out_feat_increments )<span class="keyword"> const</span>
<a name="l00325"></a>00325 <span class="keyword">                        </span>{
<a name="l00326"></a>00326                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i=0;i&lt;VEH_SIZE;i++) out_veh_increments[i] = 1e-6;
<a name="l00327"></a>00327                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i=0;i&lt;FEAT_SIZE;i++) out_feat_increments[i] = 1e-6;
<a name="l00328"></a>00328                         }
<a name="l00329"></a>00329 <span class="comment"></span>
<a name="l00330"></a>00330 <span class="comment">                        /** Computes A=A-B, which may need to be re-implemented depending on the topology of the individual scalar components (eg, angles).</span>
<a name="l00331"></a>00331 <span class="comment">                          */</span>
<a name="l00332"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a2875f05e00d512746e6a39244fb28561">00332</a>                         <span class="keyword">virtual</span> <span class="keywordtype">void</span> OnSubstractObservationVectors(<a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_OBS</a> &amp;A, <span class="keyword">const</span> <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_OBS</a> &amp;B)<span class="keyword"> const</span>
<a name="l00333"></a>00333 <span class="keyword">                        </span>{
<a name="l00334"></a>00334                                 A -= B;
<a name="l00335"></a>00335                         }
<a name="l00336"></a>00336 <span class="comment"></span>
<a name="l00337"></a>00337 <span class="comment">                        /** If applicable to the given problem, this method implements the inverse observation model needed to extend the &quot;map&quot; with a new &quot;element&quot;.</span>
<a name="l00338"></a>00338 <span class="comment">                          * \param in_z The observation vector whose inverse sensor model is to be computed. This is actually one of the vector&lt;&gt; returned by OnGetObservationsAndDataAssociation().</span>
<a name="l00339"></a>00339 <span class="comment">                          * \param out_yn The F-length vector with the inverse observation model \f$ y_n=y(x,z_n) \f$.</span>
<a name="l00340"></a>00340 <span class="comment">                          * \param out_dyn_dxv The \f$F \times V\f$ Jacobian of the inv. sensor model wrt the robot pose \f$ \frac{\partial y_n}{\partial x_v} \f$.</span>
<a name="l00341"></a>00341 <span class="comment">                          * \param out_dyn_dhn The \f$F \times O\f$ Jacobian of the inv. sensor model wrt the observation vector \f$ \frac{\partial y_n}{\partial h_n} \f$.</span>
<a name="l00342"></a>00342 <span class="comment">                          *</span>
<a name="l00343"></a>00343 <span class="comment">                          *  - O: OBS_SIZE</span>
<a name="l00344"></a>00344 <span class="comment">                          *  - V: VEH_SIZE</span>
<a name="l00345"></a>00345 <span class="comment">                          *  - F: FEAT_SIZE</span>
<a name="l00346"></a>00346 <span class="comment">                          *</span>
<a name="l00347"></a>00347 <span class="comment">                          * \note OnNewLandmarkAddedToMap will be also called after calling this method if a landmark is actually being added to the map.</span>
<a name="l00348"></a>00348 <span class="comment">                          * \deprecated This version of the method is deprecated. The alternative method is preferred to allow a greater flexibility.</span>
<a name="l00349"></a>00349 <span class="comment">                          */</span>
<a name="l00350"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a647a12e0844df2ead68949d5ed33967e">00350</a>                         <span class="keyword">virtual</span> <span class="keywordtype">void</span>  OnInverseObservationModel(
<a name="l00351"></a>00351                                 <span class="keyword">const</span> <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_OBS</a> &amp; in_z,
<a name="l00352"></a>00352                                 <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_FEAT</a>  &amp; out_yn,
<a name="l00353"></a>00353                                 <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_FxV</a>  &amp; out_dyn_dxv,
<a name="l00354"></a>00354                                 <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_FxO</a>  &amp; out_dyn_dhn )<span class="keyword"> const</span>
<a name="l00355"></a>00355 <span class="keyword">                        </span>{
<a name="l00356"></a>00356                                 <a class="code" href="mrpt__macros_8h.html#a45b840af519f33816311acdbb28d7c10">MRPT_START</a>
<a name="l00357"></a>00357                                 <a class="code" href="mrpt__macros_8h.html#aaa3f404ea85a6575a7139f8d101370ba">THROW_EXCEPTION</a>(<span class="stringliteral">&quot;Inverse sensor model required but not implemented in derived class.&quot;</span>)
<a name="l00358"></a>00358                                 <a class="code" href="mrpt__macros_8h.html#a88a917260793b56abd83ad2a0d849eb1">MRPT_END</a>
<a name="l00359"></a>00359                         }
<a name="l00360"></a>00360 <span class="comment"></span>
<a name="l00361"></a>00361 <span class="comment">                        /** If applicable to the given problem, this method implements the inverse observation model needed to extend the &quot;map&quot; with a new &quot;element&quot;.</span>
<a name="l00362"></a>00362 <span class="comment">                          *  The uncertainty in the new map feature comes from two parts: one from the vehicle uncertainty (through the out_dyn_dxv Jacobian),</span>
<a name="l00363"></a>00363 <span class="comment">                          *   and another from the uncertainty in the observation itself. By default, out_use_dyn_dhn_jacobian=true on call, and if it&#39;s left at &quot;true&quot;,</span>
<a name="l00364"></a>00364 <span class="comment">                          *   the base KalmanFilter class will compute the uncertainty of the landmark relative position from out_dyn_dhn.</span>
<a name="l00365"></a>00365 <span class="comment">                          *  Only in some problems (e.g. MonoSLAM), it&#39;ll be needed for the application to directly return the covariance matrix \a out_dyn_dhn_R_dyn_dhnT, which is the equivalent to:</span>
<a name="l00366"></a>00366 <span class="comment">                          *</span>
<a name="l00367"></a>00367 <span class="comment">                          *         \f$ \frac{\partial y_n}{\partial h_n} R \frac{\partial y_n}{\partial h_n}^\top \f$.</span>
<a name="l00368"></a>00368 <span class="comment">                          *</span>
<a name="l00369"></a>00369 <span class="comment">                          *  but may be computed from additional terms, or whatever needed by the user.</span>
<a name="l00370"></a>00370 <span class="comment">                          *</span>
<a name="l00371"></a>00371 <span class="comment">                          * \param in_z The observation vector whose inverse sensor model is to be computed. This is actually one of the vector&lt;&gt; returned by OnGetObservationsAndDataAssociation().</span>
<a name="l00372"></a>00372 <span class="comment">                          * \param out_yn The F-length vector with the inverse observation model \f$ y_n=y(x,z_n) \f$.</span>
<a name="l00373"></a>00373 <span class="comment">                          * \param out_dyn_dxv The \f$F \times V\f$ Jacobian of the inv. sensor model wrt the robot pose \f$ \frac{\partial y_n}{\partial x_v} \f$.</span>
<a name="l00374"></a>00374 <span class="comment">                          * \param out_dyn_dhn The \f$F \times O\f$ Jacobian of the inv. sensor model wrt the observation vector \f$ \frac{\partial y_n}{\partial h_n} \f$.</span>
<a name="l00375"></a>00375 <span class="comment">                          * \param out_dyn_dhn_R_dyn_dhnT See the discussion above.</span>
<a name="l00376"></a>00376 <span class="comment">                          *</span>
<a name="l00377"></a>00377 <span class="comment">                          *  - O: OBS_SIZE</span>
<a name="l00378"></a>00378 <span class="comment">                          *  - V: VEH_SIZE</span>
<a name="l00379"></a>00379 <span class="comment">                          *  - F: FEAT_SIZE</span>
<a name="l00380"></a>00380 <span class="comment">                          *</span>
<a name="l00381"></a>00381 <span class="comment">                          * \note OnNewLandmarkAddedToMap will be also called after calling this method if a landmark is actually being added to the map.</span>
<a name="l00382"></a>00382 <span class="comment">                          */</span>
<a name="l00383"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#af7c70d63832d8d45d8c5de0ed6041109">00383</a>                         <span class="keyword">virtual</span> <span class="keywordtype">void</span>  OnInverseObservationModel(
<a name="l00384"></a>00384                                 <span class="keyword">const</span> <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_OBS</a> &amp; in_z,
<a name="l00385"></a>00385                                 <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_FEAT</a>  &amp; out_yn,
<a name="l00386"></a>00386                                 <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_FxV</a>  &amp; out_dyn_dxv,
<a name="l00387"></a>00387                                 <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_FxO</a>  &amp; out_dyn_dhn,
<a name="l00388"></a>00388                                 <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_FxF</a>  &amp; out_dyn_dhn_R_dyn_dhnT,
<a name="l00389"></a>00389                                 <span class="keywordtype">bool</span>          &amp; out_use_dyn_dhn_jacobian
<a name="l00390"></a>00390                                  )<span class="keyword"> const</span>
<a name="l00391"></a>00391 <span class="keyword">                        </span>{
<a name="l00392"></a>00392                                 <a class="code" href="mrpt__macros_8h.html#a45b840af519f33816311acdbb28d7c10">MRPT_START</a>
<a name="l00393"></a>00393                                 OnInverseObservationModel(in_z,out_yn,out_dyn_dxv,out_dyn_dhn);
<a name="l00394"></a>00394                                 out_use_dyn_dhn_jacobian=<span class="keyword">true</span>;
<a name="l00395"></a>00395                                 <a class="code" href="mrpt__macros_8h.html#a88a917260793b56abd83ad2a0d849eb1">MRPT_END</a>
<a name="l00396"></a>00396                         }
<a name="l00397"></a>00397 <span class="comment"></span>
<a name="l00398"></a>00398 <span class="comment">                        /** If applicable to the given problem, do here any special handling of adding a new landmark to the map.</span>
<a name="l00399"></a>00399 <span class="comment">                          * \param in_obsIndex The index of the observation whose inverse sensor is to be computed. It corresponds to the row in in_z where the observation can be found.</span>
<a name="l00400"></a>00400 <span class="comment">                          * \param in_idxNewFeat The index that this new feature will have in the state vector (0:just after the vehicle state, 1: after that,...). Save this number so data association can be done according to these indices.</span>
<a name="l00401"></a>00401 <span class="comment">                          * \sa OnInverseObservationModel</span>
<a name="l00402"></a>00402 <span class="comment">                          */</span>
<a name="l00403"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a41be072d4693b55225b484c249db5fc2">00403</a>                         <span class="keyword">virtual</span> <span class="keywordtype">void</span> OnNewLandmarkAddedToMap(
<a name="l00404"></a>00404                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span>    in_obsIdx,
<a name="l00405"></a>00405                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span>    in_idxNewFeat )
<a name="l00406"></a>00406                         {
<a name="l00407"></a>00407                                 <span class="comment">// Do nothing in this base class.</span>
<a name="l00408"></a>00408                         }
<a name="l00409"></a>00409 <span class="comment"></span>
<a name="l00410"></a>00410 <span class="comment">                        /** This method is called after the prediction and after the update, to give the user an opportunity to normalize the state vector (eg, keep angles within -pi,pi range) if the application requires it.</span>
<a name="l00411"></a>00411 <span class="comment">                          */</span>
<a name="l00412"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a8a5246ad413ba2f6121b9f7f261283b8">00412</a>                         <span class="keyword">virtual</span> <span class="keywordtype">void</span> OnNormalizeStateVector()
<a name="l00413"></a>00413                         {
<a name="l00414"></a>00414                                 <span class="comment">// Do nothing in this base class.</span>
<a name="l00415"></a>00415                         }
<a name="l00416"></a>00416 <span class="comment"></span>
<a name="l00417"></a>00417 <span class="comment">                        /** This method is called after finishing one KF iteration and before returning from runOneKalmanIteration().</span>
<a name="l00418"></a>00418 <span class="comment">                          */</span>
<a name="l00419"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a5a3514fd81d6f81b8ff7b2c72dfae33e">00419</a>                         <span class="keyword">virtual</span> <span class="keywordtype">void</span> OnPostIteration()
<a name="l00420"></a>00420                         {
<a name="l00421"></a>00421                                 <span class="comment">// Do nothing in this base class.</span>
<a name="l00422"></a>00422                         }
<a name="l00423"></a>00423 <span class="comment"></span>
<a name="l00424"></a>00424 <span class="comment">                        /** @}</span>
<a name="l00425"></a>00425 <span class="comment">                         */</span>
<a name="l00426"></a>00426 
<a name="l00427"></a>00427                 <span class="keyword">public</span>:
<a name="l00428"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a44fae14dfa9b912420b6465fb7e8f7c5">00428</a>                         <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a44fae14dfa9b912420b6465fb7e8f7c5">CKalmanFilterCapable</a>() {} <span class="comment">//!&lt; Default constructor</span>
<a name="l00429"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a19b3a038e3ba1d3994eab0a08db733b5">00429</a> <span class="comment"></span>                        <span class="keyword">virtual</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a19b3a038e3ba1d3994eab0a08db733b5" title="Destructor.">~CKalmanFilterCapable</a>() {}  <span class="comment">//!&lt; Destructor</span>
<a name="l00430"></a>00430 <span class="comment"></span>
<a name="l00431"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a4c2d71f07ef0501d157988ebccf9f3c0">00431</a>                         mrpt<a class="code" href="classmrpt_1_1utils_1_1_c_time_logger.html" title="A versatile &quot;profiler&quot; that logs the time spent within each pair of calls to enter(X)-leave(X), among other stats.">::utils::CTimeLogger</a> &amp;<a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a4c2d71f07ef0501d157988ebccf9f3c0">getProfiler</a>() { <span class="keywordflow">return</span> m_timLogger; }
<a name="l00432"></a>00432 
<a name="l00433"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a88651951bad5ea93ae84d848aeed6414">00433</a>                         <a class="code" href="structmrpt_1_1bayes_1_1_t_k_f__options.html" title="Generic options for the Kalman Filter algorithm in itself.">TKF_options</a> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a88651951bad5ea93ae84d848aeed6414" title="Generic options for the Kalman Filter algorithm itself.">KF_options</a>; <span class="comment">//!&lt; Generic options for the Kalman Filter algorithm itself.</span>
<a name="l00434"></a>00434 <span class="comment"></span>
<a name="l00435"></a>00435 
<a name="l00436"></a>00436                 <span class="keyword">private</span>:
<a name="l00437"></a>00437                         <span class="comment">//  &quot;Local&quot; variables to runOneKalmanIteration, declared here to avoid</span>
<a name="l00438"></a>00438                         <span class="comment">//   allocating them over and over again with each call.</span>
<a name="l00439"></a>00439                         <span class="comment">//  (The variables that go into the stack remains in the function body)</span>
<a name="l00440"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a90762ef91865e4f300226f31cb187828">00440</a>                         <a class="code" href="classstd_1_1vector.html" title="STL class.">vector_KFArray_OBS</a>              <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a90762ef91865e4f300226f31cb187828">all_predictions</a>;
<a name="l00441"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a87c0cfc640df569e33a97749951a6e06">00441</a>                         <a class="code" href="classstd_1_1vector.html">vector_size_t</a>                   <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a87c0cfc640df569e33a97749951a6e06">predictLMidxs</a>;
<a name="l00442"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a581ce072177eef66789bf8024f3c2ed7">00442</a>                         <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a>                                <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a581ce072177eef66789bf8024f3c2ed7">dh_dx</a>;
<a name="l00443"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a6dcad04e08c1483c1ed5a0e5c7e5ef79">00443</a>                         <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a>                                <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a6dcad04e08c1483c1ed5a0e5c7e5ef79">dh_dx_full</a>;
<a name="l00444"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a099172f5abfc72517b79cf221200b9f2">00444</a>                         <a class="code" href="classstd_1_1vector.html">vector_size_t</a>                   <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a099172f5abfc72517b79cf221200b9f2">idxs</a>;
<a name="l00445"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a65d721081bd1d54c1d05d88c4279fe42">00445</a>                         <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a>                                <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a65d721081bd1d54c1d05d88c4279fe42">S</a>;
<a name="l00446"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a65e1419380dea75082a0aa0a09f04332">00446</a>                         <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a>                                <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a65e1419380dea75082a0aa0a09f04332">Pkk_subset</a>;
<a name="l00447"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#aa43fef4c1e7af3dee7ad10053132f47b">00447</a>                         <a class="code" href="classstd_1_1vector.html" title="STL class.">vector_KFArray_OBS</a>              <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#aa43fef4c1e7af3dee7ad10053132f47b">Z</a>;              <span class="comment">// Each entry is one observation:</span>
<a name="l00448"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#aac0376b299cfa494e755b1ddfb512b7e">00448</a>                         <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a>                                <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#aac0376b299cfa494e755b1ddfb512b7e">K</a>;              <span class="comment">// Kalman gain</span>
<a name="l00449"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a19e1025c17ff21c2714fd5bcb9d58a9b">00449</a>                         <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a>                                <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a19e1025c17ff21c2714fd5bcb9d58a9b">S_1</a>;    <span class="comment">// Inverse of S</span>
<a name="l00450"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a8eca88f65c4032f3179b8e2e5d13250b">00450</a>                         <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a>                                <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a8eca88f65c4032f3179b8e2e5d13250b">dh_dx_full_obs</a>;
<a name="l00451"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ad9c15457835641e93026e505b3c44ac7">00451</a>                         <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a>                                <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ad9c15457835641e93026e505b3c44ac7">aux_K_dh_dx</a>;
<a name="l00452"></a>00452 
<a name="l00453"></a>00453                 <span class="keyword">protected</span>:
<a name="l00454"></a>00454 <span class="comment"></span>
<a name="l00455"></a>00455 <span class="comment">                        /** The main entry point, executes one complete step: prediction + update.</span>
<a name="l00456"></a>00456 <span class="comment">                          *  It is protected since derived classes must provide a problem-specific entry point for users.</span>
<a name="l00457"></a>00457 <span class="comment">                          *  The exact order in which this method calls the virtual method is explained in http://www.mrpt.org/Kalman_Filters</span>
<a name="l00458"></a>00458 <span class="comment">                          */</span>
<a name="l00459"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#aeebd325f91acbf7d27134c8c7388649e">00459</a>                         <span class="keywordtype">void</span> runOneKalmanIteration()
<a name="l00460"></a>00460                         {
<a name="l00461"></a>00461                                 <a class="code" href="mrpt__macros_8h.html#a45b840af519f33816311acdbb28d7c10">MRPT_START</a>
<a name="l00462"></a>00462 
<a name="l00463"></a>00463                                 m_timLogger.enable(KF_options.enable_profiler || KF_options.verbose);
<a name="l00464"></a>00464                                 m_timLogger.enter(<span class="stringliteral">&quot;KF:complete_step&quot;</span>);
<a name="l00465"></a>00465 
<a name="l00466"></a>00466                                 <a class="code" href="mrpt__macros_8h.html#a47eb5a445c2bf3d9190396510ea9683e">ASSERT_</a>(<span class="keywordtype">size_t</span>(m_xkk.size())==m_pkk.getColCount())
<a name="l00467"></a>00467                                 <a class="code" href="mrpt__macros_8h.html#a47eb5a445c2bf3d9190396510ea9683e">ASSERT_</a>(<span class="keywordtype">size_t</span>(m_xkk.size())&gt;=VEH_SIZE)
<a name="l00468"></a>00468 
<a name="l00469"></a>00469                                 <span class="comment">// =============================================================</span>
<a name="l00470"></a>00470                                 <span class="comment">//  1. CREATE ACTION MATRIX u FROM ODOMETRY</span>
<a name="l00471"></a>00471                                 <span class="comment">// =============================================================</span>
<a name="l00472"></a>00472                                 <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_ACT</a>  u;
<a name="l00473"></a>00473 
<a name="l00474"></a>00474                                 m_timLogger.enter(<span class="stringliteral">&quot;KF:1.OnGetAction&quot;</span>);
<a name="l00475"></a>00475                                 OnGetAction(u);
<a name="l00476"></a>00476                                 m_timLogger.leave(<span class="stringliteral">&quot;KF:1.OnGetAction&quot;</span>);
<a name="l00477"></a>00477 
<a name="l00478"></a>00478                                 <span class="comment">// Sanity check:</span>
<a name="l00479"></a>00479                                 <span class="keywordflow">if</span> (FEAT_SIZE) { <a class="code" href="mrpt__macros_8h.html#a5ad4d8d68e2f6664f247407bf89aac55" title="Defines an assertion mechanism - only when compiled in debug.">ASSERTDEB_</a>( (((m_xkk.size()-VEH_SIZE)/FEAT_SIZE)*FEAT_SIZE)== (m_xkk.size()-VEH_SIZE) ) }
<a name="l00480"></a>00480 
<a name="l00481"></a>00481                                 <span class="comment">// =============================================================</span>
<a name="l00482"></a>00482                                 <span class="comment">//  2. PREDICTION OF NEW POSE xv_{k+1|k}</span>
<a name="l00483"></a>00483                                 <span class="comment">// =============================================================</span>
<a name="l00484"></a>00484                                 m_timLogger.enter(<span class="stringliteral">&quot;KF:2.prediction stage&quot;</span>);
<a name="l00485"></a>00485 
<a name="l00486"></a>00486                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> N_map = getNumberOfLandmarksInTheMap();
<a name="l00487"></a>00487 
<a name="l00488"></a>00488                                 <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_VEH</a> xv( &amp;m_xkk[0] );  <span class="comment">// Vehicle pose</span>
<a name="l00489"></a>00489 
<a name="l00490"></a>00490                                 <span class="keywordtype">bool</span> skipPrediction=<span class="keyword">false</span>; <span class="comment">// Wether to skip the prediction step (in SLAM this is desired for the first iteration...)</span>
<a name="l00491"></a>00491 
<a name="l00492"></a>00492                                 <span class="comment">// Update mean: xv will have the updated pose until we update it in the filterState later.</span>
<a name="l00493"></a>00493                                 <span class="comment">//  This is to maintain a copy of the last robot pose in the state vector, required for the Jacobian computation.</span>
<a name="l00494"></a>00494                                 OnTransitionModel(u, xv, skipPrediction);
<a name="l00495"></a>00495 
<a name="l00496"></a>00496                                 <span class="keywordflow">if</span> ( !skipPrediction )
<a name="l00497"></a>00497                                 {
<a name="l00498"></a>00498                                         <span class="comment">// =============================================================</span>
<a name="l00499"></a>00499                                         <span class="comment">//  3. PREDICTION OF COVARIANCE P_{k+1|k}</span>
<a name="l00500"></a>00500                                         <span class="comment">// =============================================================</span>
<a name="l00501"></a>00501                                         <span class="comment">// First, we compute de Jacobian fv_by_xv  (derivative of f_vehicle wrt x_vehicle):</span>
<a name="l00502"></a>00502                                         <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_VxV</a>  dfv_dxv;
<a name="l00503"></a>00503 
<a name="l00504"></a>00504                                         <span class="comment">// Try closed-form Jacobian first:</span>
<a name="l00505"></a>00505                                         m_user_didnt_implement_jacobian=<span class="keyword">false</span>; <span class="comment">// Set to true by the default method if not reimplemented in base class.</span>
<a name="l00506"></a>00506                                         <span class="keywordflow">if</span> (KF_options.use_analytic_transition_jacobian)
<a name="l00507"></a>00507                                                 OnTransitionJacobian(dfv_dxv);
<a name="l00508"></a>00508 
<a name="l00509"></a>00509                                         <span class="keywordflow">if</span> (m_user_didnt_implement_jacobian || !KF_options.use_analytic_transition_jacobian || KF_options.debug_verify_analytic_jacobians)
<a name="l00510"></a>00510                                         {       <span class="comment">// Numeric approximation:</span>
<a name="l00511"></a>00511                                                 <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_VEH</a> xkk_vehicle( &amp;m_xkk[0] );  <span class="comment">// A copy of the vehicle part of the state vector.</span>
<a name="l00512"></a>00512                                                 <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_VEH</a> xkk_veh_increments;
<a name="l00513"></a>00513                                                 OnTransitionJacobianNumericGetIncrements(xkk_veh_increments);
<a name="l00514"></a>00514 
<a name="l00515"></a>00515                                                 <a class="code" href="group__container__ops__grp.html#ga13e2e339d944b37f2386fc4e0bb56935" title="Estimate the Jacobian of a multi-dimensional function around a point &quot;x&quot;, using finite differences of...">mrpt::math::estimateJacobian</a>(
<a name="l00516"></a>00516                                                         xkk_vehicle,
<a name="l00517"></a>00517                                                         &amp;KF_aux_estimate_trans_jacobian, <span class="comment">//(const VECTORLIKE &amp;x,const USERPARAM &amp;y, VECTORLIKE3  &amp;out),</span>
<a name="l00518"></a>00518                                                         xkk_veh_increments,
<a name="l00519"></a>00519                                                         std::make_pair&lt;KFCLASS*,KFArray_ACT&gt;(<span class="keyword">this</span>,u),
<a name="l00520"></a>00520                                                         dfv_dxv);
<a name="l00521"></a>00521 
<a name="l00522"></a>00522                                                 <span class="keywordflow">if</span> (KF_options.debug_verify_analytic_jacobians)
<a name="l00523"></a>00523                                                 {
<a name="l00524"></a>00524                                                         <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_VxV</a> dfv_dxv_gt(<a class="code" href="namespacemrpt_1_1math.html#a27e8ae8971ff5aa1c39f1f9be334d73aa28acc66160006cb691487ec89f8d266d">UNINITIALIZED_MATRIX</a>);
<a name="l00525"></a>00525                                                         OnTransitionJacobian(dfv_dxv_gt);
<a name="l00526"></a>00526                                                         <span class="keywordflow">if</span> ((dfv_dxv-dfv_dxv_gt).<a class="code" href="eigen__plugins_8h.html#a77d94451cb53e337e050fd77ba12f8ef">Abs</a>().<a class="code" href="eigen__plugins_8h.html#a8e317bb5dedefdd9f59f2894982981ea">sumAll</a>()&gt;KF_options.debug_verify_analytic_jacobians_threshold)
<a name="l00527"></a>00527                                                         {
<a name="l00528"></a>00528                                                                 std::cerr &lt;&lt; <span class="stringliteral">&quot;[KalmanFilter] ERROR: User analytical transition Jacobians are wrong: \n&quot;</span>
<a name="l00529"></a>00529                                                                         &lt;&lt; <span class="stringliteral">&quot; Real dfv_dxv: \n&quot;</span> &lt;&lt; dfv_dxv &lt;&lt; <span class="stringliteral">&quot;\n Analytical dfv_dxv:\n&quot;</span> &lt;&lt; dfv_dxv_gt &lt;&lt; <span class="stringliteral">&quot;Diff:\n&quot;</span> &lt;&lt; (dfv_dxv-dfv_dxv_gt) &lt;&lt; <span class="stringliteral">&quot;\n&quot;</span>;
<a name="l00530"></a>00530                                                                 <a class="code" href="mrpt__macros_8h.html#aaa3f404ea85a6575a7139f8d101370ba">THROW_EXCEPTION</a>(<span class="stringliteral">&quot;ERROR: User analytical transition Jacobians are wrong (More details dumped to cerr)&quot;</span>)
<a name="l00531"></a>00531                                                         }
<a name="l00532"></a>00532                                                 }
<a name="l00533"></a>00533 
<a name="l00534"></a>00534                                         }
<a name="l00535"></a>00535 
<a name="l00536"></a>00536                                         <span class="comment">// Q is the process noise covariance matrix, is associated to the robot movement and is necesary to calculate the prediction P(k+1|k)</span>
<a name="l00537"></a>00537                                         <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_VxV</a>  Q;
<a name="l00538"></a>00538                                         OnTransitionNoise(Q);
<a name="l00539"></a>00539 
<a name="l00540"></a>00540                                         <span class="comment">// ====================================</span>
<a name="l00541"></a>00541                                         <span class="comment">//  3.1:  Pxx submatrix</span>
<a name="l00542"></a>00542                                         <span class="comment">// ====================================</span>
<a name="l00543"></a>00543                                         <span class="comment">// Replace old covariance:</span>
<a name="l00544"></a>00544                                         m_pkk.block(0,0,VEH_SIZE,VEH_SIZE) =
<a name="l00545"></a>00545                                                 Q +
<a name="l00546"></a>00546                                                 dfv_dxv * m_pkk.block(0,0,VEH_SIZE,VEH_SIZE) * dfv_dxv.transpose();
<a name="l00547"></a>00547 
<a name="l00548"></a>00548                                         <span class="comment">// ====================================</span>
<a name="l00549"></a>00549                                         <span class="comment">//  3.2:  All Pxy_i</span>
<a name="l00550"></a>00550                                         <span class="comment">// ====================================</span>
<a name="l00551"></a>00551                                         <span class="comment">// Now, update the cov. of landmarks, if any:</span>
<a name="l00552"></a>00552                                         <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_VxF</a> aux;
<a name="l00553"></a>00553                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i=0 ; i&lt;N_map ; i++)
<a name="l00554"></a>00554                                         {
<a name="l00555"></a>00555                                                 <span class="comment">// aux = dfv_dxv(...) * m_pkk(...)</span>
<a name="l00556"></a>00556                                                 dfv_dxv.multiply_subMatrix(
<a name="l00557"></a>00557                                                         m_pkk,
<a name="l00558"></a>00558                                                         aux,  <span class="comment">// Output</span>
<a name="l00559"></a>00559                                                         VEH_SIZE+i*FEAT_SIZE,   <span class="comment">// Offset col</span>
<a name="l00560"></a>00560                                                         0,                                               <span class="comment">// Offset row</span>
<a name="l00561"></a>00561                                                         FEAT_SIZE                        <span class="comment">// Number of columns desired in output</span>
<a name="l00562"></a>00562                                                 );
<a name="l00563"></a>00563 
<a name="l00564"></a>00564                                                 m_pkk.insertMatrix         (0,                VEH_SIZE+i*FEAT_SIZE,  aux );
<a name="l00565"></a>00565                                                 m_pkk.insertMatrixTranspose(VEH_SIZE+i*FEAT_SIZE, 0               ,  aux );
<a name="l00566"></a>00566                                         }
<a name="l00567"></a>00567 
<a name="l00568"></a>00568                                         <span class="comment">// =============================================================</span>
<a name="l00569"></a>00569                                         <span class="comment">//  4. NOW WE CAN OVERWRITE THE NEW STATE VECTOR</span>
<a name="l00570"></a>00570                                         <span class="comment">// =============================================================</span>
<a name="l00571"></a>00571                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i=0;i&lt;VEH_SIZE;i++)
<a name="l00572"></a>00572                                                 m_xkk[i]=xv[i];
<a name="l00573"></a>00573 
<a name="l00574"></a>00574                                         <span class="comment">// Normalize, if neccesary.</span>
<a name="l00575"></a>00575                                         OnNormalizeStateVector();
<a name="l00576"></a>00576 
<a name="l00577"></a>00577                                 } <span class="comment">// end if (!skipPrediction)</span>
<a name="l00578"></a>00578 
<a name="l00579"></a>00579 
<a name="l00580"></a>00580                                 <span class="keyword">const</span> <span class="keywordtype">double</span> tim_pred = m_timLogger.leave(<span class="stringliteral">&quot;KF:2.prediction stage&quot;</span>);
<a name="l00581"></a>00581 
<a name="l00582"></a>00582 
<a name="l00583"></a>00583                                 <span class="comment">// =============================================================</span>
<a name="l00584"></a>00584                                 <span class="comment">//  5. PREDICTION OF OBSERVATIONS AND COMPUTE JACOBIANS</span>
<a name="l00585"></a>00585                                 <span class="comment">// =============================================================</span>
<a name="l00586"></a>00586                                 m_timLogger.enter(<span class="stringliteral">&quot;KF:3.predict all obs&quot;</span>);
<a name="l00587"></a>00587 
<a name="l00588"></a>00588                                 <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_OxO</a>  R;        <span class="comment">// Sensor uncertainty (covariance matrix): R</span>
<a name="l00589"></a>00589                                 OnGetObservationNoise(R);
<a name="l00590"></a>00590 
<a name="l00591"></a>00591                                 <span class="comment">// Predict the observations for all the map LMs, so the user</span>
<a name="l00592"></a>00592                                 <span class="comment">//  can decide if their covariances (more costly) must be computed as well:</span>
<a name="l00593"></a>00593                                 all_predictions.resize(N_map);
<a name="l00594"></a>00594                                 OnObservationModel(
<a name="l00595"></a>00595                                         mrpt::math::sequenceStdVec&lt;size_t,1&gt;(0,N_map),
<a name="l00596"></a>00596                                         all_predictions);
<a name="l00597"></a>00597 
<a name="l00598"></a>00598                                 <span class="keyword">const</span> <span class="keywordtype">double</span> tim_pred_obs = m_timLogger.leave(<span class="stringliteral">&quot;KF:3.predict all obs&quot;</span>);
<a name="l00599"></a>00599 
<a name="l00600"></a>00600                                 m_timLogger.enter(<span class="stringliteral">&quot;KF:4.decide pred obs&quot;</span>);
<a name="l00601"></a>00601 
<a name="l00602"></a>00602                                 <span class="comment">// Decide if some of the covariances shouldn&#39;t be predicted.</span>
<a name="l00603"></a>00603                                 predictLMidxs.clear();
<a name="l00604"></a>00604                                 <span class="keywordflow">if</span> (FEAT_SIZE==0)
<a name="l00605"></a>00605                                         <span class="comment">// In non-SLAM problems, just do one prediction, for the entire system state:</span>
<a name="l00606"></a>00606                                         predictLMidxs.assign(1,0);
<a name="l00607"></a>00607                                 <span class="keywordflow">else</span>
<a name="l00608"></a>00608                                         <span class="comment">// On normal SLAM problems:</span>
<a name="l00609"></a>00609                                         OnPreComputingPredictions(all_predictions, predictLMidxs);
<a name="l00610"></a>00610 
<a name="l00611"></a>00611 
<a name="l00612"></a>00612                                 m_timLogger.leave(<span class="stringliteral">&quot;KF:4.decide pred obs&quot;</span>);
<a name="l00613"></a>00613 
<a name="l00614"></a>00614                                 <span class="comment">// =============================================================</span>
<a name="l00615"></a>00615                                 <span class="comment">//  6. COMPUTE INNOVATION MATRIX &quot;S&quot;</span>
<a name="l00616"></a>00616                                 <span class="comment">// =============================================================</span>
<a name="l00617"></a>00617                                 <span class="comment">// Do the prediction of the observation covariances:</span>
<a name="l00618"></a>00618                                 <span class="comment">// Compute S:  S = H P ~H + R</span>
<a name="l00619"></a>00619                                 <span class="comment">//</span>
<a name="l00620"></a>00620                                 <span class="comment">// Build a big dh_dx Jacobian composed of the small block Jacobians.</span>
<a name="l00621"></a>00621                                 <span class="comment">// , but: it&#39;s actually a subset of the full Jacobian, since the non-predicted</span>
<a name="l00622"></a>00622                                 <span class="comment">//  features do not appear.</span>
<a name="l00623"></a>00623                                 <span class="comment">//</span>
<a name="l00624"></a>00624                                 <span class="comment">//  dh_dx: O·M x V+M·F</span>
<a name="l00625"></a>00625                                 <span class="comment">//      S: O·M x O·M</span>
<a name="l00626"></a>00626                                 <span class="comment">//  M = |predictLMidxs|</span>
<a name="l00627"></a>00627                                 <span class="comment">//  O=size of each observation.</span>
<a name="l00628"></a>00628                                 <span class="comment">//  F=size of features in the map</span>
<a name="l00629"></a>00629                                 <span class="comment">//</span>
<a name="l00630"></a>00630 
<a name="l00631"></a>00631                                 <span class="comment">// This is the beginning of a loop if we are doing sequential</span>
<a name="l00632"></a>00632                                 <span class="comment">//  data association, where after each incorporation of an observation</span>
<a name="l00633"></a>00633                                 <span class="comment">//  into the filter we recompute the vehicle state, then reconsider the</span>
<a name="l00634"></a>00634                                 <span class="comment">//  data associations:</span>
<a name="l00635"></a>00635                                 <span class="comment">// TKFFusionMethod fusion_strategy</span>
<a name="l00636"></a>00636 
<a name="l00637"></a>00637 
<a name="l00638"></a>00638                                 m_timLogger.enter(<span class="stringliteral">&quot;KF:5.build Jacobians&quot;</span>);
<a name="l00639"></a>00639 
<a name="l00640"></a>00640                                 <span class="keywordtype">size_t</span> N_pred = FEAT_SIZE==0 ?
<a name="l00641"></a>00641                                         1 <span class="comment">/* In non-SLAM problems, there&#39;ll be only 1 fixed observation */</span> :
<a name="l00642"></a>00642                                         predictLMidxs.size();
<a name="l00643"></a>00643 
<a name="l00644"></a>00644                                 <a class="code" href="classstd_1_1vector.html" title="STL class.">vector_int</a>  data_association;  <span class="comment">// -1: New map feature.&gt;=0: Indexes in the state vector</span>
<a name="l00645"></a>00645 
<a name="l00646"></a>00646                                 <span class="comment">// The next loop will only do more than one iteration if the heuristic in OnPreComputingPredictions() fails, </span>
<a name="l00647"></a>00647                                 <span class="comment">//  which will be detected by the addition of extra landmarks to predict into &quot;missing_predictions_to_add&quot;</span>
<a name="l00648"></a>00648                                 std<a class="code" href="classstd_1_1vector.html">::vector&lt;size_t&gt;</a> missing_predictions_to_add;
<a name="l00649"></a>00649 
<a name="l00650"></a>00650                                 <span class="comment">// Indices in xkk (&amp; Pkk) that are involved in this observation (used below).</span>
<a name="l00651"></a>00651                                 idxs.clear();
<a name="l00652"></a>00652                                 idxs.reserve(VEH_SIZE+N_pred*FEAT_SIZE);
<a name="l00653"></a>00653                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i=0;i&lt;VEH_SIZE;i++) idxs.push_back(i);
<a name="l00654"></a>00654 
<a name="l00655"></a>00655                                 dh_dx.zeros(N_pred*OBS_SIZE, VEH_SIZE + FEAT_SIZE * N_pred ); <span class="comment">// Init to zeros.</span>
<a name="l00656"></a>00656                                 dh_dx_full.zeros(N_pred*OBS_SIZE, VEH_SIZE + FEAT_SIZE * N_map ); <span class="comment">// Init to zeros.</span>
<a name="l00657"></a>00657 
<a name="l00658"></a>00658                                 <span class="keywordtype">size_t</span> first_new_pred = 0; <span class="comment">// This will be &gt;0 only if we perform multiple loops due to failures in the prediction heuristic.</span>
<a name="l00659"></a>00659 
<a name="l00660"></a>00660                                 <span class="keywordflow">do</span>  
<a name="l00661"></a>00661                                 {
<a name="l00662"></a>00662                                         <span class="keywordflow">if</span> (!missing_predictions_to_add.empty())
<a name="l00663"></a>00663                                         {
<a name="l00664"></a>00664                                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> nNew = missing_predictions_to_add.size();
<a name="l00665"></a>00665                                                 printf_debug(<span class="stringliteral">&quot;[KF] *Performance Warning*: %u LMs were not correctly predicted by OnPreComputingPredictions()\n&quot;</span>,static_cast&lt;unsigned int&gt;(nNew));
<a name="l00666"></a>00666 
<a name="l00667"></a>00667                                                 <a class="code" href="mrpt__macros_8h.html#a5ad4d8d68e2f6664f247407bf89aac55" title="Defines an assertion mechanism - only when compiled in debug.">ASSERTDEB_</a>(FEAT_SIZE!=0)
<a name="l00668"></a>00668                                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> j=0;j&lt;nNew;j++)
<a name="l00669"></a>00669                                                         predictLMidxs.push_back( missing_predictions_to_add[j] );
<a name="l00670"></a>00670 
<a name="l00671"></a>00671                                                 N_pred = predictLMidxs.size();
<a name="l00672"></a>00672                                                 missing_predictions_to_add.clear();
<a name="l00673"></a>00673                                         }
<a name="l00674"></a>00674 
<a name="l00675"></a>00675                                         dh_dx.setSize(N_pred*OBS_SIZE, VEH_SIZE + FEAT_SIZE * N_pred ); <span class="comment">// Pad with zeros.</span>
<a name="l00676"></a>00676                                         dh_dx_full.setSize(N_pred*OBS_SIZE, VEH_SIZE + FEAT_SIZE * N_map ); <span class="comment">// Pad with zeros.</span>
<a name="l00677"></a>00677 
<a name="l00678"></a>00678                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i=first_new_pred;i&lt;N_pred;++i)
<a name="l00679"></a>00679                                         {
<a name="l00680"></a>00680                                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> lm_idx = FEAT_SIZE==0 ? 0 : predictLMidxs[i];
<a name="l00681"></a>00681                                                 <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_OxV</a> Hx(<a class="code" href="namespacemrpt_1_1math.html#a27e8ae8971ff5aa1c39f1f9be334d73aa28acc66160006cb691487ec89f8d266d">UNINITIALIZED_MATRIX</a>);
<a name="l00682"></a>00682                                                 <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_OxF</a> Hy(<a class="code" href="namespacemrpt_1_1math.html#a27e8ae8971ff5aa1c39f1f9be334d73aa28acc66160006cb691487ec89f8d266d">UNINITIALIZED_MATRIX</a>);
<a name="l00683"></a>00683 
<a name="l00684"></a>00684                                                 <span class="comment">// Try the analitic Jacobian first:</span>
<a name="l00685"></a>00685                                                 m_user_didnt_implement_jacobian=<span class="keyword">false</span>; <span class="comment">// Set to true by the default method if not reimplemented in base class.</span>
<a name="l00686"></a>00686                                                 <span class="keywordflow">if</span> (KF_options.use_analytic_observation_jacobian)
<a name="l00687"></a>00687                                                         OnObservationJacobians(lm_idx,Hx,Hy);
<a name="l00688"></a>00688 
<a name="l00689"></a>00689                                                 <span class="keywordflow">if</span> (m_user_didnt_implement_jacobian || !KF_options.use_analytic_observation_jacobian || KF_options.debug_verify_analytic_jacobians)
<a name="l00690"></a>00690                                                 {       <span class="comment">// Numeric approximation:</span>
<a name="l00691"></a>00691                                                         <span class="keyword">const</span> <span class="keywordtype">size_t</span> lm_idx_in_statevector = VEH_SIZE+lm_idx*FEAT_SIZE;
<a name="l00692"></a>00692 
<a name="l00693"></a>00693                                                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_VEH</a>  x_vehicle( &amp;m_xkk[0] );
<a name="l00694"></a>00694                                                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_FEAT</a> x_feat( &amp;m_xkk[lm_idx_in_statevector] );
<a name="l00695"></a>00695 
<a name="l00696"></a>00696                                                         <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_VEH</a>  xkk_veh_increments;
<a name="l00697"></a>00697                                                         <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_FEAT</a> feat_increments;
<a name="l00698"></a>00698                                                         OnObservationJacobiansNumericGetIncrements(xkk_veh_increments, feat_increments);
<a name="l00699"></a>00699 
<a name="l00700"></a>00700                                                         <a class="code" href="group__container__ops__grp.html#ga13e2e339d944b37f2386fc4e0bb56935" title="Estimate the Jacobian of a multi-dimensional function around a point &quot;x&quot;, using finite differences of...">mrpt::math::estimateJacobian</a>(
<a name="l00701"></a>00701                                                                 x_vehicle,
<a name="l00702"></a>00702                                                                 &amp;KF_aux_estimate_obs_Hx_jacobian,
<a name="l00703"></a>00703                                                                 xkk_veh_increments,
<a name="l00704"></a>00704                                                                 std::make_pair&lt;KFCLASS*,size_t&gt;(<span class="keyword">this</span>,lm_idx),
<a name="l00705"></a>00705                                                                 Hx);
<a name="l00706"></a>00706                                                         <span class="comment">// The state vector was temporarily modified by KF_aux_estimate_*, restore it:</span>
<a name="l00707"></a>00707                                                         <a class="code" href="group__mrpt__system__os.html#gae1184cfb1f617787dc4c9da98becbe3a" title="An OS and compiler independent version of &quot;memcpy&quot;.">::memcpy</a>(&amp;m_xkk[0],&amp;x_vehicle[0],<span class="keyword">sizeof</span>(m_xkk[0])*VEH_SIZE);
<a name="l00708"></a>00708 
<a name="l00709"></a>00709                                                         <a class="code" href="group__container__ops__grp.html#ga13e2e339d944b37f2386fc4e0bb56935" title="Estimate the Jacobian of a multi-dimensional function around a point &quot;x&quot;, using finite differences of...">mrpt::math::estimateJacobian</a>(
<a name="l00710"></a>00710                                                                 x_feat,
<a name="l00711"></a>00711                                                                 &amp;KF_aux_estimate_obs_Hy_jacobian,
<a name="l00712"></a>00712                                                                 feat_increments,
<a name="l00713"></a>00713                                                                 std::make_pair&lt;KFCLASS*,size_t&gt;(<span class="keyword">this</span>,lm_idx),
<a name="l00714"></a>00714                                                                 Hy);
<a name="l00715"></a>00715                                                         <span class="comment">// The state vector was temporarily modified by KF_aux_estimate_*, restore it:</span>
<a name="l00716"></a>00716                                                         <a class="code" href="group__mrpt__system__os.html#gae1184cfb1f617787dc4c9da98becbe3a" title="An OS and compiler independent version of &quot;memcpy&quot;.">::memcpy</a>(&amp;m_xkk[lm_idx_in_statevector],&amp;x_feat[0],<span class="keyword">sizeof</span>(m_xkk[0])*FEAT_SIZE);
<a name="l00717"></a>00717 
<a name="l00718"></a>00718                                                         <span class="keywordflow">if</span> (KF_options.debug_verify_analytic_jacobians)
<a name="l00719"></a>00719                                                         {
<a name="l00720"></a>00720                                                                 <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_OxV</a> Hx_gt(<a class="code" href="namespacemrpt_1_1math.html#a27e8ae8971ff5aa1c39f1f9be334d73aa28acc66160006cb691487ec89f8d266d">UNINITIALIZED_MATRIX</a>);
<a name="l00721"></a>00721                                                                 <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_OxF</a> Hy_gt(<a class="code" href="namespacemrpt_1_1math.html#a27e8ae8971ff5aa1c39f1f9be334d73aa28acc66160006cb691487ec89f8d266d">UNINITIALIZED_MATRIX</a>);
<a name="l00722"></a>00722                                                                 OnObservationJacobians(lm_idx,Hx_gt,Hy_gt);
<a name="l00723"></a>00723                                                                 <span class="keywordflow">if</span> ((Hx-Hx_gt).<a class="code" href="eigen__plugins_8h.html#a77d94451cb53e337e050fd77ba12f8ef">Abs</a>().<a class="code" href="eigen__plugins_8h.html#a8e317bb5dedefdd9f59f2894982981ea">sumAll</a>()&gt;KF_options.debug_verify_analytic_jacobians_threshold) {
<a name="l00724"></a>00724                                                                         std::cerr &lt;&lt; <span class="stringliteral">&quot;[KalmanFilter] ERROR: User analytical observation Hx Jacobians are wrong: \n&quot;</span>
<a name="l00725"></a>00725                                                                                 &lt;&lt; <span class="stringliteral">&quot; Real Hx: \n&quot;</span> &lt;&lt; Hx &lt;&lt; <span class="stringliteral">&quot;\n Analytical Hx:\n&quot;</span> &lt;&lt; Hx_gt &lt;&lt; <span class="stringliteral">&quot;Diff:\n&quot;</span> &lt;&lt; Hx-Hx_gt &lt;&lt; <span class="stringliteral">&quot;\n&quot;</span>;
<a name="l00726"></a>00726                                                                         <a class="code" href="mrpt__macros_8h.html#aaa3f404ea85a6575a7139f8d101370ba">THROW_EXCEPTION</a>(<span class="stringliteral">&quot;ERROR: User analytical observation Hx Jacobians are wrong (More details dumped to cerr)&quot;</span>)
<a name="l00727"></a>00727                                                                 }
<a name="l00728"></a>00728                                                                 <span class="keywordflow">if</span> ((Hy-Hy_gt).<a class="code" href="eigen__plugins_8h.html#a77d94451cb53e337e050fd77ba12f8ef">Abs</a>().<a class="code" href="eigen__plugins_8h.html#a8e317bb5dedefdd9f59f2894982981ea">sumAll</a>()&gt;KF_options.debug_verify_analytic_jacobians_threshold) {
<a name="l00729"></a>00729                                                                         std::cerr &lt;&lt; <span class="stringliteral">&quot;[KalmanFilter] ERROR: User analytical observation Hy Jacobians are wrong: \n&quot;</span>
<a name="l00730"></a>00730                                                                                 &lt;&lt; <span class="stringliteral">&quot; Real Hy: \n&quot;</span> &lt;&lt; Hy &lt;&lt; <span class="stringliteral">&quot;\n Analytical Hx:\n&quot;</span> &lt;&lt; Hy_gt &lt;&lt; <span class="stringliteral">&quot;Diff:\n&quot;</span> &lt;&lt; Hy-Hy_gt &lt;&lt; <span class="stringliteral">&quot;\n&quot;</span>;
<a name="l00731"></a>00731                                                                         <a class="code" href="mrpt__macros_8h.html#aaa3f404ea85a6575a7139f8d101370ba">THROW_EXCEPTION</a>(<span class="stringliteral">&quot;ERROR: User analytical observation Hy Jacobians are wrong (More details dumped to cerr)&quot;</span>)
<a name="l00732"></a>00732                                                                 }
<a name="l00733"></a>00733                                                         }
<a name="l00734"></a>00734                                                 }
<a name="l00735"></a>00735 
<a name="l00736"></a>00736                                                 dh_dx.insertMatrix(i*OBS_SIZE,0, Hx);
<a name="l00737"></a>00737                                                 <span class="keywordflow">if</span> (FEAT_SIZE!=0)
<a name="l00738"></a>00738                                                         dh_dx.insertMatrix(i*OBS_SIZE,VEH_SIZE+i*FEAT_SIZE, Hy);
<a name="l00739"></a>00739 
<a name="l00740"></a>00740                                                 dh_dx_full.insertMatrix(i*OBS_SIZE,0, Hx);
<a name="l00741"></a>00741                                                 <span class="keywordflow">if</span> (FEAT_SIZE!=0)
<a name="l00742"></a>00742                                                 {
<a name="l00743"></a>00743                                                         dh_dx_full.insertMatrix(i*OBS_SIZE,VEH_SIZE+lm_idx*FEAT_SIZE, Hy);
<a name="l00744"></a>00744 
<a name="l00745"></a>00745                                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> k=0;k&lt;FEAT_SIZE;k++)
<a name="l00746"></a>00746                                                                 idxs.push_back(k+VEH_SIZE+FEAT_SIZE*lm_idx);
<a name="l00747"></a>00747                                                 }
<a name="l00748"></a>00748                                         }
<a name="l00749"></a>00749                                         m_timLogger.leave(<span class="stringliteral">&quot;KF:5.build Jacobians&quot;</span>);
<a name="l00750"></a>00750 
<a name="l00751"></a>00751                                         <span class="comment">// Compute S:  S = H P ~H + R</span>
<a name="l00752"></a>00752                                         <span class="comment">// *TODO*: This can be accelerated by exploiting the sparsity of dh_dx!!!</span>
<a name="l00753"></a>00753                                         <span class="comment">// ------------------------------------</span>
<a name="l00754"></a>00754                                         m_timLogger.enter(<span class="stringliteral">&quot;KF:6.build S&quot;</span>);
<a name="l00755"></a>00755 
<a name="l00756"></a>00756                                         S.setSize(N_pred*OBS_SIZE,N_pred*OBS_SIZE);
<a name="l00757"></a>00757 
<a name="l00758"></a>00758                                         <span class="comment">// (TODO: Implement multiply_HCHt for a subset of COV directly.)</span>
<a name="l00759"></a>00759                                         <span class="comment">// Extract the subset of m_Pkk that is involved in this observation:</span>
<a name="l00760"></a>00760                                         m_pkk.extractSubmatrixSymmetrical(idxs,Pkk_subset);
<a name="l00761"></a>00761 
<a name="l00762"></a>00762                                         <span class="comment">// S = dh_dx * m_pkk(subset) * (~dh_dx);</span>
<a name="l00763"></a>00763                                         dh_dx.multiply_HCHt(Pkk_subset,S);
<a name="l00764"></a>00764 
<a name="l00765"></a>00765                                         <span class="comment">// Sum the &quot;R&quot; term:</span>
<a name="l00766"></a>00766                                         <span class="keywordflow">if</span> ( FEAT_SIZE&gt;0 )
<a name="l00767"></a>00767                                         {
<a name="l00768"></a>00768                                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i=0;i&lt;N_pred;++i)
<a name="l00769"></a>00769                                                 {
<a name="l00770"></a>00770                                                         <span class="keyword">const</span> <span class="keywordtype">size_t</span> obs_idx_off = i*OBS_SIZE;
<a name="l00771"></a>00771                                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> j=0;j&lt;OBS_SIZE;j++)
<a name="l00772"></a>00772                                                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> k=0;k&lt;OBS_SIZE;k++)
<a name="l00773"></a>00773                                                                         S.get_unsafe(obs_idx_off+j,obs_idx_off+k) += R.get_unsafe(j,k);
<a name="l00774"></a>00774                                                 }
<a name="l00775"></a>00775                                         }
<a name="l00776"></a>00776                                         <span class="keywordflow">else</span>
<a name="l00777"></a>00777                                         {       <span class="comment">// Not a SLAM-like EKF problem:</span>
<a name="l00778"></a>00778                                                 <a class="code" href="mrpt__macros_8h.html#a5ad4d8d68e2f6664f247407bf89aac55" title="Defines an assertion mechanism - only when compiled in debug.">ASSERTDEB_</a>(S.getColCount() == OBS_SIZE );
<a name="l00779"></a>00779                                                 S+=R;
<a name="l00780"></a>00780                                         }
<a name="l00781"></a>00781 
<a name="l00782"></a>00782                                         m_timLogger.leave(<span class="stringliteral">&quot;KF:6.build S&quot;</span>);
<a name="l00783"></a>00783 
<a name="l00784"></a>00784 
<a name="l00785"></a>00785                                         Z.clear();      <span class="comment">// Each entry is one observation:</span>
<a name="l00786"></a>00786 
<a name="l00787"></a>00787                                         m_timLogger.enter(<span class="stringliteral">&quot;KF:7.get obs &amp; DA&quot;</span>);
<a name="l00788"></a>00788 
<a name="l00789"></a>00789                                         <span class="comment">// Get observations and do data-association:</span>
<a name="l00790"></a>00790                                         OnGetObservationsAndDataAssociation(
<a name="l00791"></a>00791                                                 Z, data_association, <span class="comment">// Out</span>
<a name="l00792"></a>00792                                                 all_predictions, S, predictLMidxs, R  <span class="comment">// In</span>
<a name="l00793"></a>00793                                                 );
<a name="l00794"></a>00794                                         <a class="code" href="mrpt__macros_8h.html#a5ad4d8d68e2f6664f247407bf89aac55" title="Defines an assertion mechanism - only when compiled in debug.">ASSERTDEB_</a>(data_association.size()==Z.size() || (data_association.empty() &amp;&amp; FEAT_SIZE==0));
<a name="l00795"></a>00795 
<a name="l00796"></a>00796                                         <span class="comment">// Check if an observation hasn&#39;t been predicted in OnPreComputingPredictions() but has been actually </span>
<a name="l00797"></a>00797                                         <span class="comment">//  observed. This may imply an error in the heuristic of OnPreComputingPredictions(), and forces us</span>
<a name="l00798"></a>00798                                         <span class="comment">//  to rebuild the matrices </span>
<a name="l00799"></a>00799                                         missing_predictions_to_add.clear();
<a name="l00800"></a>00800                                         <span class="keywordflow">if</span> (FEAT_SIZE!=0)
<a name="l00801"></a>00801                                         {
<a name="l00802"></a>00802                                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i=0;i&lt;data_association.size();++i)
<a name="l00803"></a>00803                                                 {
<a name="l00804"></a>00804                                                         <span class="keywordflow">if</span> (data_association[i]&lt;0) <span class="keywordflow">continue</span>;
<a name="l00805"></a>00805                                                         <span class="keyword">const</span> <span class="keywordtype">size_t</span> assoc_idx_in_map = <span class="keyword">static_cast&lt;</span><span class="keywordtype">size_t</span><span class="keyword">&gt;</span>(data_association[i]);
<a name="l00806"></a>00806                                                         <span class="keyword">const</span> <span class="keywordtype">size_t</span> assoc_idx_in_pred = <a class="code" href="group__stlext__grp.html#ga0683c85522dd9009f2c2801c18e12eae" title="Returns the index of the value &quot;T&quot; in the container &quot;vect&quot; (std::vector,std::deque,etc), or string::npos if not found.">mrpt::utils::find_in_vector</a>(assoc_idx_in_map, predictLMidxs);
<a name="l00807"></a>00807                                                         <span class="keywordflow">if</span> (assoc_idx_in_pred==std::string::npos)
<a name="l00808"></a>00808                                                                 missing_predictions_to_add.push_back(assoc_idx_in_map);
<a name="l00809"></a>00809                                                 }
<a name="l00810"></a>00810                                         }
<a name="l00811"></a>00811 
<a name="l00812"></a>00812                                         first_new_pred = N_pred;  <span class="comment">// If we do another loop, start at the begin of new predictions</span>
<a name="l00813"></a>00813 
<a name="l00814"></a>00814                                 } <span class="keywordflow">while</span> (!missing_predictions_to_add.empty());
<a name="l00815"></a>00815 
<a name="l00816"></a>00816 
<a name="l00817"></a>00817                                 <span class="keyword">const</span> <span class="keywordtype">double</span> tim_obs_DA = m_timLogger.leave(<span class="stringliteral">&quot;KF:7.get obs &amp; DA&quot;</span>);
<a name="l00818"></a>00818 
<a name="l00819"></a>00819                                 <span class="comment">// =============================================================</span>
<a name="l00820"></a>00820                                 <span class="comment">//  7. UPDATE USING THE KALMAN GAIN</span>
<a name="l00821"></a>00821                                 <span class="comment">// =============================================================</span>
<a name="l00822"></a>00822                                 <span class="comment">// Update, only if there are observations!</span>
<a name="l00823"></a>00823                                 <span class="keywordflow">if</span> ( !Z.empty() )
<a name="l00824"></a>00824                                 {
<a name="l00825"></a>00825                                         m_timLogger.enter(<span class="stringliteral">&quot;KF:8.update stage&quot;</span>);
<a name="l00826"></a>00826 
<a name="l00827"></a>00827                                         <span class="keywordflow">switch</span> (KF_options.method)
<a name="l00828"></a>00828                                         {
<a name="l00829"></a>00829                                                 <span class="comment">// -----------------------</span>
<a name="l00830"></a>00830                                                 <span class="comment">//  FULL KF- METHOD</span>
<a name="l00831"></a>00831                                                 <span class="comment">// -----------------------</span>
<a name="l00832"></a>00832                                         <span class="keywordflow">case</span> <a class="code" href="group__mrpt__bayes__grp.html#gga93ff73c3a01619f01d97fd80dff40d14a5ad91d60187b5cca61d25994f7827dc0">kfEKFNaive</a>:
<a name="l00833"></a>00833                                         <span class="keywordflow">case</span> <a class="code" href="group__mrpt__bayes__grp.html#gga93ff73c3a01619f01d97fd80dff40d14ac5aee4885e69b59edf793342e96acab3">kfIKFFull</a>:
<a name="l00834"></a>00834                                         {
<a name="l00835"></a>00835                                                 <span class="comment">// Build the whole Jacobian dh_dx matrix</span>
<a name="l00836"></a>00836                                                 <span class="comment">// ---------------------------------------------</span>
<a name="l00837"></a>00837                                                 <span class="comment">// Keep only those whose DA is not -1</span>
<a name="l00838"></a>00838                                                 <a class="code" href="classstd_1_1vector.html" title="STL class.">vector_int</a>  mapIndicesForKFUpdate(data_association.size());
<a name="l00839"></a>00839                                                 mapIndicesForKFUpdate.resize( <a class="code" href="group__geometry__grp.html#ga8c0a76e906f12560cfa49fcd269c8398" title="Gets the distance between two points in a 2D space.">std::distance</a>(mapIndicesForKFUpdate.begin(),
<a name="l00840"></a>00840                                                         std::remove_copy_if(
<a name="l00841"></a>00841                                                                 data_association.begin(),
<a name="l00842"></a>00842                                                                 data_association.end(),
<a name="l00843"></a>00843                                                                 mapIndicesForKFUpdate.begin(),
<a name="l00844"></a>00844                                                                 binder1st&lt;equal_to&lt;int&gt; &gt;(equal_to&lt;int&gt;(),-1) ) ) );
<a name="l00845"></a>00845 
<a name="l00846"></a>00846                                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> N_upd = (FEAT_SIZE==0) ?
<a name="l00847"></a>00847                                                         1 :     <span class="comment">// Non-SLAM problems: Just one observation for the entire system.</span>
<a name="l00848"></a>00848                                                         mapIndicesForKFUpdate.size(); <span class="comment">// SLAM: # of observed known landmarks</span>
<a name="l00849"></a>00849 
<a name="l00850"></a>00850                                                 <span class="comment">// Just one, or several update iterations??</span>
<a name="l00851"></a>00851                                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> nKF_iterations = (KF_options.method==<a class="code" href="group__mrpt__bayes__grp.html#gga93ff73c3a01619f01d97fd80dff40d14a5ad91d60187b5cca61d25994f7827dc0">kfEKFNaive</a>) ?  1 : KF_options.IKF_iterations;
<a name="l00852"></a>00852 
<a name="l00853"></a>00853                                                 <span class="keyword">const</span> <a class="code" href="structmrpt_1_1dynamicsize__vector.html">KFVector</a> xkk_0 = m_xkk;
<a name="l00854"></a>00854 
<a name="l00855"></a>00855                                                 <span class="comment">// For each IKF iteration (or 1 for EKF)</span>
<a name="l00856"></a>00856                                                 if (N_upd&gt;0) <span class="comment">// Do not update if we have no observations!</span>
<a name="l00857"></a>00857                                                 {
<a name="l00858"></a>00858                                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> IKF_iteration=0;IKF_iteration&lt;nKF_iterations;IKF_iteration++)
<a name="l00859"></a>00859                                                         {
<a name="l00860"></a>00860                                                                 <span class="comment">// Compute ytilde = OBS - PREDICTION</span>
<a name="l00861"></a>00861                                                                 <a class="code" href="structmrpt_1_1dynamicsize__vector.html">KFVector</a>  ytilde(OBS_SIZE*N_upd);
<a name="l00862"></a>00862                                                                 <span class="keywordtype">size_t</span>    ytilde_idx = 0;
<a name="l00863"></a>00863 
<a name="l00864"></a>00864                                                                 <span class="comment">// TODO: Use a Matrix view of &quot;dh_dx_full&quot; instead of creating a copy into &quot;dh_dx_full_obs&quot;</span>
<a name="l00865"></a>00865                                                                 dh_dx_full_obs.zeros(N_upd*OBS_SIZE, VEH_SIZE + FEAT_SIZE * N_map ); <span class="comment">// Init to zeros.</span>
<a name="l00866"></a>00866                                                                 <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a> S_observed;    <span class="comment">// The KF &quot;S&quot; matrix: A re-ordered, subset, version of the prediction S:</span>
<a name="l00867"></a>00867 
<a name="l00868"></a>00868                                                                 <span class="keywordflow">if</span> (FEAT_SIZE!=0)
<a name="l00869"></a>00869                                                                 {       <span class="comment">// SLAM problems:</span>
<a name="l00870"></a>00870                                                                         <a class="code" href="classstd_1_1vector.html">vector_size_t</a> S_idxs;
<a name="l00871"></a>00871                                                                         S_idxs.reserve(OBS_SIZE*N_upd);
<a name="l00872"></a>00872 
<a name="l00873"></a>00873                                                                         <span class="keyword">const</span> <span class="keywordtype">size_t</span> row_len = VEH_SIZE + FEAT_SIZE * N_map;
<a name="l00874"></a>00874 
<a name="l00875"></a>00875                                                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i=0;i&lt;data_association.size();++i)
<a name="l00876"></a>00876                                                                         {
<a name="l00877"></a>00877                                                                                 <span class="keywordflow">if</span> (data_association[i]&lt;0) <span class="keywordflow">continue</span>;
<a name="l00878"></a>00878 
<a name="l00879"></a>00879                                                                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> assoc_idx_in_map = <span class="keyword">static_cast&lt;</span><span class="keywordtype">size_t</span><span class="keyword">&gt;</span>(data_association[i]);
<a name="l00880"></a>00880                                                                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> assoc_idx_in_pred = <a class="code" href="group__stlext__grp.html#ga0683c85522dd9009f2c2801c18e12eae" title="Returns the index of the value &quot;T&quot; in the container &quot;vect&quot; (std::vector,std::deque,etc), or string::npos if not found.">mrpt::utils::find_in_vector</a>(assoc_idx_in_map, predictLMidxs);
<a name="l00881"></a>00881                                                                                 <a class="code" href="mrpt__macros_8h.html#ad30ea0382c594c0e2efe88212e9352b0">ASSERTMSG_</a>(assoc_idx_in_pred!=string::npos, <span class="stringliteral">&quot;OnPreComputingPredictions() didn&#39;t recommend the prediction of a landmark which has been actually observed!&quot;</span>)
<a name="l00882"></a>00882                                                                                 <span class="comment">// TODO: In these cases, extend the prediction right now instead of launching an exception... or is this a bad idea??</span>
<a name="l00883"></a>00883 
<a name="l00884"></a>00884                                                                                 <span class="comment">// Build the subset dh_dx_full_obs:</span>
<a name="l00885"></a>00885                                                                                 dh_dx_full_obs.block(S_idxs.size()             ,0, OBS_SIZE, row_len)
<a name="l00886"></a>00886                                                                                 =
<a name="l00887"></a>00887                                                                                 dh_dx_full.block    (assoc_idx_in_pred*OBS_SIZE,0, OBS_SIZE, row_len);
<a name="l00888"></a>00888                                                                                 <span class="comment">// S_idxs.size() is used as counter for &quot;dh_dx_full_obs&quot;.</span>
<a name="l00889"></a>00889                                                                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> k=0;k&lt;OBS_SIZE;k++)
<a name="l00890"></a>00890                                                                                         S_idxs.push_back(assoc_idx_in_pred*OBS_SIZE+k);
<a name="l00891"></a>00891 
<a name="l00892"></a>00892                                                                                 <span class="comment">// ytilde_i = Z[i] - all_predictions[i]</span>
<a name="l00893"></a>00893                                                                                 <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_OBS</a> ytilde_i = Z[i];
<a name="l00894"></a>00894                                                                                 OnSubstractObservationVectors(ytilde_i,all_predictions[predictLMidxs[assoc_idx_in_pred]]);
<a name="l00895"></a>00895                                                                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> k=0;k&lt;OBS_SIZE;k++)
<a name="l00896"></a>00896                                                                                         ytilde[ytilde_idx++] = ytilde_i[k];
<a name="l00897"></a>00897                                                                         }
<a name="l00898"></a>00898                                                                         <span class="comment">// Extract the subset that is involved in this observation:</span>
<a name="l00899"></a>00899                                                                         S.extractSubmatrixSymmetrical(S_idxs,S_observed);
<a name="l00900"></a>00900                                                                 }
<a name="l00901"></a>00901                                                                 <span class="keywordflow">else</span>
<a name="l00902"></a>00902                                                                 {       <span class="comment">// Non-SLAM problems:</span>
<a name="l00903"></a>00903                                                                         <a class="code" href="mrpt__macros_8h.html#a47eb5a445c2bf3d9190396510ea9683e">ASSERT_</a>(Z.size()==1 &amp;&amp; all_predictions.size()==1)
<a name="l00904"></a>00904 
<a name="l00905"></a>00905                                                                         dh_dx_full_obs = dh_dx_full;
<a name="l00906"></a>00906                                                                         <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_OBS</a> ytilde_i = Z[0];
<a name="l00907"></a>00907                                                                         OnSubstractObservationVectors(ytilde_i,all_predictions[0]);
<a name="l00908"></a>00908                                                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> k=0;k&lt;OBS_SIZE;k++)
<a name="l00909"></a>00909                                                                                 ytilde[ytilde_idx++] = ytilde_i[k];
<a name="l00910"></a>00910                                                                         <span class="comment">// Extract the subset that is involved in this observation:</span>
<a name="l00911"></a>00911                                                                         S_observed = S;
<a name="l00912"></a>00912                                                                 }
<a name="l00913"></a>00913 
<a name="l00914"></a>00914                                                                 <span class="comment">// Compute the full K matrix:</span>
<a name="l00915"></a>00915                                                                 <span class="comment">// ------------------------------</span>
<a name="l00916"></a>00916                                                                 m_timLogger.enter(<span class="stringliteral">&quot;KF:8.update stage:1.FULLKF:build K&quot;</span>);
<a name="l00917"></a>00917 
<a name="l00918"></a>00918                                                                 K.setSize(m_pkk.getRowCount(), S_observed.getColCount() );
<a name="l00919"></a>00919 
<a name="l00920"></a>00920                                                                 <span class="comment">// K = m_pkk * (~dh_dx) * S.inv() );</span>
<a name="l00921"></a>00921                                                                 K.multiply_ABt(m_pkk, dh_dx_full_obs);
<a name="l00922"></a>00922 
<a name="l00923"></a>00923                                                                 <span class="comment">//KFMatrix S_1( S_observed.getRowCount(), S_observed.getColCount() );</span>
<a name="l00924"></a>00924                                                                 S_observed.inv(S_1); <span class="comment">// Do NOT call inv_fast since it destroys S</span>
<a name="l00925"></a>00925                                                                 K*=S_1;
<a name="l00926"></a>00926 
<a name="l00927"></a>00927                                                                 m_timLogger.leave(<span class="stringliteral">&quot;KF:8.update stage:1.FULLKF:build K&quot;</span>);
<a name="l00928"></a>00928 
<a name="l00929"></a>00929                                                                 <span class="comment">// Use the full K matrix to update the mean:</span>
<a name="l00930"></a>00930                                                                 <span class="keywordflow">if</span> (nKF_iterations==1)
<a name="l00931"></a>00931                                                                 {
<a name="l00932"></a>00932                                                                         m_timLogger.enter(<span class="stringliteral">&quot;KF:8.update stage:2.FULLKF:update xkk&quot;</span>);
<a name="l00933"></a>00933                                                                         m_xkk += K * ytilde;
<a name="l00934"></a>00934                                                                         m_timLogger.leave(<span class="stringliteral">&quot;KF:8.update stage:2.FULLKF:update xkk&quot;</span>);
<a name="l00935"></a>00935                                                                 }
<a name="l00936"></a>00936                                                                 <span class="keywordflow">else</span>
<a name="l00937"></a>00937                                                                 {
<a name="l00938"></a>00938                                                                         m_timLogger.enter(<span class="stringliteral">&quot;KF:8.update stage:2.FULLKF:iter.update xkk&quot;</span>);
<a name="l00939"></a>00939 
<a name="l00940"></a>00940                                                                         <a class="code" href="structmrpt_1_1dynamicsize__vector.html">KFVector</a>  HAx_column;
<a name="l00941"></a>00941                                                                         dh_dx_full_obs.multiply_Ab( m_xkk - xkk_0, HAx_column);
<a name="l00942"></a>00942 
<a name="l00943"></a>00943                                                                         m_xkk = xkk_0;
<a name="l00944"></a>00944                                                                         K.multiply_Ab(
<a name="l00945"></a>00945                                                                                 (ytilde-HAx_column),
<a name="l00946"></a>00946                                                                                 m_xkk,
<a name="l00947"></a>00947                                                                                 <span class="keyword">true</span> <span class="comment">/* Accumulate in output */</span>
<a name="l00948"></a>00948                                                                                 );
<a name="l00949"></a>00949 
<a name="l00950"></a>00950                                                                         m_timLogger.leave(<span class="stringliteral">&quot;KF:8.update stage:2.FULLKF:iter.update xkk&quot;</span>);
<a name="l00951"></a>00951                                                                 }
<a name="l00952"></a>00952 
<a name="l00953"></a>00953                                                                 <span class="comment">// Update the covariance just at the end</span>
<a name="l00954"></a>00954                                                                 <span class="comment">//  of iterations if we are in IKF, always in normal EKF.</span>
<a name="l00955"></a>00955                                                                 <span class="keywordflow">if</span> (IKF_iteration == (nKF_iterations-1) )
<a name="l00956"></a>00956                                                                 {
<a name="l00957"></a>00957                                                                         m_timLogger.enter(<span class="stringliteral">&quot;KF:8.update stage:3.FULLKF:update Pkk&quot;</span>);
<a name="l00958"></a>00958 
<a name="l00959"></a>00959                                                                         <span class="comment">// Use the full K matrix to update the covariance:</span>
<a name="l00960"></a>00960                                                                         <span class="comment">//m_pkk = (I - K*dh_dx ) * m_pkk;</span>
<a name="l00961"></a>00961                                                                         <span class="comment">// TODO: &quot;Optimize this: sparsity!&quot;</span>
<a name="l00962"></a>00962 
<a name="l00963"></a>00963                                                                         <span class="comment">// K * dh_dx_full</span>
<a name="l00964"></a>00964                                                                         aux_K_dh_dx.multiply(K,dh_dx_full_obs);
<a name="l00965"></a>00965 
<a name="l00966"></a>00966                                                                         <span class="comment">// aux_K_dh_dx  &lt;-- I-aux_K_dh_dx</span>
<a name="l00967"></a>00967                                                                         <span class="keyword">const</span> <span class="keywordtype">size_t</span> stat_len = aux_K_dh_dx.getColCount();
<a name="l00968"></a>00968                                                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> r=0;r&lt;stat_len;r++)
<a name="l00969"></a>00969                                                                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> c=0;c&lt;stat_len;c++)
<a name="l00970"></a>00970                                                                                         <span class="keywordflow">if</span> (r==c)
<a name="l00971"></a>00971                                                                                              aux_K_dh_dx.get_unsafe(r,c)=-aux_K_dh_dx.get_unsafe(r,c) + <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ad66228d2cc13705900669ccbab41f3d9" title="The numeric type used in the Kalman Filter (default=double)">kftype</a>(1);
<a name="l00972"></a>00972                                                                                         <span class="keywordflow">else</span> aux_K_dh_dx.get_unsafe(r,c)=-aux_K_dh_dx.get_unsafe(r,c);
<a name="l00973"></a>00973 
<a name="l00974"></a>00974                                                                         m_pkk.multiply_result_is_symmetric(aux_K_dh_dx, m_pkk );
<a name="l00975"></a>00975 
<a name="l00976"></a>00976                                                                         m_timLogger.leave(<span class="stringliteral">&quot;KF:8.update stage:3.FULLKF:update Pkk&quot;</span>);
<a name="l00977"></a>00977                                                                 }
<a name="l00978"></a>00978                                                         } <span class="comment">// end for each IKF iteration</span>
<a name="l00979"></a>00979                                                 }
<a name="l00980"></a>00980                                         }
<a name="l00981"></a>00981                                         <span class="keywordflow">break</span>;
<a name="l00982"></a>00982 
<a name="l00983"></a>00983                                         <span class="comment">// --------------------------------------------------------------------</span>
<a name="l00984"></a>00984                                         <span class="comment">// - EKF &#39;a la&#39; Davison: One observation element at once</span>
<a name="l00985"></a>00985                                         <span class="comment">// --------------------------------------------------------------------</span>
<a name="l00986"></a>00986                                         <span class="keywordflow">case</span> <a class="code" href="group__mrpt__bayes__grp.html#gga93ff73c3a01619f01d97fd80dff40d14acb25ab5d45035eb456de1c7250dbcf5a">kfEKFAlaDavison</a>:
<a name="l00987"></a>00987                                         {
<a name="l00988"></a>00988                                                 <span class="comment">// For each observed landmark/whole system state:</span>
<a name="l00989"></a>00989                                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> obsIdx=0;obsIdx&lt;Z.size();obsIdx++)
<a name="l00990"></a>00990                                                 {
<a name="l00991"></a>00991                                                         <span class="comment">// Known &amp; mapped landmark?</span>
<a name="l00992"></a>00992                                                         <span class="keywordtype">bool</span>   doit;
<a name="l00993"></a>00993                                                         <span class="keywordtype">size_t</span> idxInTheFilter=0;
<a name="l00994"></a>00994 
<a name="l00995"></a>00995                                                         <span class="keywordflow">if</span> (data_association.empty())
<a name="l00996"></a>00996                                                         {
<a name="l00997"></a>00997                                                                 doit = <span class="keyword">true</span>;
<a name="l00998"></a>00998                                                         }
<a name="l00999"></a>00999                                                         <span class="keywordflow">else</span>
<a name="l01000"></a>01000                                                         {
<a name="l01001"></a>01001                                                                 doit = data_association[obsIdx] &gt;= 0;
<a name="l01002"></a>01002                                                                 <span class="keywordflow">if</span> (doit)
<a name="l01003"></a>01003                                                                         idxInTheFilter = data_association[obsIdx];
<a name="l01004"></a>01004                                                         }
<a name="l01005"></a>01005 
<a name="l01006"></a>01006                                                         <span class="keywordflow">if</span> ( doit )
<a name="l01007"></a>01007                                                         {
<a name="l01008"></a>01008                                                                 m_timLogger.enter(<span class="stringliteral">&quot;KF:8.update stage:1.ScalarAtOnce.prepare&quot;</span>);
<a name="l01009"></a>01009 
<a name="l01010"></a>01010                                                                 <span class="comment">// Already mapped: OK</span>
<a name="l01011"></a>01011                                                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> idx_off = VEH_SIZE + idxInTheFilter*FEAT_SIZE; <span class="comment">// The offset in m_xkk &amp; Pkk.</span>
<a name="l01012"></a>01012 
<a name="l01013"></a>01013                                                                 <span class="comment">// Compute just the part of the Jacobian that we need using the current updated m_xkk:</span>
<a name="l01014"></a>01014                                                                 <a class="code" href="classstd_1_1vector.html" title="STL class.">vector_KFArray_OBS</a>  pred_obs;
<a name="l01015"></a>01015                                                                 OnObservationModel( <a class="code" href="namespacemrpt.html#ad4d2b1efd37ed750302c76ebbcfc310d">vector_size_t</a>(1,idxInTheFilter),pred_obs);
<a name="l01016"></a>01016                                                                 <a class="code" href="mrpt__macros_8h.html#a5ad4d8d68e2f6664f247407bf89aac55" title="Defines an assertion mechanism - only when compiled in debug.">ASSERTDEB_</a>(pred_obs.size()==1);
<a name="l01017"></a>01017 
<a name="l01018"></a>01018                                                                 <span class="comment">// ytilde = observation - prediction</span>
<a name="l01019"></a>01019                                                                 <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_OBS</a> ytilde = Z[obsIdx];
<a name="l01020"></a>01020                                                                 OnSubstractObservationVectors(ytilde, pred_obs[0]);
<a name="l01021"></a>01021 
<a name="l01022"></a>01022                                                                 <span class="comment">// Jacobians:</span>
<a name="l01023"></a>01023                                                                 <span class="comment">// dh_dx: already is (N_pred*OBS_SIZE) x (VEH_SIZE + FEAT_SIZE * N_pred )</span>
<a name="l01024"></a>01024                                                                 <span class="comment">//         with N_pred = |predictLMidxs|</span>
<a name="l01025"></a>01025 
<a name="l01026"></a>01026                                                                 <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_OxV</a> Hx(<a class="code" href="namespacemrpt_1_1math.html#a27e8ae8971ff5aa1c39f1f9be334d73aa28acc66160006cb691487ec89f8d266d">UNINITIALIZED_MATRIX</a>);
<a name="l01027"></a>01027                                                                 <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">KFMatrix_OxF</a> Hy(<a class="code" href="namespacemrpt_1_1math.html#a27e8ae8971ff5aa1c39f1f9be334d73aa28acc66160006cb691487ec89f8d266d">UNINITIALIZED_MATRIX</a>);
<a name="l01028"></a>01028                                                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> i_idx_in_preds = <a class="code" href="group__stlext__grp.html#ga0683c85522dd9009f2c2801c18e12eae" title="Returns the index of the value &quot;T&quot; in the container &quot;vect&quot; (std::vector,std::deque,etc), or string::npos if not found.">mrpt::utils::find_in_vector</a>(idxInTheFilter,predictLMidxs);
<a name="l01029"></a>01029                                                                 <a class="code" href="mrpt__macros_8h.html#ad30ea0382c594c0e2efe88212e9352b0">ASSERTMSG_</a>(i_idx_in_preds!=string::npos, <span class="stringliteral">&quot;OnPreComputingPredictions() didn&#39;t recommend the prediction of a landmark which has been actually observed!&quot;</span>)
<a name="l01030"></a>01030                                                                 dh_dx.extractMatrix(i_idx_in_preds*OBS_SIZE,0, Hx);
<a name="l01031"></a>01031                                                                 dh_dx.extractMatrix(i_idx_in_preds*OBS_SIZE,VEH_SIZE+i_idx_in_preds*OBS_SIZE, Hy);
<a name="l01032"></a>01032 
<a name="l01033"></a>01033 
<a name="l01034"></a>01034                                                                 m_timLogger.leave(<span class="stringliteral">&quot;KF:8.update stage:1.ScalarAtOnce.prepare&quot;</span>);
<a name="l01035"></a>01035 
<a name="l01036"></a>01036                                                                 <span class="comment">// For each component of the observation:</span>
<a name="l01037"></a>01037                                                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> j=0;j&lt;OBS_SIZE;j++)
<a name="l01038"></a>01038                                                                 {
<a name="l01039"></a>01039                                                                         m_timLogger.enter(<span class="stringliteral">&quot;KF:8.update stage:2.ScalarAtOnce.update&quot;</span>);
<a name="l01040"></a>01040 
<a name="l01041"></a>01041                                                                         <span class="comment">// Compute the scalar S_i for each component j of the observation:</span>
<a name="l01042"></a>01042                                                                         <span class="comment">// Sij = dhij_dxv Pxx dhij_dxv^t + 2 * dhij_dyi Pyix dhij_dxv + dhij_dyi Pyiyi dhij_dyi^t + R</span>
<a name="l01043"></a>01043                                                                         <span class="comment">//          ^^</span>
<a name="l01044"></a>01044                                                                         <span class="comment">//         Hx:(O*LxSv)</span>
<a name="l01045"></a>01045                                                                         <span class="comment">//       \----------------------/ \--------------------------/  \------------------------/ \-/</span>
<a name="l01046"></a>01046                                                                         <span class="comment">//               TERM 1                   TERM 2                        TERM 3              R</span>
<a name="l01047"></a>01047                                                                         <span class="comment">//</span>
<a name="l01048"></a>01048                                                                         <span class="comment">// O: Observation size (3)</span>
<a name="l01049"></a>01049                                                                         <span class="comment">// L: # landmarks</span>
<a name="l01050"></a>01050                                                                         <span class="comment">// Sv: Vehicle state size (6)</span>
<a name="l01051"></a>01051                                                                         <span class="comment">//</span>
<a name="l01052"></a>01052 
<a name="l01053"></a>01053 <span class="preprocessor">                #if defined(_DEBUG)</span>
<a name="l01054"></a>01054 <span class="preprocessor"></span>                                                                        {
<a name="l01055"></a>01055                                                                                 <span class="comment">// This algorithm is applicable only if the scalar component of the sensor noise are INDEPENDENT:</span>
<a name="l01056"></a>01056                                                                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> a=0;a&lt;OBS_SIZE;a++)
<a name="l01057"></a>01057                                                                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> b=0;b&lt;OBS_SIZE;b++)
<a name="l01058"></a>01058                                                                                                 <span class="keywordflow">if</span> ( a!=b )
<a name="l01059"></a>01059                                                                                                         <span class="keywordflow">if</span> (R(a,b)!=0)
<a name="l01060"></a>01060                                                                                                                 <a class="code" href="mrpt__macros_8h.html#aaa3f404ea85a6575a7139f8d101370ba">THROW_EXCEPTION</a>(<span class="stringliteral">&quot;This KF algorithm assumes independent noise components in the observation (matrix R). Select another KF algorithm.&quot;</span>)
<a name="l01061"></a>01061                                                                         }
<a name="l01062"></a>01062 <span class="preprocessor">                #endif</span>
<a name="l01063"></a>01063 <span class="preprocessor"></span>                                                                        <span class="comment">// R:</span>
<a name="l01064"></a>01064                                                                         KFTYPE Sij = R.get_unsafe(j,j);
<a name="l01065"></a>01065 
<a name="l01066"></a>01066                                                                         <span class="comment">// TERM 1:</span>
<a name="l01067"></a>01067                                                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> k=0;k&lt;VEH_SIZE;k++)
<a name="l01068"></a>01068                                                                         {
<a name="l01069"></a>01069                                                                                 KFTYPE accum = 0;
<a name="l01070"></a>01070                                                                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> q=0;q&lt;VEH_SIZE;q++)
<a name="l01071"></a>01071                                                                                         accum += Hx.get_unsafe(j,q) * m_pkk.get_unsafe(q,k);
<a name="l01072"></a>01072                                                                                 Sij+= Hx.get_unsafe(j,k) * accum;
<a name="l01073"></a>01073                                                                         }
<a name="l01074"></a>01074 
<a name="l01075"></a>01075                                                                         <span class="comment">// TERM 2:</span>
<a name="l01076"></a>01076                                                                         KFTYPE term2=0;
<a name="l01077"></a>01077                                                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> k=0;k&lt;VEH_SIZE;k++)
<a name="l01078"></a>01078                                                                         {
<a name="l01079"></a>01079                                                                                 KFTYPE accum = 0;
<a name="l01080"></a>01080                                                                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> q=0;q&lt;FEAT_SIZE;q++)
<a name="l01081"></a>01081                                                                                         accum += Hy.get_unsafe(j,q) * m_pkk.get_unsafe(idx_off+q,k);
<a name="l01082"></a>01082                                                                                 term2+= Hx.get_unsafe(j,k) * accum;
<a name="l01083"></a>01083                                                                         }
<a name="l01084"></a>01084                                                                         Sij += 2 * term2;
<a name="l01085"></a>01085 
<a name="l01086"></a>01086                                                                         <span class="comment">// TERM 3:</span>
<a name="l01087"></a>01087                                                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> k=0;k&lt;FEAT_SIZE;k++)
<a name="l01088"></a>01088                                                                         {
<a name="l01089"></a>01089                                                                                 KFTYPE accum = 0;
<a name="l01090"></a>01090                                                                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> q=0;q&lt;FEAT_SIZE;q++)
<a name="l01091"></a>01091                                                                                         accum += Hy.get_unsafe(j,q) * m_pkk.get_unsafe(idx_off+q,idx_off+k);
<a name="l01092"></a>01092                                                                                 Sij+= Hy.get_unsafe(j,k) * accum;
<a name="l01093"></a>01093                                                                         }
<a name="l01094"></a>01094 
<a name="l01095"></a>01095                                                                         <span class="comment">// Compute the Kalman gain &quot;Kij&quot; for this observation element:</span>
<a name="l01096"></a>01096                                                                         <span class="comment">// --&gt;  K = m_pkk * (~dh_dx) * S.inv() );</span>
<a name="l01097"></a>01097                                                                         <span class="keywordtype">size_t</span> N = m_pkk.getColCount();
<a name="l01098"></a>01098                                                                         <a class="code" href="classstd_1_1vector.html" title="STL class.">vector&lt;KFTYPE&gt;</a> Kij( N );
<a name="l01099"></a>01099 
<a name="l01100"></a>01100                                                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> k=0;k&lt;N;k++)
<a name="l01101"></a>01101                                                                         {
<a name="l01102"></a>01102                                                                                 KFTYPE K_tmp = 0;
<a name="l01103"></a>01103 
<a name="l01104"></a>01104                                                                                 <span class="comment">// dhi_dxv term</span>
<a name="l01105"></a>01105                                                                                 <span class="keywordtype">size_t</span> q;
<a name="l01106"></a>01106                                                                                 <span class="keywordflow">for</span> (q=0;q&lt;VEH_SIZE;q++)
<a name="l01107"></a>01107                                                                                         K_tmp+= m_pkk.get_unsafe(k,q) * Hx.get_unsafe(j,q);
<a name="l01108"></a>01108 
<a name="l01109"></a>01109                                                                                 <span class="comment">// dhi_dyi term</span>
<a name="l01110"></a>01110                                                                                 <span class="keywordflow">for</span> (q=0;q&lt;FEAT_SIZE;q++)
<a name="l01111"></a>01111                                                                                         K_tmp+= m_pkk.get_unsafe(k,idx_off+q) * Hy.get_unsafe(j,q);
<a name="l01112"></a>01112 
<a name="l01113"></a>01113                                                                                 Kij[k] = K_tmp / Sij;
<a name="l01114"></a>01114                                                                         } <span class="comment">// end for k</span>
<a name="l01115"></a>01115 
<a name="l01116"></a>01116 
<a name="l01117"></a>01117                                                                         <span class="comment">// Update the state vector m_xkk:</span>
<a name="l01118"></a>01118                                                                         <span class="comment">//  x&#39; = x + Kij * ytilde(ij)</span>
<a name="l01119"></a>01119                                                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> k=0;k&lt;N;k++)
<a name="l01120"></a>01120                                                                                 m_xkk[k] += Kij[k] * ytilde[j];
<a name="l01121"></a>01121 
<a name="l01122"></a>01122                                                                         <span class="comment">// Update the covariance Pkk:</span>
<a name="l01123"></a>01123                                                                         <span class="comment">// P&#39; =  P - Kij * Sij * Kij^t</span>
<a name="l01124"></a>01124                                                                         {
<a name="l01125"></a>01125                                                                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> k=0;k&lt;N;k++)
<a name="l01126"></a>01126                                                                                 {
<a name="l01127"></a>01127                                                                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> q=k;q&lt;N;q++)  <span class="comment">// Half matrix</span>
<a name="l01128"></a>01128                                                                                         {
<a name="l01129"></a>01129                                                                                                 m_pkk(k,q) -= Sij * Kij[k] * Kij[q];
<a name="l01130"></a>01130                                                                                                 <span class="comment">// It is symmetric</span>
<a name="l01131"></a>01131                                                                                                 m_pkk(q,k) = m_pkk(k,q);
<a name="l01132"></a>01132                                                                                         }
<a name="l01133"></a>01133 
<a name="l01134"></a>01134 <span class="preprocessor">                #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG)</span>
<a name="l01135"></a>01135 <span class="preprocessor"></span>                                                                                        <span class="keywordflow">if</span> (m_pkk(k,k)&lt;0)
<a name="l01136"></a>01136                                                                                         {
<a name="l01137"></a>01137                                                                                                 m_pkk.saveToTextFile(<span class="stringliteral">&quot;Pkk_err.txt&quot;</span>);
<a name="l01138"></a>01138                                                                                                 <a class="code" href="group__mrpt__system__os.html#ga2454cccef332c556b3efffc4d0ac24ef" title="A useful function for debuging, which saves a std::vector into a text file (compat.">mrpt::system::vectorToTextFile</a>(Kij,<span class="stringliteral">&quot;Kij.txt&quot;</span>);
<a name="l01139"></a>01139                                                                                                 <a class="code" href="mrpt__macros_8h.html#a47eb5a445c2bf3d9190396510ea9683e">ASSERT_</a>(m_pkk(k,k)&gt;0)
<a name="l01140"></a>01140                                                                                         }
<a name="l01141"></a>01141 <span class="preprocessor">                #endif</span>
<a name="l01142"></a>01142 <span class="preprocessor"></span>                                                                                }
<a name="l01143"></a>01143                                                                         }
<a name="l01144"></a>01144 
<a name="l01145"></a>01145 
<a name="l01146"></a>01146                                                                         m_timLogger.leave(<span class="stringliteral">&quot;KF:8.update stage:2.ScalarAtOnce.update&quot;</span>);
<a name="l01147"></a>01147                                                                 } <span class="comment">// end for j</span>
<a name="l01148"></a>01148                                                         } <span class="comment">// end if mapped</span>
<a name="l01149"></a>01149                                                 } <span class="comment">// end for each observed LM.</span>
<a name="l01150"></a>01150                                         }
<a name="l01151"></a>01151                                         <span class="keywordflow">break</span>;
<a name="l01152"></a>01152 
<a name="l01153"></a>01153                                         <span class="comment">// --------------------------------------------------------------------</span>
<a name="l01154"></a>01154                                         <span class="comment">// - IKF method, processing each observation scalar secuentially:</span>
<a name="l01155"></a>01155                                         <span class="comment">// --------------------------------------------------------------------</span>
<a name="l01156"></a>01156                                         <span class="keywordflow">case</span> <a class="code" href="group__mrpt__bayes__grp.html#gga93ff73c3a01619f01d97fd80dff40d14a0c3af1381c1d9b4b4ebb04370dc59ba9">kfIKF</a>:  <span class="comment">// TODO !!</span>
<a name="l01157"></a>01157                                         {
<a name="l01158"></a>01158                                                 <a class="code" href="mrpt__macros_8h.html#aaa3f404ea85a6575a7139f8d101370ba">THROW_EXCEPTION</a>(<span class="stringliteral">&quot;IKF scalar by scalar not implemented yet.&quot;</span>);
<a name="l01159"></a>01159 <span class="preprocessor">#if 0</span>
<a name="l01160"></a>01160 <span class="preprocessor"></span>                                                <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a> h,Hx,Hy;
<a name="l01161"></a>01161 
<a name="l01162"></a>01162                                                 <span class="comment">// Just one, or several update iterations??</span>
<a name="l01163"></a>01163                                                 <span class="keywordtype">size_t</span> nKF_iterations = KF_options.IKF_iterations;
<a name="l01164"></a>01164 
<a name="l01165"></a>01165                                                 <span class="comment">// To avoid wasting time, if we are doing 1 iteration only, do not reserve memory for this matrix:</span>
<a name="l01166"></a>01166                                                 <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a>                *saved_Pkk=NULL;
<a name="l01167"></a>01167                                                 <span class="keywordflow">if</span> (nKF_iterations&gt;1)
<a name="l01168"></a>01168                                                 {
<a name="l01169"></a>01169                                                         <span class="comment">// Create a copy of Pkk for later restoring it at the beginning of each iteration:</span>
<a name="l01170"></a>01170                                                         saved_Pkk = <span class="keyword">new</span> <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a>( m_pkk );
<a name="l01171"></a>01171                                                 }
<a name="l01172"></a>01172 
<a name="l01173"></a>01173                                                 <a class="code" href="structmrpt_1_1dynamicsize__vector.html">KFVector</a>        xkk_0 = m_xkk; <span class="comment">// First state vector at the beginning of IKF</span>
<a name="l01174"></a>01174                                                 <a class="code" href="structmrpt_1_1dynamicsize__vector.html">KFVector</a>        xkk_next_iter = m_xkk;  <span class="comment">// for IKF only</span>
<a name="l01175"></a>01175 
<a name="l01176"></a>01176                                                 <span class="comment">// For each IKF iteration (or 1 for EKF)</span>
<a name="l01177"></a>01177                                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> IKF_iteration=0;IKF_iteration&lt;nKF_iterations;IKF_iteration++)
<a name="l01178"></a>01178                                                 {
<a name="l01179"></a>01179                                                         <span class="comment">// Restore initial covariance matrix.</span>
<a name="l01180"></a>01180                                                         <span class="comment">// The updated mean is stored in m_xkk and is improved with each estimation,</span>
<a name="l01181"></a>01181                                                         <span class="comment">//  and so do the Jacobians which use that improving mean.</span>
<a name="l01182"></a>01182                                                         <span class="keywordflow">if</span> (IKF_iteration&gt;0)
<a name="l01183"></a>01183                                                         {
<a name="l01184"></a>01184                                                                 m_pkk = *saved_Pkk;
<a name="l01185"></a>01185                                                                 xkk_next_iter = xkk_0;
<a name="l01186"></a>01186                                                         }
<a name="l01187"></a>01187 
<a name="l01188"></a>01188                                                         <span class="comment">// For each observed landmark/whole system state:</span>
<a name="l01189"></a>01189                                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> obsIdx=0;obsIdx&lt;Z.getRowCount();obsIdx++)
<a name="l01190"></a>01190                                                         {
<a name="l01191"></a>01191                                                                 <span class="comment">// Known &amp; mapped landmark?</span>
<a name="l01192"></a>01192                                                                 <span class="keywordtype">bool</span>   doit;
<a name="l01193"></a>01193                                                                 <span class="keywordtype">size_t</span> idxInTheFilter=0;
<a name="l01194"></a>01194 
<a name="l01195"></a>01195                                                                 <span class="keywordflow">if</span> (data_association.empty())
<a name="l01196"></a>01196                                                                 {
<a name="l01197"></a>01197                                                                         doit = <span class="keyword">true</span>;
<a name="l01198"></a>01198                                                                 }
<a name="l01199"></a>01199                                                                 <span class="keywordflow">else</span>
<a name="l01200"></a>01200                                                                 {
<a name="l01201"></a>01201                                                                         doit = data_association[obsIdx] &gt;= 0;
<a name="l01202"></a>01202                                                                         <span class="keywordflow">if</span> (doit)
<a name="l01203"></a>01203                                                                                 idxInTheFilter = data_association[obsIdx];
<a name="l01204"></a>01204                                                                 }
<a name="l01205"></a>01205 
<a name="l01206"></a>01206                                                                 <span class="keywordflow">if</span> ( doit )
<a name="l01207"></a>01207                                                                 {
<a name="l01208"></a>01208                                                                         <span class="comment">// Already mapped: OK</span>
<a name="l01209"></a>01209                                                                         <span class="keyword">const</span> <span class="keywordtype">size_t</span> idx_off      = VEH_SIZE + idxInTheFilter *FEAT_SIZE; <span class="comment">// The offset in m_xkk &amp; Pkk.</span>
<a name="l01210"></a>01210                                                                         <span class="keyword">const</span> <span class="keywordtype">size_t</span> R_row_offset = obsIdx*OBS_SIZE;  <span class="comment">// Offset row in R</span>
<a name="l01211"></a>01211 
<a name="l01212"></a>01212                                                                         <span class="comment">// Compute just the part of the Jacobian that we need using the current updated m_xkk:</span>
<a name="l01213"></a>01213                                                                         <a class="code" href="structmrpt_1_1dynamicsize__vector.html">KFVector</a>   ytilde; <span class="comment">// Diff. observation - prediction</span>
<a name="l01214"></a>01214                                                                         OnObservationModelAndJacobians(
<a name="l01215"></a>01215                                                                                 Z,
<a name="l01216"></a>01216                                                                                 data_association,
<a name="l01217"></a>01217                                                                                 <span class="keyword">false</span>,                  <span class="comment">// Only a partial Jacobian</span>
<a name="l01218"></a>01218                                                                                 (<span class="keywordtype">int</span>)obsIdx,    <span class="comment">// Which row from Z</span>
<a name="l01219"></a>01219                                                                                 ytilde,
<a name="l01220"></a>01220                                                                                 Hx,
<a name="l01221"></a>01221                                                                                 Hy );
<a name="l01222"></a>01222 
<a name="l01223"></a>01223                                                                         <a class="code" href="mrpt__macros_8h.html#a5ad4d8d68e2f6664f247407bf89aac55" title="Defines an assertion mechanism - only when compiled in debug.">ASSERTDEB_</a>(ytilde.size() == OBS_SIZE )
<a name="l01224"></a>01224                                                                         <a class="code" href="mrpt__macros_8h.html#a5ad4d8d68e2f6664f247407bf89aac55" title="Defines an assertion mechanism - only when compiled in debug.">ASSERTDEB_</a>(Hx.getRowCount() == OBS_SIZE )
<a name="l01225"></a>01225                                                                         <a class="code" href="mrpt__macros_8h.html#a5ad4d8d68e2f6664f247407bf89aac55" title="Defines an assertion mechanism - only when compiled in debug.">ASSERTDEB_</a>(Hx.getColCount() == VEH_SIZE )
<a name="l01226"></a>01226 
<a name="l01227"></a>01227                                                                         <span class="keywordflow">if</span> (FEAT_SIZE&gt;0)
<a name="l01228"></a>01228                                                                         {
<a name="l01229"></a>01229                                                                                 <a class="code" href="mrpt__macros_8h.html#a5ad4d8d68e2f6664f247407bf89aac55" title="Defines an assertion mechanism - only when compiled in debug.">ASSERTDEB_</a>(Hy.getRowCount() == OBS_SIZE )
<a name="l01230"></a>01230                                                                                 <a class="code" href="mrpt__macros_8h.html#a5ad4d8d68e2f6664f247407bf89aac55" title="Defines an assertion mechanism - only when compiled in debug.">ASSERTDEB_</a>(Hy.getColCount() == FEAT_SIZE )
<a name="l01231"></a>01231                                                                         }
<a name="l01232"></a>01232 
<a name="l01233"></a>01233                                                                         <span class="comment">// Compute the OxO matrix S_i for each observation:</span>
<a name="l01234"></a>01234                                                                         <span class="comment">// Si  = TERM1 + TERM2 + TERM2^t + TERM3 + R</span>
<a name="l01235"></a>01235                                                                         <span class="comment">//</span>
<a name="l01236"></a>01236                                                                         <span class="comment">// TERM1: dhi_dxv Pxx dhi_dxv^t</span>
<a name="l01237"></a>01237                                                                         <span class="comment">//          ^^</span>
<a name="l01238"></a>01238                                                                         <span class="comment">//         Hx:(OxV)</span>
<a name="l01239"></a>01239                                                                         <span class="comment">//</span>
<a name="l01240"></a>01240                                                                         <span class="comment">// TERM2: dhi_dyi Pyix dhi_dxv</span>
<a name="l01241"></a>01241                                                                         <span class="comment">//          ^^</span>
<a name="l01242"></a>01242                                                                         <span class="comment">//         Hy:(OxF)</span>
<a name="l01243"></a>01243                                                                         <span class="comment">//</span>
<a name="l01244"></a>01244                                                                         <span class="comment">// TERM3: dhi_dyi Pyiyi dhi_dyi^t</span>
<a name="l01245"></a>01245                                                                         <span class="comment">//</span>
<a name="l01246"></a>01246                                                                         <span class="comment">// i: obsIdx</span>
<a name="l01247"></a>01247                                                                         <span class="comment">// O: Observation size</span>
<a name="l01248"></a>01248                                                                         <span class="comment">// F: Feature size</span>
<a name="l01249"></a>01249                                                                         <span class="comment">// V: Vehicle state size</span>
<a name="l01250"></a>01250                                                                         <span class="comment">//</span>
<a name="l01251"></a>01251 
<a name="l01252"></a>01252                                                                         <span class="comment">// R:</span>
<a name="l01253"></a>01253                                                                         <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a> Si(OBS_SIZE,OBS_SIZE);
<a name="l01254"></a>01254                                                                         R.extractMatrix(R_row_offset,0, Si);
<a name="l01255"></a>01255 
<a name="l01256"></a>01256                                                                         <span class="keywordtype">size_t</span> k;
<a name="l01257"></a>01257                                                                         <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a>        term(OBS_SIZE,OBS_SIZE);
<a name="l01258"></a>01258 
<a name="l01259"></a>01259                                                                         <span class="comment">// TERM1: dhi_dxv Pxx dhi_dxv^t</span>
<a name="l01260"></a>01260                                                                         Hx.multiply_HCHt(
<a name="l01261"></a>01261                                                                                 m_pkk,          <span class="comment">// The cov. matrix</span>
<a name="l01262"></a>01262                                                                                 Si,                     <span class="comment">// The output</span>
<a name="l01263"></a>01263                                                                                 <span class="keyword">true</span>,           <span class="comment">// Yes, submatrix of m_pkk only</span>
<a name="l01264"></a>01264                                                                                 0,                      <span class="comment">// Offset in m_pkk</span>
<a name="l01265"></a>01265                                                                                 <span class="keyword">true</span>            <span class="comment">// Yes, accum results in output.</span>
<a name="l01266"></a>01266                                                                         );
<a name="l01267"></a>01267 
<a name="l01268"></a>01268                                                                         <span class="comment">// TERM2: dhi_dyi Pyix dhi_dxv</span>
<a name="l01269"></a>01269                                                                         <span class="comment">//  + its transpose:</span>
<a name="l01270"></a>01270                                                                         <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a>        Pyix( FEAT_SIZE, VEH_SIZE );
<a name="l01271"></a>01271                                                                         m_pkk.extractMatrix(idx_off,0, Pyix);  <span class="comment">// Extract cross cov. to Pyix</span>
<a name="l01272"></a>01272 
<a name="l01273"></a>01273                                                                         term.multiply_ABCt( Hy, Pyix, Hx ); <span class="comment">//term = Hy * Pyix * ~Hx;</span>
<a name="l01274"></a>01274                                                                         Si.add_AAt( term );  <span class="comment">// Si += A + ~A</span>
<a name="l01275"></a>01275 
<a name="l01276"></a>01276                                                                         <span class="comment">// TERM3: dhi_dyi Pyiyi dhi_dyi^t</span>
<a name="l01277"></a>01277                                                                         Hy.multiply_HCHt(
<a name="l01278"></a>01278                                                                                 m_pkk,          <span class="comment">// The cov. matrix</span>
<a name="l01279"></a>01279                                                                                 Si,                     <span class="comment">// The output</span>
<a name="l01280"></a>01280                                                                                 <span class="keyword">true</span>,           <span class="comment">// Yes, submatrix of m_pkk only</span>
<a name="l01281"></a>01281                                                                                 idx_off,    <span class="comment">// Offset in m_pkk</span>
<a name="l01282"></a>01282                                                                                 <span class="keyword">true</span>            <span class="comment">// Yes, accum results in output.</span>
<a name="l01283"></a>01283                                                                         );
<a name="l01284"></a>01284 
<a name="l01285"></a>01285                                                                         <span class="comment">// Compute the inverse of Si:</span>
<a name="l01286"></a>01286                                                                         <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a> Si_1(OBS_SIZE,OBS_SIZE);
<a name="l01287"></a>01287 
<a name="l01288"></a>01288                                                                         <span class="comment">// Compute the Kalman gain &quot;Ki&quot; for this i&#39;th observation:</span>
<a name="l01289"></a>01289                                                                         <span class="comment">// --&gt;  Ki = m_pkk * (~dh_dx) * S.inv();</span>
<a name="l01290"></a>01290                                                                         <span class="keywordtype">size_t</span> N = m_pkk.getColCount();
<a name="l01291"></a>01291 
<a name="l01292"></a>01292                                                                         <a class="code" href="classmrpt_1_1math_1_1_c_matrix_template_numeric.html">KFMatrix</a> Ki( N, OBS_SIZE );
<a name="l01293"></a>01293 
<a name="l01294"></a>01294                                                                         <span class="keywordflow">for</span> (k=0;k&lt;N;k++)  <span class="comment">// for each row of K</span>
<a name="l01295"></a>01295                                                                         {
<a name="l01296"></a>01296                                                                                 <span class="keywordtype">size_t</span> q;
<a name="l01297"></a>01297 
<a name="l01298"></a>01298                                                                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> c=0;c&lt;OBS_SIZE;c++)  <span class="comment">// for each column of K</span>
<a name="l01299"></a>01299                                                                                 {
<a name="l01300"></a>01300                                                                                         KFTYPE  K_tmp = 0;
<a name="l01301"></a>01301 
<a name="l01302"></a>01302                                                                                         <span class="comment">// dhi_dxv term</span>
<a name="l01303"></a>01303                                                                                         <span class="keywordflow">for</span> (q=0;q&lt;VEH_SIZE;q++)
<a name="l01304"></a>01304                                                                                                 K_tmp+= m_pkk.get_unsafe(k,q) * Hx.get_unsafe(c,q);
<a name="l01305"></a>01305 
<a name="l01306"></a>01306                                                                                         <span class="comment">// dhi_dyi term</span>
<a name="l01307"></a>01307                                                                                         <span class="keywordflow">for</span> (q=0;q&lt;FEAT_SIZE;q++)
<a name="l01308"></a>01308                                                                                                 K_tmp+= m_pkk.get_unsafe(k,idx_off+q) * Hy.get_unsafe(c,q);
<a name="l01309"></a>01309 
<a name="l01310"></a>01310                                                                                         Ki.set_unsafe(k,c, K_tmp);
<a name="l01311"></a>01311                                                                                 } <span class="comment">// end for c</span>
<a name="l01312"></a>01312                                                                         } <span class="comment">// end for k</span>
<a name="l01313"></a>01313 
<a name="l01314"></a>01314                                                                         Ki.multiply(Ki, Si.inv() );  <span class="comment">// K = (...) * S^-1</span>
<a name="l01315"></a>01315 
<a name="l01316"></a>01316 
<a name="l01317"></a>01317                                                                         <span class="comment">// Update the state vector m_xkk:</span>
<a name="l01318"></a>01318                                                                         <span class="keywordflow">if</span> (nKF_iterations==1)
<a name="l01319"></a>01319                                                                         {
<a name="l01320"></a>01320                                                                                 <span class="comment">// EKF:</span>
<a name="l01321"></a>01321                                                                                 <span class="comment">//  x&#39; = x + Kij * ytilde(ij)</span>
<a name="l01322"></a>01322                                                                                 <span class="keywordflow">for</span> (k=0;k&lt;N;k++)
<a name="l01323"></a>01323                                                                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> q=0;q&lt;OBS_SIZE;q++)
<a name="l01324"></a>01324                                                                                                 m_xkk[k] += Ki.get_unsafe(k,q) * ytilde[q];
<a name="l01325"></a>01325                                                                         }
<a name="l01326"></a>01326                                                                         <span class="keywordflow">else</span>
<a name="l01327"></a>01327                                                                         {
<a name="l01328"></a>01328                                                                                 <span class="comment">// IKF:</span>
<a name="l01329"></a>01329                                                                                 mrpt<a class="code" href="structmrpt_1_1dynamicsize__vector.html">::dynamicsize_vector&lt;KFTYPE&gt;</a> HAx(OBS_SIZE);
<a name="l01330"></a>01330                                                                                 <span class="keywordtype">size_t</span> o,q;
<a name="l01331"></a>01331                                                                                 <span class="comment">// HAx = H*(x0-xi)</span>
<a name="l01332"></a>01332                                                                                 <span class="keywordflow">for</span> (o=0;o&lt;OBS_SIZE;o++)
<a name="l01333"></a>01333                                                                                 {
<a name="l01334"></a>01334                                                                                         KFTYPE  tmp = 0;
<a name="l01335"></a>01335                                                                                         <span class="keywordflow">for</span> (q=0;q&lt;VEH_SIZE;q++)
<a name="l01336"></a>01336                                                                                                 tmp += Hx.get_unsafe(o,q) * (xkk_0[q] - m_xkk[q]);
<a name="l01337"></a>01337 
<a name="l01338"></a>01338                                                                                         <span class="keywordflow">for</span> (q=0;q&lt;FEAT_SIZE;q++)
<a name="l01339"></a>01339                                                                                                 tmp += Hy.get_unsafe(o,q) * (xkk_0[idx_off+q] - m_xkk[idx_off+q]);
<a name="l01340"></a>01340 
<a name="l01341"></a>01341                                                                                         HAx[o] = tmp;
<a name="l01342"></a>01342                                                                                 }
<a name="l01343"></a>01343 
<a name="l01344"></a>01344                                                                                 <span class="comment">// Compute only once (ytilde[j] - HAx)</span>
<a name="l01345"></a>01345                                                                                 <span class="keywordflow">for</span> (o=0;o&lt;OBS_SIZE;o++)
<a name="l01346"></a>01346                                                                                         HAx[o] = ytilde[o] - HAx[o];
<a name="l01347"></a>01347 
<a name="l01348"></a>01348                                                                                 <span class="comment">//  x&#39; = x_0 + Kij * ( ytilde(ij) - H*(x0-xi))   -&gt; xi: i=this iteration</span>
<a name="l01349"></a>01349                                                                                 <span class="comment">//  xkk_next_iter is initialized to xkk_0 at each IKF iteration.</span>
<a name="l01350"></a>01350                                                                                 <span class="keywordflow">for</span> (k=0;k&lt;N;k++)
<a name="l01351"></a>01351                                                                                 {
<a name="l01352"></a>01352                                                                                         KFTYPE   tmp = xkk_next_iter[k];
<a name="l01353"></a>01353                                                                                         <span class="comment">//m_xkk[k] = xkk_0[k] + Kij[k] * (ytilde[j] - HAx );</span>
<a name="l01354"></a>01354                                                                                         <span class="keywordflow">for</span> (o=0;o&lt;OBS_SIZE;o++)
<a name="l01355"></a>01355                                                                                                 tmp += Ki.get_unsafe(k,o) * HAx[o];
<a name="l01356"></a>01356 
<a name="l01357"></a>01357                                                                                         xkk_next_iter[k] = tmp;
<a name="l01358"></a>01358                                                                                 }
<a name="l01359"></a>01359                                                                         }
<a name="l01360"></a>01360 
<a name="l01361"></a>01361                                                                         <span class="comment">// Update the covariance Pkk:</span>
<a name="l01362"></a>01362                                                                         <span class="comment">// P&#39; =  P - Kij * Sij * Kij^t</span>
<a name="l01363"></a>01363                                                                         <span class="comment">//if (IKF_iteration==(nKF_iterations-1))   // Just for the last IKF iteration</span>
<a name="l01364"></a>01364                                                                         {
<a name="l01365"></a>01365                                                                                 <span class="comment">// m_pkk -= Ki * Si * ~Ki;</span>
<a name="l01366"></a>01366                                                                                 Ki.multiplyByMatrixAndByTransposeNonSymmetric(
<a name="l01367"></a>01367                                                                                         Si,
<a name="l01368"></a>01368                                                                                         m_pkk,   <span class="comment">// Output</span>
<a name="l01369"></a>01369                                                                                         <span class="keyword">true</span>,    <span class="comment">// Accumulate</span>
<a name="l01370"></a>01370                                                                                         <span class="keyword">true</span>);   <span class="comment">// Substract instead of sum.</span>
<a name="l01371"></a>01371 
<a name="l01372"></a>01372                                                                                 m_pkk.force_symmetry();
<a name="l01373"></a>01373 
<a name="l01374"></a>01374                         <span class="comment">/*                                                      for (k=0;k&lt;N;k++)</span>
<a name="l01375"></a>01375 <span class="comment">                                                                                {</span>
<a name="l01376"></a>01376 <span class="comment">                                                                                        for (size_t q=k;q&lt;N;q++)  // Half matrix</span>
<a name="l01377"></a>01377 <span class="comment">                                                                                        {</span>
<a name="l01378"></a>01378 <span class="comment">                                                                                                m_pkk(k,q) -= Sij * Kij[k] * Kij[q];</span>
<a name="l01379"></a>01379 <span class="comment">                                                                                                // It is symmetric</span>
<a name="l01380"></a>01380 <span class="comment">                                                                                                m_pkk(q,k) = m_pkk(k,q);</span>
<a name="l01381"></a>01381 <span class="comment">                                                                                        }</span>
<a name="l01382"></a>01382 <span class="comment"></span>
<a name="l01383"></a>01383 <span class="comment">                        #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG)</span>
<a name="l01384"></a>01384 <span class="comment">                                                                                        if (m_pkk(k,k)&lt;0)</span>
<a name="l01385"></a>01385 <span class="comment">                                                                                        {</span>
<a name="l01386"></a>01386 <span class="comment">                                                                                                m_pkk.saveToTextFile(&quot;Pkk_err.txt&quot;);</span>
<a name="l01387"></a>01387 <span class="comment">                                                                                                mrpt::system::vectorToTextFile(Kij,&quot;Kij.txt&quot;);</span>
<a name="l01388"></a>01388 <span class="comment">                                                                                                ASSERT_(m_pkk(k,k)&gt;0)</span>
<a name="l01389"></a>01389 <span class="comment">                                                                                        }</span>
<a name="l01390"></a>01390 <span class="comment">                        #endif</span>
<a name="l01391"></a>01391 <span class="comment">                                                                                }</span>
<a name="l01392"></a>01392 <span class="comment">                                                                                */</span>
<a name="l01393"></a>01393                                                                         }
<a name="l01394"></a>01394 
<a name="l01395"></a>01395                                                                 } <span class="comment">// end if doit</span>
<a name="l01396"></a>01396 
<a name="l01397"></a>01397                                                         } <span class="comment">// end for each observed LM.</span>
<a name="l01398"></a>01398 
<a name="l01399"></a>01399                                                         <span class="comment">// Now, save the new iterated mean:</span>
<a name="l01400"></a>01400                                                         <span class="keywordflow">if</span> (nKF_iterations&gt;1)
<a name="l01401"></a>01401                                                         {
<a name="l01402"></a>01402 <span class="preprocessor">                        #if 0</span>
<a name="l01403"></a>01403 <span class="preprocessor"></span>                                                                cout &lt;&lt; <span class="stringliteral">&quot;IKF iter: &quot;</span> &lt;&lt; IKF_iteration &lt;&lt; <span class="stringliteral">&quot; -&gt; &quot;</span> &lt;&lt; xkk_next_iter &lt;&lt; endl;
<a name="l01404"></a>01404 <span class="preprocessor">                        #endif</span>
<a name="l01405"></a>01405 <span class="preprocessor"></span>                                                                m_xkk = xkk_next_iter;
<a name="l01406"></a>01406                                                         }
<a name="l01407"></a>01407 
<a name="l01408"></a>01408                                                 } <span class="comment">// end for each IKF_iteration</span>
<a name="l01409"></a>01409 
<a name="l01410"></a>01410                                                 <span class="comment">// Copy of pkk not required anymore:</span>
<a name="l01411"></a>01411                                                 <span class="keywordflow">if</span> (saved_Pkk) <span class="keyword">delete</span> saved_Pkk;
<a name="l01412"></a>01412 
<a name="l01413"></a>01413 <span class="preprocessor">#endif</span>
<a name="l01414"></a>01414 <span class="preprocessor"></span>                                                }
<a name="l01415"></a>01415                                                 <span class="keywordflow">break</span>;
<a name="l01416"></a>01416 
<a name="l01417"></a>01417                                                 <span class="keywordflow">default</span>:
<a name="l01418"></a>01418                                                         <a class="code" href="mrpt__macros_8h.html#aaa3f404ea85a6575a7139f8d101370ba">THROW_EXCEPTION</a>(<span class="stringliteral">&quot;Invalid value of options.KF_method&quot;</span>);
<a name="l01419"></a>01419                                                 } <span class="comment">// end switch method</span>
<a name="l01420"></a>01420 
<a name="l01421"></a>01421                                         }
<a name="l01422"></a>01422 
<a name="l01423"></a>01423                                         <span class="keyword">const</span> <span class="keywordtype">double</span> tim_update = m_timLogger.leave(<span class="stringliteral">&quot;KF:8.update stage&quot;</span>);
<a name="l01424"></a>01424 
<a name="l01425"></a>01425                                         OnNormalizeStateVector();
<a name="l01426"></a>01426 
<a name="l01427"></a>01427                                         <span class="comment">// =============================================================</span>
<a name="l01428"></a>01428                                         <span class="comment">//  8. INTRODUCE NEW LANDMARKS</span>
<a name="l01429"></a>01429                                         <span class="comment">// =============================================================</span>
<a name="l01430"></a>01430                                         <span class="keywordflow">if</span> (!data_association.empty())
<a name="l01431"></a>01431                                         {
<a name="l01432"></a>01432                                                 <a class="code" href="structmrpt_1_1bayes_1_1detail_1_1_c_run_one_kalman_iteration__add_new_landmarks.html">detail::CRunOneKalmanIteration_addNewLandmarks</a>()(*<span class="keyword">this</span>, Z, data_association,R);
<a name="l01433"></a>01433                                         } <span class="comment">// end if data_association!=empty</span>
<a name="l01434"></a>01434 
<a name="l01435"></a>01435                                         <span class="keywordflow">if</span> (KF_options.verbose)
<a name="l01436"></a>01436                                         {
<a name="l01437"></a>01437                                                 printf_debug(<span class="stringliteral">&quot;[KF] %u LMs | Pr: %.2fms | Pr.Obs: %.2fms | Obs.DA: %.2fms | Upd: %.2fms\n&quot;</span>,
<a name="l01438"></a>01438                                                         static_cast&lt;unsigned int&gt;(getNumberOfLandmarksInTheMap()),
<a name="l01439"></a>01439                                                         1e3*tim_pred,
<a name="l01440"></a>01440                                                         1e3*tim_pred_obs,
<a name="l01441"></a>01441                                                         1e3*tim_obs_DA,
<a name="l01442"></a>01442                                                         1e3*tim_update
<a name="l01443"></a>01443                                                         );
<a name="l01444"></a>01444                                         }
<a name="l01445"></a>01445 
<a name="l01446"></a>01446                                         <span class="comment">// Post iteration user code:</span>
<a name="l01447"></a>01447                                         OnPostIteration();
<a name="l01448"></a>01448 
<a name="l01449"></a>01449                                         m_timLogger.leave(<span class="stringliteral">&quot;KF:complete_step&quot;</span>);
<a name="l01450"></a>01450 
<a name="l01451"></a>01451                                         <a class="code" href="mrpt__macros_8h.html#a88a917260793b56abd83ad2a0d849eb1">MRPT_END</a>
<a name="l01452"></a>01452 
<a name="l01453"></a>01453                                 } <span class="comment">// End of &quot;runOneKalmanIteration&quot;</span>
<a name="l01454"></a>01454 
<a name="l01455"></a>01455 
<a name="l01456"></a>01456 
<a name="l01457"></a>01457                 <span class="keyword">private</span>:
<a name="l01458"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ada33322b67cea44a95948712be1c131b">01458</a>                         <span class="keyword">mutable</span> <span class="keywordtype">bool</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#ada33322b67cea44a95948712be1c131b">m_user_didnt_implement_jacobian</a>;
<a name="l01459"></a>01459 <span class="comment"></span>
<a name="l01460"></a>01460 <span class="comment">                        /** Auxiliary functions for Jacobian numeric estimation */</span>
<a name="l01461"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a713c4352da9cc10f827a52ed852a9e6a">01461</a>                         <span class="keyword">static</span> <span class="keywordtype">void</span> KF_aux_estimate_trans_jacobian(
<a name="l01462"></a>01462                                 <span class="keyword">const</span> <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_VEH</a> &amp;x,
<a name="l01463"></a>01463                                 <span class="keyword">const</span> std::pair&lt;KFCLASS*,KFArray_ACT&gt; &amp;dat,
<a name="l01464"></a>01464                                 <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_VEH</a> &amp;out_x)
<a name="l01465"></a>01465                         {
<a name="l01466"></a>01466                                 <span class="keywordtype">bool</span> dumm;
<a name="l01467"></a>01467                                 out_x=x;
<a name="l01468"></a>01468                                 dat.first-&gt;OnTransitionModel(dat.second,out_x, dumm);
<a name="l01469"></a>01469                         }
<a name="l01470"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a8fb02067b7c9ff1210085bbd8ba25204">01470</a>                         <span class="keyword">static</span> <span class="keywordtype">void</span> KF_aux_estimate_obs_Hx_jacobian(
<a name="l01471"></a>01471                                 <span class="keyword">const</span> <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_VEH</a> &amp;x,
<a name="l01472"></a>01472                                 <span class="keyword">const</span> std::pair&lt;KFCLASS*,size_t&gt; &amp;dat,
<a name="l01473"></a>01473                                 <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_OBS</a> &amp;out_x)
<a name="l01474"></a>01474                         {
<a name="l01475"></a>01475                                 <a class="code" href="classstd_1_1vector.html">vector_size_t</a>  idxs_to_predict(1,dat.second);
<a name="l01476"></a>01476                                 <a class="code" href="classstd_1_1vector.html" title="STL class.">vector_KFArray_OBS</a> prediction;
<a name="l01477"></a>01477                                 <span class="comment">// Overwrite (temporarily!) the affected part of the state vector:</span>
<a name="l01478"></a>01478                                 <a class="code" href="group__mrpt__system__os.html#gae1184cfb1f617787dc4c9da98becbe3a" title="An OS and compiler independent version of &quot;memcpy&quot;.">::memcpy</a>(&amp;dat.first-&gt;m_xkk[0],&amp;x[0],<span class="keyword">sizeof</span>(x[0])*VEH_SIZE);
<a name="l01479"></a>01479                                 dat.first-&gt;OnObservationModel(idxs_to_predict,prediction);
<a name="l01480"></a>01480                                 <a class="code" href="mrpt__macros_8h.html#a5ad4d8d68e2f6664f247407bf89aac55" title="Defines an assertion mechanism - only when compiled in debug.">ASSERTDEB_</a>(prediction.size()==1);
<a name="l01481"></a>01481                                 out_x=prediction[0];
<a name="l01482"></a>01482                         }
<a name="l01483"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a07208df3280ab8f80b4952ab09bfd55a">01483</a>                         <span class="keyword">static</span> <span class="keywordtype">void</span> KF_aux_estimate_obs_Hy_jacobian(
<a name="l01484"></a>01484                                 <span class="keyword">const</span> <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_FEAT</a> &amp;x,
<a name="l01485"></a>01485                                 <span class="keyword">const</span> std::pair&lt;KFCLASS*,size_t&gt; &amp;dat,
<a name="l01486"></a>01486                                 <a class="code" href="classmrpt_1_1math_1_1_c_array_numeric.html" title="CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...">KFArray_OBS</a> &amp;out_x)
<a name="l01487"></a>01487                         {
<a name="l01488"></a>01488                                 <a class="code" href="classstd_1_1vector.html">vector_size_t</a>  idxs_to_predict(1,dat.second);
<a name="l01489"></a>01489                                 <a class="code" href="classstd_1_1vector.html" title="STL class.">vector_KFArray_OBS</a>  prediction;
<a name="l01490"></a>01490                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> lm_idx_in_statevector = VEH_SIZE+FEAT_SIZE*dat.second;
<a name="l01491"></a>01491                                 <span class="comment">// Overwrite (temporarily!) the affected part of the state vector:</span>
<a name="l01492"></a>01492                                 <a class="code" href="group__mrpt__system__os.html#gae1184cfb1f617787dc4c9da98becbe3a" title="An OS and compiler independent version of &quot;memcpy&quot;.">::memcpy</a>(&amp;dat.first-&gt;m_xkk[lm_idx_in_statevector],&amp;x[0],<span class="keyword">sizeof</span>(x[0])*FEAT_SIZE);
<a name="l01493"></a>01493                                 dat.first-&gt;OnObservationModel(idxs_to_predict,prediction);
<a name="l01494"></a>01494                                 <a class="code" href="mrpt__macros_8h.html#a5ad4d8d68e2f6664f247407bf89aac55" title="Defines an assertion mechanism - only when compiled in debug.">ASSERTDEB_</a>(prediction.size()==1);
<a name="l01495"></a>01495                                 out_x=prediction[0];
<a name="l01496"></a>01496                         }
<a name="l01497"></a>01497 
<a name="l01498"></a>01498 
<a name="l01499"></a><a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html#a1f7c0688afe03ffd6f14c4e9f4e5a050">01499</a>                         <span class="keyword">friend</span> <span class="keyword">struct </span><a class="code" href="structmrpt_1_1bayes_1_1detail_1_1_c_run_one_kalman_iteration__add_new_landmarks.html">detail::CRunOneKalmanIteration_addNewLandmarks</a>;
<a name="l01500"></a>01500 
<a name="l01501"></a>01501                 }; <span class="comment">// end class</span>
<a name="l01502"></a>01502 
<a name="l01503"></a>01503                 <span class="keyword">namespace </span>detail
<a name="l01504"></a>01504                 {
<a name="l01505"></a>01505                         <span class="comment">// generic version for SLAM. There is a speciation below for NON-SLAM problems.</span>
<a name="l01506"></a>01506                         <span class="keyword">struct </span>CRunOneKalmanIteration_addNewLandmarks {
<a name="l01507"></a>01507                                 <span class="keyword">template</span> &lt;<span class="keywordtype">size_t</span> VEH_SIZE, <span class="keywordtype">size_t</span> OBS_SIZE, <span class="keywordtype">size_t</span> FEAT_SIZE, <span class="keywordtype">size_t</span> ACT_SIZE, <span class="keyword">typename</span> KFTYPE&gt;
<a name="l01508"></a><a class="code" href="structmrpt_1_1bayes_1_1detail_1_1_c_run_one_kalman_iteration__add_new_landmarks.html#a33a1d2428276d43021c282e611d4f9a2">01508</a>                                 <span class="keywordtype">void</span> operator()(
<a name="l01509"></a>01509                                         <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html" title="Virtual base for Kalman Filter (EKF,IEKF,UKF) implementations.">CKalmanFilterCapable&lt;VEH_SIZE,OBS_SIZE,FEAT_SIZE,ACT_SIZE,KFTYPE&gt;</a> &amp;obj,
<a name="l01510"></a>01510                                         <span class="keyword">const</span> <span class="keyword">typename</span> <a class="code" href="classstd_1_1vector.html" title="STL class.">CKalmanFilterCapable&lt;VEH_SIZE,OBS_SIZE,FEAT_SIZE,ACT_SIZE,KFTYPE&gt;::vector_KFArray_OBS</a> &amp; Z,
<a name="l01511"></a>01511                                         <span class="keyword">const</span> <a class="code" href="classstd_1_1vector.html" title="STL class.">vector_int</a>       &amp;data_association,
<a name="l01512"></a>01512                                         <span class="keyword">const</span> <span class="keyword">typename</span> <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">CKalmanFilterCapable&lt;VEH_SIZE,OBS_SIZE,FEAT_SIZE,ACT_SIZE,KFTYPE&gt;::KFMatrix_OxO</a>          &amp;R
<a name="l01513"></a>01513                                         )
<a name="l01514"></a>01514                                 {
<a name="l01515"></a>01515                                         <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html" title="Virtual base for Kalman Filter (EKF,IEKF,UKF) implementations.">CKalmanFilterCapable&lt;VEH_SIZE,OBS_SIZE,FEAT_SIZE,ACT_SIZE,KFTYPE&gt;</a> KF;
<a name="l01516"></a>01516 
<a name="l01517"></a>01517                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> idxObs=0;idxObs&lt;Z.size();idxObs++)
<a name="l01518"></a>01518                                         {
<a name="l01519"></a>01519                                                 <span class="comment">// Is already in the map?</span>
<a name="l01520"></a>01520                                                 <span class="keywordflow">if</span> ( data_association[idxObs] &lt; 0 )  <span class="comment">// Not in the map yet!</span>
<a name="l01521"></a>01521                                                 {
<a name="l01522"></a>01522                                                         obj.m_timLogger.enter(<span class="stringliteral">&quot;KF:9.create new LMs&quot;</span>);
<a name="l01523"></a>01523                                                         <span class="comment">// Add it:</span>
<a name="l01524"></a>01524 
<a name="l01525"></a>01525                                                         <span class="comment">// Append to map of IDs &lt;-&gt; position in the state vector:</span>
<a name="l01526"></a>01526                                                         <a class="code" href="mrpt__macros_8h.html#a5ad4d8d68e2f6664f247407bf89aac55" title="Defines an assertion mechanism - only when compiled in debug.">ASSERTDEB_</a>(FEAT_SIZE&gt;0)
<a name="l01527"></a>01527                                                         <a class="code" href="mrpt__macros_8h.html#a5ad4d8d68e2f6664f247407bf89aac55" title="Defines an assertion mechanism - only when compiled in debug.">ASSERTDEB_</a>( 0 == ((obj.m_xkk.size() - VEH_SIZE) % FEAT_SIZE) ) <span class="comment">// Sanity test</span>
<a name="l01528"></a>01528 
<a name="l01529"></a>01529                                                         <span class="keyword">const</span> <span class="keywordtype">size_t</span>  newIndexInMap = (obj.m_xkk.size() - VEH_SIZE) / FEAT_SIZE;
<a name="l01530"></a>01530 
<a name="l01531"></a>01531                                                         <span class="comment">// Inverse sensor model:</span>
<a name="l01532"></a>01532                                                         <span class="keyword">typename</span> KF::KFArray_FEAT yn;
<a name="l01533"></a>01533                                                         <span class="keyword">typename</span> KF::KFMatrix_FxV dyn_dxv;
<a name="l01534"></a>01534                                                         <span class="keyword">typename</span> KF::KFMatrix_FxO dyn_dhn;
<a name="l01535"></a>01535                                                         <span class="keyword">typename</span> KF::KFMatrix_FxF dyn_dhn_R_dyn_dhnT;
<a name="l01536"></a>01536                                                         <span class="keywordtype">bool</span> use_dyn_dhn_jacobian=<span class="keyword">true</span>;
<a name="l01537"></a>01537 
<a name="l01538"></a>01538                                                         <span class="comment">// Compute the inv. sensor model and its Jacobians:</span>
<a name="l01539"></a>01539                                                         obj.OnInverseObservationModel(
<a name="l01540"></a>01540                                                                 Z[idxObs],
<a name="l01541"></a>01541                                                                 yn,
<a name="l01542"></a>01542                                                                 dyn_dxv,
<a name="l01543"></a>01543                                                                 dyn_dhn,
<a name="l01544"></a>01544                                                                 dyn_dhn_R_dyn_dhnT,
<a name="l01545"></a>01545                                                                 use_dyn_dhn_jacobian );
<a name="l01546"></a>01546 
<a name="l01547"></a>01547                                                         <span class="comment">// And let the application do any special handling of adding a new feature to the map:</span>
<a name="l01548"></a>01548                                                         obj.OnNewLandmarkAddedToMap(
<a name="l01549"></a>01549                                                                 idxObs,
<a name="l01550"></a>01550                                                                 newIndexInMap
<a name="l01551"></a>01551                                                                 );
<a name="l01552"></a>01552 
<a name="l01553"></a>01553                                                         <a class="code" href="mrpt__macros_8h.html#a5ad4d8d68e2f6664f247407bf89aac55" title="Defines an assertion mechanism - only when compiled in debug.">ASSERTDEB_</a>( yn.size() == FEAT_SIZE )
<a name="l01554"></a>01554 
<a name="l01555"></a>01555                                                         <span class="comment">// Append to m_xkk:</span>
<a name="l01556"></a>01556                                                         <span class="keywordtype">size_t</span> q;
<a name="l01557"></a>01557                                                         <span class="keywordtype">size_t</span> idx = obj.m_xkk.size();
<a name="l01558"></a>01558                                                         obj.m_xkk.resize( obj.m_xkk.size() + FEAT_SIZE );
<a name="l01559"></a>01559 
<a name="l01560"></a>01560                                                         <span class="keywordflow">for</span> (q=0;q&lt;FEAT_SIZE;q++)
<a name="l01561"></a>01561                                                                 obj.m_xkk[idx+q] = yn[q];
<a name="l01562"></a>01562 
<a name="l01563"></a>01563                                                         <span class="comment">// --------------------</span>
<a name="l01564"></a>01564                                                         <span class="comment">// Append to Pkk:</span>
<a name="l01565"></a>01565                                                         <span class="comment">// --------------------</span>
<a name="l01566"></a>01566                                                         <a class="code" href="mrpt__macros_8h.html#a5ad4d8d68e2f6664f247407bf89aac55" title="Defines an assertion mechanism - only when compiled in debug.">ASSERTDEB_</a>( obj.m_pkk.getColCount()==idx &amp;&amp; obj.m_pkk.getRowCount()==idx );
<a name="l01567"></a>01567 
<a name="l01568"></a>01568                                                         obj.m_pkk.setSize( idx+FEAT_SIZE,idx+FEAT_SIZE );
<a name="l01569"></a>01569 
<a name="l01570"></a>01570                                                         <span class="comment">// Fill the Pxyn term:</span>
<a name="l01571"></a>01571                                                         <span class="comment">// --------------------</span>
<a name="l01572"></a>01572                                                         <span class="keyword">typename</span> KF::KFMatrix_VxV Pxx;
<a name="l01573"></a>01573                                                         obj.m_pkk.extractMatrix(0,0,Pxx);
<a name="l01574"></a>01574                                                         <span class="keyword">typename</span> KF::KFMatrix_FxV Pxyn; <span class="comment">// Pxyn = dyn_dxv * Pxx</span>
<a name="l01575"></a>01575                                                         Pxyn.multiply( dyn_dxv, Pxx );
<a name="l01576"></a>01576 
<a name="l01577"></a>01577                                                         obj.m_pkk.insertMatrix( idx,0, Pxyn );
<a name="l01578"></a>01578                                                         obj.m_pkk.insertMatrixTranspose( 0,idx, Pxyn );
<a name="l01579"></a>01579 
<a name="l01580"></a>01580                                                         <span class="comment">// Fill the Pyiyn terms:</span>
<a name="l01581"></a>01581                                                         <span class="comment">// --------------------</span>
<a name="l01582"></a>01582                                                         <span class="keyword">const</span> <span class="keywordtype">size_t</span> nLMs = (idx-VEH_SIZE)/FEAT_SIZE; <span class="comment">// Number of previous landmarks:</span>
<a name="l01583"></a>01583                                                         <span class="keywordflow">for</span> (q=0;q&lt;nLMs;q++)
<a name="l01584"></a>01584                                                         {
<a name="l01585"></a>01585                                                                 <span class="keyword">typename</span> KF::KFMatrix_VxF  P_x_yq(<a class="code" href="namespacemrpt_1_1math.html#a27e8ae8971ff5aa1c39f1f9be334d73aa28acc66160006cb691487ec89f8d266d">UNINITIALIZED_MATRIX</a>);
<a name="l01586"></a>01586                                                                 obj.m_pkk.extractMatrix(0,VEH_SIZE+q*FEAT_SIZE,P_x_yq) ;
<a name="l01587"></a>01587 
<a name="l01588"></a>01588                                                                 <span class="keyword">typename</span> KF::KFMatrix_FxF P_cross(<a class="code" href="namespacemrpt_1_1math.html#a27e8ae8971ff5aa1c39f1f9be334d73aa28acc66160006cb691487ec89f8d266d">UNINITIALIZED_MATRIX</a>);
<a name="l01589"></a>01589                                                                 P_cross.multiply(dyn_dxv, P_x_yq );
<a name="l01590"></a>01590 
<a name="l01591"></a>01591                                                                 obj.m_pkk.insertMatrix(idx,VEH_SIZE+q*FEAT_SIZE, P_cross );
<a name="l01592"></a>01592                                                                 obj.m_pkk.insertMatrixTranspose(VEH_SIZE+q*FEAT_SIZE,idx, P_cross );
<a name="l01593"></a>01593                                                         } <span class="comment">// end each previous LM(q)</span>
<a name="l01594"></a>01594 
<a name="l01595"></a>01595                                                         <span class="comment">// Fill the Pynyn term:</span>
<a name="l01596"></a>01596                                                         <span class="comment">//  P_yn_yn =  (dyn_dxv * Pxx * ~dyn_dxv) + (dyn_dhn * R * ~dyn_dhn);</span>
<a name="l01597"></a>01597                                                         <span class="comment">// --------------------</span>
<a name="l01598"></a>01598                                                         <span class="keyword">typename</span> KF::KFMatrix_FxF P_yn_yn(<a class="code" href="namespacemrpt_1_1math.html#a27e8ae8971ff5aa1c39f1f9be334d73aa28acc66160006cb691487ec89f8d266d">UNINITIALIZED_MATRIX</a>);
<a name="l01599"></a>01599                                                         dyn_dxv.multiply_HCHt(Pxx,  P_yn_yn);
<a name="l01600"></a>01600                                                         <span class="keywordflow">if</span> (use_dyn_dhn_jacobian)
<a name="l01601"></a>01601                                                                         dyn_dhn.multiply_HCHt(R, P_yn_yn, <span class="keyword">true</span>); <span class="comment">// Accumulate in P_yn_yn</span>
<a name="l01602"></a>01602                                                         <span class="keywordflow">else</span>    P_yn_yn+=dyn_dhn_R_dyn_dhnT;
<a name="l01603"></a>01603 
<a name="l01604"></a>01604                                                         obj.m_pkk.insertMatrix(idx,idx, P_yn_yn );
<a name="l01605"></a>01605 
<a name="l01606"></a>01606                                                         obj.m_timLogger.leave(<span class="stringliteral">&quot;KF:9.create new LMs&quot;</span>);
<a name="l01607"></a>01607                                                 }
<a name="l01608"></a>01608                                         }
<a name="l01609"></a>01609                                 }
<a name="l01610"></a>01610 
<a name="l01611"></a>01611                                 <span class="keyword">template</span> &lt;<span class="keywordtype">size_t</span> VEH_SIZE, <span class="keywordtype">size_t</span> OBS_SIZE, <span class="keywordtype">size_t</span> ACT_SIZE, <span class="keyword">typename</span> KFTYPE&gt;
<a name="l01612"></a><a class="code" href="structmrpt_1_1bayes_1_1detail_1_1_c_run_one_kalman_iteration__add_new_landmarks.html#a7fb7cdc74f9d74130b0e4983e6c11543">01612</a>                                 <span class="keywordtype">void</span> operator()(
<a name="l01613"></a>01613                                         <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html" title="Virtual base for Kalman Filter (EKF,IEKF,UKF) implementations.">CKalmanFilterCapable&lt;VEH_SIZE,OBS_SIZE,0 /* FEAT_SIZE=0 */,ACT_SIZE,KFTYPE&gt;</a> &amp;obj,
<a name="l01614"></a>01614                                         <span class="keyword">const</span> <span class="keyword">typename</span> <a class="code" href="classstd_1_1vector.html" title="STL class.">CKalmanFilterCapable&lt;VEH_SIZE,OBS_SIZE,0 /* FEAT_SIZE=0 */,ACT_SIZE,KFTYPE&gt;::vector_KFArray_OBS</a> &amp; Z,
<a name="l01615"></a>01615                                         <span class="keyword">const</span> <a class="code" href="classstd_1_1vector.html" title="STL class.">vector_int</a>       &amp;data_association,
<a name="l01616"></a>01616                                         <span class="keyword">const</span> <span class="keyword">typename</span> <a class="code" href="classmrpt_1_1math_1_1_c_matrix_fixed_numeric.html" title="A numeric matrix of compile-time fixed size.">CKalmanFilterCapable&lt;VEH_SIZE,OBS_SIZE,0 /* FEAT_SIZE=0 */,ACT_SIZE,KFTYPE&gt;::KFMatrix_OxO</a>                &amp;R
<a name="l01617"></a>01617                                 )
<a name="l01618"></a>01618                                 {
<a name="l01619"></a>01619                                         <span class="comment">// Do nothing: this is NOT a SLAM problem.</span>
<a name="l01620"></a>01620                                 }
<a name="l01621"></a>01621 
<a name="l01622"></a>01622                         }; <span class="comment">// end runOneKalmanIteration_addNewLandmarks</span>
<a name="l01623"></a>01623 
<a name="l01624"></a>01624                         <span class="keyword">template</span> &lt;<span class="keywordtype">size_t</span> VEH_SIZE, <span class="keywordtype">size_t</span> OBS_SIZE, <span class="keywordtype">size_t</span> FEAT_SIZE, <span class="keywordtype">size_t</span> ACT_SIZE, <span class="keyword">typename</span> KFTYPE&gt;
<a name="l01625"></a><a class="code" href="namespacemrpt_1_1bayes_1_1detail.html#aeec894a458a3e7175e707871cd796f34">01625</a>                         <span class="keyword">inline</span> <span class="keywordtype">size_t</span> <a class="code" href="namespacemrpt_1_1bayes_1_1detail.html#aeec894a458a3e7175e707871cd796f34">getNumberOfLandmarksInMap</a>(<span class="keyword">const</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html" title="Virtual base for Kalman Filter (EKF,IEKF,UKF) implementations.">CKalmanFilterCapable&lt;VEH_SIZE,OBS_SIZE,FEAT_SIZE,ACT_SIZE,KFTYPE&gt;</a> &amp;obj)
<a name="l01626"></a>01626                         {
<a name="l01627"></a>01627                                 <span class="keywordflow">return</span> (obj.getStateVectorLength()-VEH_SIZE)/FEAT_SIZE;
<a name="l01628"></a>01628                         }
<a name="l01629"></a>01629                         <span class="comment">// Specialization for FEAT_SIZE=0</span>
<a name="l01630"></a>01630                         <span class="keyword">template</span> &lt;<span class="keywordtype">size_t</span> VEH_SIZE, <span class="keywordtype">size_t</span> OBS_SIZE, <span class="keywordtype">size_t</span> ACT_SIZE, <span class="keyword">typename</span> KFTYPE&gt;
<a name="l01631"></a><a class="code" href="namespacemrpt_1_1bayes_1_1detail.html#abb695f7e7ecf6a5deb79b1c4190536b7">01631</a>                         <span class="keyword">inline</span> <span class="keywordtype">size_t</span> <a class="code" href="namespacemrpt_1_1bayes_1_1detail.html#aeec894a458a3e7175e707871cd796f34">getNumberOfLandmarksInMap</a>(<span class="keyword">const</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html" title="Virtual base for Kalman Filter (EKF,IEKF,UKF) implementations.">CKalmanFilterCapable&lt;VEH_SIZE,OBS_SIZE,0 /*FEAT_SIZE*/,ACT_SIZE,KFTYPE&gt;</a> &amp;obj)
<a name="l01632"></a>01632                         {
<a name="l01633"></a>01633                                 <span class="keywordflow">return</span> 0;
<a name="l01634"></a>01634                         }
<a name="l01635"></a>01635 
<a name="l01636"></a>01636                         <span class="keyword">template</span> &lt;<span class="keywordtype">size_t</span> VEH_SIZE, <span class="keywordtype">size_t</span> OBS_SIZE, <span class="keywordtype">size_t</span> FEAT_SIZE, <span class="keywordtype">size_t</span> ACT_SIZE, <span class="keyword">typename</span> KFTYPE&gt;
<a name="l01637"></a><a class="code" href="namespacemrpt_1_1bayes_1_1detail.html#aafff1b2b519f6fb209de6ebde0830c19">01637</a>                         <span class="keyword">inline</span> <span class="keywordtype">bool</span> <a class="code" href="namespacemrpt_1_1bayes_1_1detail.html#aafff1b2b519f6fb209de6ebde0830c19">isMapEmpty</a>(<span class="keyword">const</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html" title="Virtual base for Kalman Filter (EKF,IEKF,UKF) implementations.">CKalmanFilterCapable&lt;VEH_SIZE,OBS_SIZE,FEAT_SIZE,ACT_SIZE,KFTYPE&gt;</a> &amp;obj)
<a name="l01638"></a>01638                         {
<a name="l01639"></a>01639                                 <span class="keywordflow">return</span> (obj.getStateVectorLength()==VEH_SIZE);
<a name="l01640"></a>01640                         }
<a name="l01641"></a>01641                         <span class="comment">// Specialization for FEAT_SIZE=0</span>
<a name="l01642"></a>01642                         <span class="keyword">template</span> &lt;<span class="keywordtype">size_t</span> VEH_SIZE, <span class="keywordtype">size_t</span> OBS_SIZE, <span class="keywordtype">size_t</span> ACT_SIZE, <span class="keyword">typename</span> KFTYPE&gt;
<a name="l01643"></a><a class="code" href="namespacemrpt_1_1bayes_1_1detail.html#af98c0e1cce6e03e69204df0c376392eb">01643</a>                         <span class="keyword">inline</span> <span class="keywordtype">bool</span> <a class="code" href="namespacemrpt_1_1bayes_1_1detail.html#aafff1b2b519f6fb209de6ebde0830c19">isMapEmpty</a> (<span class="keyword">const</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_kalman_filter_capable.html" title="Virtual base for Kalman Filter (EKF,IEKF,UKF) implementations.">CKalmanFilterCapable&lt;VEH_SIZE,OBS_SIZE,0 /*FEAT_SIZE*/,ACT_SIZE,KFTYPE&gt;</a> &amp;obj)
<a name="l01644"></a>01644                         {
<a name="l01645"></a>01645                                 <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01646"></a>01646                         }
<a name="l01647"></a>01647 
<a name="l01648"></a>01648                 } <span class="comment">// end namespace &quot;detail&quot;</span>
<a name="l01649"></a>01649 
<a name="l01650"></a>01650         } <span class="comment">// end namespace</span>
<a name="l01651"></a>01651 
<a name="l01652"></a>01652         <span class="comment">// Specializations MUST occur at the same namespace:</span>
<a name="l01653"></a>01653         <span class="keyword">namespace </span>utils
<a name="l01654"></a>01654         {
<a name="l01655"></a>01655                 <span class="keyword">template</span> &lt;&gt;
<a name="l01656"></a>01656                 <span class="keyword">struct </span><a class="code" href="structmrpt_1_1utils_1_1_t_enum_type_filler.html" title="Only specializations of this class are defined for each enum type of interest.">TEnumTypeFiller</a>&lt;bayes::<a class="code" href="group__mrpt__bayes__grp.html#ga93ff73c3a01619f01d97fd80dff40d14" title="The Kalman Filter algorithm to employ in bayes::CKalmanFilterCapable For further details on each algo...">TKFMethod</a>&gt;
<a name="l01657"></a>01657                 {
<a name="l01658"></a><a class="code" href="structmrpt_1_1utils_1_1_t_enum_type_filler_3_01bayes_1_1_t_k_f_method_01_4.html#acf78d97716e240c8ba8e5a6b8380b075">01658</a>                         <span class="keyword">typedef</span> bayes<a class="code" href="group__mrpt__bayes__grp.html#ga93ff73c3a01619f01d97fd80dff40d14" title="The Kalman Filter algorithm to employ in bayes::CKalmanFilterCapable For further details on each algo...">::TKFMethod</a> <a class="code" href="structmrpt_1_1utils_1_1_t_enum_type_filler_3_01bayes_1_1_t_k_f_method_01_4.html#acf78d97716e240c8ba8e5a6b8380b075">enum_t</a>;
<a name="l01659"></a><a class="code" href="structmrpt_1_1utils_1_1_t_enum_type_filler_3_01bayes_1_1_t_k_f_method_01_4.html#a995cd62ac02eeefa56cf7026e9a3a25c">01659</a>                         <span class="keyword">static</span> <span class="keywordtype">void</span> <a class="code" href="eigen__plugins_8h.html#a57fce471b07c3c84924883b5e17e2388">fill</a>(<a class="code" href="classmrpt_1_1utils_1_1bimap.html" title="A bidirectional version of std::map, declared as bimap&lt;KEY,VALUE&gt; and which actually contains two std::...">bimap&lt;enum_t,std::string&gt;</a>  &amp;m_map)
<a name="l01660"></a>01660                         {
<a name="l01661"></a>01661                                 m_map.<a class="code" href="classmrpt_1_1utils_1_1bimap.html#af21e6b0fcd4c2046adf6e6a9a9b3c997" title="Insert a new pair KEY&lt;-&gt;VALUE in the bi-map.">insert</a>(<a class="code" href="group__mrpt__bayes__grp.html#gga93ff73c3a01619f01d97fd80dff40d14a5ad91d60187b5cca61d25994f7827dc0">bayes::kfEKFNaive</a>,          <span class="stringliteral">&quot;kfEKFNaive&quot;</span>);
<a name="l01662"></a>01662                                 m_map.<a class="code" href="classmrpt_1_1utils_1_1bimap.html#af21e6b0fcd4c2046adf6e6a9a9b3c997" title="Insert a new pair KEY&lt;-&gt;VALUE in the bi-map.">insert</a>(<a class="code" href="group__mrpt__bayes__grp.html#gga93ff73c3a01619f01d97fd80dff40d14acb25ab5d45035eb456de1c7250dbcf5a">bayes::kfEKFAlaDavison</a>,     <span class="stringliteral">&quot;kfEKFAlaDavison&quot;</span>);
<a name="l01663"></a>01663                                 m_map.<a class="code" href="classmrpt_1_1utils_1_1bimap.html#af21e6b0fcd4c2046adf6e6a9a9b3c997" title="Insert a new pair KEY&lt;-&gt;VALUE in the bi-map.">insert</a>(<a class="code" href="group__mrpt__bayes__grp.html#gga93ff73c3a01619f01d97fd80dff40d14ac5aee4885e69b59edf793342e96acab3">bayes::kfIKFFull</a>,           <span class="stringliteral">&quot;kfIKFFull&quot;</span>);
<a name="l01664"></a>01664                                 m_map.<a class="code" href="classmrpt_1_1utils_1_1bimap.html#af21e6b0fcd4c2046adf6e6a9a9b3c997" title="Insert a new pair KEY&lt;-&gt;VALUE in the bi-map.">insert</a>(<a class="code" href="group__mrpt__bayes__grp.html#gga93ff73c3a01619f01d97fd80dff40d14a0c3af1381c1d9b4b4ebb04370dc59ba9">bayes::kfIKF</a>,               <span class="stringliteral">&quot;kfIKF&quot;</span>);
<a name="l01665"></a>01665                         }
<a name="l01666"></a>01666                 };
<a name="l01667"></a>01667         } <span class="comment">// End of namespace</span>
<a name="l01668"></a>01668 
<a name="l01669"></a>01669 } <span class="comment">// end namespace</span>
<a name="l01670"></a>01670 
<a name="l01671"></a>01671 <span class="preprocessor">#endif</span>
</pre></div></div>
</div>
<br><hr><br> <table border="0" width="100%"> <tr> <td> Page generated by <a href="http://www.doxygen.org" target="_blank">Doxygen 1.7.5</a> for MRPT 0.9.5 SVN: at Sun Sep 25 17:20:18 UTC 2011</td><td></td> <td width="100"> </td> <td width="150">  </td></tr> </table>  </body></html>