Commit 844211ec authored by Thomas Moulard's avatar Thomas Moulard
Browse files

Convert full HTML pages to Asciidoc.



	* configure.ac: Do not generate HTML pages anymore.
	* doc/develop.html.in: Remove.
	* doc/develop.txt: New.
	* doc/install.html.in: Remove.
	* doc/install.txt: New.
Signed-off-by: default avatarThomas Moulard <thomas.moulard@gmail.com>
parent 26eb058d
2010-01-09 Thomas Moulard <thomas.moulard@gmail.com>
Convert full HTML pages to Asciidoc.
* configure.ac: Do not generate HTML pages anymore.
* doc/develop.html.in: Remove.
* doc/develop.txt: New.
* doc/install.html.in: Remove.
* doc/install.txt: New.
2010-01-09 Thomas Moulard <thomas.moulard@gmail.com>
Add Asciidoc support.
......
......@@ -123,8 +123,6 @@ AC_CONFIG_FILES([
doc/main.html
doc/index.html
doc/tree.html
doc/develop.html
doc/install.html
])
# Write files.
......
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="tabs.css" rel="stylesheet" type="text/css">
<link href="custom.css" rel="stylesheet" type="text/css">
<title>Humanoid Path Planner documentation</title>
</head>
<body>
<h1><a class="anchor" name="hppDoc_development">
Developing in Hpp
</a></h1>
This page explains some development rules applied in Hpp project.
<ul>
<li><a href="#hppDoc_rules">
General rules to be followed in HPP developement
</a>
</li>
<ul>
<li><a href="#hppDoc_separate_algo_middleware">
Make clear distinction between algorithms, middleware and graphical interface
</a>
</li>
<li><a href="#hppDoc_small_packages">
Modularity
</a>
</li>
<ul>
<li><a href="#hppDoc_example1">
Example
</a>
</li>
</ul>
<li><a href="#hppDoc_level_generality">
Level of generality
</a>
</li>
<ul>
<li><a href="#hppDoc_example2">
Example
</a>
</li>
<li><a href="#hppDoc_humanoid">
Humanoid robots
</a>
</li>
</ul>
</ul>
<li><a href="#hppDoc_howto">
How to implement a new algorithm in HPP.
</a>
</li>
<ul>
<li><a href="#hppDoc_new_algo">
Create a new software package implementing your algorithm
</a>
</li>
<li><a href="#hppDoc_new_interface">
Create a new KPP-interface for your package
</a>
</li>
</ul>
<li><a href="#hppDoc_programming_conventions">
Programming conventions
</a>
<ul>
<li><a href="#hppDoc_naming_conventions">
Naming conventions
</a>
</li>
<li><a href="#hppDoc_programming_rules">
Programming rules
</a>
</li>
<ul>
<li><a href="#hppDoc_private_attributes">
Private attributes
</a>
</li>
</li>
</ul>
</ul>
</li>
</ul>
<h2><a class="anchor" name="hppDoc_rules">
General rules to be followed in HPP developement
</a></h2>
<h3><a class="anchor" name="hppDoc_separate_algo_middleware">
Make clear distinction between algorithms, middleware and graphical interface
</a></h3>
<div align="center">
<img src="figures/archi.png" alt="archi.png">
<p><strong>Architecture of HPP: the functionalities are distributed into separate software packages. The architecture is composed of Three types of packages: algorithms, CORBA interfaces and KPP-SDK interfaces.</strong></p></div>
HPP is composed of several software packages divided into three groups as explained in the above figure: <ul>
<li>algorithms, </li>
<li>Corba server </li>
<li>KPP-interfaces</li>
</ul>
KPP-interface and Corba server should be considered as visualization and debugging-testing tools. It is mostly important that packages implementing path planning algorithms for humanoid robots are independent from a given middleware (CORBA) and from a given GUI (KineoPathPlanner). As a consequence, no CORBA::xxx attribute should be in a class belonging to the algorithm part.<p>
This simple principle will enable to easily insert the algorithmic software packages into different middlewares (GenoM, RT-middleware for instance).
<h3><a class="anchor" name="hppDoc_small_packages">
Modularity
</a></h3>
Try to avoid developing huge packages including many functions. Instead, build several small packages with simple interfaces and easy to understand functionalities.
<h4><a class="anchor" name="hppDoc_example1">
Example
</a></h4>
Let us assume that you are developing a path planning algorithm and you want to use quaternions to represent the orientations of rigid-bodies. <ul>
<li>The first step consists in trying to find an existing implementation of quaternions that you can use. </li>
<li>Let us assume (this is very unlikeky) that you cannot find a good implementation of quaternions, then, instead of developing operations on quaternions in your path planning package, it is much more clever to create a package that will handle quaternion operations and to make your path planning package depend on it. Later, other users will be able to use your quaternion package.</li>
</ul>
<h3><a class="anchor" name="hppDoc_level_generality">
Level of generality
</a></h3>
When you implement an algorithm, always ask yourself the question: "Could my algorihtm be applied to applications more general than the one I am dealing with?" If yes, try to make your algorithm take more general input than your practical problem of today.
<h4><a class="anchor" name="hppDoc_example2">
Example
</a></h4>
Let us assume that you want to implement Newton algoritm to find a root of a polynomial function. Your algorithm requires the derivative of the polynomial. You can get an expression of a polynomial derivative using the polynomial coefficients.<p>
However, it would be more clever to develop the same algorithm taking as input a function that might not be a polynomial. For that you can define an abstract class <div class="fragment"><pre class="fragment"><span class="keyword">class </span>Cmapping {
<span class="keyword">public</span>:
<span class="keyword">virtual</span> <span class="keywordtype">double</span> value(<span class="keywordtype">double</span> inParamter) = 0;
<span class="keyword">virtual</span> <span class="keywordtype">double</span> derivative(<span class="keywordtype">double</span> inParamter) = 0;
};
</pre></div> make your Newton implementation take as input an object <code>Cmapping</code> and then derive this class into a concrete polynomial class. Thus, your algorithm can be used by other people wanting to find the root of non-polynomial functions.
<h4><a class="anchor" name="hppDoc_humanoid">
Humanoid robots
</a></h4>
The algorithms we develop are mostly applied to one type of humanoid robot: HRP2. It is therefore important to develop these algorithms in such a way that they can be applied to any other humanoid robot. For that developers should avoid to make too strong asumptions about the robot structure. The abstract <a class="elRef" doxygen="abstractRobotDynamics.doxytag:/home/florent/devel/share/doc/abstractRobotDynamics/" href="/home/florent/devel/share/doc/abstractRobotDynamics/class_cjrl_humanoid_dynamic_robot.html">CjrlHumanoidDynamicRobot</a> interface for dynamic humanoid robots have been designed in this aim.
<h2><a class="anchor" name="hppDoc_howto">
How to implement a new algorithm in HPP.
</a></h2>
To implement a new algorithm in HPP, you need to create new software packages as described below. To create new software packages, we advise developers to use perl script <code>packageCreate</code>. <div class="fragment"><pre class="fragment">[~] cd devel/src
[src] cg-clone git+ssh:<span class="comment">//[git|softs].laas.fr/git/robots/scripts</span>
</pre></div>
<h3><a class="anchor" name="hppDoc_new_algo">
Create a new software package implementing your algorithm
</a></h3>
To create a new package depending on <code>hppCore</code>, type the following commands. <div class="fragment"><pre class="fragment">[~] cd devel/src
[src] perl ./scripts/packageCreate hppNewAlgo -d hppCore HPPCORE
</pre></div> If you want your package to depend on other packages add -d package PACKAGE for each dependence.<p>
This operation creates a template of software package with all necessary files to compile. There are four subdirectories in this package: <ul>
<li><code>doc:</code> contains necessary files to generate doxygen documentation, </li>
<li><code>include</code> contains headers files </li>
<li><code>src</code> contains source code files </li>
<li><code>unitTesting</code> contains files used to test the algorithm developed in the package.</li>
</ul>
Define in <code>include/hppNewAlgo.h</code> a class that derives from <a class="elRef" href="@HPPCORE_DOCDIR@/html/main.html">ChppPlanner</a>. <div class="fragment"><pre class="fragment"><span class="preprocessor">#include "<a class="codeRef" doxygen="hppCore.doxytag:/home/florent/devel/share/doc/hppCore/" href="@HPPCORE_DOCDIR@/html/main.html">hppPlanner.h</a>"</span>
<span class="keyword">class </span>ChppNewAlgo : <span class="keyword">public</span> <a class="codeRef" doxygen="hppCore.doxytag:/home/florent/devel/share/doc/hppCore/" href="@HPPCORE_DOCDIR@/html/main.html">ChppPlanner</a> {
<span class="keyword">public</span>:
...
ktStatus solve();
};
</pre></div> Class <a class="elRef" doxygen="hppCore.doxytag:/home/florent/devel/share/doc/hppCore/" href="@HPPCORE_DOCDIR@/html/main.html">ChppPlanner</a> proposes an interface functions to insert a robot and obstacles:
<div class="fragment"><pre class="fragment">ktStatus <a class="codeRef" doxygen="hppCore.doxytag:/home/florent/devel/share/doc/hppCore/" href="@HPPCORE_DOCDIR@/html/main.html">ChppPlanner::addHppProblem</a>(CkppDeviceComponentShPtr robot);
</pre></div>
<div class="fragment"><pre class="fragment">ktStatus <a class="codeRef" doxygen="hppCore.doxytag:/home/florent/devel/share/doc/hppCore/" href="@HPPCORE_DOCDIR@/html/main.html">ChppPlanner::addObstacle</a>(CkcdObjectShPtr object);
</pre></div>
Independently from how the robot and obstacles are inserted, you can use them as the input of your algorithm in your class ChppNewAlgo:
<div class="fragment"><pre class="fragment">CkppDeviceComponentShPtr robot = robotIthProblem(0);
</pre></div><p>
Write in <code>src/hppNewAlgo.cpp</code> function <div class="fragment"><pre class="fragment">ktStatus <a class="codeRef" doxygen="hppCore.doxytag:/home/florent/devel/share/doc/hppCore/" href="@HPPCORE_DOCDIR@/html/main.html">ChppNewAlgo::solve</a>()
{
CkwsPath path = resultOfNewAlgo();
<a class="codeRef" doxygen="hppCore.doxytag:/home/florent/devel/share/doc/hppCore/" href="@HPPCORE_DOCDIR@/html/main.html">ChppProblem</a>&amp; hppProblem = hppProblemVector[problemId];
hppProblem.<a class="codeRef" doxygen="hppCore.doxytag:/home/florent/devel/share/doc/hppCore/" href="@HPPCORE_DOCDIR@/html/main.html">addPath</a>(kwsPath);
}
</pre></div> that runs your algorithm. The two last lines insert the result of your path in KPP interface if the interface is running.<p>
To compile and install your package do the following step: <div class="fragment"><pre class="fragment">[~] cd devel/src/hppNewAlgo
[hppNewAlgo] mkdir build
[hppNewAlgo] cd build
[hppNewAlgo] cmake -DCMAKE_INSTALL_PREFIX=${HOME}/devel ..
[hppNewAlgo] make install
</pre></div>
<h3><a class="anchor" name="hppDoc_new_interface">
Create a new KPP-interface for your package
</a></h3>
To be able to see the result of your algorithm, you need to create a new KPP-interface deriving from CkppInterface <div class="fragment"><pre class="fragment">[~] cd devel/src
[src] perl ./scripts/packageCreate kppInterfaceNewAlgo -d kppInterface KPPINTERFACE -d hppNewAlgo HPPNEWALGO
</pre></div> and depending on your algorithm software package.<p>
See package <code>kppInterfaceTutorial</code> for an example, and especially for managing Kineo license issue in <code>src/Makefile.am</code> <div class="fragment"><pre class="fragment">[~] cd devel/src
[src] cg-clone git+ssh:<span class="comment">//[git|softs].laas.fr/git/jrl/hppTutorialPlanner</span>
[src] cg-clone git+ssh:<span class="comment">//[git|softs].laas.fr/git/jrl/kppInterfaceTutorial</span>
</pre></div><p>
To run your interface into KineoPathPlanner, do the following: <div class="fragment"><pre class="fragment">[~] KineoPathPlanner -ModulePath ${HOME}/lib/modules/${HOST}/libkppInterfaceNewAlgo
</pre></div> <br><br>
<h2><a class="anchor" name="hppDoc_programming_conventions">
Programming conventions
</a></h2>
<h3><a class="anchor" name="hppDoc_naming_conventions">
Naming conventions
</a>
</h3>
<table border="1" cellpadding="5" cellspacing="0">
<tr>
<td><b>Type</b></td><td><b>Convention</b></td><td><b>Example</b> </td></tr>
<tr>
<td>Class</td><td><code><em>CclassName or ChppClassName</em></code></td><td><code>ChppDevice</code> </td></tr>
<tr>
<td>Enum</td><td><code>E<em>Enum</em></code></td><td><code>ERsCurveType</code> </td></tr>
<tr>
<td>Namespace</td><td><code>N<em>namespace</em></code></td><td><code>NglobalApprox</code> </td></tr>
<tr>
<td>Typedef</td><td><code>T<em>type</em></code></td><td><code>TflatConfig</code> </td></tr>
<tr>
<td>Private attribute</td><td><code>att<em>NameOfAttribute</em></code></td><td><code>attMaxCurvature</code> </td></tr>
<tr>
<td>input argument of function</td><td><code>in<em>Parameter</em></code></td><td><code>bool setMaxcurvature(double inDouble)</code> </td></tr>
<tr>
<td>output argument of function</td><td><code>out<em>Parameter</em></code></td><td><code>void getBounds(double& outMinBound, double& outMaxBound)</code> </td></tr>
<tr>
</table>
<p>
<h3><a class="anchor" name="hppDoc_programming_rules">
Programming rules
</a>
</h3>
Besides the general rules explained above, some more specific rules should be enforced when writing a new class.
<h4><a class="anchor" name="hppDoc_private_attributes">
Private attributes
</a>
</h4>
All attributes in a class should be private since they represent the internal state of the object.
Access to these attributes can be controlled through protected or public access functions.
<h5>Example</h5>
<div class="fragment">
<pre class="fragment"><span class="keywordflow">class ConeClass </span> {
<pre class="keywordflow">public:</pre>
/**
\brief Public read access
\return Internal value of the object.
*/
inline double value()
{
return inValue;
};
<pre class="keywordflow">protected:</pre>
/**
\brief Write access for derived classes
\param inValue new internal value of the object.
*/
inline void value(double inValue)
{
attValue = inValue;
};
<pre class="keywordflow">private:</pre>
/**
\brief Internal value of the object
*/
double attValue;
<pre class="keywordflow">};</span>
</pre></div><p>
<br><br>
<hr>
<center>
<img src="images/footer.jpg" height="100" alt="footer"><br>
Humanoid Path Planner documentation<br>
</center>
</body>
</html>
Developing in Hpp
=================
This page explains some development rules applied in *HPP* project.
General rules to be followed in HPP developement
------------------------------------------------
Make clear distinction between algorithms, middleware and graphical interface
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.*HPP* architecture: the functionalities are distributed into separate software packages. The architecture is composed of three types of packages: algorithms, CORBA interfaces and KPP-SDK interfaces.
image:figures/archi.png[HPP architecture]
*HPP* is composed of several software packages divided into three
groups as explained in the above figure:
* algorithms,
* Corba server
* KPP-interfaces
KPP-interface and Corba server should be considered as visualization
and debugging-testing tools. It is mostly important that packages
implementing path planning algorithms for humanoid robots are
independent from a given middleware (CORBA) and from a given GUI
(KineoPathPlanner). As a consequence, no CORBA::xxx attribute should
be in a class belonging to the algorithm part.
This simple principle will enable to easily insert the algorithmic
software packages into different middlewares (GenoM, RT-middleware for
instance).
Modularity
~~~~~~~~~~
Try to avoid developing huge packages including many
functions. Instead, build several small packages with simple
interfaces and easy to understand functionalities.
Example
^^^^^^^
Let us assume that you are developing a path planning algorithm and
you want to use quaternions to represent the orientations of
rigid-bodies.
* The first step consists in trying to find an existing implementation
of quaternions that you can use.
* Let us assume (this is very unlikeky) that you cannot find a good
implementation of quaternions, then, instead of developing
operations on quaternions in your path planning package, it is much
more clever to create a package that will handle quaternion
operations and to make your path planning package depend on
it. Later, other users will be able to use your quaternion package.
Level of generality
~~~~~~~~~~~~~~~~~~~
When you implement an algorithm, always ask yourself the question:
"Could my algorihtm be applied to applications more general than the
one I am dealing with?" If yes, try to make your algorithm take more
general input than your practical problem of today.
Example
^^^^^^^
Let us assume that you want to implement Newton algoritm to find a
root of a polynomial function. Your algorithm requires the derivative
of the polynomial. You can get an expression of a polynomial
derivative using the polynomial coefficients.
However, it would be more clever to develop the same algorithm taking
as input a function that might not be a polynomial. For that you can
define an abstract class:
[source,cc]
class Cmapping {
public:
virtual double value(double inParamter) = 0;
virtual double derivative(double inParamter) = 0;
};
make your Newton implementation take as input an object Cmapping and
then derive this class into a concrete polynomial class. Thus, your
algorithm can be used by other people wanting to find the root of
non-polynomial functions.
Humanoid robots
^^^^^^^^^^^^^^^
The algorithms we develop are mostly applied to one type of humanoid
robot: HRP2. It is therefore important to develop these algorithms in
such a way that they can be applied to any other humanoid robot. For
that developers should avoid to make too strong asumptions about the
robot structure. The abstract CjrlHumanoidDynamicRobot interface for
dynamic humanoid robots have been designed in this aim.
How to implement a new algorithm in HPP
----------------------------------------
To implement a new algorithm in HPP, you need to create new software
packages as described below. To create new software packages, we
advise developers to use perl script packageCreate.
[source,shell]
[~] cd devel/src
[src] cg-clone git+ssh://[git|softs].laas.fr/git/robots/scripts
Create a new software package implementing your algorithm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To create a new package depending on hppCore, type the following
commands.
[source,shell]
[~] cd devel/src
[src] perl ./scripts/packageCreate hppNewAlgo -d hppCore HPPCORE
If you want your package to depend on other packages add `-d package
PACKAGE` for each dependence.
This operation creates a template of software package with all
necessary files to compile. There are four subdirectories in this
package:
* `doc` contains necessary files to generate doxygen documentation,
* `include` contains headers files
* `src` contains source code files
* `unitTesting` contains files used to test the algorithm developed in
the package.
Define in `include/hppNewAlgo.h` a class that derives from `ChppPlanner`.
[source,cc]
---------------------------------------------------------------------
#include "hppPlanner.h"
class ChppNewAlgo : public ChppPlanner {
public:
...
ktStatus solve();
};
---------------------------------------------------------------------
`Class ChppPlanner` proposes an interface functions to insert a robot
and obstacles:
[source,cc]
ktStatus ChppPlanner::addHppProblem(CkppDeviceComponentShPtr robot);
[source,cc]
ktStatus ChppPlanner::addObstacle(CkcdObjectShPtr object);
Independently from how the robot and obstacles are inserted, you can
use them as the input of your algorithm in your `class ChppNewAlgo`:
[source,cc]
CkppDeviceComponentShPtr robot = robotIthProblem(0);
Write in `src/hppNewAlgo.cpp` function:
[source,cc]
---------------------------------------------------------------------
ktStatus ChppNewAlgo::solve()
{
CkwsPath path = resultOfNewAlgo();
ChppProblem& hppProblem = hppProblemVector[problemId];
hppProblem.addPath(kwsPath);
}
---------------------------------------------------------------------
that runs your algorithm. The two last lines insert the result of your
path in KPP interface if the interface is running.
To compile and install your package do the following step:
[source,shell]
[~] cd devel/src/hppNewAlgo
[hppNewAlgo] mkdir build
[hppNewAlgo] cd build
[hppNewAlgo] cmake -DCMAKE_INSTALL_PREFIX=${HOME}/devel ..
[hppNewAlgo] make install
Create a new KPP-interface for your package
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To be able to see the result of your algorithm, you need to create a
new KPP-interface deriving from CkppInterface:
[source,shell]
[~] cd devel/src
[src] perl ./scripts/packageCreate kppInterfaceNewAlgo -d kppInterface KPPINTERFACE -d hppNewAlgo HPPNEWALGO
and depending on your algorithm software package.
See package kppInterfaceTutorial for an example, and especially for
managing Kineo license issue in `src/Makefile.am`:
[source,shell]
[~] cd devel/src
[src] cg-clone git+ssh://[git|softs].laas.fr/git/jrl/hppTutorialPlanner
[src] cg-clone git+ssh://[git|softs].laas.fr/git/jrl/kppInterfaceTutorial
To run your interface into KineoPathPlanner, do the following:
[source,shell]
[~] KineoPathPlanner -ModulePath ${HOME}/lib/modules/${HOST}/libkppInterfaceNewAlgo
Programming conventions
-----------------------
Naming conventions
~~~~~~~~~~~~~~~~~~
[options="header"]
|=======================
| Type | Convention | Example
| Class | CclassName or ChppClassName | ChppDevice
| Enum | EEnum | ERsCurveType
| Namespace | Nnamespace | NglobalApprox
| Typedef | Ttype | TflatConfig
| Private attribute | attNameOfAttribute | attMaxCurvature
| Function input argument | inParameter | bool setMaxcurvature(double inDouble)
| Function output argument | outParameter | void getBounds(double& outMinBound, double& outMaxBound)
|=======================
Programming rules
~~~~~~~~~~~~~~~~~
Besides the general rules explained above, some more specific rules
should be enforced when writing a new class.
Private attributes
^^^^^^^^^^^^^^^^^^
All attributes in a class should be private since they represent the
internal state of the object. Access to these attributes can be
controlled through protected or public access functions.
.Example
[source,cc]
---------------------------------------------------------------------
class ConeClass {
public:
/**
\brief Public read access
\return Internal value of the object.
*/
inline double value()
{
return inValue;
};
protected:
/**
\brief Write access for derived classes
\param inValue new internal value of the object.
*/
inline void value(double inValue)
{
attValue = inValue;
};
private:
/**
\brief Internal value of the object
*/
double attValue;
};
---------------------------------------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="tabs.css" rel="stylesheet" type="text/css">
<link href="custom.css" rel="stylesheet" type="text/css">
<title>Humanoid Path Planner documentation</title>
</head>
<body>
<h1><a class="anchor" name="hppDoc_howToInstall">How to install HPP</a></h1><h2><a class="anchor" name="hppDoc_install_intro">
Introduction</a></h2>
HPP (Humanoid Path Planner) is composed of several software modules packaged by autotools. These software modules are stored in a git repositories on git.laas.fr (or softs.laas.fr for people working at LAAS).<p>