diff --git a/src/dynamic_graph/sot/dynamics/hrp2.py.in b/src/dynamic_graph/sot/dynamics/hrp2.py.in
index 5cfd0829241610a7548adafa4a2759e15843173b..63b1c314571a68e25d49172acbe97ba0cb79b2fb 100755
--- a/src/dynamic_graph/sot/dynamics/hrp2.py.in
+++ b/src/dynamic_graph/sot/dynamics/hrp2.py.in
@@ -57,6 +57,9 @@ class Hrp2(AbstractHumanoidRobot):
         0.261799, 0.17453,  0., -0.523599, 0., 0., 0.1,
         )
 
+    def smallToFull(self, config):
+        res = (config + 10*(0.,))
+        return res
 
     def __init__(self, name,
                  simu,
diff --git a/src/dynamic_graph/sot/dynamics/humanoid_robot.py b/src/dynamic_graph/sot/dynamics/humanoid_robot.py
index 7696b1cdbe4cd52a57658d65676b57ccb329e463..eb03da556a4b7b4b3ea83a1da3666a56877ced98 100755
--- a/src/dynamic_graph/sot/dynamics/humanoid_robot.py
+++ b/src/dynamic_graph/sot/dynamics/humanoid_robot.py
@@ -204,6 +204,17 @@ class AbstractHumanoidRobot (object):
         else:
             self.simu = False
 
+    def restart(self):
+        if self.robotSimu:
+            self.robotSimu.set(self.halfSitting)
+        self.dynamicRobot.signal('position').value = self.halfSitting
+        self.dynamicRobot.signal('velocity').value = self.dimension * (0.,)
+        self.dynamicRobot.signal('acceleration').value = self.dimension * (0.,)
+        if self.robotSimu:
+            self.robotSimu.increment(.001)
+
+
+
 
 class HumanoidRobot(AbstractHumanoidRobot):
 
diff --git a/unitTesting/python/quasistatic_walking.py b/unitTesting/python/quasistatic_walking.py
index dd83b1f487f3c3c57ac4bac9aa7394df296be3c3..cf146ad649134fd15bbad2a8f35ef338c543b617 100755
--- a/unitTesting/python/quasistatic_walking.py
+++ b/unitTesting/python/quasistatic_walking.py
@@ -21,57 +21,9 @@ from dynamic_graph.sot.dynamics.hrp2 import Hrp2
 
 from dynamic_graph import enableTrace, plug
 
-# Robotviewer is optional
-enableRobotViewer = True
-try:
-    import robotviewer
-except ImportError:
-    enableRobotViewer = False
+from tools import *
 
 
-
-def displayHomogeneousMatrix(matrix):
-    """
-    Display nicely a 4x4 matrix (usually homogeneous matrix).
-    """
-    import itertools
-
-    matrix_tuple = tuple(itertools.chain.from_iterable(matrix))
-
-    formatStr = ''
-    for i in xrange(4*4):
-        formatStr += '{0[' + str(i) + ']: <10} '
-        if i != 0 and (i + 1) % 4 == 0:
-            formatStr += '\n'
-    print formatStr.format(matrix_tuple)
-
-def toList(tupleOfTuple):
-    result = [[0, 0, 0, 0],
-              [0, 0, 0, 0],
-              [0, 0, 0, 0],
-              [0, 0, 0, 0]]
-    for i in xrange(4):
-        for j in xrange(4):
-            result[i][j] = tupleOfTuple[i][j]
-    return result
-
-def toTuple(listOfList):
-    return ((listOfList[0][0], listOfList[0][1],
-             listOfList[0][2], listOfList[0][3]),
-
-            (listOfList[1][0], listOfList[1][1],
-             listOfList[1][2], listOfList[1][3]),
-
-            (listOfList[2][0], listOfList[2][1],
-             listOfList[2][2], listOfList[2][3]),
-
-            (listOfList[3][0], listOfList[3][1],
-             listOfList[3][2], listOfList[3][3]))
-
-def smallToFull(config):
-    res = (config + 10*(0.,))
-    return res
-
 class QuasiStaticWalking:
     leftFoot = 0
     rightFoot = 1
@@ -200,34 +152,6 @@ class QuasiStaticWalking:
             # Trigger actions to move to next state.
             self.do(self.state)
 
-robot = Hrp2("robot", True)
-
-# Initialize robotviewer is possible.
-clt = None
-if enableRobotViewer:
-    try:
-        clt = robotviewer.client()
-    except:
-        enableRobotViewer = False
-
-timeStep = .02
-
-class Solver:
-    robot = None
-    sot = None
-
-    def __init__(self, robot):
-        self.robot = robot
-        self.sot = SOT('solver')
-        self.sot.signal('damping').value = 1e-6
-        self.sot.setNumberDofs(self.robot.dimension)
-
-        if robot.robotSimu:
-            plug(self.sot.signal('control'), robot.robotSimu.signal('control'))
-            plug(self.robot.robotSimu.signal('state'),
-                 self.robot.dynamicRobot.signal('position'))
-
-solver = Solver (robot)
 
 # Push tasks
 #  Feet tasks.
@@ -262,7 +186,7 @@ for i in xrange(totalSteps + 1):
 
     if clt:
         clt.updateElementConfig(
-            'hrp', smallToFull(robot.robotSimu.signal('state').value))
+            'hrp', robot.smallToFull(robot.robotSimu.signal('state').value))
 
 #  Security: switch back to double support.
 quasiStaticWalking.moveCoM('origin')
