develop.txt 8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
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
-----------------------


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;
};
---------------------------------------------------------------------