<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8"/> <title>OMPL: Implementing a new motion planner</title> <meta name="author" content="Ioan A. Șucan, Mark Moll, Lydia E. Kavraki"> <link rel="stylesheet" href="../css/screen.css" type="text/css" media="screen, projection"> <link rel="stylesheet" href="../css/print.css" type="text/css" media="print"> <!--[if lt IE 7]> <script type="text/javascript" src="../js/jquery/jquery.js"></script> <script type="text/javascript" src="../js/jquery/jquery.dropdown.js"></script> <![endif]--> <script type="text/javaScript" src="search/search.js"></script> <script type="text/javascript"> var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-9156598-2']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); </script> </head> <body onload='searchBox.OnSelectItem(0);'> <script type="text/javascript"><!-- var searchBox = new SearchBox("searchBox", "search",false,'Search API'); --></script> <div class="navigation" id="top"> <div class="tabs" id="ompltitle"> <ul class="tablist"> <li>The Open Motion Planning Library</li> <li id="searchli"> <div id="MSearchBox" class="MSearchBoxInactive"> <span class="left"> <img id="MSearchSelect" src="search/mag_sel.png" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()" alt=""/> <input type="text" id="MSearchField" value="Search API" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)" onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> </span><span class="right"> <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a> </span> </div> </li> </ul> </div> <ul id="nav" class="dropdown"> <li class="first"><a href="index.html">Home</a></li> <li><a href="download.html">Download</a></li> <li><a href="documentation.html">Documentation</a></li> <li><span class="dir">Code API</span> <ul> <li><a href="api_overview.html">API Overview</a></li> <li><a href="namespaces.html">Namespaces</a></li> <li><a href="annotated.html">Classes</a></li> <li><a href="files.html">Files</a></li> <li><a href="dirs.html">Directories</a></li> </ul> </li> <li><span class="dir">Community</span> <ul> <li><a href="developers.html">Developers</a></li> <li><a href="thirdparty.html">Contributions</a></li> <li><a href="education.html">Education</a></li> <li><a href="gallery.html">Gallery</a></li> </ul> </li> <li><span class="dir">About</span> <ul> <li><a href="license.html">License</a></li> <li><a href="citations.html">Citations</a></li> <li><a href="acknowledgements.html">Acknowledgments</a></li> <li><a href="contact.html">Contact Us</a></li> </ul> </li> </ul> </div> <!--- window showing the filter options --> <div id="MSearchSelectWindow" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()" onkeydown="return searchBox.OnSearchSelectKey(event)"> <a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark"> </span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark"> </span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark"> </span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark"> </span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark"> </span>Enumerator</a></div> <!-- iframe showing the search results (closed by default) --> <div id="MSearchResultsWindow"> <iframe src="" frameborder="0"name="MSearchResults" id="MSearchResults"></iframe> </div> <div class="container"> <div class="span-22 push-2 first last"> <div> <!-- Generated by Doxygen 1.7.4 --> <script type="text/javascript"><!-- var searchBox = new SearchBox("searchBox", "search",false,'Search'); --></script> </div> <div class="header"> <div class="headertitle"> <div class="title">Implementing a new motion planner </div> </div> </div> <div class="contents"> <div class="textblock"><p>In order to implement a new motion planner the following rules need to be followed:</p> <ul> <li>Define the new planner as a class that inherits from <a class="el" href="classompl_1_1base_1_1Planner.html" title="Base class for a planner.">ompl::base::Planner</a></li> <li>Provide an implementation of <a class="el" href="classompl_1_1base_1_1Planner.html#acc87e95df04aa24ec52e24281c9fc223" title="Function that can solve the motion planning problem. This function can be called multiple times on th...">ompl::base::Planner::solve()</a>. We suggest leveraging the implementations of the routines available in <a class="el" href="classompl_1_1base_1_1SpaceInformation.html" title="The base class for space information. This contains all the information about the space planning is d...">ompl::base::SpaceInformation</a>, but this is not required.</li> <li>If a solution is found, this function should return true and set the found solution path in the goal instance contained by <a class="el" href="classompl_1_1base_1_1ProblemDefinition.html" title="Definition of a problem to be solved. This includes the start state(s) for the system and a goal spec...">ompl::base::ProblemDefinition</a>. If no solution is found, the function should return false.</li> <li>The function should terminate when a termination condition is met</li> <li>It is desirable that calling solve() multiple times consecutively continues the solving process rather than restarting it.</li> <li>Provide an implementation of <a class="el" href="classompl_1_1base_1_1Planner.html#a7e99408ada6e1572a14509fd566ae8b8" title="Clear all internal datastructures. Planner settings are not affected. Subsequent calls to solve() wil...">ompl::base::Planner::clear()</a>. The state of the planner should be restored to what it was at creation time.</li> <li>Provide an implementation of <a class="el" href="classompl_1_1base_1_1Planner.html#afaaf08c87f8797803fbeb60771635ea5" title="Get information about the current run of the motion planner. Repeated calls to this function will upd...">ompl::base::Planner::getPlannerData()</a>. The provided implementation can be empty. This function is provided for debugging purposes: it allows the user of the algorithm to inspect the constructed exploration data structure.</li> </ul> <div class="fragment"><pre class="fragment"><span class="preprocessor"> #include "ompl/base/Planner.h"</span> <span class="comment">// often useful headers:</span> <span class="preprocessor"> #include "ompl/util/RandomNumbers.h"</span> <span class="preprocessor"> #include "ompl/tools/config/SelfConfig.h"</span> <span class="keyword">namespace </span>ompl { <span class="keyword">class </span>myNewPlanner : <span class="keyword">public</span> base::Planner { <span class="keyword">public</span>: myNewPlanner(<span class="keyword">const</span> base::SpaceInformationPtr &si) : base::Planner(si, <span class="stringliteral">"the planner's name"</span>) { <span class="comment">// the specifications of this planner (ompl::base::PlannerSpecs)</span> specs_.approximateSolutions = ...; specs_.recognizedGoal = ...; ... } <span class="keyword">virtual</span> ~myNewPlanner(<span class="keywordtype">void</span>) { <span class="comment">// free any allocated memory</span> } <span class="keyword">virtual</span> <span class="keywordtype">bool</span> solve(<span class="keyword">const</span> base::PlannerTerminationCondition &ptc) { <span class="comment">// make sure the planner is configured correctly; this makes sure there </span> <span class="comment">// are input states and a goal is specified</span> checkValidity(); <span class="comment">// get problem definition from pdef_</span> base::Goal *goal = pdef_->getGoal().get(); <span class="comment">// get input states with pis_</span> <span class="keywordflow">while</span> (<span class="keyword">const</span> base::State *st = pis_.nextStart()) { <span class="comment">// use start states</span> <span class="comment">// usually, copies of st should be made</span> } <span class="comment">// if needed, sample states from the goal region (and wait until a state is sampled)</span> <span class="keyword">const</span> base::State *st = pis_.nextGoal(ptc); <span class="comment">// or sample a new goal state only if available:</span> <span class="keyword">const</span> base::State *st = pis_.nextGoal(); <span class="comment">// call routines from si_ as needed</span> <span class="comment">// periodically check if ptc() returns true.</span> <span class="comment">// if it does, terminate planning.</span> <span class="comment">// use msg_ to output messages.</span> <span class="comment">// compute a valid motion plan and set it in the goal</span> pdef_->getGoal()->setSolutionPath(...); <span class="keywordflow">return</span> pdef_->getGoal()->isAchieved(); } <span class="keyword">virtual</span> <span class="keywordtype">void</span> clear(<span class="keywordtype">void</span>) { Planner::clear(); <span class="comment">// clear the data structures</span> } <span class="comment">// optionally, if additional setup/configuration is needed, the setup() method can be implemented</span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> setup(<span class="keywordtype">void</span>) { Planner::setup(); <span class="comment">// perhaps attempt some auto-configuration</span> SelfConfig sc(si_, getName()); sc.configure... } <span class="keyword">virtual</span> <span class="keywordtype">void</span> getPlannerData(base::PlannerData &data)<span class="keyword"> const</span> <span class="keyword"> </span>{ <span class="comment">// fill data with the states and edges that were created</span> <span class="comment">// in the exploration data structure</span> <span class="comment">// perhaps also fill control::PlannerData</span> } }; } </pre></div><p>Testing a newly added planner:</p> <ul> <li>Basic test to ensure that the functionality of <a class="el" href="classompl_1_1base_1_1Planner.html#a7e99408ada6e1572a14509fd566ae8b8" title="Clear all internal datastructures. Planner settings are not affected. Subsequent calls to solve() wil...">ompl::base::Planner::clear()</a> and <a class="el" href="classompl_1_1base_1_1Planner.html#acc87e95df04aa24ec52e24281c9fc223" title="Function that can solve the motion planning problem. This function can be called multiple times on th...">ompl::base::Planner::solve()</a> is correct: <div class="fragment"><pre class="fragment"> <span class="comment">// create a planning context such that planner->solve() can be called and expected to find a solution</span> base::PlannerPtr planner; <span class="comment">// create a testing scenario for the planner</span> PlannerTest pt(planner); pt.test(); </pre></div></li> <li>Use the <a class="el" href="classompl_1_1Benchmark.html" title="Benchmark a set of planners on a problem instance.">ompl::Benchmark</a> class to evaluate performance </li> </ul> </div></div> <!-- window showing the filter options --> <div id="MSearchSelectWindow" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()" onkeydown="return searchBox.OnSearchSelectKey(event)"> <a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark"> </span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark"> </span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark"> </span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark"> </span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark"> </span>Enumerator</a></div> <!-- iframe showing the search results (closed by default) --> <div id="MSearchResultsWindow"> <iframe src="javascript:void(0)" frameborder="0" name="MSearchResults" id="MSearchResults"> </iframe> </div> </div> <div class="footer span-22 push-2 last"> <a href="http://www.kavrakilab.org">Physical and Biological Computing Group</a> • <a href="http://www.cs.rice.edu">Department of Computer Science</a> • <a href="http://www.rice.edu">Rice University</a><br> <div class="gray">Generated on Sun Oct 9 2011 23:04:41 by <a href="http://www.doxygen.org/index.html">doxygen</a> 1.7.4</div> </div> </div> </body> </html>