Sophie

Sophie

distrib > Fedora > 14 > x86_64 > by-pkgid > 1099e73f16f15ba3cf656e619f52a447 > files > 1681

ompl-devel-0.9.5-1.fc14.x86_64.rpm

<!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: Python Bindings</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">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</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">Python Bindings </div>  </div>
</div>
<div class="contents">
<div class="textblock"><p>Almost all of the functionality of the C++ OMPL library is accessible through Python using more or less the same API. Some important differences will be described below. The Python bindings are generated with <a href="http://www.language-binding.net/pyplusplus/pyplusplus.html">Py++</a>, which relies on <a href="http://www.boost.org/doc/libs/release/libs/python/doc">Boost.Python</a>. The bindings are packaged in the ompl module. The main namespaces (<a class="el" href="namespaceompl_1_1base.html" title="This namespace contains sampling based planning routines shared by both planning under geometric cons...">ompl::base</a>, <a class="el" href="namespaceompl_1_1control.html" title="This namespace contains sampling based planning routines used by planning under differential constrai...">ompl::control</a>, <a class="el" href="namespaceompl_1_1geometric.html" title="This namespace contains code that is specific to planning under geometric constraints.">ompl::geometric</a>) are available as sub-modules. To quickly get an idea of what classes, functions, etc., are available within each submodule, type something like this at the Python prompt: </p>
<div class="fragment"><pre class="fragment">&gt;&gt;&gt; from ompl <span class="keyword">import</span> base, control, geometric, util
&gt;&gt;&gt; dir(base), dir(control), dir(geometric), dir(util)
</pre></div><dl class="user"><dt><b>Contents:</b></dt><dd><ul>
<li><a class="el" href="python.html#cpp_py_diffs">Important differences between C++ and Python</a></li>
<li><a class="el" href="python.html#py_api_diffs">Differences between the C++ and Python API's</a></li>
<li><a class="el" href="python.html#py_example">A simple example</a></li>
<li><a class="el" href="python.html#updating_python_bindings">Updating the Python bindings</a></li>
</ul>
</dd></dl>
<h2><a class="anchor" id="cpp_py_diffs"></a>
Important differences between C++ and Python:</h2>
<ul>
<li>There are no templates in Python, so templated classes and functions need to be fully instantiated to allow them to be exposed to python.</li>
<li>There are no C-style pointers in python, and no "new" or "delete" operators. This could be a problem, but can be dealt with mostly by using Boost <a href="http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm">shared_ptr</a>'s. If a C++ function takes pointer input/output parameters, <em>usually</em> a reference to the object is passed in the python bindings. In other words, you should be able to get and set the current value of an object through its methods. In some cases odd side effects may occur if you pass temporary objects (e.g., <code>function_call(Constructor_call())</code>), so it's advisable to create variables with the appropriate scope.</li>
</ul>
<h2><a class="anchor" id="py_api_diffs"></a>
Differences between the C++ and Python API's</h2>
<ul>
<li>An STL vector of int's is of type vectorInt in Python (analogously for other types).</li>
<li>The C++ class State has been renamed AbstractState, while the C++ class ScopedState&lt;&gt; is called State in Python.</li>
<li>The C++ class ScopedState&lt;RealVectorStateSpace&gt; is called RealVectorState. The ScopedState's for the other pre-defined state spaces have been renamed analogously.</li>
<li>The C++ class RealVectorStateSpace::StateType has been renamed to RealVectorStateInternal (analogously for the other state space types), to emphasize that an end user should really be using RealVectorState.</li>
<li>To get a reference to a C++ State stored inside a ScopedState from Python, use the "()" operator: <div class="fragment"><pre class="fragment">spc = SE3StateSpace()  <span class="preprocessor"># create an SE(3) state space</span>
<span class="preprocessor"></span>s = State(spc)         <span class="preprocessor"># allocate a state corresponding to a C++ ScopedState&lt;SE3StateSpace&gt;</span>
<span class="preprocessor"></span>sref = s()             <span class="preprocessor"># sref corresponds to a C++ State*. In this case sref is</span>
<span class="preprocessor"></span><span class="preprocessor">                       # a reference SE3StateSpace::StateType</span>
<span class="preprocessor"></span>sref.setX(1.0)         # <span class="keyword">set</span> the X coordinate
s().setX(1.0)          # <span class="keyword">this</span> also works
</pre></div></li>
<li>The print method (for classes that have one) is mapped to the special python method __str__, so a C++ call like <code>foo.print(std::cout)</code> becomes <code>print foo</code> in python. Similarly, a C++ call like <code>foo.printSettings(std::cout)</code> becomes <code>print foo.settings()</code> in python.</li>
<li>The signature of the state validity checker is changed. In python the state validity checker has the following form: <div class="fragment"><pre class="fragment">def isStateValid(spaceInformation, state):
    return spaceInformation.satiesfiesBounds(state)
