mirror of
https://github.com/introlab/rtabmap.git
synced 2026-10-04 00:57:46 +08:00
365 lines
55 KiB
HTML
365 lines
55 KiB
HTML
<!-- HTML header for doxygen 1.9.8-->
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
|
|
<meta name="generator" content="Doxygen 1.9.8"/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
<title>RTAB-Map: RTAB-Map C++ API</title>
|
|
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="jquery.js"></script>
|
|
<script type="text/javascript" src="dynsections.js"></script>
|
|
<link href="navtree.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="resize.js"></script>
|
|
<script type="text/javascript" src="navtreedata.js"></script>
|
|
<script type="text/javascript" src="navtree.js"></script>
|
|
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="search/searchdata.js"></script>
|
|
<script type="text/javascript" src="search/search.js"></script>
|
|
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
|
<link href="doxygen-awesome.css" rel="stylesheet" type="text/css"/>
|
|
<link href="custom.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript">window.RTABMAP_DOC_ROOT="";</script>
|
|
<script type="text/javascript" src="../versions.js"></script>
|
|
<script type="text/javascript" src="version-switcher.js"></script>
|
|
<script type="text/javascript" src="doxygen-awesome-darkmode-toggle.js"></script>
|
|
<script type="text/javascript">DoxygenAwesomeDarkModeToggle.init();</script>
|
|
</head>
|
|
<body>
|
|
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
|
<div id="titlearea">
|
|
<table cellspacing="0" cellpadding="0">
|
|
<tbody>
|
|
<tr id="projectrow">
|
|
<td id="projectalign">
|
|
<div id="projectname">RTAB-Map<span id="projectnumber"> 0.23.13</span>
|
|
</div>
|
|
<div id="projectbrief">Real-Time Appearance-Based Mapping</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<!-- end header part -->
|
|
<!-- Generated by Doxygen 1.9.8 -->
|
|
<script type="text/javascript">
|
|
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
|
|
var searchBox = new SearchBox("searchBox", "search/",'.html');
|
|
/* @license-end */
|
|
</script>
|
|
<script type="text/javascript" src="menudata.js"></script>
|
|
<script type="text/javascript" src="menu.js"></script>
|
|
<script type="text/javascript">
|
|
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
|
|
$(function() {
|
|
initMenu('',true,false,'search.php','Search');
|
|
$(document).ready(function() { init_search(); });
|
|
});
|
|
/* @license-end */
|
|
</script>
|
|
<div id="main-nav"></div>
|
|
</div><!-- top -->
|
|
<div id="side-nav" class="ui-resizable side-nav-resizable">
|
|
<div id="nav-tree">
|
|
<div id="nav-tree-contents">
|
|
<div id="nav-sync" class="sync"></div>
|
|
</div>
|
|
</div>
|
|
<div id="splitbar" style="-moz-user-select:none;"
|
|
class="ui-resizable-handle">
|
|
</div>
|
|
</div>
|
|
<script type="text/javascript">
|
|
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
|
|
$(document).ready(function(){initNavTree('index.html',''); initResizable(); });
|
|
/* @license-end */
|
|
</script>
|
|
<div id="doc-content">
|
|
<!-- window showing the filter options -->
|
|
<div id="MSearchSelectWindow"
|
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
|
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
|
</div>
|
|
|
|
<!-- iframe showing the search results (closed by default) -->
|
|
<div id="MSearchResultsWindow">
|
|
<div id="MSearchResults">
|
|
<div class="SRPage">
|
|
<div id="SRIndex">
|
|
<div id="SRResults"></div>
|
|
<div class="SRStatus" id="Loading">Loading...</div>
|
|
<div class="SRStatus" id="Searching">Searching...</div>
|
|
<div class="SRStatus" id="NoMatches">No Matches</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div><div class="header">
|
|
<div class="headertitle"><div class="title">RTAB-Map C++ API </div></div>
|
|
</div><!--header-->
|
|
<div class="contents">
|
|
<div class="textblock"><p><a class="anchor" id="mainpage"></a></p>
|
|
<p>RTAB-Map (Real-Time Appearance-Based Mapping) is a RGB-D, stereo and lidar graph-based SLAM library built around an incremental appearance-based loop closure detector, with memory management that keeps the online constraints satisfiable on large-scale, long-term maps.</p>
|
|
<p>These pages document the public C++ API of the <code>rtabmap_core</code> and <code>rtabmap_utilite</code> libraries. For installation, tutorials and the ROS packages, see the <a href="https://introlab.github.io/rtabmap/">project website</a> and the <a href="https://github.com/introlab/rtabmap/wiki">wiki</a>.</p>
|
|
<h1><a class="anchor" id="autotoc_md0"></a>
|
|
Start here</h1>
|
|
<p><a class="el" href="classrtabmap_1_1Rtabmap.html" title="Top-level RTAB-Map SLAM pipeline (mapping, localization and loop closure).">rtabmap::Rtabmap</a> is the entry point: it owns the map and runs one full SLAM iteration per call to <a class="el" href="classrtabmap_1_1Rtabmap.html#ad7f085b6ae0fd3c7077c500c028fd5c3" title="Main RTAB-Map iteration: ingests one sensor frame and updates the map.">rtabmap::Rtabmap::process()</a>. A minimal loop feeds it a <a class="el" href="classrtabmap_1_1SensorData.html" title="Container class for all sensor data captured at a specific time.">rtabmap::SensorData</a> and the odometry pose that goes with it:</p>
|
|
<div class="fragment"><div class="line"><span class="preprocessor">#include <rtabmap/core/Rtabmap.h></span></div>
|
|
<div class="line"><span class="preprocessor">#include <rtabmap/core/Odometry.h></span></div>
|
|
<div class="line"> </div>
|
|
<div class="line"><a class="code hl_class" href="classrtabmap_1_1Odometry.html">rtabmap::Odometry</a> * odometry = <a class="code hl_function" href="classrtabmap_1_1Odometry.html#ac8992df0b92a86c10fe8e8da2b5f3627">rtabmap::Odometry::create</a>();</div>
|
|
<div class="line"><a class="code hl_class" href="classrtabmap_1_1Rtabmap.html">rtabmap::Rtabmap</a> <a class="code hl_namespace" href="namespacertabmap.html">rtabmap</a>;</div>
|
|
<div class="line"><a class="code hl_namespace" href="namespacertabmap.html">rtabmap</a>.init(); <span class="comment">// optionally: init(parameters, databasePath)</span></div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="keyword">const</span> <span class="keywordtype">double</span> mapUpdateRate = 1.0; <span class="comment">// Hz, i.e. Rtabmap/DetectionRate</span></div>
|
|
<div class="line"><span class="keywordtype">double</span> lastProcessStamp = -1.0;</div>
|
|
<div class="line"><a class="code hl_class" href="classrtabmap_1_1Transform.html">rtabmap::Transform</a> mapToOdom = <a class="code hl_function" href="classrtabmap_1_1Transform.html#a8ea4368f2018d751d2733038081d56a2">rtabmap::Transform::getIdentity</a>();</div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="keywordflow">while</span>(<span class="comment">/* frames available */</span>)</div>
|
|
<div class="line">{</div>
|
|
<div class="line"> <a class="code hl_class" href="classrtabmap_1_1SensorData.html">rtabmap::SensorData</a> data = camera.takeImage();</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> <span class="comment">// Odometry sees every frame: dropping any would break the motion tracking.</span></div>
|
|
<div class="line"> <a class="code hl_class" href="classrtabmap_1_1Transform.html">rtabmap::Transform</a> odomPose = odometry-><a class="code hl_function" href="classrtabmap_1_1Odometry.html#a0c2d39ed9b76c2c411a9e62e16e3bce1">process</a>(data);</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> <span class="comment">// The map is updated at a lower rate. The frames skipped here are not lost</span></div>
|
|
<div class="line"> <span class="comment">// work: the motion they carry is already integrated in the pose above, so</span></div>
|
|
<div class="line"> <span class="comment">// the next accepted frame arrives with an up-to-date odometry pose.</span></div>
|
|
<div class="line"> <span class="keywordflow">if</span>(lastProcessStamp < 0.0 ||</div>
|
|
<div class="line"> data.<a class="code hl_function" href="classrtabmap_1_1SensorData.html#a566e5600bc0369f2f88ff0c597cefcfb">stamp</a>() - lastProcessStamp >= 1.0/mapUpdateRate)</div>
|
|
<div class="line"> {</div>
|
|
<div class="line"> lastProcessStamp = data.<a class="code hl_function" href="classrtabmap_1_1SensorData.html#a566e5600bc0369f2f88ff0c597cefcfb">stamp</a>();</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> <span class="keywordflow">if</span>(<a class="code hl_namespace" href="namespacertabmap.html">rtabmap</a>.process(data, odomPose)) <span class="comment">// true when a new node was added</span></div>
|
|
<div class="line"> {</div>
|
|
<div class="line"> <span class="keyword">const</span> <a class="code hl_class" href="classrtabmap_1_1Statistics.html">rtabmap::Statistics</a> & stats = <a class="code hl_namespace" href="namespacertabmap.html">rtabmap</a>.getStatistics();</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> <span class="comment">// A loop closure or a proximity detection re-optimizes the graph,</span></div>
|
|
<div class="line"> <span class="comment">// which shifts the map frame under the odometry frame.</span></div>
|
|
<div class="line"> <span class="keywordflow">if</span>(!stats.<a class="code hl_function" href="classrtabmap_1_1Statistics.html#a775992631cd8d976a94ea6c1560dad0d">mapCorrection</a>().<a class="code hl_function" href="classrtabmap_1_1Transform.html#a0d6a1985391a45de4fe208e58c51b9d2">isNull</a>())</div>
|
|
<div class="line"> {</div>
|
|
<div class="line"> mapToOdom = stats.<a class="code hl_function" href="classrtabmap_1_1Statistics.html#a775992631cd8d976a94ea6c1560dad0d">mapCorrection</a>();</div>
|
|
<div class="line"> }</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> <span class="keywordflow">if</span>(<a class="code hl_namespace" href="namespacertabmap.html">rtabmap</a>.getLoopClosureId() > 0)</div>
|
|
<div class="line"> {</div>
|
|
<div class="line"> <span class="comment">// a loop closure was accepted on this iteration</span></div>
|
|
<div class="line"> }</div>
|
|
<div class="line"> }</div>
|
|
<div class="line"> }</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> <span class="comment">// Robot pose in the map frame, on every frame and always with the matching</span></div>
|
|
<div class="line"> <span class="comment">// correction: composed after the block above, so an iteration that just</span></div>
|
|
<div class="line"> <span class="comment">// re-optimized the graph uses its new correction rather than the previous</span></div>
|
|
<div class="line"> <span class="comment">// one. In ROS terms: (/map -> /odom) * (/odom -> /base_link).</span></div>
|
|
<div class="line"> <a class="code hl_class" href="classrtabmap_1_1Transform.html">rtabmap::Transform</a> mapPose = mapToOdom * odomPose;</div>
|
|
<div class="line">}</div>
|
|
<div class="ttc" id="aclassrtabmap_1_1Odometry_html"><div class="ttname"><a href="classrtabmap_1_1Odometry.html">rtabmap::Odometry</a></div><div class="ttdoc">Abstract base class for visual, lidar and visual-inertial odometry backends.</div><div class="ttdef"><b>Definition</b> <a href="Odometry_8h_source.html#l00056">Odometry.h:57</a></div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1Odometry_html_a0c2d39ed9b76c2c411a9e62e16e3bce1"><div class="ttname"><a href="classrtabmap_1_1Odometry.html#a0c2d39ed9b76c2c411a9e62e16e3bce1">rtabmap::Odometry::process</a></div><div class="ttdeci">Transform process(SensorData &data, OdometryInfo *info=0)</div><div class="ttdoc">Processes a sensor frame and updates the integrated pose.</div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1Odometry_html_ac8992df0b92a86c10fe8e8da2b5f3627"><div class="ttname"><a href="classrtabmap_1_1Odometry.html#ac8992df0b92a86c10fe8e8da2b5f3627">rtabmap::Odometry::create</a></div><div class="ttdeci">static Odometry * create(const ParametersMap &parameters=ParametersMap())</div><div class="ttdoc">Creates an odometry instance from Parameters::kOdomStrategy() in parameters.</div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1Rtabmap_html"><div class="ttname"><a href="classrtabmap_1_1Rtabmap.html">rtabmap::Rtabmap</a></div><div class="ttdoc">Top-level RTAB-Map SLAM pipeline (mapping, localization and loop closure).</div><div class="ttdef"><b>Definition</b> <a href="Rtabmap_8h_source.html#l00193">Rtabmap.h:194</a></div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1SensorData_html"><div class="ttname"><a href="classrtabmap_1_1SensorData.html">rtabmap::SensorData</a></div><div class="ttdoc">Container class for all sensor data captured at a specific time.</div><div class="ttdef"><b>Definition</b> <a href="SensorData_8h_source.html#l00096">SensorData.h:97</a></div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1SensorData_html_a566e5600bc0369f2f88ff0c597cefcfb"><div class="ttname"><a href="classrtabmap_1_1SensorData.html#a566e5600bc0369f2f88ff0c597cefcfb">rtabmap::SensorData::stamp</a></div><div class="ttdeci">double stamp() const</div><div class="ttdoc">Returns the timestamp.</div><div class="ttdef"><b>Definition</b> <a href="SensorData_8h_source.html#l00538">SensorData.h:538</a></div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1Statistics_html"><div class="ttname"><a href="classrtabmap_1_1Statistics.html">rtabmap::Statistics</a></div><div class="ttdoc">Collects and manages runtime statistics for RTAB-Map.</div><div class="ttdef"><b>Definition</b> <a href="Statistics_8h_source.html#l00107">Statistics.h:108</a></div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1Statistics_html_a775992631cd8d976a94ea6c1560dad0d"><div class="ttname"><a href="classrtabmap_1_1Statistics.html#a775992631cd8d976a94ea6c1560dad0d">rtabmap::Statistics::mapCorrection</a></div><div class="ttdeci">const Transform & mapCorrection() const</div><div class="ttdoc">Returns the map correction transform.</div><div class="ttdef"><b>Definition</b> <a href="Statistics_8h_source.html#l00657">Statistics.h:657</a></div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1Transform_html"><div class="ttname"><a href="classrtabmap_1_1Transform.html">rtabmap::Transform</a></div><div class="ttdoc">Represents a 3D rigid body transformation (rotation + translation).</div><div class="ttdef"><b>Definition</b> <a href="Transform_8h_source.html#l00052">Transform.h:53</a></div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1Transform_html_a0d6a1985391a45de4fe208e58c51b9d2"><div class="ttname"><a href="classrtabmap_1_1Transform.html#a0d6a1985391a45de4fe208e58c51b9d2">rtabmap::Transform::isNull</a></div><div class="ttdeci">bool isNull() const</div><div class="ttdoc">Checks whether the transform is null (all zeros).</div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1Transform_html_a8ea4368f2018d751d2733038081d56a2"><div class="ttname"><a href="classrtabmap_1_1Transform.html#a8ea4368f2018d751d2733038081d56a2">rtabmap::Transform::getIdentity</a></div><div class="ttdeci">static Transform getIdentity()</div><div class="ttdoc">Returns identity transform.</div></div>
|
|
<div class="ttc" id="anamespacertabmap_html"><div class="ttname"><a href="namespacertabmap.html">rtabmap</a></div><div class="ttdef"><b>Definition</b> <a href="BayesFilter_8h_source.html#l00042">BayesFilter.h:42</a></div></div>
|
|
</div><!-- fragment --><p>Throttling is the caller's job here: <a class="el" href="classrtabmap_1_1Rtabmap.html#ad7f085b6ae0fd3c7077c500c028fd5c3" title="Main RTAB-Map iteration: ingests one sensor frame and updates the map.">rtabmap::Rtabmap::process()</a> maps every frame it is given. <a class="el" href="classrtabmap_1_1RtabmapThread.html" title="Runs a Rtabmap instance in its own thread, driven by events.">rtabmap::RtabmapThread</a> does this same stamp comparison internally, from <a class="el" href="classrtabmap_1_1Parameters.html#ab4330bb97358203a6e229a7e7d3b3160">Rtabmap/DetectionRate</a>, so the threaded pipeline only needs the parameter to be set.</p>
|
|
<p>Odometry drifts and the graph gets re-optimized, so the odometry pose is not a map pose. <a class="el" href="classrtabmap_1_1Statistics.html#a775992631cd8d976a94ea6c1560dad0d" title="Returns the map correction transform.">rtabmap::Statistics::mapCorrection()</a> is what reconciles the two, and since it only changes on a map update it can be applied to every incoming frame – which is how the pose stays available at full rate while the map is built at 1 Hz. This is the transform published as <code>/map</code> → <code>/odom</code> by the ROS wrapper, and what the <code>MapBuilder</code> of each example composes with the live odometry pose to place the clouds. It is also readable outside the statistics, as <a class="el" href="classrtabmap_1_1Rtabmap.html#a7b71f70a20f1ef42a65fa9571e254711">rtabmap::Rtabmap::getMapCorrection()</a>.</p>
|
|
<p>Complete programs live under <a href="https://github.com/introlab/rtabmap/tree/master/examples"><code>examples/</code></a> in the source tree:</p>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Example </th><th class="markdownTableHeadNone">What it shows </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><a href="https://github.com/introlab/rtabmap/blob/master/examples/BOWMapping/main.cpp">BOWMapping</a> </td><td class="markdownTableBodyNone">The smallest useful loop: images from disk into <a class="el" href="classrtabmap_1_1Rtabmap.html" title="Top-level RTAB-Map SLAM pipeline (mapping, localization and loop closure).">rtabmap::Rtabmap</a>, appearance-only loop closure detection (no odometry, no GUI) </td></tr>
|
|
<tr class="markdownTableRowEven">
|
|
<td class="markdownTableBodyNone"><a href="https://github.com/introlab/rtabmap/blob/master/examples/NoEventsExample/main.cpp">NoEventsExample</a> </td><td class="markdownTableBodyNone">Driving the pipeline by direct calls – camera, <a class="el" href="classrtabmap_1_1Odometry.html" title="Abstract base class for visual, lidar and visual-inertial odometry backends.">rtabmap::Odometry</a> and <a class="el" href="classrtabmap_1_1Rtabmap.html" title="Top-level RTAB-Map SLAM pipeline (mapping, localization and loop closure).">rtabmap::Rtabmap</a> in one explicit loop, without the event system </td></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><a href="https://github.com/introlab/rtabmap/blob/master/examples/RGBDMapping/main.cpp">RGBDMapping</a> </td><td class="markdownTableBodyNone">The threaded event-based pipeline (<a class="el" href="classrtabmap_1_1SensorCaptureThread.html" title="Thread-based sensor data capture and event posting for RTAB-Map.">rtabmap::SensorCaptureThread</a> → <a class="el" href="classrtabmap_1_1OdometryThread.html" title="Runs an Odometry front-end in its own thread, driven by events.">rtabmap::OdometryThread</a> → <a class="el" href="classrtabmap_1_1RtabmapThread.html" title="Runs a Rtabmap instance in its own thread, driven by events.">rtabmap::RtabmapThread</a>) with any supported RGB-D or stereo camera </td></tr>
|
|
<tr class="markdownTableRowEven">
|
|
<td class="markdownTableBodyNone"><a href="https://github.com/introlab/rtabmap/blob/master/examples/LidarMapping/main.cpp">LidarMapping</a> </td><td class="markdownTableBodyNone">The same threaded pipeline driven by a 3D lidar (<a class="el" href="classrtabmap_1_1LidarVLP16.html">rtabmap::LidarVLP16</a>) instead of a camera </td></tr>
|
|
</table>
|
|
<p>What each iteration does, and which parameters influence it, is documented on <a class="el" href="classrtabmap_1_1Rtabmap.html" title="Top-level RTAB-Map SLAM pipeline (mapping, localization and loop closure).">rtabmap::Rtabmap</a> itself – memory update, loop-closure hypothesis, hypothesis selection, retrieval, proximity detection and transfer to long-term memory.</p>
|
|
<h1><a class="anchor" id="autotoc_md1"></a>
|
|
Occupancy grid</h1>
|
|
<p>With <a class="el" href="classrtabmap_1_1Parameters.html#ad46e3bb3b9e42c989763832a1f7b0f3e">RGBD/CreateOccupancyGrid</a> enabled, every node carries a local occupancy grid computed from its depth images or laser scan (<a class="el" href="classrtabmap_1_1LocalGridMaker.html" title="Builds per-node local occupancy grids from laser scans or depth clouds.">rtabmap::LocalGridMaker</a>). Assembling those into a global grid is left to the caller, so that the result always follows the optimized poses:</p>
|
|
<div class="fragment"><div class="line"><span class="preprocessor">#include <rtabmap/core/global_map/OccupancyGrid.h></span></div>
|
|
<div class="line"> </div>
|
|
<div class="line"><a class="code hl_class" href="classrtabmap_1_1LocalGridCache.html">rtabmap::LocalGridCache</a> localGrids;</div>
|
|
<div class="line"><a class="code hl_class" href="classrtabmap_1_1OccupancyGrid.html">rtabmap::OccupancyGrid</a> grid(&localGrids, parameters); <span class="comment">// reads the Grid/... parameters</span></div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="comment">// ... inside the "if(rtabmap.process(data, odomPose))" block of the loop above:</span></div>
|
|
<div class="line"><span class="keyword">const</span> <a class="code hl_class" href="classrtabmap_1_1Signature.html">rtabmap::Signature</a> & node = stats.<a class="code hl_function" href="classrtabmap_1_1Statistics.html#a582cb4d6d0b3034062d508a6cac77081">getLastSignatureData</a>();</div>
|
|
<div class="line"><span class="keywordflow">if</span>(node.<a class="code hl_function" href="classrtabmap_1_1Signature.html#a24c257c2ff3fe156910ac82c41de8738">sensorData</a>().<a class="code hl_function" href="classrtabmap_1_1SensorData.html#a984ce55b6b75152a63441bd07288dc6c">gridCellSize</a>() > 0.0f &&</div>
|
|
<div class="line"> grid.addedNodes().find(node.<a class="code hl_function" href="classrtabmap_1_1Signature.html#a31c6e7b7e720eca20fb5935e0ee1d9f9">id</a>()) == grid.addedNodes().end())</div>
|
|
<div class="line">{</div>
|
|
<div class="line"> <span class="comment">// Local grid of the new node, as stored in the database (compressed).</span></div>
|
|
<div class="line"> cv::Mat ground, obstacles, empty;</div>
|
|
<div class="line"> node.<a class="code hl_function" href="classrtabmap_1_1Signature.html#a24c257c2ff3fe156910ac82c41de8738">sensorData</a>().<a class="code hl_function" href="classrtabmap_1_1SensorData.html#a2e0be45871fa8dbce1c3cf727953358f">uncompressDataConst</a>(0, 0, 0, 0, &ground, &obstacles, &empty);</div>
|
|
<div class="line"> localGrids.<a class="code hl_function" href="classrtabmap_1_1LocalGridCache.html#a2e83e9c0c11051b5da84bf04b603a99b">add</a>(node.<a class="code hl_function" href="classrtabmap_1_1Signature.html#a31c6e7b7e720eca20fb5935e0ee1d9f9">id</a>(), ground, obstacles, empty,</div>
|
|
<div class="line"> node.<a class="code hl_function" href="classrtabmap_1_1Signature.html#a24c257c2ff3fe156910ac82c41de8738">sensorData</a>().<a class="code hl_function" href="classrtabmap_1_1SensorData.html#a984ce55b6b75152a63441bd07288dc6c">gridCellSize</a>(),</div>
|
|
<div class="line"> node.<a class="code hl_function" href="classrtabmap_1_1Signature.html#a24c257c2ff3fe156910ac82c41de8738">sensorData</a>().<a class="code hl_function" href="classrtabmap_1_1SensorData.html#a51f21b98088ceec4c5d108d0fbe03200">gridViewPoint</a>());</div>
|
|
<div class="line">}</div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="comment">// Draws the nodes that are not assembled yet. If the last optimization moved</span></div>
|
|
<div class="line"><span class="comment">// poses by more than GridGlobal/UpdateError, the grid is cleared first and</span></div>
|
|
<div class="line"><span class="comment">// redrawn entirely from the cache -- which is why the cache is kept around.</span></div>
|
|
<div class="line">grid.update(stats.<a class="code hl_function" href="classrtabmap_1_1Statistics.html#acb80fff8690d88228ebda369e0e06289">poses</a>());</div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="keywordtype">float</span> xMin, yMin; <span class="comment">// grid origin (m), in the map frame</span></div>
|
|
<div class="line">cv::Mat map = grid.getMap(xMin, yMin); <span class="comment">// CV_8S: -1 unknown, 0 free, 100 occupied</span></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1LocalGridCache_html"><div class="ttname"><a href="classrtabmap_1_1LocalGridCache.html">rtabmap::LocalGridCache</a></div><div class="ttdoc">Cache of LocalGrid entries keyed by map node id.</div><div class="ttdef"><b>Definition</b> <a href="LocalGrid_8h_source.html#l00097">LocalGrid.h:98</a></div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1LocalGridCache_html_a2e83e9c0c11051b5da84bf04b603a99b"><div class="ttname"><a href="classrtabmap_1_1LocalGridCache.html#a2e83e9c0c11051b5da84bf04b603a99b">rtabmap::LocalGridCache::add</a></div><div class="ttdeci">void add(int nodeId, const cv::Mat &ground, const cv::Mat &obstacles, const cv::Mat &empty, float cellSize, const cv::Point3f &viewPoint=cv::Point3f(0, 0, 0))</div><div class="ttdoc">Inserts or replaces the grid for nodeId (from separate cell mats).</div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1OccupancyGrid_html"><div class="ttname"><a href="classrtabmap_1_1OccupancyGrid.html">rtabmap::OccupancyGrid</a></div><div class="ttdef"><b>Definition</b> <a href="global__map_2OccupancyGrid_8h_source.html#l00040">OccupancyGrid.h:41</a></div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1SensorData_html_a2e0be45871fa8dbce1c3cf727953358f"><div class="ttname"><a href="classrtabmap_1_1SensorData.html#a2e0be45871fa8dbce1c3cf727953358f">rtabmap::SensorData::uncompressDataConst</a></div><div class="ttdeci">void uncompressDataConst(cv::Mat *imageRaw, cv::Mat *depthOrRightRaw, LaserScan *laserScanRaw=0, cv::Mat *userDataRaw=0, cv::Mat *groundCellsRaw=0, cv::Mat *obstacleCellsRaw=0, cv::Mat *emptyCellsRaw=0, cv::Mat *depthConfidenceRaw=0) const</div><div class="ttdoc">Uncompresses compressed data into provided output buffers (const version)</div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1SensorData_html_a51f21b98088ceec4c5d108d0fbe03200"><div class="ttname"><a href="classrtabmap_1_1SensorData.html#a51f21b98088ceec4c5d108d0fbe03200">rtabmap::SensorData::gridViewPoint</a></div><div class="ttdeci">const cv::Point3f & gridViewPoint() const</div><div class="ttdoc">Returns the occupancy grid viewpoint.</div><div class="ttdef"><b>Definition</b> <a href="SensorData_8h_source.html#l00827">SensorData.h:827</a></div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1SensorData_html_a984ce55b6b75152a63441bd07288dc6c"><div class="ttname"><a href="classrtabmap_1_1SensorData.html#a984ce55b6b75152a63441bd07288dc6c">rtabmap::SensorData::gridCellSize</a></div><div class="ttdeci">float gridCellSize() const</div><div class="ttdoc">Returns the occupancy grid cell size.</div><div class="ttdef"><b>Definition</b> <a href="SensorData_8h_source.html#l00821">SensorData.h:821</a></div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1Signature_html"><div class="ttname"><a href="classrtabmap_1_1Signature.html">rtabmap::Signature</a></div><div class="ttdoc">Represents a node in RTAB-Map's pose graph.</div><div class="ttdef"><b>Definition</b> <a href="Signature_8h_source.html#l00083">Signature.h:84</a></div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1Signature_html_a24c257c2ff3fe156910ac82c41de8738"><div class="ttname"><a href="classrtabmap_1_1Signature.html#a24c257c2ff3fe156910ac82c41de8738">rtabmap::Signature::sensorData</a></div><div class="ttdeci">SensorData & sensorData()</div><div class="ttdoc">Returns mutable access to the sensor data.</div><div class="ttdef"><b>Definition</b> <a href="Signature_8h_source.html#l00597">Signature.h:597</a></div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1Signature_html_a31c6e7b7e720eca20fb5935e0ee1d9f9"><div class="ttname"><a href="classrtabmap_1_1Signature.html#a31c6e7b7e720eca20fb5935e0ee1d9f9">rtabmap::Signature::id</a></div><div class="ttdeci">int id() const</div><div class="ttdoc">Returns the signature ID.</div><div class="ttdef"><b>Definition</b> <a href="Signature_8h_source.html#l00168">Signature.h:168</a></div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1Statistics_html_a582cb4d6d0b3034062d508a6cac77081"><div class="ttname"><a href="classrtabmap_1_1Statistics.html#a582cb4d6d0b3034062d508a6cac77081">rtabmap::Statistics::getLastSignatureData</a></div><div class="ttdeci">const Signature & getLastSignatureData() const</div><div class="ttdoc">Returns the last signature data.</div><div class="ttdef"><b>Definition</b> <a href="Statistics_8h_source.html#l00630">Statistics.h:630</a></div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1Statistics_html_acb80fff8690d88228ebda369e0e06289"><div class="ttname"><a href="classrtabmap_1_1Statistics.html#acb80fff8690d88228ebda369e0e06289">rtabmap::Statistics::poses</a></div><div class="ttdeci">const std::map< int, Transform > & poses() const</div><div class="ttdoc">Returns the pose graph.</div><div class="ttdef"><b>Definition</b> <a href="Statistics_8h_source.html#l00642">Statistics.h:642</a></div></div>
|
|
</div><!-- fragment --><p>For the node that was just added, the cells are already there uncompressed, and <a class="el" href="classrtabmap_1_1SensorData.html#a2e0be45871fa8dbce1c3cf727953358f" title="Uncompresses compressed data into provided output buffers (const version)">rtabmap::SensorData::uncompressDataConst()</a> returns them as they are – it only decompresses what comes back empty, which is what makes the same code work for a node retrieved from the database. The occupancy grid is kept on the published copy even with <a class="el" href="classrtabmap_1_1Parameters.html#a1476c605d078b36f19b41617159fcc05">Rtabmap/PublishLastSignature</a> disabled (only images, scans and user data are dropped), precisely so that the global grid can still be assembled; statistics themselves must be published (<a class="el" href="classrtabmap_1_1Parameters.html#ac946ad95d43dbfaaf3c38e0570cda48c">Rtabmap/PublishStats</a>, on by default). <a class="el" href="classrtabmap_1_1OccupancyGrid.html">rtabmap::OccupancyGrid</a> is one of the <a class="el" href="classrtabmap_1_1GlobalMap.html" title="Abstract base for assembling per-node LocalGrid data into a global map.">rtabmap::GlobalMap</a> back-ends: <a class="el" href="classrtabmap_1_1OctoMap.html">rtabmap::OctoMap</a>, <a class="el" href="classrtabmap_1_1CloudMap.html">rtabmap::CloudMap</a> and <a class="el" href="classrtabmap_1_1GridMap.html">rtabmap::GridMap</a> consume the same cache the same way. Each example's <code>MapBuilder</code> does exactly this, then hands the result to the viewer.</p>
|
|
<p>For a 3D map, <a class="el" href="classrtabmap_1_1CloudMap.html">rtabmap::CloudMap</a> assembles the very same cells into PCL clouds instead of a 2D grid. It shares the cache, so both can be kept up to date from one set of local grids:</p>
|
|
<div class="fragment"><div class="line"><span class="preprocessor">#include <rtabmap/core/global_map/CloudMap.h></span></div>
|
|
<div class="line"><span class="preprocessor">#include <pcl/io/pcd_io.h></span></div>
|
|
<div class="line"> </div>
|
|
<div class="line"><a class="code hl_class" href="classrtabmap_1_1CloudMap.html">rtabmap::CloudMap</a> cloudMap(&localGrids, parameters); <span class="comment">// same cache as above</span></div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="comment">// ... right after the localGrids.add() of the block above:</span></div>
|
|
<div class="line">cloudMap.update(stats.<a class="code hl_function" href="classrtabmap_1_1Statistics.html#acb80fff8690d88228ebda369e0e06289">poses</a>());</div>
|
|
<div class="line"> </div>
|
|
<div class="line">pcl::PointCloud<pcl::PointXYZRGB>::Ptr ground = cloudMap.getMapGround();</div>
|
|
<div class="line">pcl::PointCloud<pcl::PointXYZRGB>::Ptr obstacles = cloudMap.getMapObstacles();</div>
|
|
<div class="line">pcl::PointCloud<pcl::PointXYZ>::Ptr emptySpace = cloudMap.getMapEmptyCells();</div>
|
|
<div class="line"> </div>
|
|
<div class="line">pcl::io::savePCDFileBinary(<span class="stringliteral">"obstacles.pcd"</span>, *obstacles);</div>
|
|
<div class="ttc" id="aclassrtabmap_1_1CloudMap_html"><div class="ttname"><a href="classrtabmap_1_1CloudMap.html">rtabmap::CloudMap</a></div><div class="ttdef"><b>Definition</b> <a href="CloudMap_8h_source.html#l00040">CloudMap.h:41</a></div></div>
|
|
</div><!-- fragment --><p>The clouds are in the map frame and voxelized at <a class="el" href="classrtabmap_1_1Parameters.html#a9ba0c8ad336348dd5a031bf858efb2d1">Grid/CellSize</a>. Points keep the colour of the local grid when it has one, otherwise ground is green and obstacles red. Note that this assembles the <em>cells</em>, not the raw sensor clouds: with <a class="el" href="classrtabmap_1_1Parameters.html#a9cc690fcb9e611d424ad844ae825ccfd">Grid/3D</a> disabled they are flattened onto the xy plane, so it must stay enabled for a 3D result.</p>
|
|
<p>For a full-resolution cloud, assemble the nodes themselves rather than their cells. Ask <a class="el" href="classrtabmap_1_1Rtabmap.html#a456fa0c95770f052d78f6d9f745fa1e3" title="Extracts a full snapshot of the current pose graph.">rtabmap::Rtabmap::getGraph()</a> for the optimized poses along with the node data, then rebuild a cloud per node and transform it to its pose:</p>
|
|
<div class="fragment"><div class="line"><span class="preprocessor">#include <rtabmap/core/util3d.h></span></div>
|
|
<div class="line"><span class="preprocessor">#include <rtabmap/core/util3d_filtering.h></span></div>
|
|
<div class="line"><span class="preprocessor">#include <rtabmap/core/util3d_transforms.h></span></div>
|
|
<div class="line"> </div>
|
|
<div class="line">std::map<int, rtabmap::Transform> poses;</div>
|
|
<div class="line">std::multimap<int, rtabmap::Link> links;</div>
|
|
<div class="line">std::map<int, rtabmap::Signature> nodes;</div>
|
|
<div class="line"><a class="code hl_namespace" href="namespacertabmap.html">rtabmap</a>.getGraph(poses, links, <span class="keyword">true</span>, <span class="keyword">true</span>, &nodes, <span class="keyword">true</span>); <span class="comment">// optimized, global, with images</span></div>
|
|
<div class="line"> </div>
|
|
<div class="line">pcl::PointCloud<pcl::PointXYZRGB>::Ptr assembled(<span class="keyword">new</span> pcl::PointCloud<pcl::PointXYZRGB>);</div>
|
|
<div class="line"><span class="keywordflow">for</span>(std::map<int, rtabmap::Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)</div>
|
|
<div class="line">{</div>
|
|
<div class="line"> <a class="code hl_class" href="classrtabmap_1_1SensorData.html">rtabmap::SensorData</a> data = nodes.at(iter->first).sensorData();</div>
|
|
<div class="line"> data.<a class="code hl_function" href="classrtabmap_1_1SensorData.html#aa356c9d5e9e7ea55ccdbe99c215bcb52">uncompressData</a>();</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> pcl::IndicesPtr indices(<span class="keyword">new</span> std::vector<int>);</div>
|
|
<div class="line"> pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud = <a class="code hl_function" href="namespacertabmap_1_1util3d.html#a29ece82e01f041cab271fe9322cf9745">rtabmap::util3d::cloudRGBFromSensorData</a>(</div>
|
|
<div class="line"> data,</div>
|
|
<div class="line"> 4, <span class="comment">// image decimation</span></div>
|
|
<div class="line"> 4.0f, <span class="comment">// max depth (m), 0 = no limit</span></div>
|
|
<div class="line"> 0.0f, <span class="comment">// min depth (m)</span></div>
|
|
<div class="line"> indices.get());</div>
|
|
<div class="line"> cloud = <a class="code hl_function" href="group__VoxelFiltering.html#gad8d88a06174857cf53b1dc2cf2310d89">rtabmap::util3d::voxelize</a>(cloud, indices, 0.01f); <span class="comment">// 1 cm</span></div>
|
|
<div class="line"> *assembled += *<a class="code hl_function" href="group__TransformPointcloud.html#ga46b86abad0f4aa2ba7f191da0e07ba69">rtabmap::util3d::transformPointCloud</a>(cloud, iter->second);</div>
|
|
<div class="line">}</div>
|
|
<div class="line">assembled = <a class="code hl_function" href="group__VoxelFiltering.html#gad8d88a06174857cf53b1dc2cf2310d89">rtabmap::util3d::voxelize</a>(assembled, 0.01f); <span class="comment">// one last pass over the overlaps</span></div>
|
|
<div class="line">pcl::io::savePCDFileBinary(<span class="stringliteral">"cloud.pcd"</span>, *assembled);</div>
|
|
<div class="ttc" id="aclassrtabmap_1_1SensorData_html_aa356c9d5e9e7ea55ccdbe99c215bcb52"><div class="ttname"><a href="classrtabmap_1_1SensorData.html#aa356c9d5e9e7ea55ccdbe99c215bcb52">rtabmap::SensorData::uncompressData</a></div><div class="ttdeci">void uncompressData()</div><div class="ttdoc">Uncompresses all compressed data in-place.</div></div>
|
|
<div class="ttc" id="agroup__TransformPointcloud_html_ga46b86abad0f4aa2ba7f191da0e07ba69"><div class="ttname"><a href="group__TransformPointcloud.html#ga46b86abad0f4aa2ba7f191da0e07ba69">rtabmap::util3d::transformPointCloud</a></div><div class="ttdeci">pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_CORE_EXPORT transformPointCloud(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const Transform &transform)</div><div class="ttdoc">Transforms pcl::PointXYZ point cloud type.</div></div>
|
|
<div class="ttc" id="agroup__VoxelFiltering_html_gad8d88a06174857cf53b1dc2cf2310d89"><div class="ttname"><a href="group__VoxelFiltering.html#gad8d88a06174857cf53b1dc2cf2310d89">rtabmap::util3d::voxelize</a></div><div class="ttdeci">pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_CORE_EXPORT voxelize(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const pcl::IndicesPtr &indices, float voxelSize)</div><div class="ttdoc">Performs voxel grid downsampling on a point cloud of type pcl::PointXYZ on provided indices.</div></div>
|
|
<div class="ttc" id="anamespacertabmap_1_1util3d_html_a29ece82e01f041cab271fe9322cf9745"><div class="ttname"><a href="namespacertabmap_1_1util3d.html#a29ece82e01f041cab271fe9322cf9745">rtabmap::util3d::cloudRGBFromSensorData</a></div><div class="ttdeci">pcl::PointCloud< pcl::PointXYZRGB >::Ptr RTABMAP_CORE_EXPORT cloudRGBFromSensorData(const SensorData &sensorData, int decimation=1, float maxDepth=0.0f, float minDepth=0.0f, std::vector< int > *validIndices=0, const ParametersMap &stereoParameters=ParametersMap(), const std::vector< float > &roiRatios=std::vector< float >(), unsigned char confidenceThr=0)</div><div class="ttdoc">Generates a point cloud of type pcl::PointXYZRGB from sensor data.</div></div>
|
|
</div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>Do this once the session is over, not on every iteration. It decompresses and re-projects every node, so the cost grows with the whole map, and the poses are only worth exporting once the graph has been optimized – the same cloud assembled mid-session would carry the drift that later loop closures correct. This is what <a class="el" href="tools.html#tool_export">rtabmap-export</a> does, with more filtering options.</dd></dl>
|
|
<h1><a class="anchor" id="autotoc_md2"></a>
|
|
Memory management</h1>
|
|
<p>RTAB-Map keeps the map in three tiers (<a class="el" href="classrtabmap_1_1Memory.html" title="Three-tiered memory management (STM, WM, LTM) for RTAB-Map.">rtabmap::Memory</a>): a <b>short-term memory</b> of the last <a class="el" href="classrtabmap_1_1Parameters.html#a46dc1a24b02bb00014262f7f4d818a49">Mem/STMSize</a> nodes, where neighbours are too similar to be loop closure candidates; a <b>working memory</b> holding everything loop closure detection compares against; and a <b>long-term memory</b>, the part of the map that stays in the database and is not searched.</p>
|
|
<p>By default nothing leaves the working memory, so the iteration time grows with the map. Memory management caps it, and is enabled by setting a budget – either one, or both:</p>
|
|
<div class="fragment"><div class="line"><a class="code hl_typedef" href="namespacertabmap.html#ad08b6f1796a27dd7316c99c385e2cc55">rtabmap::ParametersMap</a> parameters;</div>
|
|
<div class="line"><span class="comment">// Keep each update under 700 ms...</span></div>
|
|
<div class="line">parameters.insert(<a class="code hl_typedef" href="namespacertabmap.html#a4d38c2e87cb7a46dc4299f7bd4d95a01">rtabmap::ParametersPair</a>(<a class="code hl_function" href="classrtabmap_1_1Parameters.html#a8ee7e153cfb26574c7d1c7b427593f8a">rtabmap::Parameters::kRtabmapTimeThr</a>(), <span class="stringliteral">"700"</span>));</div>
|
|
<div class="line"><span class="comment">// ... and/or keep at most 500 nodes in the working memory.</span></div>
|
|
<div class="line">parameters.insert(<a class="code hl_typedef" href="namespacertabmap.html#a4d38c2e87cb7a46dc4299f7bd4d95a01">rtabmap::ParametersPair</a>(<a class="code hl_function" href="classrtabmap_1_1Parameters.html#a66882ccd6f0a49f2c23db8718d12a59c">rtabmap::Parameters::kRtabmapMemoryThr</a>(), <span class="stringliteral">"500"</span>));</div>
|
|
<div class="line"><a class="code hl_namespace" href="namespacertabmap.html">rtabmap</a>.init(parameters, <span class="stringliteral">"map.db"</span>);</div>
|
|
<div class="ttc" id="aclassrtabmap_1_1Parameters_html_a66882ccd6f0a49f2c23db8718d12a59c"><div class="ttname"><a href="classrtabmap_1_1Parameters.html#a66882ccd6f0a49f2c23db8718d12a59c">rtabmap::Parameters::kRtabmapMemoryThr</a></div><div class="ttdeci">static std::string kRtabmapMemoryThr()</div><div class="ttdoc">Key of parameter Rtabmap/MemoryThr : uFormat("Maximum nodes in the Working Memory (0 means infinity)....</div><div class="ttdef"><b>Definition</b> <a href="Parameters_8h_source.html#l00193">Parameters.h:193</a></div></div>
|
|
<div class="ttc" id="aclassrtabmap_1_1Parameters_html_a8ee7e153cfb26574c7d1c7b427593f8a"><div class="ttname"><a href="classrtabmap_1_1Parameters.html#a8ee7e153cfb26574c7d1c7b427593f8a">rtabmap::Parameters::kRtabmapTimeThr</a></div><div class="ttdeci">static std::string kRtabmapTimeThr()</div><div class="ttdoc">Key of parameter Rtabmap/TimeThr : "Maximum time allowed for map update (ms) (0 means infinity)....</div><div class="ttdef"><b>Definition</b> <a href="Parameters_8h_source.html#l00192">Parameters.h:192</a></div></div>
|
|
<div class="ttc" id="anamespacertabmap_html_a4d38c2e87cb7a46dc4299f7bd4d95a01"><div class="ttname"><a href="namespacertabmap.html#a4d38c2e87cb7a46dc4299f7bd4d95a01">rtabmap::ParametersPair</a></div><div class="ttdeci">std::pair< std::string, std::string > ParametersPair</div><div class="ttdoc">A single parameter key/value pair, the entry type of ParametersMap.</div><div class="ttdef"><b>Definition</b> <a href="Parameters_8h_source.html#l00046">Parameters.h:46</a></div></div>
|
|
<div class="ttc" id="anamespacertabmap_html_ad08b6f1796a27dd7316c99c385e2cc55"><div class="ttname"><a href="namespacertabmap.html#ad08b6f1796a27dd7316c99c385e2cc55">rtabmap::ParametersMap</a></div><div class="ttdeci">std::map< std::string, std::string > ParametersMap</div><div class="ttdoc">Parameter keys mapped to their values, as used by every configurable class (see Parameters).</div><div class="ttdef"><b>Definition</b> <a href="Parameters_8h_source.html#l00044">Parameters.h:44</a></div></div>
|
|
</div><!-- fragment --><p>When an iteration goes over budget, the nodes of lowest weight are moved to the long-term memory at the end of it – age only breaks ties between equal weights, so it is not simply the oldest that go. Weight is how often a place has been seen: while a node is still in the short-term memory, a new node similar enough to it (<a class="el" href="classrtabmap_1_1Parameters.html#a634f4790c9c84772935bf406265bc692">Mem/RehearsalSimilarity</a>) is merged into it and raises its weight – the rehearsal mechanism. Places the robot dwells on or revisits therefore stay in the working memory, while views seen once leave first. They are not lost: when a loop closure is found, their neighbours are brought back into the working memory for the next iterations, up to <a class="el" href="classrtabmap_1_1Parameters.html#ae42b8a843c6830eff62087a9e0df72b1">Rtabmap/MaxRetrieved</a> nodes (plus <a class="el" href="classrtabmap_1_1Parameters.html#a0ba27238802e7bbd1a7c0327bbc11d99">RGBD/MaxLocalRetrieved</a> around the current pose and along a planned path). This is what makes long-term mapping practical: the robot keeps a bounded, relevant working set and pulls the rest back as it recognizes where it is. Retrieval and node immunization only run when memory management is on.</p>
|
|
<p>Which nodes go first is controlled by three parameters: <a class="el" href="classrtabmap_1_1Parameters.html#a4459441e2574e19b15fedb9cb0bc3fd9">Mem/RecentWmRatio</a> protects the most recent part of the working memory, <a class="el" href="classrtabmap_1_1Parameters.html#a7197e89c24af786042c4f3854c14627f">RGBD/LocalImmunizationRatio</a> protects the nodes around the current pose, and <a class="el" href="classrtabmap_1_1Parameters.html#aea65d81db6cbca6869d7ee1b8e1003a7">Mem/TransferSortingByWeightId</a> selects the ordering. The step-by-step behaviour is documented on <a class="el" href="classrtabmap_1_1Rtabmap.html" title="Top-level RTAB-Map SLAM pipeline (mapping, localization and loop closure).">rtabmap::Rtabmap</a> (steps 4 and 6), and the <code>Memory/Working_memory_size</code> and <code>Memory/Signatures_retrieved</code> entries of <a class="el" href="classrtabmap_1_1Statistics.html" title="Collects and manages runtime statistics for RTAB-Map.">rtabmap::Statistics</a> report what happens at runtime.</p>
|
|
<h1><a class="anchor" id="autotoc_md3"></a>
|
|
Configuration</h1>
|
|
<p>Every parameter is a string key/value pair in a <a class="el" href="namespacertabmap.html#ad08b6f1796a27dd7316c99c385e2cc55" title="Parameter keys mapped to their values, as used by every configurable class (see Parameters).">rtabmap::ParametersMap</a>, declared with its default and description in <code><a class="el" href="Parameters_8h_source.html">Parameters.h</a></code> (for example <code>Parameters::kMemSTMSize()</code>, <code>Parameters::kRGBDLinearUpdate()</code>). The same keys are used by the applications, the ROS wrappers and the <code>--Param value</code> command-line arguments of the tools, so a setting found here applies everywhere.</p>
|
|
<p>The <a class="el" href="parameters.html">Parameter reference</a> lists all of them, grouped, with their type, default value and description.</p>
|
|
<div class="fragment"><div class="line"><a class="code hl_typedef" href="namespacertabmap.html#ad08b6f1796a27dd7316c99c385e2cc55">rtabmap::ParametersMap</a> parameters;</div>
|
|
<div class="line">parameters.insert(<a class="code hl_typedef" href="namespacertabmap.html#a4d38c2e87cb7a46dc4299f7bd4d95a01">rtabmap::ParametersPair</a>(<a class="code hl_function" href="classrtabmap_1_1Parameters.html#a46dc1a24b02bb00014262f7f4d818a49">rtabmap::Parameters::kMemSTMSize</a>(), <span class="stringliteral">"20"</span>));</div>
|
|
<div class="line"><a class="code hl_namespace" href="namespacertabmap.html">rtabmap</a>.init(parameters, <span class="stringliteral">"map.db"</span>);</div>
|
|
<div class="ttc" id="aclassrtabmap_1_1Parameters_html_a46dc1a24b02bb00014262f7f4d818a49"><div class="ttname"><a href="classrtabmap_1_1Parameters.html#a46dc1a24b02bb00014262f7f4d818a49">rtabmap::Parameters::kMemSTMSize</a></div><div class="ttdeci">static std::string kMemSTMSize()</div><div class="ttdoc">Key of parameter Mem/STMSize : "Short-term memory size." Default value: 10 ( unsigned int ).</div><div class="ttdef"><b>Definition</b> <a href="Parameters_8h_source.html#l00226">Parameters.h:226</a></div></div>
|
|
</div><!-- fragment --><h1><a class="anchor" id="autotoc_md4"></a>
|
|
The main classes</h1>
|
|
<p>Doxygen lists the classes alphabetically; this is the same set arranged by the role they play, as a starting point into the API.</p>
|
|
<h2>The map structure</h2>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Class </th><th class="markdownTableHeadNone">Role </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><a class="el" href="classrtabmap_1_1Rtabmap.html" title="Top-level RTAB-Map SLAM pipeline (mapping, localization and loop closure).">rtabmap::Rtabmap</a> </td><td class="markdownTableBodyNone">The entry point: one SLAM iteration per call, owning everything below </td></tr>
|
|
<tr class="markdownTableRowEven">
|
|
<td class="markdownTableBodyNone"><a class="el" href="classrtabmap_1_1Memory.html" title="Three-tiered memory management (STM, WM, LTM) for RTAB-Map.">rtabmap::Memory</a> </td><td class="markdownTableBodyNone">Three-tiered memory (STM / WM / LTM) holding the map and deciding what stays online </td></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><a class="el" href="classrtabmap_1_1Signature.html" title="Represents a node in RTAB-Map's pose graph.">rtabmap::Signature</a> </td><td class="markdownTableBodyNone">One node: sensor data, visual words, pose and links </td></tr>
|
|
<tr class="markdownTableRowEven">
|
|
<td class="markdownTableBodyNone"><a class="el" href="classrtabmap_1_1Link.html" title="Directed constraint between two nodes in RTAB-Map's pose graph.">rtabmap::Link</a> </td><td class="markdownTableBodyNone">One edge: neighbour, loop closure, landmark or prior constraint </td></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><a class="el" href="classrtabmap_1_1DBDriver.html" title="Abstract database driver for RTAB-Map maps (signatures, links, words, statistics).">rtabmap::DBDriver</a> </td><td class="markdownTableBodyNone">Persistence of the map to the database (see <a class="el" href="classrtabmap_1_1DBDriverSqlite3.html" title="SQLite3 implementation of DBDriver for RTAB-Map map databases.">rtabmap::DBDriverSqlite3</a>) </td></tr>
|
|
<tr class="markdownTableRowEven">
|
|
<td class="markdownTableBodyNone"><a class="el" href="classrtabmap_1_1Statistics.html" title="Collects and manages runtime statistics for RTAB-Map.">rtabmap::Statistics</a> </td><td class="markdownTableBodyNone">Everything the pipeline reports about an iteration </td></tr>
|
|
</table>
|
|
<h2>Inputs</h2>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Class </th><th class="markdownTableHeadNone">Role </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><a class="el" href="classrtabmap_1_1SensorData.html" title="Container class for all sensor data captured at a specific time.">rtabmap::SensorData</a> </td><td class="markdownTableBodyNone">An observation: images, depth, laser scan, IMU, GPS, landmarks </td></tr>
|
|
<tr class="markdownTableRowEven">
|
|
<td class="markdownTableBodyNone"><a class="el" href="classrtabmap_1_1CameraModel.html" title="Represents a pinhole camera model containing intrinsic and extrinsic parameters, used for projection,...">rtabmap::CameraModel</a>, <a class="el" href="classrtabmap_1_1StereoCameraModel.html" title="A class representing a calibrated stereo camera system.">rtabmap::StereoCameraModel</a> </td><td class="markdownTableBodyNone">Intrinsics, extrinsics and rectification </td></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><a class="el" href="classrtabmap_1_1LaserScan.html" title="Represents 2D or 3D laser scan data with support for multiple point data formats.">rtabmap::LaserScan</a> </td><td class="markdownTableBodyNone">Point cloud / laser scan container and its formats </td></tr>
|
|
<tr class="markdownTableRowEven">
|
|
<td class="markdownTableBodyNone"><a class="el" href="classrtabmap_1_1Transform.html" title="Represents a 3D rigid body transformation (rotation + translation).">rtabmap::Transform</a> </td><td class="markdownTableBodyNone">The 3D rigid transform used everywhere in the API </td></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><a class="el" href="classrtabmap_1_1SensorCapture.html" title="Abstract base class for sensor data capture (cameras, lidars, etc.)">rtabmap::SensorCapture</a>, <a class="el" href="classrtabmap_1_1SensorCaptureThread.html" title="Thread-based sensor data capture and event posting for RTAB-Map.">rtabmap::SensorCaptureThread</a> </td><td class="markdownTableBodyNone">Drivers and the thread that pumps them </td></tr>
|
|
</table>
|
|
<h2>Building blocks</h2>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Class </th><th class="markdownTableHeadNone">Role </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><a class="el" href="classrtabmap_1_1Odometry.html" title="Abstract base class for visual, lidar and visual-inertial odometry backends.">rtabmap::Odometry</a> </td><td class="markdownTableBodyNone">Visual / lidar odometry front-ends </td></tr>
|
|
<tr class="markdownTableRowEven">
|
|
<td class="markdownTableBodyNone"><a class="el" href="classrtabmap_1_1Registration.html" title="Abstract base for registering two observations (visual, ICP, or both).">rtabmap::Registration</a>, <a class="el" href="classrtabmap_1_1RegistrationVis.html" title="Visual registration between two signatures using features and geometry.">rtabmap::RegistrationVis</a>, <a class="el" href="classrtabmap_1_1RegistrationIcp.html">rtabmap::RegistrationIcp</a> </td><td class="markdownTableBodyNone">Relative transform between two nodes </td></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><a class="el" href="classrtabmap_1_1Optimizer.html" title="Abstract base for pose-graph and bundle-adjustment optimizers.">rtabmap::Optimizer</a> </td><td class="markdownTableBodyNone">Graph optimization back-ends (g2o, GTSAM, Ceres, TORO) </td></tr>
|
|
<tr class="markdownTableRowEven">
|
|
<td class="markdownTableBodyNone"><a class="el" href="classrtabmap_1_1Feature2D.html" title="Abstract 2D feature detector and descriptor extractor for visual SLAM.">rtabmap::Feature2D</a>, <a class="el" href="classrtabmap_1_1VWDictionary.html" title="Manages a dictionary of visual words for visual place recognition and loop closure detection.">rtabmap::VWDictionary</a> </td><td class="markdownTableBodyNone">Keypoint detectors/descriptors and the bag-of-words dictionary </td></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><a class="el" href="classrtabmap_1_1BayesFilter.html" title="Recursive Bayesian filter for loop-closure hypothesis estimation in RTAB-Map.">rtabmap::BayesFilter</a> </td><td class="markdownTableBodyNone">Loop-closure hypothesis estimation </td></tr>
|
|
<tr class="markdownTableRowEven">
|
|
<td class="markdownTableBodyNone"><a class="el" href="classrtabmap_1_1LocalGridMaker.html" title="Builds per-node local occupancy grids from laser scans or depth clouds.">rtabmap::LocalGridMaker</a>, <a class="el" href="classrtabmap_1_1GlobalMap.html" title="Abstract base for assembling per-node LocalGrid data into a global map.">rtabmap::GlobalMap</a> </td><td class="markdownTableBodyNone">Occupancy grid generation and assembly </td></tr>
|
|
</table>
|
|
<p>Free functions for point cloud, image and geometry processing are grouped in <code><a class="el" href="util2d_8h_source.html">util2d.h</a></code>, <code><a class="el" href="util3d_8h_source.html">util3d.h</a></code>, <code><a class="el" href="util3d__filtering_8h_source.html">util3d_filtering.h</a></code>, <code><a class="el" href="util3d__registration_8h_source.html">util3d_registration.h</a></code>, <code><a class="el" href="util3d__surface_8h_source.html">util3d_surface.h</a></code>, <code><a class="el" href="util3d__transforms_8h_source.html">util3d_transforms.h</a></code> and <code><a class="el" href="util3d__mapping_8h_source.html">util3d_mapping.h</a></code>. </p>
|
|
</div></div><!-- PageDoc -->
|
|
</div><!-- contents -->
|
|
</div><!-- doc-content -->
|
|
<!-- start footer part -->
|
|
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
|
|
<ul>
|
|
<li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.8 </li>
|
|
</ul>
|
|
</div>
|
|
</body>
|
|
</html>
|