Sophie

Sophie

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

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>PF_implementations.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">PF_implementations.h</div>  </div>
</div>
<div class="contents">
<a href="_p_f__implementations_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 
<a name="l00029"></a>00029 <span class="preprocessor">#ifndef PF_implementations_H</span>
<a name="l00030"></a>00030 <span class="preprocessor"></span><span class="preprocessor">#define PF_implementations_H</span>
<a name="l00031"></a>00031 <span class="preprocessor"></span>
<a name="l00032"></a>00032 <span class="preprocessor">#include &lt;<a class="code" href="stl__extensions_8h.html">mrpt/utils/stl_extensions.h</a>&gt;</span>
<a name="l00033"></a>00033 <span class="preprocessor">#include &lt;<a class="code" href="_c_particle_filter_data_8h.html">mrpt/bayes/CParticleFilterData.h</a>&gt;</span>
<a name="l00034"></a>00034 <span class="preprocessor">#include &lt;<a class="code" href="random_8h.html">mrpt/random.h</a>&gt;</span>
<a name="l00035"></a>00035 <span class="preprocessor">#include &lt;<a class="code" href="_c_action_collection_8h.html">mrpt/slam/CActionCollection.h</a>&gt;</span>
<a name="l00036"></a>00036 <span class="preprocessor">#include &lt;<a class="code" href="_c_action_robot_movement3_d_8h.html">mrpt/slam/CActionRobotMovement3D.h</a>&gt;</span>
<a name="l00037"></a>00037 <span class="preprocessor">#include &lt;<a class="code" href="_c_action_robot_movement2_d_8h.html">mrpt/slam/CActionRobotMovement2D.h</a>&gt;</span>
<a name="l00038"></a>00038 <span class="preprocessor">#include &lt;<a class="code" href="_t_k_l_d_params_8h.html">mrpt/slam/TKLDParams.h</a>&gt;</span>
<a name="l00039"></a>00039 
<a name="l00040"></a>00040 <span class="preprocessor">#include &lt;<a class="code" href="distributions_8h.html">mrpt/math/distributions.h</a>&gt;</span>  <span class="comment">// chi2inv</span>
<a name="l00041"></a>00041 
<a name="l00042"></a>00042 <span class="preprocessor">#include &lt;<a class="code" href="_p_f__implementations__data_8h.html">mrpt/slam/PF_implementations_data.h</a>&gt;</span>
<a name="l00043"></a>00043 
<a name="l00044"></a>00044 <span class="preprocessor">#include &lt;<a class="code" href="slam_2include_2mrpt_2slam_2link__pragmas_8h.html">mrpt/slam/link_pragmas.h</a>&gt;</span>
<a name="l00045"></a>00045 
<a name="l00046"></a>00046 <span class="comment"></span>
<a name="l00047"></a>00047 <span class="comment">/** \file PF_implementations.h</span>
<a name="l00048"></a>00048 <span class="comment">  *  This file contains the implementations of the template members declared in mrpt::slam::PF_implementation</span>
<a name="l00049"></a>00049 <span class="comment">  */</span>
<a name="l00050"></a>00050 
<a name="l00051"></a>00051 <span class="keyword">namespace </span>mrpt
<a name="l00052"></a>00052 {
<a name="l00053"></a>00053         <span class="keyword">namespace </span>slam
<a name="l00054"></a>00054         {
<a name="l00055"></a>00055                 <span class="keyword">using namespace </span>std;
<a name="l00056"></a>00056                 <span class="keyword">using namespace </span>mrpt::utils;
<a name="l00057"></a>00057                 <span class="keyword">using namespace </span>mrpt::random;
<a name="l00058"></a>00058                 <span class="keyword">using namespace </span>mrpt::poses;
<a name="l00059"></a>00059                 <span class="keyword">using namespace </span>mrpt::bayes;
<a name="l00060"></a>00060                 <span class="keyword">using namespace </span>mrpt::math;
<a name="l00061"></a>00061 <span class="comment"></span>
<a name="l00062"></a>00062 <span class="comment">                /** Auxiliary method called by PF implementations: return true if we have both action &amp; observation,</span>
<a name="l00063"></a>00063 <span class="comment">                  *   otherwise, return false AND accumulate the odometry so when we have an observation we didn&#39;t lose a thing.</span>
<a name="l00064"></a>00064 <span class="comment">                  *   On return=true, the &quot;m_movementDrawer&quot; member is loaded and ready to draw samples of the increment of pose since last step.</span>
<a name="l00065"></a>00065 <span class="comment">                  *  This method is smart enough to accumulate CActionRobotMovement2D or CActionRobotMovement3D, whatever comes in.</span>
<a name="l00066"></a>00066 <span class="comment">                  *   \ingroup mrpt_slam_grp </span>
<a name="l00067"></a>00067 <span class="comment">                  */</span>
<a name="l00068"></a>00068                 <span class="keyword">template</span> &lt;<span class="keyword">class</span> PARTICLE_TYPE,<span class="keyword">class</span> MY<span class="keywordtype">SEL</span>F&gt;
<a name="l00069"></a>00069                 <span class="keyword">template</span> &lt;<span class="keyword">class</span> BINTYPE&gt;
<a name="l00070"></a><a class="code" href="group__mrpt__slam__grp.html#gaf10ab5d4285a563ed99d28aed9a31c39">00070</a>                 <span class="keywordtype">bool</span> <a class="code" href="classmrpt_1_1slam_1_1_p_f__implementation.html" title="A set of common data shared by PF implementations for both SLAM and localization.">PF_implementation&lt;PARTICLE_TYPE,MYSELF&gt;::PF_SLAM_implementation_gatherActionsCheckBothActObs</a>(
<a name="l00071"></a>00071                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1slam_1_1_c_action_collection.html" title="Declares a class for storing a collection of robot actions.">CActionCollection</a> * actions,
<a name="l00072"></a>00072                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1slam_1_1_c_sensory_frame.html" title="Declares a class for storing a &quot;sensory frame&quot;, a set of &quot;observations&quot; taken by the robot approximat...">CSensoryFrame</a>             * sf )
<a name="l00073"></a>00073                 {
<a name="l00074"></a>00074                         MYSELF *me = <span class="keyword">static_cast&lt;</span>MYSELF*<span class="keyword">&gt;</span>(<span class="keyword">this</span>);
<a name="l00075"></a>00075 
<a name="l00076"></a>00076                         <span class="keywordflow">if</span> (actions!=NULL)      <span class="comment">// A valid action?</span>
<a name="l00077"></a>00077                         {
<a name="l00078"></a>00078                                 {
<a name="l00079"></a>00079                                         <a class="code" href="structmrpt_1_1slam_1_1_c_action_robot_movement2_d_ptr.html">CActionRobotMovement2DPtr</a>       robotMovement2D = actions-&gt;<a class="code" href="classmrpt_1_1slam_1_1_c_action_collection.html#a03485a37d5f8b0057ad5722b800ced25" title="Returns the best pose increment estimator in the collection, based on the determinant of its pose cha...">getBestMovementEstimation</a>();
<a name="l00080"></a>00080                                         <span class="keywordflow">if</span> (robotMovement2D.present())
<a name="l00081"></a>00081                                         {
<a name="l00082"></a>00082                                                 <span class="keywordflow">if</span> (m_accumRobotMovement3DIsValid) <a class="code" href="mrpt__macros_8h.html#aaa3f404ea85a6575a7139f8d101370ba">THROW_EXCEPTION</a>(<span class="stringliteral">&quot;Mixing 2D and 3D actions is not allowed.&quot;</span>)
<a name="l00083"></a>00083 
<a name="l00084"></a>00084                                                 <span class="keywordflow">if</span> (!m_accumRobotMovement2DIsValid)
<a name="l00085"></a>00085                                                 {               <span class="comment">// First time:</span>
<a name="l00086"></a>00086                                                         robotMovement2D-&gt;poseChange-&gt;getMean( m_accumRobotMovement2D.rawOdometryIncrementReading );
<a name="l00087"></a>00087                                                         m_accumRobotMovement2D.motionModelConfiguration = robotMovement2D-&gt;motionModelConfiguration;
<a name="l00088"></a>00088                                                 }
<a name="l00089"></a>00089                                                 <span class="keywordflow">else</span>  m_accumRobotMovement2D.rawOdometryIncrementReading += robotMovement2D-&gt;poseChange-&gt;getMeanVal();
<a name="l00090"></a>00090 
<a name="l00091"></a>00091                                                 m_accumRobotMovement2DIsValid = <span class="keyword">true</span>;
<a name="l00092"></a>00092                                         }
<a name="l00093"></a>00093                                         <span class="keywordflow">else</span> <span class="comment">// If there is no 2D action, look for a 3D action:</span>
<a name="l00094"></a>00094                                         {
<a name="l00095"></a>00095                                                 <a class="code" href="structmrpt_1_1slam_1_1_c_action_robot_movement3_d_ptr.html">CActionRobotMovement3DPtr</a>       robotMovement3D = actions-&gt;<a class="code" href="classmrpt_1_1slam_1_1_c_action_collection.html#a831ca7e47b84a4537ac8b6b2ff096040" title="Access to the i&#39;th action of a given class, or a NULL smart pointer if there is no action of that cla...">getActionByClass</a>&lt;<a class="code" href="classmrpt_1_1slam_1_1_c_action_robot_movement3_d.html" title="Represents a probabilistic 3D (6D) movement.">CActionRobotMovement3D</a>&gt;();
<a name="l00096"></a>00096                                                 <span class="keywordflow">if</span> (robotMovement3D)
<a name="l00097"></a>00097                                                 {
<a name="l00098"></a>00098                                                         <span class="keywordflow">if</span> (m_accumRobotMovement2DIsValid) <a class="code" href="mrpt__macros_8h.html#aaa3f404ea85a6575a7139f8d101370ba">THROW_EXCEPTION</a>(<span class="stringliteral">&quot;Mixing 2D and 3D actions is not allowed.&quot;</span>)
<a name="l00099"></a>00099 
<a name="l00100"></a>00100                                                         <span class="keywordflow">if</span> (!m_accumRobotMovement3DIsValid)
<a name="l00101"></a>00101                                                                         m_accumRobotMovement3D = robotMovement3D-&gt;poseChange;
<a name="l00102"></a>00102                                                         <span class="keywordflow">else</span>    m_accumRobotMovement3D += robotMovement3D-&gt;poseChange;
<a name="l00103"></a>00103                                                         <span class="comment">// This &quot;+=&quot; takes care of all the Jacobians, etc... You MUST love C++!!! ;-)</span>
<a name="l00104"></a>00104 
<a name="l00105"></a>00105                                                         m_accumRobotMovement3DIsValid = <span class="keyword">true</span>;
<a name="l00106"></a>00106                                                 }
<a name="l00107"></a>00107                                                 <span class="keywordflow">else</span>
<a name="l00108"></a>00108                                                         <span class="keywordflow">return</span> <span class="keyword">false</span>; <span class="comment">// We have no actions...</span>
<a name="l00109"></a>00109                                         }
<a name="l00110"></a>00110                                 }
<a name="l00111"></a>00111                         }
<a name="l00112"></a>00112 
<a name="l00113"></a>00113                         <span class="keyword">const</span> <span class="keywordtype">bool</span> SFhasValidObservations = (sf==NULL) ? <span class="keyword">false</span> : PF_SLAM_implementation_doWeHaveValidObservations(me-&gt;m_particles,sf);
<a name="l00114"></a>00114 
<a name="l00115"></a>00115                         <span class="comment">// All the things we need?</span>
<a name="l00116"></a>00116                         <span class="keywordflow">if</span> (! ((m_accumRobotMovement2DIsValid || m_accumRobotMovement3DIsValid) &amp;&amp; SFhasValidObservations))
<a name="l00117"></a>00117                                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00118"></a>00118 
<a name="l00119"></a>00119                         <span class="comment">// Since we&#39;re gonna return true, load the pose-drawer:</span>
<a name="l00120"></a>00120                         <span class="comment">// Take the accum. actions as input:</span>
<a name="l00121"></a>00121                         <span class="keywordflow">if</span> (m_accumRobotMovement3DIsValid)
<a name="l00122"></a>00122                         {
<a name="l00123"></a>00123                                 m_movementDrawer.setPosePDF( m_accumRobotMovement3D );  <span class="comment">// &lt;--- Set mov. drawer</span>
<a name="l00124"></a>00124                                 m_accumRobotMovement3DIsValid = <span class="keyword">false</span>; <span class="comment">// Reset odometry for next iteration</span>
<a name="l00125"></a>00125                         }
<a name="l00126"></a>00126                         <span class="keywordflow">else</span>
<a name="l00127"></a>00127                         {
<a name="l00128"></a>00128                                 <a class="code" href="classmrpt_1_1slam_1_1_c_action_robot_movement2_d.html" title="Represents a probabilistic 2D movement of the robot mobile base.">CActionRobotMovement2D</a>  theResultingRobotMov;
<a name="l00129"></a>00129                                 theResultingRobotMov.<a class="code" href="classmrpt_1_1slam_1_1_c_action_robot_movement2_d.html#ae311480bde721a04b002cc7b08597fbf" title="Computes the PDF of the pose increment from an odometry reading and according to the given motion mod...">computeFromOdometry</a>(
<a name="l00130"></a>00130                                         m_accumRobotMovement2D.rawOdometryIncrementReading,
<a name="l00131"></a>00131                                         m_accumRobotMovement2D.motionModelConfiguration );
<a name="l00132"></a>00132 
<a name="l00133"></a>00133                                 m_movementDrawer.setPosePDF( theResultingRobotMov.<a class="code" href="classmrpt_1_1slam_1_1_c_action_robot_movement2_d.html#a657f5eb086d62c2cd601e5ea2ab11514" title="The 2D pose change probabilistic estimation.">poseChange</a> );  <span class="comment">// &lt;--- Set mov. drawer</span>
<a name="l00134"></a>00134                                 m_accumRobotMovement2DIsValid = <span class="keyword">false</span>; <span class="comment">// Reset odometry for next iteration</span>
<a name="l00135"></a>00135                         }
<a name="l00136"></a>00136                         <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00137"></a>00137                 } <span class="comment">// end of PF_SLAM_implementation_gatherActionsCheckBothActObs</span>
<a name="l00138"></a>00138 <span class="comment"></span>
<a name="l00139"></a>00139 <span class="comment">                /** A generic implementation of the PF method &quot;prediction_and_update_pfAuxiliaryPFOptimal&quot; (optimal sampling with rejection sampling approximation),</span>
<a name="l00140"></a>00140 <span class="comment">                  *  common to both localization and mapping.</span>
<a name="l00141"></a>00141 <span class="comment">                  *</span>
<a name="l00142"></a>00142 <span class="comment">                  * - BINTYPE: TPoseBin or whatever to discretize the sample space for KLD-sampling.</span>
<a name="l00143"></a>00143 <span class="comment">                  *</span>
<a name="l00144"></a>00144 <span class="comment">                  *  This method implements optimal sampling with a rejection sampling-based approximation of the true posterior.</span>
<a name="l00145"></a>00145 <span class="comment">                  *  For details, see the papers:</span>
<a name="l00146"></a>00146 <span class="comment">                  *</span>
<a name="l00147"></a>00147 <span class="comment">                  *  J.-L. Blanco, J. González, and J.-A. Fernández-Madrigal,</span>
<a name="l00148"></a>00148 <span class="comment">                  *    &quot;An Optimal Filtering Algorithm for Non-Parametric Observation Models in</span>
<a name="l00149"></a>00149 <span class="comment">                  *     Robot Localization,&quot; in Proc. IEEE International Conference on Robotics</span>
<a name="l00150"></a>00150 <span class="comment">                  *     and Automation (ICRA&#39;08), 2008, pp. 461–466.</span>
<a name="l00151"></a>00151 <span class="comment">                  */</span>
<a name="l00152"></a>00152                 <span class="keyword">template</span> &lt;<span class="keyword">class</span> PARTICLE_TYPE,<span class="keyword">class</span> MY<span class="keywordtype">SEL</span>F&gt;
<a name="l00153"></a>00153                 <span class="keyword">template</span> &lt;<span class="keyword">class</span> BINTYPE&gt;
<a name="l00154"></a><a class="code" href="classmrpt_1_1slam_1_1_p_f__implementation.html#ab73b076d0b8f477deb4b0a8bcf0fdedb">00154</a>                 <span class="keywordtype">void</span> <a class="code" href="classmrpt_1_1slam_1_1_p_f__implementation.html" title="A set of common data shared by PF implementations for both SLAM and localization.">PF_implementation&lt;PARTICLE_TYPE,MYSELF&gt;::PF_SLAM_implementation_pfAuxiliaryPFOptimal</a>(
<a name="l00155"></a>00155                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1slam_1_1_c_action_collection.html" title="Declares a class for storing a collection of robot actions.">CActionCollection</a> * actions,
<a name="l00156"></a>00156                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1slam_1_1_c_sensory_frame.html" title="Declares a class for storing a &quot;sensory frame&quot;, a set of &quot;observations&quot; taken by the robot approximat...">CSensoryFrame</a>             * sf,
<a name="l00157"></a>00157                         <span class="keyword">const</span> <a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html" title="The configuration of a particle filter.">CParticleFilter::TParticleFilterOptions</a> &amp;PF_options,
<a name="l00158"></a>00158                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1slam_1_1_t_k_l_d_params.html" title="Option set for KLD algorithm.">TKLDParams</a> &amp;KLD_options)
<a name="l00159"></a>00159                 {
<a name="l00160"></a>00160                         <span class="comment">// Standard and Optimal AuxiliaryPF actually have a shared implementation body:</span>
<a name="l00161"></a>00161                         PF_SLAM_implementation_pfAuxiliaryPFStandardAndOptimal&lt;BINTYPE&gt;(actions,sf,PF_options,KLD_options, <span class="keyword">true</span> <span class="comment">/*Optimal PF*/</span> );
<a name="l00162"></a>00162                 }
<a name="l00163"></a>00163 
<a name="l00164"></a>00164 <span class="comment"></span>
<a name="l00165"></a>00165 <span class="comment">                /** A generic implementation of the PF method &quot;pfStandardProposal&quot; (standard proposal distribution, that is, a simple SIS particle filter),</span>
<a name="l00166"></a>00166 <span class="comment">                  *  common to both localization and mapping.</span>
<a name="l00167"></a>00167 <span class="comment">                  *</span>
<a name="l00168"></a>00168 <span class="comment">                  * - BINTYPE: TPoseBin or whatever to discretize the sample space for KLD-sampling.</span>
<a name="l00169"></a>00169 <span class="comment">                  */</span>
<a name="l00170"></a>00170                 <span class="keyword">template</span> &lt;<span class="keyword">class</span> PARTICLE_TYPE,<span class="keyword">class</span> MY<span class="keywordtype">SEL</span>F&gt;
<a name="l00171"></a>00171                 <span class="keyword">template</span> &lt;<span class="keyword">class</span> BINTYPE&gt;
<a name="l00172"></a><a class="code" href="classmrpt_1_1slam_1_1_p_f__implementation.html#a5feefe2d7fb194f0fb74608f561e94a7">00172</a>                 <span class="keywordtype">void</span> <a class="code" href="classmrpt_1_1slam_1_1_p_f__implementation.html" title="A set of common data shared by PF implementations for both SLAM and localization.">PF_implementation&lt;PARTICLE_TYPE,MYSELF&gt;::PF_SLAM_implementation_pfStandardProposal</a>(
<a name="l00173"></a>00173                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1slam_1_1_c_action_collection.html" title="Declares a class for storing a collection of robot actions.">CActionCollection</a> * actions,
<a name="l00174"></a>00174                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1slam_1_1_c_sensory_frame.html" title="Declares a class for storing a &quot;sensory frame&quot;, a set of &quot;observations&quot; taken by the robot approximat...">CSensoryFrame</a>             * sf,
<a name="l00175"></a>00175                         <span class="keyword">const</span> <a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html" title="The configuration of a particle filter.">CParticleFilter::TParticleFilterOptions</a> &amp;PF_options,
<a name="l00176"></a>00176                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1slam_1_1_t_k_l_d_params.html" title="Option set for KLD algorithm.">TKLDParams</a> &amp;KLD_options)
<a name="l00177"></a>00177                 {
<a name="l00178"></a>00178                         <a class="code" href="mrpt__macros_8h.html#a45b840af519f33816311acdbb28d7c10">MRPT_START</a>
<a name="l00179"></a>00179                         <span class="keyword">typedef</span> std<a class="code" href="classstd_1_1set.html" title="STL class.">::set&lt;BINTYPE,typename BINTYPE::lt_operator&gt;</a>         TSetStateSpaceBins;
<a name="l00180"></a>00180 
<a name="l00181"></a>00181                         MYSELF *me = <span class="keyword">static_cast&lt;</span>MYSELF*<span class="keyword">&gt;</span>(<span class="keyword">this</span>);
<a name="l00182"></a>00182 
<a name="l00183"></a>00183                         <span class="comment">// In this method we don&#39;t need the &quot;PF_SLAM_implementation_gatherActionsCheckBothActObs&quot; machinery,</span>
<a name="l00184"></a>00184                         <span class="comment">//  since prediction &amp; update are two independent stages well separated for this algorithm.</span>
<a name="l00185"></a>00185 
<a name="l00186"></a>00186                         <span class="comment">// --------------------------------------------------------------------------------------</span>
<a name="l00187"></a>00187                         <span class="comment">//  Prediction: Simply draw samples from the motion model</span>
<a name="l00188"></a>00188                         <span class="comment">// --------------------------------------------------------------------------------------</span>
<a name="l00189"></a>00189                         <span class="keywordflow">if</span> (actions)
<a name="l00190"></a>00190                         {
<a name="l00191"></a>00191                                 <span class="comment">// Find a robot movement estimation:</span>
<a name="l00192"></a>00192                                 <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a>                         motionModelMeanIncr;
<a name="l00193"></a>00193                                 {
<a name="l00194"></a>00194                                         <a class="code" href="structmrpt_1_1slam_1_1_c_action_robot_movement2_d_ptr.html">CActionRobotMovement2DPtr</a>       robotMovement2D = actions-&gt;<a class="code" href="classmrpt_1_1slam_1_1_c_action_collection.html#a03485a37d5f8b0057ad5722b800ced25" title="Returns the best pose increment estimator in the collection, based on the determinant of its pose cha...">getBestMovementEstimation</a>();
<a name="l00195"></a>00195                                         <span class="comment">// If there is no 2D action, look for a 3D action:</span>
<a name="l00196"></a>00196                                         <span class="keywordflow">if</span> (robotMovement2D.present())
<a name="l00197"></a>00197                                         {
<a name="l00198"></a>00198                                                 m_movementDrawer.setPosePDF( robotMovement2D-&gt;poseChange );
<a name="l00199"></a>00199                                                 motionModelMeanIncr = robotMovement2D-&gt;poseChange-&gt;getMeanVal();
<a name="l00200"></a>00200                                         }
<a name="l00201"></a>00201                                         <span class="keywordflow">else</span>
<a name="l00202"></a>00202                                         {
<a name="l00203"></a>00203                                                 <a class="code" href="structmrpt_1_1slam_1_1_c_action_robot_movement3_d_ptr.html">CActionRobotMovement3DPtr</a>       robotMovement3D = actions-&gt;<a class="code" href="classmrpt_1_1slam_1_1_c_action_collection.html#a831ca7e47b84a4537ac8b6b2ff096040" title="Access to the i&#39;th action of a given class, or a NULL smart pointer if there is no action of that cla...">getActionByClass</a>&lt;<a class="code" href="classmrpt_1_1slam_1_1_c_action_robot_movement3_d.html" title="Represents a probabilistic 3D (6D) movement.">CActionRobotMovement3D</a>&gt;();
<a name="l00204"></a>00204                                                 <span class="keywordflow">if</span> (robotMovement3D)
<a name="l00205"></a>00205                                                 {
<a name="l00206"></a>00206                                                         m_movementDrawer.setPosePDF( robotMovement3D-&gt;poseChange );
<a name="l00207"></a>00207                                                         robotMovement3D-&gt;poseChange.getMean( motionModelMeanIncr );
<a name="l00208"></a>00208                                                 }
<a name="l00209"></a>00209                                                 <span class="keywordflow">else</span> { <a class="code" href="mrpt__macros_8h.html#aaa3f404ea85a6575a7139f8d101370ba">THROW_EXCEPTION</a>(<span class="stringliteral">&quot;Action list does not contain any CActionRobotMovement2D or CActionRobotMovement3D object!&quot;</span>); }
<a name="l00210"></a>00210                                         }
<a name="l00211"></a>00211                                 }
<a name="l00212"></a>00212 
<a name="l00213"></a>00213                                 <span class="comment">// Update particle poses:</span>
<a name="l00214"></a>00214                                 <span class="keywordflow">if</span> ( !PF_options.<a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html#ae1373ee71fb2a0131f448042291d85f0" title="A flag that indicates whether the CParticleFilterCapable object should perform adative sample size (d...">adaptiveSampleSize</a> )
<a name="l00215"></a>00215                                 {
<a name="l00216"></a>00216                                         <span class="keyword">const</span> <span class="keywordtype">size_t</span> M = me-&gt;m_particles.size();
<a name="l00217"></a>00217                                         <span class="comment">// -------------------------------------------------------------</span>
<a name="l00218"></a>00218                                         <span class="comment">// FIXED SAMPLE SIZE</span>
<a name="l00219"></a>00219                                         <span class="comment">// -------------------------------------------------------------</span>
<a name="l00220"></a>00220                                         <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a> incrPose;
<a name="l00221"></a>00221                                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i=0;i&lt;M;i++)
<a name="l00222"></a>00222                                         {
<a name="l00223"></a>00223                                                 <span class="comment">// Generate gaussian-distributed 2D-pose increments according to mean-cov:</span>
<a name="l00224"></a>00224                                                 m_movementDrawer.drawSample( incrPose );
<a name="l00225"></a>00225                                                 <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a> finalPose = <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a>(*getLastPose(i)) + incrPose;
<a name="l00226"></a>00226 
<a name="l00227"></a>00227                                                 <span class="comment">// Update the particle with the new pose: this part is caller-dependant and must be implemented there:</span>
<a name="l00228"></a>00228                                                 PF_SLAM_implementation_custom_update_particle_with_new_pose( me-&gt;m_particles[i].d, <a class="code" href="structmrpt_1_1math_1_1_t_pose3_d.html" title="Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).">TPose3D</a>(finalPose) );
<a name="l00229"></a>00229                                         }
<a name="l00230"></a>00230                                 }
<a name="l00231"></a>00231                                 <span class="keywordflow">else</span>
<a name="l00232"></a>00232                                 {
<a name="l00233"></a>00233                                         <span class="comment">// -------------------------------------------------------------</span>
<a name="l00234"></a>00234                                         <span class="comment">//   ADAPTIVE SAMPLE SIZE</span>
<a name="l00235"></a>00235                                         <span class="comment">// Implementation of Dieter Fox&#39;s KLD algorithm</span>
<a name="l00236"></a>00236                                         <span class="comment">//  31-Oct-2006 (JLBC): First version</span>
<a name="l00237"></a>00237                                         <span class="comment">//  19-Jan-2009 (JLBC): Rewriten within a generic template</span>
<a name="l00238"></a>00238                                         <span class="comment">// -------------------------------------------------------------</span>
<a name="l00239"></a>00239                                         TSetStateSpaceBins stateSpaceBins;
<a name="l00240"></a>00240 
<a name="l00241"></a>00241                                         <span class="keywordtype">size_t</span> Nx = KLD_options.<a class="code" href="classmrpt_1_1slam_1_1_t_k_l_d_params.html#a3d919d633f69c9daefd18be697d0dc71" title="Parameters for the KLD adaptive sample size algorithm (see Dieter Fox&#39;s papers), which is used only i...">KLD_minSampleSize</a>;
<a name="l00242"></a>00242                                         <span class="keyword">const</span> <span class="keywordtype">double</span> delta_1 = 1.0 - KLD_options.<a class="code" href="classmrpt_1_1slam_1_1_t_k_l_d_params.html#a787e1c15d3653be9638c8e41d786a191">KLD_delta</a>;
<a name="l00243"></a>00243                                         <span class="keyword">const</span> <span class="keywordtype">double</span> epsilon_1 = 0.5 / KLD_options.<a class="code" href="classmrpt_1_1slam_1_1_t_k_l_d_params.html#a92daf8859b1e75f467c23e37d280e466">KLD_epsilon</a>;
<a name="l00244"></a>00244 
<a name="l00245"></a>00245                                         <span class="comment">// Prepare data for executing &quot;fastDrawSample&quot;</span>
<a name="l00246"></a>00246                                         me-&gt;prepareFastDrawSample(PF_options);
<a name="l00247"></a>00247 
<a name="l00248"></a>00248                                         <span class="comment">// The new particle set:</span>
<a name="l00249"></a>00249                                         std<a class="code" href="classstd_1_1vector.html">::vector&lt;TPose3D&gt;</a>  newParticles;
<a name="l00250"></a>00250                                         <a class="code" href="structmrpt_1_1dynamicsize__vector.html" title="The base class of MRPT vectors, actually, Eigen column matrices of dynamic size with specialized cons...">vector_double</a>         newParticlesWeight;
<a name="l00251"></a>00251                                         std<a class="code" href="classstd_1_1vector.html">::vector&lt;size_t&gt;</a>   newParticlesDerivedFromIdx;
<a name="l00252"></a>00252 
<a name="l00253"></a>00253                                         <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a>  increment_i;
<a name="l00254"></a>00254                                         <span class="keywordtype">size_t</span> N = 1;
<a name="l00255"></a>00255 
<a name="l00256"></a>00256                                         <span class="keywordflow">do</span>      <span class="comment">// THE MAIN DRAW SAMPLING LOOP</span>
<a name="l00257"></a>00257                                         {
<a name="l00258"></a>00258                                                 <span class="comment">// Draw a robot movement increment:</span>
<a name="l00259"></a>00259                                                 m_movementDrawer.drawSample( increment_i );
<a name="l00260"></a>00260 
<a name="l00261"></a>00261                                                 <span class="comment">// generate the new particle:</span>
<a name="l00262"></a>00262                                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> drawn_idx = me-&gt;fastDrawSample(PF_options);
<a name="l00263"></a>00263                                                 <span class="keyword">const</span> <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a> newPose = <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a>(*getLastPose(drawn_idx)) + increment_i;
<a name="l00264"></a>00264                                                 <span class="keyword">const</span> <a class="code" href="structmrpt_1_1math_1_1_t_pose3_d.html" title="Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).">TPose3D</a> newPose_s = newPose;
<a name="l00265"></a>00265 
<a name="l00266"></a>00266                                                 <span class="comment">// Add to the new particles list:</span>
<a name="l00267"></a>00267                                                 newParticles.push_back( newPose_s );
<a name="l00268"></a>00268                                                 newParticlesWeight.push_back(0);
<a name="l00269"></a>00269                                                 newParticlesDerivedFromIdx.push_back(drawn_idx);
<a name="l00270"></a>00270 
<a name="l00271"></a>00271                                                 <span class="comment">// Now, look if the particle falls in a new bin or not:</span>
<a name="l00272"></a>00272                                                 <span class="comment">// --------------------------------------------------------</span>
<a name="l00273"></a>00273                                                 BINTYPE p;
<a name="l00274"></a>00274                                                 KLF_loadBinFromParticle&lt;PARTICLE_TYPE,BINTYPE&gt;(p,KLD_options, me-&gt;m_particles[drawn_idx].d, &amp;newPose_s);
<a name="l00275"></a>00275 
<a name="l00276"></a>00276                                                 <span class="keywordflow">if</span> (stateSpaceBins.find( p )==stateSpaceBins.end())
<a name="l00277"></a>00277                                                 {
<a name="l00278"></a>00278                                                         <span class="comment">// It falls into a new bin:</span>
<a name="l00279"></a>00279                                                         <span class="comment">// Add to the stateSpaceBins:</span>
<a name="l00280"></a>00280                                                         stateSpaceBins.insert( p );
<a name="l00281"></a>00281 
<a name="l00282"></a>00282                                                         <span class="comment">// K = K + 1</span>
<a name="l00283"></a>00283                                                         <span class="keywordtype">size_t</span>  K = stateSpaceBins.size();
<a name="l00284"></a>00284                                                         <span class="keywordflow">if</span> ( K&gt;1) <span class="comment">//&amp;&amp; newParticles.size() &gt; options.KLD_minSampleSize )</span>
<a name="l00285"></a>00285                                                         {
<a name="l00286"></a>00286                                                                 <span class="comment">// Update the number of m_particles!!</span>
<a name="l00287"></a>00287                                                                 Nx =  <a class="code" href="namespacemrpt_1_1utils.html#ab7d9cdf7d271c2f41fc1c5c9fa7d0828" title="Returns the closer integer (int) to x.">round</a>(epsilon_1 * <a class="code" href="group__stats__grp.html#ga68b8a2208349a297c19f3a45c24457b1" title="The &quot;quantile&quot; of the Chi-Square distribution, for dimension &quot;dim&quot; and probability 0&lt;P&lt;1 (the inverse...">math::chi2inv</a>(delta_1,K-1));
<a name="l00288"></a>00288                                                                 <span class="comment">//printf(&quot;k=%u \tn=%u \tNx:%u\n&quot;, k, newParticles.size(), Nx);</span>
<a name="l00289"></a>00289                                                         }
<a name="l00290"></a>00290                                                 }
<a name="l00291"></a>00291                                                 N = newParticles.size();
<a name="l00292"></a>00292                                         } <span class="keywordflow">while</span> (       N &lt; max(Nx,(<span class="keywordtype">size_t</span>)KLD_options.<a class="code" href="classmrpt_1_1slam_1_1_t_k_l_d_params.html#a3d919d633f69c9daefd18be697d0dc71" title="Parameters for the KLD adaptive sample size algorithm (see Dieter Fox&#39;s papers), which is used only i...">KLD_minSampleSize</a>) &amp;&amp;
<a name="l00293"></a>00293                                                                 N &lt; KLD_options.<a class="code" href="classmrpt_1_1slam_1_1_t_k_l_d_params.html#aeb1dd89a8987c1f6957653d35aa0ccae">KLD_maxSampleSize</a> );
<a name="l00294"></a>00294 
<a name="l00295"></a>00295                                         <span class="comment">// ---------------------------------------------------------------------------------</span>
<a name="l00296"></a>00296                                         <span class="comment">// Substitute old by new particle set:</span>
<a name="l00297"></a>00297                                         <span class="comment">//   Old are in &quot;m_particles&quot;</span>
<a name="l00298"></a>00298                                         <span class="comment">//   New are in &quot;newParticles&quot;, &quot;newParticlesWeight&quot;,&quot;newParticlesDerivedFromIdx&quot;</span>
<a name="l00299"></a>00299                                         <span class="comment">// ---------------------------------------------------------------------------------</span>
<a name="l00300"></a>00300                                         this-&gt;PF_SLAM_implementation_replaceByNewParticleSet(
<a name="l00301"></a>00301                                                 me-&gt;m_particles,
<a name="l00302"></a>00302                                                 newParticles,newParticlesWeight,newParticlesDerivedFromIdx );
<a name="l00303"></a>00303 
<a name="l00304"></a>00304                                 } <span class="comment">// end adaptive sample size</span>
<a name="l00305"></a>00305                         }
<a name="l00306"></a>00306 
<a name="l00307"></a>00307                         <span class="keywordflow">if</span> (sf)
<a name="l00308"></a>00308                         {
<a name="l00309"></a>00309                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> M = me-&gt;m_particles.size();
<a name="l00310"></a>00310                                 <span class="comment">//      UPDATE STAGE</span>
<a name="l00311"></a>00311                                 <span class="comment">// ----------------------------------------------------------------------</span>
<a name="l00312"></a>00312                                 <span class="comment">// Compute all the likelihood values &amp; update particles weight:</span>
<a name="l00313"></a>00313                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i=0;i&lt;M;i++)
<a name="l00314"></a>00314                                 {
<a name="l00315"></a>00315                                         <span class="keyword">const</span> <a class="code" href="structmrpt_1_1math_1_1_t_pose3_d.html" title="Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).">TPose3D</a>  *partPose= getLastPose(i); <span class="comment">// Take the particle data:</span>
<a name="l00316"></a>00316                                         <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a>  partPose2 = <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a>(*partPose);
<a name="l00317"></a>00317                                         <span class="keyword">const</span> <span class="keywordtype">double</span> obs_log_likelihood = PF_SLAM_computeObservationLikelihoodForParticle(PF_options,i,*sf,partPose2);
<a name="l00318"></a>00318                                         me-&gt;m_particles[i].log_w += obs_log_likelihood * PF_options.<a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html#a6ad1667bac7faa62a2376c83527c0414" title="An optional step to &quot;smooth&quot; dramatic changes in the observation model to affect the variance of the ...">powFactor</a>;
<a name="l00319"></a>00319                                 } <span class="comment">// for each particle &quot;i&quot;</span>
<a name="l00320"></a>00320 
<a name="l00321"></a>00321                                 <span class="comment">// Normalization of weights is done outside of this method automatically.</span>
<a name="l00322"></a>00322                         }
<a name="l00323"></a>00323 
<a name="l00324"></a>00324                         <a class="code" href="mrpt__macros_8h.html#a88a917260793b56abd83ad2a0d849eb1">MRPT_END</a>
<a name="l00325"></a>00325                 }  <span class="comment">// end of PF_SLAM_implementation_pfStandardProposal</span>
<a name="l00326"></a>00326 <span class="comment"></span>
<a name="l00327"></a>00327 <span class="comment">                /** A generic implementation of the PF method &quot;prediction_and_update_pfAuxiliaryPFStandard&quot; (Auxiliary particle filter with the standard proposal),</span>
<a name="l00328"></a>00328 <span class="comment">                  *  common to both localization and mapping.</span>
<a name="l00329"></a>00329 <span class="comment">                  *</span>
<a name="l00330"></a>00330 <span class="comment">                  * - BINTYPE: TPoseBin or whatever to discretize the sample space for KLD-sampling.</span>
<a name="l00331"></a>00331 <span class="comment">                  *</span>
<a name="l00332"></a>00332 <span class="comment">                  *  This method is described in the paper:</span>
<a name="l00333"></a>00333 <span class="comment">                  *   Pitt, M.K.; Shephard, N. (1999). &quot;Filtering Via Simulation: Auxiliary Particle Filters&quot;.</span>
<a name="l00334"></a>00334 <span class="comment">                  *    Journal of the American Statistical Association 94 (446): 590–591. doi:10.2307/2670179.</span>
<a name="l00335"></a>00335 <span class="comment">                  *</span>
<a name="l00336"></a>00336 <span class="comment">                  */</span>
<a name="l00337"></a>00337                 <span class="keyword">template</span> &lt;<span class="keyword">class</span> PARTICLE_TYPE,<span class="keyword">class</span> MY<span class="keywordtype">SEL</span>F&gt;
<a name="l00338"></a>00338                 <span class="keyword">template</span> &lt;<span class="keyword">class</span> BINTYPE&gt;
<a name="l00339"></a><a class="code" href="classmrpt_1_1slam_1_1_p_f__implementation.html#a3c73c4b465bd78e4213c25546ccd328f">00339</a>                 <span class="keywordtype">void</span> <a class="code" href="classmrpt_1_1slam_1_1_p_f__implementation.html" title="A set of common data shared by PF implementations for both SLAM and localization.">PF_implementation&lt;PARTICLE_TYPE,MYSELF&gt;::PF_SLAM_implementation_pfAuxiliaryPFStandard</a>(
<a name="l00340"></a>00340                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1slam_1_1_c_action_collection.html" title="Declares a class for storing a collection of robot actions.">CActionCollection</a> * actions,
<a name="l00341"></a>00341                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1slam_1_1_c_sensory_frame.html" title="Declares a class for storing a &quot;sensory frame&quot;, a set of &quot;observations&quot; taken by the robot approximat...">CSensoryFrame</a>             * sf,
<a name="l00342"></a>00342                         <span class="keyword">const</span> <a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html" title="The configuration of a particle filter.">CParticleFilter::TParticleFilterOptions</a> &amp;PF_options,
<a name="l00343"></a>00343                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1slam_1_1_t_k_l_d_params.html" title="Option set for KLD algorithm.">TKLDParams</a> &amp;KLD_options)
<a name="l00344"></a>00344                 {
<a name="l00345"></a>00345                         <span class="comment">// Standard and Optimal AuxiliaryPF actually have a shared implementation body:</span>
<a name="l00346"></a>00346                         PF_SLAM_implementation_pfAuxiliaryPFStandardAndOptimal&lt;BINTYPE&gt;(actions,sf,PF_options,KLD_options, <span class="keyword">false</span> <span class="comment">/*APF*/</span> );
<a name="l00347"></a>00347                 }
<a name="l00348"></a>00348 
<a name="l00349"></a>00349                 <span class="comment">/*---------------------------------------------------------------</span>
<a name="l00350"></a>00350 <span class="comment">                                        PF_SLAM_particlesEvaluator_AuxPFOptimal</span>
<a name="l00351"></a>00351 <span class="comment">                 ---------------------------------------------------------------*/</span>
<a name="l00352"></a>00352                 <span class="keyword">template</span> &lt;<span class="keyword">class</span> PARTICLE_TYPE,<span class="keyword">class</span> MY<span class="keywordtype">SEL</span>F&gt;
<a name="l00353"></a>00353                 <span class="keyword">template</span> &lt;<span class="keyword">class</span> BINTYPE&gt;
<a name="l00354"></a><a class="code" href="classmrpt_1_1slam_1_1_p_f__implementation.html#aa6e1f16839702a7119de03deae4d7225">00354</a>                 <span class="keywordtype">double</span>  <a class="code" href="classmrpt_1_1slam_1_1_p_f__implementation.html" title="A set of common data shared by PF implementations for both SLAM and localization.">PF_implementation&lt;PARTICLE_TYPE,MYSELF&gt;::PF_SLAM_particlesEvaluator_AuxPFOptimal</a>(
<a name="l00355"></a>00355                         <span class="keyword">const</span> <a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html" title="The configuration of a particle filter.">CParticleFilter::TParticleFilterOptions</a> &amp;PF_options,
<a name="l00356"></a>00356                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_particle_filter_capable.html" title="This virtual class defines the interface that any particles based PDF class must implement in order t...">CParticleFilterCapable</a>    *obj,
<a name="l00357"></a>00357                         <span class="keywordtype">size_t</span>                                  index,
<a name="l00358"></a>00358                         <span class="keyword">const</span> <span class="keywordtype">void</span>                              *action,
<a name="l00359"></a>00359                         <span class="keyword">const</span> <span class="keywordtype">void</span>                              *observation )
<a name="l00360"></a>00360                 {
<a name="l00361"></a>00361                         <a class="code" href="mrpt__macros_8h.html#a45b840af519f33816311acdbb28d7c10">MRPT_START</a>
<a name="l00362"></a>00362 
<a name="l00363"></a>00363                         <span class="comment">//const PF_implementation&lt;PARTICLE_TYPE,MYSELF&gt; *myObj = reinterpret_cast&lt;const PF_implementation&lt;PARTICLE_TYPE,MYSELF&gt;*&gt;( obj );</span>
<a name="l00364"></a>00364                         <span class="keyword">const</span> MYSELF *me = <span class="keyword">static_cast&lt;</span><span class="keyword">const </span>MYSELF*<span class="keyword">&gt;</span>(obj);
<a name="l00365"></a>00365 
<a name="l00366"></a>00366                         <span class="comment">// Compute the quantity:</span>
<a name="l00367"></a>00367                         <span class="comment">//     w[i]·p(zt|z^{t-1},x^{[i],t-1})</span>
<a name="l00368"></a>00368                         <span class="comment">// As the Monte-Carlo approximation of the integral over all posible $x_t$.</span>
<a name="l00369"></a>00369                         <span class="comment">// --------------------------------------------</span>
<a name="l00370"></a>00370                         <span class="keywordtype">double</span>  indivLik, maxLik= -1e300;
<a name="l00371"></a>00371                         <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a> maxLikDraw;
<a name="l00372"></a>00372                         <span class="keywordtype">size_t</span>  N = PF_options.<a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html#a4054623753f30e03e99e94e85c3ff84d" title="In the algorithm &quot;CParticleFilter::pfAuxiliaryPFOptimal&quot; (and in &quot;CParticleFilter::pfAuxiliaryPFStand...">pfAuxFilterOptimal_MaximumSearchSamples</a>;
<a name="l00373"></a>00373                         <a class="code" href="mrpt__macros_8h.html#a47eb5a445c2bf3d9190396510ea9683e">ASSERT_</a>(N&gt;1)
<a name="l00374"></a>00374 
<a name="l00375"></a>00375                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a> oldPose = *me-&gt;getLastPose(index);
<a name="l00376"></a>00376                         <a class="code" href="structmrpt_1_1dynamicsize__vector.html" title="The base class of MRPT vectors, actually, Eigen column matrices of dynamic size with specialized cons...">vector_double</a>   vectLiks(N,0);          <span class="comment">// The vector with the individual log-likelihoods.</span>
<a name="l00377"></a>00377                         <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a>                 drawnSample;
<a name="l00378"></a>00378                         <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> q=0;q&lt;N;q++)
<a name="l00379"></a>00379                         {
<a name="l00380"></a>00380                                 me-&gt;m_movementDrawer.drawSample(drawnSample);
<a name="l00381"></a>00381                                 <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a> x_predict = oldPose + drawnSample;
<a name="l00382"></a>00382 
<a name="l00383"></a>00383                                 <span class="comment">// Estimate the mean...</span>
<a name="l00384"></a>00384                                 indivLik = me-&gt;PF_SLAM_computeObservationLikelihoodForParticle(
<a name="l00385"></a>00385                                         PF_options,
<a name="l00386"></a>00386                                         index,
<a name="l00387"></a>00387                                         *static_cast&lt;const CSensoryFrame*&gt;(observation),
<a name="l00388"></a>00388                                         x_predict );
<a name="l00389"></a>00389 
<a name="l00390"></a>00390                                 <a class="code" href="mrpt__macros_8h.html#ab76a796755b4c538a2e5b4d15ef9f7e2">MRPT_CHECK_NORMAL_NUMBER</a>(indivLik);
<a name="l00391"></a>00391                                 vectLiks[q] = indivLik;
<a name="l00392"></a>00392                                 <span class="keywordflow">if</span> ( indivLik &gt; maxLik )
<a name="l00393"></a>00393                                 {       <span class="comment">// Keep the maximum value:</span>
<a name="l00394"></a>00394                                         maxLikDraw      = drawnSample;
<a name="l00395"></a>00395                                         maxLik          = indivLik;
<a name="l00396"></a>00396                                 }
<a name="l00397"></a>00397                         }
<a name="l00398"></a>00398 
<a name="l00399"></a>00399                         <span class="comment">// This is done to avoid floating point overflow!!</span>
<a name="l00400"></a>00400                         <span class="comment">//      average_lik    =      \sum(e^liks)   * e^maxLik  /     N</span>
<a name="l00401"></a>00401                         <span class="comment">// log( average_lik  ) = log( \sum(e^liks) ) + maxLik   - log( N )</span>
<a name="l00402"></a>00402                         <span class="keywordtype">double</span> avrgLogLik = <a class="code" href="group__stats__grp.html#ga6cb458d9d6c45fae59084fc57e88666b" title="A numerically-stable method to compute average likelihood values with strongly different ranges (unwe...">math::averageLogLikelihood</a>( vectLiks );
<a name="l00403"></a>00403 
<a name="l00404"></a>00404                         <span class="comment">// Save into the object:</span>
<a name="l00405"></a>00405                         me-&gt;m_pfAuxiliaryPFOptimal_estimatedProb[index] = avrgLogLik; <span class="comment">// log( accum / N );</span>
<a name="l00406"></a>00406                         me-&gt;m_pfAuxiliaryPFOptimal_maxLikelihood[index] = maxLik;
<a name="l00407"></a>00407 
<a name="l00408"></a>00408                         <span class="keywordflow">if</span> (PF_options.<a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html#a99406b39b2963dce127a86634f13871f" title="(Default=false) In the algorithm &quot;CParticleFilter::pfAuxiliaryPFOptimal&quot;, if set to true...">pfAuxFilterOptimal_MLE</a>)
<a name="l00409"></a>00409                                 me-&gt;m_pfAuxiliaryPFOptimal_maxLikDrawnMovement[index] = maxLikDraw;
<a name="l00410"></a>00410 
<a name="l00411"></a>00411                         <span class="comment">// and compute the resulting probability of this particle:</span>
<a name="l00412"></a>00412                         <span class="comment">// ------------------------------------------------------------</span>
<a name="l00413"></a>00413                         <span class="keywordflow">return</span> me-&gt;m_particles[index].log_w + me-&gt;m_pfAuxiliaryPFOptimal_estimatedProb[index];
<a name="l00414"></a>00414 
<a name="l00415"></a>00415                         <a class="code" href="mrpt__macros_8h.html#a88a917260793b56abd83ad2a0d849eb1">MRPT_END</a>
<a name="l00416"></a>00416                 } <span class="comment">// end of PF_SLAM_particlesEvaluator_AuxPFOptimal</span>
<a name="l00417"></a>00417 
<a name="l00418"></a>00418 <span class="comment"></span>
<a name="l00419"></a>00419 <span class="comment">                /**  Compute w[i]·p(z_t | mu_t^i), with mu_t^i being</span>
<a name="l00420"></a>00420 <span class="comment">                  *    the mean of the new robot pose</span>
<a name="l00421"></a>00421 <span class="comment">                  *</span>
<a name="l00422"></a>00422 <span class="comment">                  * \param action MUST be a &quot;const CPose3D*&quot;</span>
<a name="l00423"></a>00423 <span class="comment">                  * \param observation MUST be a &quot;const CSensoryFrame*&quot;</span>
<a name="l00424"></a>00424 <span class="comment">                  */</span>
<a name="l00425"></a>00425                 <span class="keyword">template</span> &lt;<span class="keyword">class</span> PARTICLE_TYPE,<span class="keyword">class</span> MY<span class="keywordtype">SEL</span>F&gt;
<a name="l00426"></a>00426                 <span class="keyword">template</span> &lt;<span class="keyword">class</span> BINTYPE&gt;
<a name="l00427"></a><a class="code" href="classmrpt_1_1slam_1_1_p_f__implementation.html#ae92af2f05313e99e6137a78724f198f9">00427</a>                 <span class="keywordtype">double</span>  <a class="code" href="classmrpt_1_1slam_1_1_p_f__implementation.html" title="A set of common data shared by PF implementations for both SLAM and localization.">PF_implementation&lt;PARTICLE_TYPE,MYSELF&gt;::PF_SLAM_particlesEvaluator_AuxPFStandard</a>(
<a name="l00428"></a>00428                         <span class="keyword">const</span> <a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html" title="The configuration of a particle filter.">CParticleFilter::TParticleFilterOptions</a> &amp;PF_options,
<a name="l00429"></a>00429                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1bayes_1_1_c_particle_filter_capable.html" title="This virtual class defines the interface that any particles based PDF class must implement in order t...">CParticleFilterCapable</a>    *obj,
<a name="l00430"></a>00430                         <span class="keywordtype">size_t</span>                                  index,
<a name="l00431"></a>00431                         <span class="keyword">const</span> <span class="keywordtype">void</span>                              *action,
<a name="l00432"></a>00432                         <span class="keyword">const</span> <span class="keywordtype">void</span>                              *observation )
<a name="l00433"></a>00433                 {
<a name="l00434"></a>00434                         <a class="code" href="mrpt__macros_8h.html#a45b840af519f33816311acdbb28d7c10">MRPT_START</a>
<a name="l00435"></a>00435 
<a name="l00436"></a>00436                         <span class="comment">//const PF_implementation&lt;PARTICLE_TYPE,MYSELF&gt; *myObj = reinterpret_cast&lt;const PF_implementation&lt;PARTICLE_TYPE,MYSELF&gt;*&gt;( obj );</span>
<a name="l00437"></a>00437                         <span class="keyword">const</span> MYSELF *myObj = <span class="keyword">static_cast&lt;</span><span class="keyword">const </span>MYSELF*<span class="keyword">&gt;</span>(obj);
<a name="l00438"></a>00438 
<a name="l00439"></a>00439                         <span class="comment">// Take the previous particle weight:</span>
<a name="l00440"></a>00440                         <span class="keyword">const</span> <span class="keywordtype">double</span> cur_logweight = myObj-&gt;m_particles[index].log_w;
<a name="l00441"></a>00441                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a> oldPose = *myObj-&gt;getLastPose(index);
<a name="l00442"></a>00442 
<a name="l00443"></a>00443                         <span class="keywordflow">if</span> (!PF_options.<a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html#a16a5d97f9246477c32e742cc23e20a74" title="Only for PF_algorithm==pfAuxiliaryPFStandard: If false, the APF will predict the first stage weights ...">pfAuxFilterStandard_FirstStageWeightsMonteCarlo</a>)
<a name="l00444"></a>00444                         {
<a name="l00445"></a>00445                                 <span class="comment">// Just use the mean:</span>
<a name="l00446"></a>00446                                 <span class="comment">// , take the mean of the posterior density:</span>
<a name="l00447"></a>00447                                 <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a>  x_predict;
<a name="l00448"></a>00448                                 x_predict.<a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html#a88f72fa352303454295616213fc10c2d" title="Makes &quot;this = A (+) B&quot;; this method is slightly more efficient than &quot;this= A + B;&quot; since it avoids th...">composeFrom</a>( oldPose, *static_cast&lt;const CPose3D*&gt;(action) );
<a name="l00449"></a>00449 
<a name="l00450"></a>00450                                 <span class="comment">// and compute the obs. likelihood:</span>
<a name="l00451"></a>00451                                 <span class="comment">// --------------------------------------------</span>
<a name="l00452"></a>00452                                 myObj-&gt;m_pfAuxiliaryPFStandard_estimatedProb[index] = myObj-&gt;PF_SLAM_computeObservationLikelihoodForParticle(
<a name="l00453"></a>00453                                         PF_options, index,
<a name="l00454"></a>00454                                         *static_cast&lt;const CSensoryFrame*&gt;(observation), x_predict );
<a name="l00455"></a>00455 
<a name="l00456"></a>00456                                 <span class="comment">// Combined log_likelihood: Previous weight * obs_likelihood:</span>
<a name="l00457"></a>00457                                 <span class="keywordflow">return</span> cur_logweight + myObj-&gt;m_pfAuxiliaryPFStandard_estimatedProb[index];
<a name="l00458"></a>00458                         }
<a name="l00459"></a>00459                         <span class="keywordflow">else</span>
<a name="l00460"></a>00460                         {
<a name="l00461"></a>00461                                 <span class="comment">// Do something similar to in Optimal sampling:</span>
<a name="l00462"></a>00462                                 <span class="comment">// Compute the quantity:</span>
<a name="l00463"></a>00463                                 <span class="comment">//     w[i]·p(zt|z^{t-1},x^{[i],t-1})</span>
<a name="l00464"></a>00464                                 <span class="comment">// As the Monte-Carlo approximation of the integral over all posible $x_t$.</span>
<a name="l00465"></a>00465                                 <span class="comment">// --------------------------------------------</span>
<a name="l00466"></a>00466                                 <span class="keywordtype">double</span>  indivLik, maxLik= -1e300;
<a name="l00467"></a>00467                                 <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a> maxLikDraw;
<a name="l00468"></a>00468                                 <span class="keywordtype">size_t</span>  N = PF_options.<a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html#a4054623753f30e03e99e94e85c3ff84d" title="In the algorithm &quot;CParticleFilter::pfAuxiliaryPFOptimal&quot; (and in &quot;CParticleFilter::pfAuxiliaryPFStand...">pfAuxFilterOptimal_MaximumSearchSamples</a>;
<a name="l00469"></a>00469                                 <a class="code" href="mrpt__macros_8h.html#a47eb5a445c2bf3d9190396510ea9683e">ASSERT_</a>(N&gt;1)
<a name="l00470"></a>00470 
<a name="l00471"></a>00471                                 <a class="code" href="structmrpt_1_1dynamicsize__vector.html" title="The base class of MRPT vectors, actually, Eigen column matrices of dynamic size with specialized cons...">vector_double</a>   vectLiks(N,0);          <span class="comment">// The vector with the individual log-likelihoods.</span>
<a name="l00472"></a>00472                                 <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a>         drawnSample;
<a name="l00473"></a>00473                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> q=0;q&lt;N;q++)
<a name="l00474"></a>00474                                 {
<a name="l00475"></a>00475                                         myObj-&gt;m_movementDrawer.drawSample(drawnSample);
<a name="l00476"></a>00476                                         <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a> x_predict = oldPose + drawnSample;
<a name="l00477"></a>00477 
<a name="l00478"></a>00478                                         <span class="comment">// Estimate the mean...</span>
<a name="l00479"></a>00479                                         indivLik = myObj-&gt;PF_SLAM_computeObservationLikelihoodForParticle(
<a name="l00480"></a>00480                                                 PF_options,
<a name="l00481"></a>00481                                                 index,
<a name="l00482"></a>00482                                                 *static_cast&lt;const CSensoryFrame*&gt;(observation),
<a name="l00483"></a>00483                                                 x_predict );
<a name="l00484"></a>00484 
<a name="l00485"></a>00485                                         <a class="code" href="mrpt__macros_8h.html#ab76a796755b4c538a2e5b4d15ef9f7e2">MRPT_CHECK_NORMAL_NUMBER</a>(indivLik);
<a name="l00486"></a>00486                                         vectLiks[q] = indivLik;
<a name="l00487"></a>00487                                         <span class="keywordflow">if</span> ( indivLik &gt; maxLik )
<a name="l00488"></a>00488                                         {       <span class="comment">// Keep the maximum value:</span>
<a name="l00489"></a>00489                                                 maxLikDraw      = drawnSample;
<a name="l00490"></a>00490                                                 maxLik          = indivLik;
<a name="l00491"></a>00491                                         }
<a name="l00492"></a>00492                                 }
<a name="l00493"></a>00493 
<a name="l00494"></a>00494                                 <span class="comment">// This is done to avoid floating point overflow!!</span>
<a name="l00495"></a>00495                                 <span class="comment">//      average_lik    =      \sum(e^liks)   * e^maxLik  /     N</span>
<a name="l00496"></a>00496                                 <span class="comment">// log( average_lik  ) = log( \sum(e^liks) ) + maxLik   - log( N )</span>
<a name="l00497"></a>00497                                 <span class="keywordtype">double</span> avrgLogLik = <a class="code" href="group__stats__grp.html#ga6cb458d9d6c45fae59084fc57e88666b" title="A numerically-stable method to compute average likelihood values with strongly different ranges (unwe...">math::averageLogLikelihood</a>( vectLiks );
<a name="l00498"></a>00498 
<a name="l00499"></a>00499                                 <span class="comment">// Save into the object:</span>
<a name="l00500"></a>00500                                 myObj-&gt;m_pfAuxiliaryPFStandard_estimatedProb[index] = avrgLogLik; <span class="comment">// log( accum / N );</span>
<a name="l00501"></a>00501 
<a name="l00502"></a>00502                                 myObj-&gt;m_pfAuxiliaryPFOptimal_maxLikelihood[index] = maxLik;
<a name="l00503"></a>00503                                 <span class="keywordflow">if</span> (PF_options.<a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html#a99406b39b2963dce127a86634f13871f" title="(Default=false) In the algorithm &quot;CParticleFilter::pfAuxiliaryPFOptimal&quot;, if set to true...">pfAuxFilterOptimal_MLE</a>)
<a name="l00504"></a>00504                                         myObj-&gt;m_pfAuxiliaryPFOptimal_maxLikDrawnMovement[index] = maxLikDraw;
<a name="l00505"></a>00505 
<a name="l00506"></a>00506                                 <span class="comment">// and compute the resulting probability of this particle:</span>
<a name="l00507"></a>00507                                 <span class="comment">// ------------------------------------------------------------</span>
<a name="l00508"></a>00508                                 <span class="keywordflow">return</span> cur_logweight + myObj-&gt;m_pfAuxiliaryPFOptimal_estimatedProb[index];
<a name="l00509"></a>00509                         }
<a name="l00510"></a>00510                         <a class="code" href="mrpt__macros_8h.html#a88a917260793b56abd83ad2a0d849eb1">MRPT_END</a>
<a name="l00511"></a>00511                 }
<a name="l00512"></a>00512 
<a name="l00513"></a>00513                 <span class="comment">// USE_OPTIMAL_SAMPLING:</span>
<a name="l00514"></a>00514                 <span class="comment">//   true -&gt; PF_SLAM_implementation_pfAuxiliaryPFOptimal</span>
<a name="l00515"></a>00515                 <span class="comment">//  false -&gt; PF_SLAM_implementation_pfAuxiliaryPFStandard</span>
<a name="l00516"></a>00516                 <span class="keyword">template</span> &lt;<span class="keyword">class</span> PARTICLE_TYPE,<span class="keyword">class</span> MY<span class="keywordtype">SEL</span>F&gt;
<a name="l00517"></a>00517                 <span class="keyword">template</span> &lt;<span class="keyword">class</span> BINTYPE&gt;
<a name="l00518"></a><a class="code" href="classmrpt_1_1slam_1_1_p_f__implementation.html#a2b357386ceaa7967b124b6481edee37a">00518</a>                 <span class="keywordtype">void</span> <a class="code" href="classmrpt_1_1slam_1_1_p_f__implementation.html" title="A set of common data shared by PF implementations for both SLAM and localization.">PF_implementation&lt;PARTICLE_TYPE,MYSELF&gt;::PF_SLAM_implementation_pfAuxiliaryPFStandardAndOptimal</a>(
<a name="l00519"></a>00519                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1slam_1_1_c_action_collection.html" title="Declares a class for storing a collection of robot actions.">CActionCollection</a> * actions,
<a name="l00520"></a>00520                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1slam_1_1_c_sensory_frame.html" title="Declares a class for storing a &quot;sensory frame&quot;, a set of &quot;observations&quot; taken by the robot approximat...">CSensoryFrame</a>             * sf,
<a name="l00521"></a>00521                         <span class="keyword">const</span> <a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html" title="The configuration of a particle filter.">CParticleFilter::TParticleFilterOptions</a> &amp;PF_options,
<a name="l00522"></a>00522                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1slam_1_1_t_k_l_d_params.html" title="Option set for KLD algorithm.">TKLDParams</a> &amp;KLD_options,
<a name="l00523"></a>00523                         <span class="keyword">const</span> <span class="keywordtype">bool</span> USE_OPTIMAL_SAMPLING  )
<a name="l00524"></a>00524                 {
<a name="l00525"></a>00525                         <a class="code" href="mrpt__macros_8h.html#a45b840af519f33816311acdbb28d7c10">MRPT_START</a>
<a name="l00526"></a>00526                         <span class="keyword">typedef</span> std<a class="code" href="classstd_1_1set.html" title="STL class.">::set&lt;BINTYPE,typename BINTYPE::lt_operator&gt;</a>         TSetStateSpaceBins;
<a name="l00527"></a>00527 
<a name="l00528"></a>00528                         MYSELF *me = <span class="keyword">static_cast&lt;</span>MYSELF*<span class="keyword">&gt;</span>(<span class="keyword">this</span>);
<a name="l00529"></a>00529 
<a name="l00530"></a>00530                         <span class="keyword">const</span> <span class="keywordtype">size_t</span> M = me-&gt;m_particles.size();
<a name="l00531"></a>00531 
<a name="l00532"></a>00532                         <span class="comment">// ----------------------------------------------------------------------</span>
<a name="l00533"></a>00533                         <span class="comment">//        We can execute optimal PF only when we have both, an action, and</span>
<a name="l00534"></a>00534                         <span class="comment">//     a valid observation from which to compute the likelihood:</span>
<a name="l00535"></a>00535                         <span class="comment">//   Accumulate odometry/actions until we have a valid observation, then</span>
<a name="l00536"></a>00536                         <span class="comment">//    process them simultaneously.</span>
<a name="l00537"></a>00537                         <span class="comment">// ----------------------------------------------------------------------</span>
<a name="l00538"></a>00538                         <span class="keywordflow">if</span> (!PF_SLAM_implementation_gatherActionsCheckBothActObs&lt;BINTYPE&gt;(actions,sf))
<a name="l00539"></a>00539                                 <span class="keywordflow">return</span>; <span class="comment">// Nothing we can do here...</span>
<a name="l00540"></a>00540                         <span class="comment">// OK, we have m_movementDrawer loaded and observations...let&#39;s roll!</span>
<a name="l00541"></a>00541 
<a name="l00542"></a>00542 
<a name="l00543"></a>00543                         <span class="comment">// -------------------------------------------------------------------------------</span>
<a name="l00544"></a>00544                         <span class="comment">//              0) Common part:  Prepare m_particles &quot;draw&quot; and compute &quot;fastDrawSample&quot;</span>
<a name="l00545"></a>00545                         <span class="comment">// -------------------------------------------------------------------------------</span>
<a name="l00546"></a>00546                         <span class="comment">// We need the (aproximate) maximum likelihood value for each</span>
<a name="l00547"></a>00547                         <span class="comment">//  previous particle [i]:</span>
<a name="l00548"></a>00548                         <span class="comment">//     max{ p( z^t | data^[i], x_(t-1)^[i], u_(t) ) }</span>
<a name="l00549"></a>00549                         <span class="comment">//</span>
<a name="l00550"></a>00550 
<a name="l00551"></a>00551                         m_pfAuxiliaryPFOptimal_maxLikelihood.assign(M, <a class="code" href="_c_particle_filter_capable_8h.html#acf80e35e34b1c4db82ffb680dc74227e">INVALID_LIKELIHOOD_VALUE</a>);
<a name="l00552"></a>00552                         m_pfAuxiliaryPFOptimal_maxLikDrawnMovement.resize(M);
<a name="l00553"></a>00553 <span class="comment">//                      if (USE_OPTIMAL_SAMPLING)</span>
<a name="l00554"></a>00554                                 m_pfAuxiliaryPFOptimal_estimatedProb.resize(M);
<a name="l00555"></a>00555 <span class="comment">//                      else</span>
<a name="l00556"></a>00556                                 m_pfAuxiliaryPFStandard_estimatedProb.resize(M);
<a name="l00557"></a>00557 
<a name="l00558"></a>00558                         <span class="comment">// Pass the &quot;mean&quot; robot movement to the &quot;weights&quot; computing function:</span>
<a name="l00559"></a>00559                         <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a> meanRobotMovement;
<a name="l00560"></a>00560                         m_movementDrawer.getSamplingMean3D(meanRobotMovement);
<a name="l00561"></a>00561 
<a name="l00562"></a>00562                         <span class="comment">// Prepare data for executing &quot;fastDrawSample&quot;</span>
<a name="l00563"></a>00563                         <span class="keyword">typedef</span> <a class="code" href="classmrpt_1_1slam_1_1_p_f__implementation.html" title="A set of common data shared by PF implementations for both SLAM and localization.">PF_implementation&lt;PARTICLE_TYPE,MYSELF&gt;</a> TMyClass; <span class="comment">// Use this longer declaration to avoid errors in old GCC.</span>
<a name="l00564"></a>00564                         <a class="code" href="classmrpt_1_1bayes_1_1_c_particle_filter_capable.html" title="This virtual class defines the interface that any particles based PDF class must implement in order t...">CParticleFilterCapable</a>::TParticleProbabilityEvaluator funcOpt = &amp;TMyClass::template PF_SLAM_particlesEvaluator_AuxPFOptimal&lt;BINTYPE&gt;;
<a name="l00565"></a>00565                         <a class="code" href="classmrpt_1_1bayes_1_1_c_particle_filter_capable.html" title="This virtual class defines the interface that any particles based PDF class must implement in order t...">CParticleFilterCapable</a>::TParticleProbabilityEvaluator funcStd = &amp;TMyClass::template PF_SLAM_particlesEvaluator_AuxPFStandard&lt;BINTYPE&gt;;
<a name="l00566"></a>00566 
<a name="l00567"></a>00567                         me-&gt;<a class="code" href="classmrpt_1_1bayes_1_1_c_particle_filter_capable.html#a02d7ff724a4b73d449a0f5dc28216e63" title="Prepares data structures for calling fastDrawSample method next.">prepareFastDrawSample</a>(
<a name="l00568"></a>00568                                 PF_options,
<a name="l00569"></a>00569                                 USE_OPTIMAL_SAMPLING ? funcOpt : funcStd,
<a name="l00570"></a>00570                                 &amp;meanRobotMovement,
<a name="l00571"></a>00571                                 sf );
<a name="l00572"></a>00572 
<a name="l00573"></a>00573                         <span class="comment">// For USE_OPTIMAL_SAMPLING=1,  m_pfAuxiliaryPFOptimal_maxLikelihood is now computed.</span>
<a name="l00574"></a>00574 
<a name="l00575"></a>00575                         <span class="keywordflow">if</span> (USE_OPTIMAL_SAMPLING &amp;&amp; PF_options.<a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html#a33e80606a59d313f3338f71367010957" title="Enable extra messages for each PF iteration (Default=false)">verbose</a>)
<a name="l00576"></a>00576                         {
<a name="l00577"></a>00577                                 printf(<span class="stringliteral">&quot;[prepareFastDrawSample] max      (log) = %10.06f\n&quot;</span>,  <a class="code" href="namespacemrpt_1_1math.html#adeb0bd3138c2f716e4b0317cacfc46a1">math::maximum</a>(m_pfAuxiliaryPFOptimal_estimatedProb) );
<a name="l00578"></a>00578                                 printf(<span class="stringliteral">&quot;[prepareFastDrawSample] max-mean (log) = %10.06f\n&quot;</span>, -<a class="code" href="namespacemrpt_1_1math.html#a414456e3e3b75b19cfda5e0a37c46e31" title="Computes the mean value of a vector.">math::mean</a>(m_pfAuxiliaryPFOptimal_estimatedProb) + <a class="code" href="namespacemrpt_1_1math.html#adeb0bd3138c2f716e4b0317cacfc46a1">math::maximum</a>(m_pfAuxiliaryPFOptimal_estimatedProb) );
<a name="l00579"></a>00579                                 printf(<span class="stringliteral">&quot;[prepareFastDrawSample] max-min  (log) = %10.06f\n&quot;</span>, -<a class="code" href="namespacemrpt_1_1math.html#a2aad5c4db5fdafc3f8c83f7b1adcbfda">math::minimum</a>(m_pfAuxiliaryPFOptimal_estimatedProb) + <a class="code" href="namespacemrpt_1_1math.html#adeb0bd3138c2f716e4b0317cacfc46a1">math::maximum</a>(m_pfAuxiliaryPFOptimal_estimatedProb) );
<a name="l00580"></a>00580                         }
<a name="l00581"></a>00581 
<a name="l00582"></a>00582                         <span class="comment">// Now we have the vector &quot;m_fastDrawProbability&quot; filled out with:</span>
<a name="l00583"></a>00583                         <span class="comment">//               w[i]·p(zt|z^{t-1},x^{[i],t-1},X)</span>
<a name="l00584"></a>00584                         <span class="comment">//  where,</span>
<a name="l00585"></a>00585                         <span class="comment">//</span>
<a name="l00586"></a>00586                         <span class="comment">//  =========== For USE_OPTIMAL_SAMPLING = true ====================</span>
<a name="l00587"></a>00587                         <span class="comment">//  X is the robot pose prior (as implemented in</span>
<a name="l00588"></a>00588                         <span class="comment">//  the aux. function &quot;PF_SLAM_particlesEvaluator_AuxPFOptimal&quot;),</span>
<a name="l00589"></a>00589                         <span class="comment">//  and also the &quot;m_pfAuxiliaryPFOptimal_maxLikelihood&quot; filled with the maximum lik. values.</span>
<a name="l00590"></a>00590                         <span class="comment">//</span>
<a name="l00591"></a>00591                         <span class="comment">//  =========== For USE_OPTIMAL_SAMPLING = false ====================</span>
<a name="l00592"></a>00592                         <span class="comment">//  X is a single point close to the mean of the robot pose prior (as implemented in</span>
<a name="l00593"></a>00593                         <span class="comment">//  the aux. function &quot;PF_SLAM_particlesEvaluator_AuxPFStandard&quot;).</span>
<a name="l00594"></a>00594                         <span class="comment">//</span>
<a name="l00595"></a>00595                         <a class="code" href="classstd_1_1vector.html">vector&lt;TPose3D&gt;</a>                 newParticles;
<a name="l00596"></a>00596                         <a class="code" href="classstd_1_1vector.html">vector&lt;double&gt;</a>                  newParticlesWeight;
<a name="l00597"></a>00597                         <a class="code" href="classstd_1_1vector.html">vector&lt;size_t&gt;</a>                  newParticlesDerivedFromIdx;
<a name="l00598"></a>00598 
<a name="l00599"></a>00599                         <span class="comment">// We need the (aproximate) maximum likelihood value for each</span>
<a name="l00600"></a>00600                         <span class="comment">//  previous particle [i]:</span>
<a name="l00601"></a>00601                         <span class="comment">//</span>
<a name="l00602"></a>00602                         <span class="comment">//     max{ p( z^t | data^[i], x_(t-1)^[i], u_(t) ) }</span>
<a name="l00603"></a>00603                         <span class="comment">//</span>
<a name="l00604"></a>00604                         <span class="keywordflow">if</span> (PF_options.<a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html#a99406b39b2963dce127a86634f13871f" title="(Default=false) In the algorithm &quot;CParticleFilter::pfAuxiliaryPFOptimal&quot;, if set to true...">pfAuxFilterOptimal_MLE</a>)
<a name="l00605"></a>00605                                 m_pfAuxiliaryPFOptimal_maxLikMovementDrawHasBeenUsed.assign(M, <span class="keyword">false</span>);
<a name="l00606"></a>00606 
<a name="l00607"></a>00607                         <span class="keyword">const</span> <span class="keywordtype">double</span>            maxMeanLik = <a class="code" href="eigen__plugins_8h.html#a29bcf29c0462f07b71b310f5cdf01cb5" title="[VECTORS OR MATRICES] Finds the maximum value On an empty input container">math::maximum</a>(
<a name="l00608"></a>00608                                 USE_OPTIMAL_SAMPLING ?
<a name="l00609"></a>00609                                         m_pfAuxiliaryPFOptimal_estimatedProb :
<a name="l00610"></a>00610                                         m_pfAuxiliaryPFStandard_estimatedProb );
<a name="l00611"></a>00611 
<a name="l00612"></a>00612                         <span class="keywordflow">if</span> ( !PF_options.<a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html#ae1373ee71fb2a0131f448042291d85f0" title="A flag that indicates whether the CParticleFilterCapable object should perform adative sample size (d...">adaptiveSampleSize</a> )
<a name="l00613"></a>00613                         {
<a name="l00614"></a>00614                                 <span class="comment">// ----------------------------------------------------------------------</span>
<a name="l00615"></a>00615                                 <span class="comment">//                                              1) FIXED SAMPLE SIZE VERSION</span>
<a name="l00616"></a>00616                                 <span class="comment">// ----------------------------------------------------------------------</span>
<a name="l00617"></a>00617                                 newParticles.resize(M);
<a name="l00618"></a>00618                                 newParticlesWeight.resize(M);
<a name="l00619"></a>00619                                 newParticlesDerivedFromIdx.resize(M);
<a name="l00620"></a>00620 
<a name="l00621"></a>00621                                 <span class="keyword">const</span> <span class="keywordtype">bool</span> doResample = me-&gt;ESS() &lt; PF_options.<a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html#ac905494cf568dd8291428306661acaf2" title="The resampling of particles will be performed when ESS (in range [0,1]) &lt; BETA (default is 0...">BETA</a>;
<a name="l00622"></a>00622 
<a name="l00623"></a>00623                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i=0;i&lt;M;i++)
<a name="l00624"></a>00624                                 {
<a name="l00625"></a>00625                                         <span class="keywordtype">size_t</span> k;
<a name="l00626"></a>00626 
<a name="l00627"></a>00627                                         <span class="comment">// Generate a new particle:</span>
<a name="l00628"></a>00628                                         <span class="comment">//   (a) Draw a &quot;t-1&quot; m_particles&#39; index:</span>
<a name="l00629"></a>00629                                         <span class="comment">// ----------------------------------------------------------------</span>
<a name="l00630"></a>00630                                         <span class="keywordflow">if</span> (doResample)
<a name="l00631"></a>00631                                                         k = me-&gt;fastDrawSample(PF_options);             <span class="comment">// Based on weights of last step only!</span>
<a name="l00632"></a>00632                                         <span class="keywordflow">else</span>    k = i;
<a name="l00633"></a>00633 
<a name="l00634"></a>00634                                         <span class="comment">// Do one rejection sampling step:</span>
<a name="l00635"></a>00635                                         <span class="comment">// ---------------------------------------------</span>
<a name="l00636"></a>00636                                         <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a>         newPose;
<a name="l00637"></a>00637                                         <span class="keywordtype">double</span>          newParticleLogWeight;
<a name="l00638"></a>00638                                         PF_SLAM_aux_perform_one_rejection_sampling_step&lt;BINTYPE&gt;(
<a name="l00639"></a>00639                                                 USE_OPTIMAL_SAMPLING,doResample,maxMeanLik,
<a name="l00640"></a>00640                                                 k,
<a name="l00641"></a>00641                                                 sf,PF_options,
<a name="l00642"></a>00642                                                 newPose, newParticleLogWeight);
<a name="l00643"></a>00643 
<a name="l00644"></a>00644                                         <span class="comment">// Insert the new particle</span>
<a name="l00645"></a>00645                                         newParticles[i] = newPose;
<a name="l00646"></a>00646                                         newParticlesDerivedFromIdx[i] = k;
<a name="l00647"></a>00647                                         newParticlesWeight[i] = newParticleLogWeight;
<a name="l00648"></a>00648 
<a name="l00649"></a>00649                                 } <span class="comment">// for i</span>
<a name="l00650"></a>00650                         } <span class="comment">// end fixed sample size</span>
<a name="l00651"></a>00651                         <span class="keywordflow">else</span>
<a name="l00652"></a>00652                         {
<a name="l00653"></a>00653                                 <span class="comment">// -------------------------------------------------------------------------------------------------</span>
<a name="l00654"></a>00654                                 <span class="comment">//                                                              2) ADAPTIVE SAMPLE SIZE VERSION</span>
<a name="l00655"></a>00655                                 <span class="comment">//</span>
<a name="l00656"></a>00656                                 <span class="comment">//      Implementation of Dieter Fox&#39;s KLD algorithm</span>
<a name="l00657"></a>00657                                 <span class="comment">//              JLBC (3/OCT/2006)</span>
<a name="l00658"></a>00658                                 <span class="comment">// -------------------------------------------------------------------------------------------------</span>
<a name="l00659"></a>00659                                 <span class="comment">// The new particle set:</span>
<a name="l00660"></a>00660                                 newParticles.clear();
<a name="l00661"></a>00661                                 newParticlesWeight.clear();
<a name="l00662"></a>00662                                 newParticlesDerivedFromIdx.clear();
<a name="l00663"></a>00663 
<a name="l00664"></a>00664                                 <span class="comment">// ------------------------------------------------------------------------------</span>
<a name="l00665"></a>00665                                 <span class="comment">// 2.1) PRELIMINARY STAGE: Build a list of pairs&lt;TPathBin,vector_uint&gt; with the</span>
<a name="l00666"></a>00666                                 <span class="comment">//      indexes of m_particles that fall into each multi-dimensional-path bins</span>
<a name="l00667"></a>00667                                 <span class="comment">//      //The bins will be saved into &quot;stateSpaceBinsLastTimestep&quot;, and the list</span>
<a name="l00668"></a>00668                                 <span class="comment">//      //of corresponding m_particles (in the last timestep), in &quot;stateSpaceBinsLastTimestepParticles&quot;</span>
<a name="l00669"></a>00669                                 <span class="comment">//  - Added JLBC (01/DEC/2006)</span>
<a name="l00670"></a>00670                                 <span class="comment">// ------------------------------------------------------------------------------</span>
<a name="l00671"></a>00671                                 TSetStateSpaceBins                      stateSpaceBinsLastTimestep;
<a name="l00672"></a>00672                                 std<a class="code" href="classstd_1_1vector.html">::vector&lt;vector_uint&gt;</a>        stateSpaceBinsLastTimestepParticles;
<a name="l00673"></a>00673                                 <span class="keyword">typename</span> MYSELF<a class="code" href="eigen__plugins_8h.html#a39c5d6430ea9395ae7ae729dd0c3f18c">::CParticleList::iterator</a>                partIt;
<a name="l00674"></a>00674                                 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>    partIndex;
<a name="l00675"></a>00675 
<a name="l00676"></a>00676                                 printf( <span class="stringliteral">&quot;[FIXED_SAMPLING] Computing...&quot;</span>);
<a name="l00677"></a>00677                                 <span class="keywordflow">for</span> (partIt = me-&gt;m_particles.begin(),partIndex=0; partIt!=me-&gt;m_particles.end(); ++partIt,++partIndex)
<a name="l00678"></a>00678                                 {
<a name="l00679"></a>00679                                         <span class="comment">// Load the bin from the path data:</span>
<a name="l00680"></a>00680                                         BINTYPE p;
<a name="l00681"></a>00681                                         KLF_loadBinFromParticle&lt;PARTICLE_TYPE,BINTYPE&gt;(p, KLD_options,partIt-&gt;d );
<a name="l00682"></a>00682 
<a name="l00683"></a>00683                                         <span class="comment">// Is it a new bin?</span>
<a name="l00684"></a>00684                                         <span class="keyword">typename</span> TSetStateSpaceBins<a class="code" href="eigen__plugins_8h.html#a39c5d6430ea9395ae7ae729dd0c3f18c">::iterator</a> posFound=stateSpaceBinsLastTimestep.find(p);
<a name="l00685"></a>00685                                         <span class="keywordflow">if</span> ( posFound == stateSpaceBinsLastTimestep.end() )
<a name="l00686"></a>00686                                         {       <span class="comment">// Yes, create a new pair &lt;bin,index_list&gt; in the list:</span>
<a name="l00687"></a>00687                                                 stateSpaceBinsLastTimestep.insert( p );
<a name="l00688"></a>00688                                                 stateSpaceBinsLastTimestepParticles.push_back( <a class="code" href="namespacemrpt.html#aa4dc027dbc3804c847a78892a2982047">vector_uint</a>(1,partIndex) );
<a name="l00689"></a>00689                                         }
<a name="l00690"></a>00690                                         <span class="keywordflow">else</span>
<a name="l00691"></a>00691                                         { <span class="comment">// No, add the particle&#39;s index to the existing entry:</span>
<a name="l00692"></a>00692                                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> idx = <a class="code" href="group__geometry__grp.html#ga8c0a76e906f12560cfa49fcd269c8398" title="Gets the distance between two points in a 2D space.">std::distance</a>(stateSpaceBinsLastTimestep.begin(),posFound);
<a name="l00693"></a>00693                                                 stateSpaceBinsLastTimestepParticles[idx].push_back( partIndex );
<a name="l00694"></a>00694                                         }
<a name="l00695"></a>00695                                 }
<a name="l00696"></a>00696                                 printf( <span class="stringliteral">&quot;done (%u bins in t-1)\n&quot;</span>,(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>)stateSpaceBinsLastTimestep.size());
<a name="l00697"></a>00697 
<a name="l00698"></a>00698                                 <span class="comment">// ------------------------------------------------------------------------------</span>
<a name="l00699"></a>00699                                 <span class="comment">// 2.2)    THE MAIN KLD-BASED DRAW SAMPLING LOOP</span>
<a name="l00700"></a>00700                                 <span class="comment">// ------------------------------------------------------------------------------</span>
<a name="l00701"></a>00701                                 <span class="keywordtype">double</span>          delta_1 = 1.0 - KLD_options.<a class="code" href="classmrpt_1_1slam_1_1_t_k_l_d_params.html#a787e1c15d3653be9638c8e41d786a191">KLD_delta</a>;
<a name="l00702"></a>00702                                 <span class="keywordtype">double</span>          epsilon_1 = 0.5 / KLD_options.<a class="code" href="classmrpt_1_1slam_1_1_t_k_l_d_params.html#a92daf8859b1e75f467c23e37d280e466">KLD_epsilon</a>;
<a name="l00703"></a>00703                                 <span class="keywordtype">bool</span>            doResample = me-&gt;ESS() &lt; 0.5;
<a name="l00704"></a>00704                                 <span class="comment">//double        maxLik = math::maximum(m_pfAuxiliaryPFOptimal_maxLikelihood); // For normalization purposes only</span>
<a name="l00705"></a>00705 
<a name="l00706"></a>00706                                 <span class="comment">// The desired dynamic number of m_particles (to be modified dynamically below):</span>
<a name="l00707"></a>00707                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span>  minNumSamples_KLD = max((<span class="keywordtype">size_t</span>)KLD_options.<a class="code" href="classmrpt_1_1slam_1_1_t_k_l_d_params.html#a3d919d633f69c9daefd18be697d0dc71" title="Parameters for the KLD adaptive sample size algorithm (see Dieter Fox&#39;s papers), which is used only i...">KLD_minSampleSize</a>, (<span class="keywordtype">size_t</span>)<a class="code" href="namespacemrpt_1_1utils.html#ab7d9cdf7d271c2f41fc1c5c9fa7d0828" title="Returns the closer integer (int) to x.">round</a>(KLD_options.<a class="code" href="classmrpt_1_1slam_1_1_t_k_l_d_params.html#afa336d11d377a93c23130caef4d3a4b2" title="(Default: KLD_minSamplesPerBin=0) The minimum number of samples will be the maximum of KLD_minSampleS...">KLD_minSamplesPerBin</a>*stateSpaceBinsLastTimestep.size()) );
<a name="l00708"></a>00708                                 <span class="keywordtype">size_t</span> Nx = minNumSamples_KLD ;
<a name="l00709"></a>00709 
<a name="l00710"></a>00710                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> Np1 = me-&gt;m_particles.size();
<a name="l00711"></a>00711                                 <a class="code" href="classstd_1_1vector.html">vector_size_t</a> oldPartIdxsStillNotPropragated(Np1);  <span class="comment">// Use a list since we&#39;ll use &quot;erase&quot; a lot here.</span>
<a name="l00712"></a>00712                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> k=0;k&lt;Np1;k++) oldPartIdxsStillNotPropragated[k]=k; <span class="comment">//.push_back(k);</span>
<a name="l00713"></a>00713 
<a name="l00714"></a>00714                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> Np = stateSpaceBinsLastTimestepParticles.size();
<a name="l00715"></a>00715                                 <a class="code" href="classstd_1_1vector.html">vector_size_t</a> permutationPathsAuxVector(Np);
<a name="l00716"></a>00716                                 <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> k=0;k&lt;Np;k++) permutationPathsAuxVector[k]=k;
<a name="l00717"></a>00717 
<a name="l00718"></a>00718                                 <span class="comment">// Instead of picking randomly from &quot;permutationPathsAuxVector&quot;, we can shuffle it now just once,</span>
<a name="l00719"></a>00719                                 <span class="comment">// then pick in sequence from the tail and resize the container:</span>
<a name="l00720"></a>00720                                 std::random_shuffle(
<a name="l00721"></a>00721                                         permutationPathsAuxVector.begin(),
<a name="l00722"></a>00722                                         permutationPathsAuxVector.end(),
<a name="l00723"></a>00723                                         mrpt<a class="code" href="namespacemrpt_1_1random.html#a4b8c2d5323417f5760fb2ed586b07d0c" title="A random number generator for usage in STL algorithms expecting a function like this (eg...">::random::random_generator_for_STL</a> );
<a name="l00724"></a>00724 
<a name="l00725"></a>00725                                 <span class="keywordtype">size_t</span> k = 0;
<a name="l00726"></a>00726                                 <span class="keywordtype">size_t</span> N = 0;
<a name="l00727"></a>00727 
<a name="l00728"></a>00728                                 TSetStateSpaceBins              stateSpaceBins;
<a name="l00729"></a>00729 
<a name="l00730"></a>00730                                 <span class="keywordflow">do</span> <span class="comment">// &quot;N&quot; is the index of the current &quot;new particle&quot;:</span>
<a name="l00731"></a>00731                                 {
<a name="l00732"></a>00732                                         <span class="comment">// Generate a new particle:</span>
<a name="l00733"></a>00733                                         <span class="comment">//</span>
<a name="l00734"></a>00734                                         <span class="comment">//   (a) Propagate the last set of m_particles, and only if the</span>
<a name="l00735"></a>00735                                         <span class="comment">//       desired number of m_particles in this step is larger,</span>
<a name="l00736"></a>00736                                         <span class="comment">//       perform a UNIFORM sampling from the last set. In this way</span>
<a name="l00737"></a>00737                                         <span class="comment">//       the new weights can be computed in the same way for all m_particles.</span>
<a name="l00738"></a>00738                                         <span class="comment">// ---------------------------------------------------------------------------</span>
<a name="l00739"></a>00739                                         <span class="keywordflow">if</span> (doResample)
<a name="l00740"></a>00740                                         {
<a name="l00741"></a>00741                                                 k = me-&gt;fastDrawSample(PF_options);             <span class="comment">// Based on weights of last step only!</span>
<a name="l00742"></a>00742                                         }
<a name="l00743"></a>00743                                         <span class="keywordflow">else</span>
<a name="l00744"></a>00744                                         {
<a name="l00745"></a>00745                                                 <span class="comment">// Assure that at least one particle per &quot;discrete-path&quot; is taken (if the</span>
<a name="l00746"></a>00746                                                 <span class="comment">//  number of samples allows it)</span>
<a name="l00747"></a>00747                                                 <span class="keywordflow">if</span> (permutationPathsAuxVector.size())
<a name="l00748"></a>00748                                                 {
<a name="l00749"></a>00749                                                         <span class="keyword">const</span> <span class="keywordtype">size_t</span> idxBinSpacePath = *permutationPathsAuxVector.rbegin();
<a name="l00750"></a>00750                                                         permutationPathsAuxVector.resize(permutationPathsAuxVector.size()-1);
<a name="l00751"></a>00751 
<a name="l00752"></a>00752                                                         <span class="keyword">const</span> <span class="keywordtype">size_t</span> idx = <a class="code" href="namespacemrpt_1_1random.html#a4743bfa8fcb282b6f5d66395ccabaa73" title="A static instance of a CRandomGenerator class, for use in single-thread applications.">randomGenerator</a>.<a class="code" href="classmrpt_1_1random_1_1_c_random_generator.html#aede40e77053b8b4350fd786f1683e260" title="Generate a uniformly distributed pseudo-random number using the MT19937 algorithm, in the whole range of 32-bit integers.">drawUniform32bit</a>() % stateSpaceBinsLastTimestepParticles[idxBinSpacePath].size();
<a name="l00753"></a>00753                                                         k = stateSpaceBinsLastTimestepParticles[idxBinSpacePath][idx];
<a name="l00754"></a>00754                                                         <a class="code" href="mrpt__macros_8h.html#a47eb5a445c2bf3d9190396510ea9683e">ASSERT_</a>(k&lt;me-&gt;m_particles.size());
<a name="l00755"></a>00755 
<a name="l00756"></a>00756                                                         <span class="comment">// Also erase it from the other permutation vector list:</span>
<a name="l00757"></a>00757                                                         oldPartIdxsStillNotPropragated.erase(std::find(oldPartIdxsStillNotPropragated.begin(),oldPartIdxsStillNotPropragated.end(),k));
<a name="l00758"></a>00758                                                 }
<a name="l00759"></a>00759                                                 <span class="keywordflow">else</span>
<a name="l00760"></a>00760                                                 {
<a name="l00761"></a>00761                                                         <span class="comment">// Select a particle from the previous set with a UNIFORM distribution,</span>
<a name="l00762"></a>00762                                                         <span class="comment">// in such a way we will assign each particle the updated weight accounting</span>
<a name="l00763"></a>00763                                                         <span class="comment">// for its last weight.</span>
<a name="l00764"></a>00764                                                         <span class="comment">// The first &quot;old_N&quot; m_particles will be drawn using a uniform random selection</span>
<a name="l00765"></a>00765                                                         <span class="comment">// without repetitions:</span>
<a name="l00766"></a>00766                                                         <span class="comment">//</span>
<a name="l00767"></a>00767                                                         <span class="comment">// Select a index from &quot;oldPartIdxsStillNotPropragated&quot; and remove it from the list:</span>
<a name="l00768"></a>00768                                                         <span class="keywordflow">if</span> (oldPartIdxsStillNotPropragated.size())
<a name="l00769"></a>00769                                                         {
<a name="l00770"></a>00770                                                                 <span class="keyword">const</span> <span class="keywordtype">size_t</span> idx = <a class="code" href="namespacemrpt_1_1random.html#a4743bfa8fcb282b6f5d66395ccabaa73" title="A static instance of a CRandomGenerator class, for use in single-thread applications.">randomGenerator</a>.<a class="code" href="classmrpt_1_1random_1_1_c_random_generator.html#aede40e77053b8b4350fd786f1683e260" title="Generate a uniformly distributed pseudo-random number using the MT19937 algorithm, in the whole range of 32-bit integers.">drawUniform32bit</a>() % oldPartIdxsStillNotPropragated.size();
<a name="l00771"></a>00771                                                                 <a class="code" href="classstd_1_1vector.html">vector_size_t</a><a class="code" href="eigen__plugins_8h.html#a39c5d6430ea9395ae7ae729dd0c3f18c">::iterator</a> it = oldPartIdxsStillNotPropragated.begin() + idx; <span class="comment">//advance(it,idx);</span>
<a name="l00772"></a>00772                                                                 k = *it;
<a name="l00773"></a>00773                                                                 oldPartIdxsStillNotPropragated.erase(it);
<a name="l00774"></a>00774                                                         }
<a name="l00775"></a>00775                                                         <span class="keywordflow">else</span>
<a name="l00776"></a>00776                                                         {
<a name="l00777"></a>00777                                                                 <span class="comment">// N&gt;N_old -&gt; Uniformly draw index:</span>
<a name="l00778"></a>00778                                                                 k = <a class="code" href="namespacemrpt_1_1random.html#a4743bfa8fcb282b6f5d66395ccabaa73" title="A static instance of a CRandomGenerator class, for use in single-thread applications.">randomGenerator</a>.<a class="code" href="classmrpt_1_1random_1_1_c_random_generator.html#aede40e77053b8b4350fd786f1683e260" title="Generate a uniformly distributed pseudo-random number using the MT19937 algorithm, in the whole range of 32-bit integers.">drawUniform32bit</a>() % me-&gt;m_particles.size();
<a name="l00779"></a>00779                                                         }
<a name="l00780"></a>00780                                                 }
<a name="l00781"></a>00781                                         }
<a name="l00782"></a>00782 
<a name="l00783"></a>00783                                         <span class="comment">// Do one rejection sampling step:</span>
<a name="l00784"></a>00784                                         <span class="comment">// ---------------------------------------------</span>
<a name="l00785"></a>00785                                         <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a>         newPose;
<a name="l00786"></a>00786                                         <span class="keywordtype">double</span>          newParticleLogWeight;
<a name="l00787"></a>00787                                         PF_SLAM_aux_perform_one_rejection_sampling_step&lt;BINTYPE&gt;(
<a name="l00788"></a>00788                                                 USE_OPTIMAL_SAMPLING,doResample,maxMeanLik,
<a name="l00789"></a>00789                                                 k,
<a name="l00790"></a>00790                                                 sf,PF_options,
<a name="l00791"></a>00791                                                 newPose, newParticleLogWeight);
<a name="l00792"></a>00792 
<a name="l00793"></a>00793                                         <span class="comment">// Insert the new particle</span>
<a name="l00794"></a>00794                                         newParticles.push_back( newPose );
<a name="l00795"></a>00795                                         newParticlesDerivedFromIdx.push_back( k );
<a name="l00796"></a>00796                                         newParticlesWeight.push_back(newParticleLogWeight);
<a name="l00797"></a>00797 
<a name="l00798"></a>00798                                         <span class="comment">// ----------------------------------------------------------------</span>
<a name="l00799"></a>00799                                         <span class="comment">// Now, the KLD-sampling dynamic sample size stuff:</span>
<a name="l00800"></a>00800                                         <span class="comment">//  look if the particle&#39;s PATH falls into a new bin or not:</span>
<a name="l00801"></a>00801                                         <span class="comment">// ----------------------------------------------------------------</span>
<a name="l00802"></a>00802                                         BINTYPE p;
<a name="l00803"></a>00803                                         <span class="keyword">const</span> <a class="code" href="structmrpt_1_1math_1_1_t_pose3_d.html" title="Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).">TPose3D</a>  newPose_s = newPose;
<a name="l00804"></a>00804                                         KLF_loadBinFromParticle&lt;PARTICLE_TYPE,BINTYPE&gt;( p,KLD_options, me-&gt;m_particles[k].d, &amp;newPose_s );
<a name="l00805"></a>00805 
<a name="l00806"></a>00806                                         <span class="comment">// -----------------------------------------------------------------------------</span>
<a name="l00807"></a>00807                                         <span class="comment">// Look for the bin &quot;p&quot; into &quot;stateSpaceBins&quot;: If it is not yet into the set,</span>
<a name="l00808"></a>00808                                         <span class="comment">//  then we may increase the desired particle number:</span>
<a name="l00809"></a>00809                                         <span class="comment">// -----------------------------------------------------------------------------</span>
<a name="l00810"></a>00810 
<a name="l00811"></a>00811                                         <span class="comment">// Found?</span>
<a name="l00812"></a>00812                                         <span class="keywordflow">if</span> ( stateSpaceBins.find(p)==stateSpaceBins.end() )
<a name="l00813"></a>00813                                         {
<a name="l00814"></a>00814                                                 <span class="comment">// It falls into a new bin: add to the stateSpaceBins:</span>
<a name="l00815"></a>00815                                                 stateSpaceBins.insert( p );
<a name="l00816"></a>00816 
<a name="l00817"></a>00817                                                 <span class="comment">// K = K + 1</span>
<a name="l00818"></a>00818                                                 <span class="keywordtype">int</span> K = stateSpaceBins.<a class="code" href="structmrpt_1_1math_1_1_t_pose3_d.html#a47889c4995254b4457d9a41a501508fc">size</a>();
<a name="l00819"></a>00819                                                 <span class="keywordflow">if</span> ( K&gt;1 )
<a name="l00820"></a>00820                                                 {
<a name="l00821"></a>00821                                                         <span class="comment">// Update the number of m_particles!!</span>
<a name="l00822"></a>00822                                                         Nx = (size_t) (epsilon_1 * <a class="code" href="group__stats__grp.html#ga68b8a2208349a297c19f3a45c24457b1" title="The &quot;quantile&quot; of the Chi-Square distribution, for dimension &quot;dim&quot; and probability 0&lt;P&lt;1 (the inverse...">math::chi2inv</a>(delta_1,K-1));
<a name="l00823"></a>00823                                                         <span class="comment">//printf(&quot;k=%u \tn=%u \tNx:%u\n&quot;, k, newParticles.size(), Nx);</span>
<a name="l00824"></a>00824                                                 }
<a name="l00825"></a>00825                                         }
<a name="l00826"></a>00826 
<a name="l00827"></a>00827                                         N = newParticles.size();
<a name="l00828"></a>00828 
<a name="l00829"></a>00829                                 } <span class="keywordflow">while</span> ((  N &lt; KLD_options.<a class="code" href="classmrpt_1_1slam_1_1_t_k_l_d_params.html#aeb1dd89a8987c1f6957653d35aa0ccae">KLD_maxSampleSize</a> &amp;&amp;
<a name="l00830"></a>00830                                                         N &lt; max(Nx,minNumSamples_KLD)) ||
<a name="l00831"></a>00831                                                         (permutationPathsAuxVector.size() &amp;&amp; !doResample) );
<a name="l00832"></a>00832 
<a name="l00833"></a>00833                                 printf(<span class="stringliteral">&quot;\n[ADAPTIVE SAMPLE SIZE]  #Bins: %u \t #Particles: %u \t Nx=%u\n&quot;</span>, static_cast&lt;unsigned&gt;(stateSpaceBins.size()),static_cast&lt;unsigned&gt;(N), (unsigned)Nx);
<a name="l00834"></a>00834                         } <span class="comment">// end adaptive sample size</span>
<a name="l00835"></a>00835 
<a name="l00836"></a>00836 
<a name="l00837"></a>00837                         <span class="comment">// ---------------------------------------------------------------------------------</span>
<a name="l00838"></a>00838                         <span class="comment">// Substitute old by new particle set:</span>
<a name="l00839"></a>00839                         <span class="comment">//   Old are in &quot;m_particles&quot;</span>
<a name="l00840"></a>00840                         <span class="comment">//   New are in &quot;newParticles&quot;, &quot;newParticlesWeight&quot;,&quot;newParticlesDerivedFromIdx&quot;</span>
<a name="l00841"></a>00841                         <span class="comment">// ---------------------------------------------------------------------------------</span>
<a name="l00842"></a>00842                         this-&gt;PF_SLAM_implementation_replaceByNewParticleSet(
<a name="l00843"></a>00843                                 me-&gt;m_particles,
<a name="l00844"></a>00844                                 newParticles,newParticlesWeight,newParticlesDerivedFromIdx );
<a name="l00845"></a>00845 
<a name="l00846"></a>00846 
<a name="l00847"></a>00847                         <span class="comment">// In this PF_algorithm, we must do weight normalization by ourselves:</span>
<a name="l00848"></a>00848                         me-&gt;normalizeWeights();
<a name="l00849"></a>00849 
<a name="l00850"></a>00850                         <a class="code" href="mrpt__macros_8h.html#a88a917260793b56abd83ad2a0d849eb1">MRPT_END</a>
<a name="l00851"></a>00851                 } <span class="comment">// end of PF_SLAM_implementation_pfAuxiliaryPFStandardAndOptimal</span>
<a name="l00852"></a>00852 
<a name="l00853"></a>00853 
<a name="l00854"></a>00854                 <span class="comment">/* ------------------------------------------------------------------------</span>
<a name="l00855"></a>00855 <span class="comment">                                                        PF_SLAM_aux_perform_one_rejection_sampling_step</span>
<a name="l00856"></a>00856 <span class="comment">                   ------------------------------------------------------------------------ */</span>
<a name="l00857"></a>00857                 <span class="keyword">template</span> &lt;<span class="keyword">class</span> PARTICLE_TYPE,<span class="keyword">class</span> MY<span class="keywordtype">SEL</span>F&gt;
<a name="l00858"></a>00858                 <span class="keyword">template</span> &lt;<span class="keyword">class</span> BINTYPE&gt;
<a name="l00859"></a><a class="code" href="classmrpt_1_1slam_1_1_p_f__implementation.html#a366299a9fa08391084c9719dedf2af48">00859</a>                 <span class="keywordtype">void</span> <a class="code" href="classmrpt_1_1slam_1_1_p_f__implementation.html" title="A set of common data shared by PF implementations for both SLAM and localization.">PF_implementation&lt;PARTICLE_TYPE,MYSELF&gt;::PF_SLAM_aux_perform_one_rejection_sampling_step</a>(
<a name="l00860"></a>00860                         <span class="keyword">const</span> <span class="keywordtype">bool</span>              USE_OPTIMAL_SAMPLING,
<a name="l00861"></a>00861                         <span class="keyword">const</span> <span class="keywordtype">bool</span>              doResample,
<a name="l00862"></a>00862                         <span class="keyword">const</span> <span class="keywordtype">double</span>    maxMeanLik,
<a name="l00863"></a>00863                         <span class="keywordtype">size_t</span>    k, <span class="comment">// The particle from the old set &quot;m_particles[]&quot;</span>
<a name="l00864"></a>00864                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1slam_1_1_c_sensory_frame.html" title="Declares a class for storing a &quot;sensory frame&quot;, a set of &quot;observations&quot; taken by the robot approximat...">CSensoryFrame</a>             * sf,
<a name="l00865"></a>00865                         <span class="keyword">const</span> <a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html" title="The configuration of a particle filter.">CParticleFilter::TParticleFilterOptions</a> &amp;PF_options,
<a name="l00866"></a>00866                         <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a>                 &amp; out_newPose,
<a name="l00867"></a>00867                         <span class="keywordtype">double</span>                  &amp; out_newParticleLogWeight)
<a name="l00868"></a>00868                 {
<a name="l00869"></a>00869                         MYSELF *me = <span class="keyword">static_cast&lt;</span>MYSELF*<span class="keyword">&gt;</span>(<span class="keyword">this</span>);
<a name="l00870"></a>00870 
<a name="l00871"></a>00871                         <span class="comment">// ADD-ON: If the &#39;m_pfAuxiliaryPFOptimal_estimatedProb[k]&#39; is **extremelly** low relative to the other m_particles,</span>
<a name="l00872"></a>00872                         <span class="comment">//  resample only this particle with a copy of another one, uniformly:</span>
<a name="l00873"></a>00873                         <span class="keywordflow">while</span> ( ( (USE_OPTIMAL_SAMPLING ? m_pfAuxiliaryPFOptimal_estimatedProb[k] : m_pfAuxiliaryPFStandard_estimatedProb[k] )
<a name="l00874"></a>00874                                                 -maxMeanLik) &lt; -PF_options.<a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html#a8613b2d409e3a78de42dba07f6cdcec3" title="Only for PF_algorithm=pfAuxiliaryPFOptimal: If a given particle has a max_likelihood (from the a-prio...">max_loglikelihood_dyn_range</a> )
<a name="l00875"></a>00875                         {
<a name="l00876"></a>00876                                 <span class="comment">// Select another &#39;k&#39; uniformly:</span>
<a name="l00877"></a>00877                                 k = <a class="code" href="namespacemrpt_1_1random.html#a4743bfa8fcb282b6f5d66395ccabaa73" title="A static instance of a CRandomGenerator class, for use in single-thread applications.">randomGenerator</a>.<a class="code" href="classmrpt_1_1random_1_1_c_random_generator.html#aede40e77053b8b4350fd786f1683e260" title="Generate a uniformly distributed pseudo-random number using the MT19937 algorithm, in the whole range of 32-bit integers.">drawUniform32bit</a>() % me-&gt;m_particles.size();
<a name="l00878"></a>00878                                 <span class="keywordflow">if</span> (PF_options.<a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html#a33e80606a59d313f3338f71367010957" title="Enable extra messages for each PF iteration (Default=false)">verbose</a>) cout &lt;&lt; <span class="stringliteral">&quot;[PF_implementation] Warning: Discarding very unlikely particle&quot;</span> &lt;&lt; endl;
<a name="l00879"></a>00879                         }
<a name="l00880"></a>00880 
<a name="l00881"></a>00881                         <span class="keyword">const</span> <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a> oldPose = *getLastPose(k);        <span class="comment">// Get the current pose of the k&#39;th particle</span>
<a name="l00882"></a>00882 
<a name="l00883"></a>00883                         <span class="comment">//   (b) Rejection-sampling: Draw a new robot pose from x[k],</span>
<a name="l00884"></a>00884                         <span class="comment">//       and accept it with probability p(zk|x) / maxLikelihood:</span>
<a name="l00885"></a>00885                         <span class="comment">// ----------------------------------------------------------------</span>
<a name="l00886"></a>00886                         <span class="keywordtype">double</span> poseLogLik;
<a name="l00887"></a>00887                         <span class="keywordflow">if</span> ( PF_SLAM_implementation_skipRobotMovement() )
<a name="l00888"></a>00888                         {
<a name="l00889"></a>00889                                 <span class="comment">// The first robot pose in the SLAM execution: All m_particles start</span>
<a name="l00890"></a>00890                                 <span class="comment">// at the same point (this is the lowest bound of subsequent uncertainty):</span>
<a name="l00891"></a>00891                                 out_newPose = oldPose;
<a name="l00892"></a>00892                                 poseLogLik = 0;
<a name="l00893"></a>00893                         }
<a name="l00894"></a>00894                         <span class="keywordflow">else</span>
<a name="l00895"></a>00895                         {
<a name="l00896"></a>00896                                 <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a> movementDraw;
<a name="l00897"></a>00897                                 <span class="keywordflow">if</span> (!USE_OPTIMAL_SAMPLING)
<a name="l00898"></a>00898                                 {       <span class="comment">// APF:</span>
<a name="l00899"></a>00899                                         m_movementDrawer.drawSample( movementDraw );
<a name="l00900"></a>00900                                         out_newPose.<a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html#a88f72fa352303454295616213fc10c2d" title="Makes &quot;this = A (+) B&quot;; this method is slightly more efficient than &quot;this= A + B;&quot; since it avoids th...">composeFrom</a>(oldPose, movementDraw); <span class="comment">// newPose = oldPose + movementDraw;</span>
<a name="l00901"></a>00901                                         <span class="comment">// Compute likelihood:</span>
<a name="l00902"></a>00902                                         poseLogLik = PF_SLAM_computeObservationLikelihoodForParticle(PF_options, k,*sf,out_newPose);
<a name="l00903"></a>00903                                 }
<a name="l00904"></a>00904                                 <span class="keywordflow">else</span>
<a name="l00905"></a>00905                                 {       <span class="comment">// Optimal APF with rejection sampling:</span>
<a name="l00906"></a>00906                                         <span class="comment">// Rejection-sampling:</span>
<a name="l00907"></a>00907                                         <span class="keywordtype">double</span> acceptanceProb;
<a name="l00908"></a>00908                                         <span class="keywordtype">int</span>             timeout = 0;
<a name="l00909"></a>00909                                         <span class="keyword">const</span> <span class="keywordtype">int</span>       maxTries=10000;
<a name="l00910"></a>00910                                         <span class="keywordtype">double</span>      bestTryByNow_loglik= -std::numeric_limits&lt;double&gt;::max();
<a name="l00911"></a>00911                                         <a class="code" href="structmrpt_1_1math_1_1_t_pose3_d.html" title="Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).">TPose3D</a>         bestTryByNow_pose;
<a name="l00912"></a>00912                                         <span class="keywordflow">do</span>
<a name="l00913"></a>00913                                         {
<a name="l00914"></a>00914                                                 <span class="comment">// Draw new robot pose:</span>
<a name="l00915"></a>00915                                                 <span class="keywordflow">if</span> (PF_options.<a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html#a99406b39b2963dce127a86634f13871f" title="(Default=false) In the algorithm &quot;CParticleFilter::pfAuxiliaryPFOptimal&quot;, if set to true...">pfAuxFilterOptimal_MLE</a> &amp;&amp; !m_pfAuxiliaryPFOptimal_maxLikMovementDrawHasBeenUsed[k])
<a name="l00916"></a>00916                                                 {       <span class="comment">// No! first take advantage of a good drawn value, but only once!!</span>
<a name="l00917"></a>00917                                                         m_pfAuxiliaryPFOptimal_maxLikMovementDrawHasBeenUsed[k] = <span class="keyword">true</span>;
<a name="l00918"></a>00918                                                         movementDraw = <a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html" title="A class used to store a 3D pose (a 3D translation + a rotation in 3D).">CPose3D</a>( m_pfAuxiliaryPFOptimal_maxLikDrawnMovement[k] );
<a name="l00919"></a>00919                                                 }
<a name="l00920"></a>00920                                                 <span class="keywordflow">else</span>
<a name="l00921"></a>00921                                                 {
<a name="l00922"></a>00922                                                         <span class="comment">// Draw new robot pose:</span>
<a name="l00923"></a>00923                                                         m_movementDrawer.drawSample( movementDraw );
<a name="l00924"></a>00924                                                 }
<a name="l00925"></a>00925 
<a name="l00926"></a>00926                                                 out_newPose.<a class="code" href="classmrpt_1_1poses_1_1_c_pose3_d.html#a88f72fa352303454295616213fc10c2d" title="Makes &quot;this = A (+) B&quot;; this method is slightly more efficient than &quot;this= A + B;&quot; since it avoids th...">composeFrom</a>(oldPose, movementDraw); <span class="comment">// out_newPose = oldPose + movementDraw;</span>
<a name="l00927"></a>00927 
<a name="l00928"></a>00928                                                 <span class="comment">// Compute acceptance probability:</span>
<a name="l00929"></a>00929                                                 poseLogLik = PF_SLAM_computeObservationLikelihoodForParticle(PF_options, k,*sf,out_newPose);
<a name="l00930"></a>00930 
<a name="l00931"></a>00931                                                 <span class="keywordflow">if</span> (poseLogLik&gt;bestTryByNow_loglik)
<a name="l00932"></a>00932                                                 {
<a name="l00933"></a>00933                                                         bestTryByNow_loglik = poseLogLik;
<a name="l00934"></a>00934                                                         bestTryByNow_pose = out_newPose;
<a name="l00935"></a>00935                                                 }
<a name="l00936"></a>00936 
<a name="l00937"></a>00937                                                 <span class="keywordtype">double</span> ratioLikLik = std::exp( poseLogLik - m_pfAuxiliaryPFOptimal_maxLikelihood[k] );
<a name="l00938"></a>00938                                                 acceptanceProb = std::min( 1.0, ratioLikLik );
<a name="l00939"></a>00939 
<a name="l00940"></a>00940                                                 <span class="keywordflow">if</span> ( ratioLikLik &gt; 1)
<a name="l00941"></a>00941                                                 {
<a name="l00942"></a>00942                                                         m_pfAuxiliaryPFOptimal_maxLikelihood[k] = poseLogLik; <span class="comment">//  :&#39;-( !!!</span>
<a name="l00943"></a>00943                                                         <span class="comment">//acceptanceProb = 0;           // Keep searching or keep this one?</span>
<a name="l00944"></a>00944                                                 }
<a name="l00945"></a>00945                                         } <span class="keywordflow">while</span> ( ++timeout&lt;maxTries &amp;&amp; acceptanceProb &lt; <a class="code" href="namespacemrpt_1_1random.html#a4743bfa8fcb282b6f5d66395ccabaa73" title="A static instance of a CRandomGenerator class, for use in single-thread applications.">randomGenerator</a>.<a class="code" href="classmrpt_1_1random_1_1_c_random_generator.html#a7a4bbaa961f106cd88a872986737a2fb" title="Generate a uniformly distributed pseudo-random number using the MT19937 algorithm, scaled to the selected range.">drawUniform</a>(0.0,0.999) );
<a name="l00946"></a>00946 
<a name="l00947"></a>00947                                         <span class="keywordflow">if</span> (timeout&gt;=maxTries)
<a name="l00948"></a>00948                                         {
<a name="l00949"></a>00949                                                 out_newPose = bestTryByNow_pose;
<a name="l00950"></a>00950                                                 poseLogLik = bestTryByNow_loglik;
<a name="l00951"></a>00951                                                 <span class="keywordflow">if</span> (PF_options.<a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html#a33e80606a59d313f3338f71367010957" title="Enable extra messages for each PF iteration (Default=false)">verbose</a>) cout &lt;&lt; <span class="stringliteral">&quot;[PF_implementation] Warning: timeout in rejection sampling.&quot;</span> &lt;&lt; endl;
<a name="l00952"></a>00952                                         }
<a name="l00953"></a>00953 
<a name="l00954"></a>00954                                 }
<a name="l00955"></a>00955 
<a name="l00956"></a>00956                                 <span class="comment">// And its weight:</span>
<a name="l00957"></a>00957                                 <span class="keywordflow">if</span> (USE_OPTIMAL_SAMPLING)
<a name="l00958"></a>00958                                 {       <span class="comment">// Optimal PF</span>
<a name="l00959"></a>00959                                         <span class="keywordflow">if</span> (doResample)
<a name="l00960"></a>00960                                                 out_newParticleLogWeight = 0;  <span class="comment">// By definition of our optimal PF, all samples have identical weights.</span>
<a name="l00961"></a>00961                                         <span class="keywordflow">else</span>
<a name="l00962"></a>00962                                         {
<a name="l00963"></a>00963                                                 <span class="keyword">const</span> <span class="keywordtype">double</span> weightFact = m_pfAuxiliaryPFOptimal_estimatedProb[k] * PF_options.<a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html#a6ad1667bac7faa62a2376c83527c0414" title="An optional step to &quot;smooth&quot; dramatic changes in the observation model to affect the variance of the ...">powFactor</a>;
<a name="l00964"></a>00964                                                 out_newParticleLogWeight = me-&gt;m_particles[k].log_w + weightFact;
<a name="l00965"></a>00965                                         }
<a name="l00966"></a>00966                                 }
<a name="l00967"></a>00967                                 <span class="keywordflow">else</span>
<a name="l00968"></a>00968                                 {       <span class="comment">// APF:</span>
<a name="l00969"></a>00969                                         <span class="keyword">const</span> <span class="keywordtype">double</span> weightFact = (poseLogLik-m_pfAuxiliaryPFStandard_estimatedProb[k]) * PF_options.<a class="code" href="structmrpt_1_1bayes_1_1_c_particle_filter_1_1_t_particle_filter_options.html#a6ad1667bac7faa62a2376c83527c0414" title="An optional step to &quot;smooth&quot; dramatic changes in the observation model to affect the variance of the ...">powFactor</a>;
<a name="l00970"></a>00970                                         if (doResample)
<a name="l00971"></a>00971                                                         out_newParticleLogWeight = weightFact;
<a name="l00972"></a>00972                                         <span class="keywordflow">else</span>    out_newParticleLogWeight = weightFact + me-&gt;m_particles[k].log_w;
<a name="l00973"></a>00973                                 }
<a name="l00974"></a>00974 
<a name="l00975"></a>00975                         }
<a name="l00976"></a>00976                         <span class="comment">// Done.</span>
<a name="l00977"></a>00977                 } <span class="comment">// end PF_SLAM_aux_perform_one_rejection_sampling_step</span>
<a name="l00978"></a>00978 
<a name="l00979"></a>00979 
<a name="l00980"></a>00980         } <span class="comment">// end namespace</span>
<a name="l00981"></a>00981 } <span class="comment">// end namespace</span>
<a name="l00982"></a>00982 
<a name="l00983"></a>00983 <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>