@@ -274,7 +198,7 @@ for i in xrange(int(duration / timeStep)):
 
     if clt:
         clt.updateElementConfig(
-            'hrp', smallToFull(robot.robotSimu.signal('state').value))
+            'hrp', robot.smallToFull(robot.robotSimu.signal('state').value))
 
 
 print "FINISHED"
diff --git a/unitTesting/python/reach_right_hand.py b/unitTesting/python/reach_right_hand.py
new file mode 100755
index 0000000000000000000000000000000000000000..ce18882c43a64b72a74ebb6d2ed1532a6ddc5ca3
--- /dev/null
+++ b/unitTesting/python/reach_right_hand.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright 2011, Florent Lamiraux, Thomas Moulard, JRL, CNRS/AIST
+#
+# This file is part of dynamic-graph.
+# dynamic-graph is free software: you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# dynamic-graph is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Lesser Public License for more details.  You should have
+# received a copy of the GNU Lesser General Public License along with
+# dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
+
+from dynamic_graph.sot.core import FeaturePoint6d, FeatureGeneric, SOT
+from dynamic_graph.sot.dynamics.humanoid_robot import HumanoidRobot
+from dynamic_graph.sot.dynamics.hrp2 import Hrp2
+
+from dynamic_graph import enableTrace, plug
+
+from tools import *
+
+
+# Move right wrist
+sdes = toList(robot.dynamicRobot.signal('right-wrist').value)
+sdes[0][3] += 0.25 # Move reference point forward.
+sdes[2][3] += 0.1 # Increment reference point altitude.
+robot.features['right-wrist'].reference.signal('position').value = toTuple(sdes)
+# Select translation only.
+robot.features['right-wrist'].feature.signal('selec').value = '000111'
+robot.tasks['right-wrist'].signal('controlGain').value = 1.
+
+# Push tasks
+#  Operational points tasks
+solver.sot.push(robot.name + '.task.right-ankle')
+solver.sot.push(robot.name + '.task.left-ankle')
+solver.sot.push(robot.name + '.task.right-wrist')
+
+#  Center of mass
+solver.sot.push(robot.name + '.task.com')
+
+# Main.
+#  Main loop
+for i in xrange(500):
+    robot.robotSimu.increment(timeStep)
+
+    if clt:
+        clt.updateElementConfig(
+            'hrp', robot.smallToFull(robot.robotSimu.signal('state').value))
+
+print "FINISHED"
diff --git a/unitTesting/python/tools.py b/unitTesting/python/tools.py
new file mode 100755
index 0000000000000000000000000000000000000000..317d139b8dc75bda40579d69922b2e0c39b52699
--- /dev/null
+++ b/unitTesting/python/tools.py
@@ -0,0 +1,129 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright 2011, Florent Lamiraux, Thomas Moulard, JRL, CNRS/AIST
+#
+# This file is part of dynamic-graph.
+# dynamic-graph is free software: you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# dynamic-graph is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Lesser Public License for more details.  You should have
+# received a copy of the GNU Lesser General Public License along with
+# dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
+
+from optparse import OptionParser
+
+from dynamic_graph import plug
+from dynamic_graph.sot.core import SOT
+from dynamic_graph.sot.dynamics.hrp2 import Hrp2
+
+
+# Robotviewer is optional
+hasRobotViewer = True
+try:
+    import robotviewer
+except ImportError:
+    hasRobotViewer = False
+
+
+####################
+# Helper functions #
+####################
+
+def toList(tupleOfTuple):
+    result = [[0, 0, 0, 0],
+              [0, 0, 0, 0],
+              [0, 0, 0, 0],
+              [0, 0, 0, 0]]
+    for i in xrange(4):
+        for j in xrange(4):
+            result[i][j] = tupleOfTuple[i][j]
+    return result
+
+def toTuple(listOfList):
+    return ((listOfList[0][0], listOfList[0][1],
+             listOfList[0][2], listOfList[0][3]),
+
+            (listOfList[1][0], listOfList[1][1],
+             listOfList[1][2], listOfList[1][3]),
+
+            (listOfList[2][0], listOfList[2][1],
+             listOfList[2][2], listOfList[2][3]),
+
+            (listOfList[3][0], listOfList[3][1],
+             listOfList[3][2], listOfList[3][3]))
+
+def displayHomogeneousMatrix(matrix):
+    """
+    Display nicely a 4x4 matrix (usually homogeneous matrix).
+    """
+    import itertools
+
+    matrix_tuple = tuple(itertools.chain.from_iterable(matrix))
+
+    formatStr = ''
+    for i in xrange(4*4):
+        formatStr += '{0[' + str(i) + ']: <10} '
+        if i != 0 and (i + 1) % 4 == 0:
+            formatStr += '\n'
+    print formatStr.format(matrix_tuple)
+
+def initRobotViewer():
+    """Initialize robotviewer is possible."""
+    clt = None
+    if hasRobotViewer:
+        try:
+            clt = robotviewer.client()
+        except:
+            print "failed to connect to robotviewer"
+    return clt
+
+
+##################
+# Helper classes #
+##################
+
+class Solver:
+    robot = None
+    sot = None
+
+    def __init__(self, robot):
+        self.robot = robot
+        self.sot = SOT('solver')
+        self.sot.signal('damping').value = 1e-6
+        self.sot.setNumberDofs(self.robot.dimension)
+
+        if robot.robotSimu:
+            plug(self.sot.signal('control'), robot.robotSimu.signal('control'))
+            plug(self.robot.robotSimu.signal('state'),
+                 self.robot.dynamicRobot.signal('position'))
+
+
+##################
+# Initialization #
+##################
+
+# Parse options and enable robotviewer client if wanted.
+clt = None
+parser = OptionParser()
+parser.add_option("-d", "--display",
+                  action="store_true", dest="display", default=False,
+                  help="enable display using robotviewer")
+(options, args) = parser.parse_args()
+
+if options.display:
+    if not hasRobotViewer:
+        print "Failed to import robotviewer client library."
+    clt = initRobotViewer()
+    if not clt:
+        print "Failed to initialize robotviewer client library."
+
+
+# Initialize the stack of tasks.
+robot = Hrp2("robot", True)
+timeStep = .02
+solver = Solver(robot)