</pre></div></li>
</ul>
<p>Many of the python demo and test programs are direct ports of the corresponding C++ programs. If you compare these programs, the sometimes subtle differences will become more obvious. In the python programs you will notice that we can create python classes that derive from C++ classes and pass instances of such classes to C++ functions. Similarly, we can create python functions (such as state validity checkers or propagate functions) that can be called by C++ code.</p>
<h2><a class="anchor" id="py_example"></a>
A simple example</h2>
<p>Below is a simple annotated example. It is available in ompl/py-bindings/demos/RigidBodyPlanning.py.</p>
<div class="fragment"><pre class="fragment">from ompl <span class="keyword">import</span> base as ob
from ompl <span class="keyword">import</span> geometric as og

def isStateValid(spaceInformation, state):
    # <span class="stringliteral">&quot;state&quot;</span> is of type SE2StateInternal, so we don<span class="stringliteral">&#39;t need to use the &quot;()&quot;</span>
<span class="stringliteral">    # operator.</span>
<span class="stringliteral">    #</span>
<span class="stringliteral">    # Some arbitrary condition on the state (note that thanks to</span>
<span class="stringliteral">    # dynamic type checking we can just call getX() and do not need</span>
<span class="stringliteral">    # to convert state to an SE2State.)</span>
<span class="stringliteral">    return state.getX() &lt; .6</span>
<span class="stringliteral"></span>
<span class="stringliteral">def plan():</span>
<span class="stringliteral">    # create an SE2 state space</span>
<span class="stringliteral">    space = ob.SE2StateSpace()</span>
<span class="stringliteral"></span>
<span class="stringliteral">    # set lower and upper bounds</span>
<span class="stringliteral">    bounds = ob.RealVectorBounds(2)</span>
<span class="stringliteral">    bounds.setLow(-1)</span>
<span class="stringliteral">    bounds.setHigh(1)</span>
<span class="stringliteral">    space.setBounds(bounds)</span>
<span class="stringliteral"></span>
<span class="stringliteral">    # create a simple setup object</span>
<span class="stringliteral">    ss = og.SimpleSetup(space)</span>
<span class="stringliteral">    ss.setStateValidityChecker(isStateValid)</span>
<span class="stringliteral"></span>
<span class="stringliteral">    start = ob.State(space)</span>
<span class="stringliteral">    # we can pick a random start state...</span>
<span class="stringliteral">    start.random()</span>
<span class="stringliteral">    # ... or set specific values</span>
<span class="stringliteral">    start().setX(.5)</span>
<span class="stringliteral"></span>
<span class="stringliteral">    goal = ob.State(space)</span>
<span class="stringliteral">    # we can pick a random goal state...</span>
<span class="stringliteral">    goal.random()</span>
<span class="stringliteral">    # ... or set specific values</span>
<span class="stringliteral">    goal().setY(-.5)</span>
<span class="stringliteral"></span>
<span class="stringliteral">    ss.setStartAndGoalStates(start, goal)</span>
<span class="stringliteral"></span>
<span class="stringliteral">    # this will automatically choose a default planner with</span>
<span class="stringliteral">    # default parameters</span>
<span class="stringliteral">    solved = ss.solve(1.0)</span>
<span class="stringliteral"></span>
<span class="stringliteral">    if solved:</span>
<span class="stringliteral">        # try to shorten the path</span>
<span class="stringliteral">        ss.simplifySolution()</span>
<span class="stringliteral">        # print the simplified path</span>
<span class="stringliteral">        print ss.getSolutionPath()</span>
<span class="stringliteral"></span>
<span class="stringliteral"></span>
<span class="stringliteral">if __name__ == &quot;__main__&quot;:</span>
<span class="stringliteral">    plan()</span>
</pre></div><h2><a class="anchor" id="updating_python_bindings"></a>
(Re)generating the Python bindings</h2>
<p>The Python bindings are subdivided into modules, to reflect the main namespaces: <a class="el" href="namespaceompl_1_1base.html" title="This namespace contains sampling based planning routines shared by both planning under geometric cons...">ompl::base</a>, <a class="el" href="namespaceompl_1_1control.html" title="This namespace contains sampling based planning routines used by planning under differential constrai...">ompl::control</a>, and <a class="el" href="namespaceompl_1_1geometric.html" title="This namespace contains code that is specific to planning under geometric constraints.">ompl::geometric</a>. The code in the ompl/src/ompl/util directory is available in a submodule as well. Whenever you change the API to OMPL, you will need to update the Python bindings. Updating the bindings is a two-step process. First, the code for the modules needs to be generated. Second, the code needs to be compiled into binary Python modules.</p>
<h3><a class="anchor" id="binding_code_generation"></a>
Code generation</h3>
<p><b>The code for the Python bindings can be generated by typing “<code>make update_bindings</code>.”</b> This creates one header file per module, formed by concatenating all relevant header files for that module. This header file is then parsed by Py++ and the appropriate C++ code is generated. This code uses Boost.Python. Py++ is smart enough to create wrapper classes when necessary, register Python &lt;-&gt; C++ type conversions, and so on. If you only need to update the bindings for one module (say <code>base</code>), you can type “<code>make update_base_bindings</code>.” Any diagnostic information from Py++ is stored in a log file in the build directory for each module (<code>pyplusplus_base.log</code> for the module <code>base</code> and likewise for other modules).</p>
<p>For each module the relevant header files are listed in <code>ompl/py-bindings/headers_&lt;<em>modulename</em>&gt;.txt.</code> The order in which the header files are listed is important. A header file should not be included by another header file listed above it.</p>
<h3><a class="anchor" id="compile_bindings"></a>
Compiling the Python modules</h3>
<p>To compile the Python modules type “<code>make py_ompl</code>.” If you only want to compile one python module (say <code>base</code>), type “<code>make py_ompl_base</code>.” The modules will appear as libraries in the lib subdirectory in the build directory, but they are also copied to <code>ompl/py-bindings/ompl/&lt;<em>modulename</em>&gt;/_&lt;<em>modulename</em>&gt;.so</code>.</p>
<h3><a class="anchor" id="bindings_cmake"></a>
Forcing CMake to do The Right Thing</h3>
<p>Every attempt has been to have CMake correctly identify dependencies and only compile code when necessary. If you want force CMake to regenerate the bindings from scratch, you can remove the directory <code>ompl/py-bindings/bindings</code> and type “<code>make update_bindings</code>” again. If, on the other hand, you want to (temporarily) disable the compilation of Python bindings, type: </p>
<div class="fragment"><pre class="fragment">cmake -D OMPL_BUILD_PYBINDINGS:BOOL=OFF .
</pre></div><p> in your build directory. You can re-enable them, by running this command again, but with OFF changed to ON. Changing these settings can also be done through the CMake GUI. </p>
</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">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</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> &bull;
  <a href="http://www.cs.rice.edu">Department of Computer Science</a> &bull;
  <a href="http://www.rice.edu">Rice University</a><br>
  <div class="gray">Generated on Sun Oct 9 2011 23:04:30 by&#160;<a href="http://www.doxygen.org/index.html">doxygen</a> 1.7.4</div>
</div>
</div>
</body>
</html>