diff --git a/README.md b/README.md
index 334fb91..45bfe9d 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ The various tutorials are:
2. [tutorial 2](./tutorial_2/README.md) How to define and solve a simple pick and place problem.
3. [tutorial 3](./tutorial_3/README.md) How to use HPP in manufacturing.
4. [tutorial 4](./tutorial_4/README.md) How to control the trajectory of a tool.
-5. [tutorial 5](./tutorial_5/README.md)
+5. [tutorial 5](./tutorial_5/README.md) How to optimize and time-parameterize paths.
6. [tutorial 6](./tutorial_6/README.md) How to execute motions on a real robot.
[](https://gitlab.laas.fr/humanoid-path-planner/hpp_tutorial/commits/master)
diff --git a/doc/Doxyfile.extra.in b/doc/Doxyfile.extra.in
index 1a2941a..bbbd040 100644
--- a/doc/Doxyfile.extra.in
+++ b/doc/Doxyfile.extra.in
@@ -3,7 +3,7 @@ TAGFILES = @HPP_CORE_DOXYGENDOCDIR@/hpp-core.doxytag=@HPP_CORE_DOXYGENDOCDIR@ \
@HPP_MANIPULATION_DOXYGENDOCDIR@/hpp-manipulation.doxytag=@HPP_MANIPULATION_DOXYGENDOCDIR@ \
@HPP_MANIPULATION_CORBA_DOXYGENDOCDIR@/hpp-manipulation-corba.doxytag=@HPP_MANIPULATION_CORBA_DOXYGENDOCDIR@ \
-INPUT=@CMAKE_SOURCE_DIR@/include @CMAKE_SOURCE_DIR@/src/hpp/corbaserver/pr2/robot.py
+INPUT=@CMAKE_SOURCE_DIR@/include
IMAGE_PATH = @CMAKE_SOURCE_DIR@/doc/figures
USE_MATHJAX= YES
diff --git a/include/hpp_tutorial/doc.hh b/include/hpp_tutorial/doc.hh
index 202315f..5651ecf 100644
--- a/include/hpp_tutorial/doc.hh
+++ b/include/hpp_tutorial/doc.hh
@@ -2,50 +2,36 @@
// Copyright (c) 2014 CNRS
// Authors: Florent Lamiraux
//
-//
-// This file is part of hpp_tutorial
-// hpp_tutorial 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.
-//
-// hpp_tutorial 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
-// hpp_tutorial If not, see
-// .
+// BSD 2-Clause License
+
+// Copyright (c) 2014-2024, CNRS
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice,
+// this
+// list of conditions and the following disclaimer.
+
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
/// \mainpage Tutorials
/// \anchor hpp_tutorial_documentation
///
-/// \par Introduction
-///
-/// These tutorials explain how to define and solve a path planning
-/// problem, how to display the resulting paths in gepetto-viewer, and
-/// how to implement a new path planning algorithm.
-///
-/// \par Setting up your environment
-///
-/// Before starting, make sure that
-/// \li \c bash is you default shell script language,
-/// \li the line \code source $DEVEL_DIR/config.sh \endcode is in your .bashrc
-/// file, where \c DEVEL_DIR is the environment variable defined in the
-///
-/// installation instructions.
-///
-/// \par Tutorials
-///
-/// \li \link hpp_tutorial_tutorial_1 Tutorial 1 (python)\endlink: how to
-/// define and solve a path planning problem using CORBA.
-/// \li \link hpp_tutorial_tutorial_1_cpp Tutorial 1 (C++)\endlink how to
-/// define and solve the same path planning problem without middleware.
-/// \li \link hpp_tutorial_tutorial_2 Tutorial 2 - plugin\endlink : how to
-/// implement
-/// a new path planning algorithm in C++.
-/// \li \link hpp_tutorial_tutorial_3 Tutorial 3 - manipulation \endlink : how
-/// to define and solve a manipulation planning problem. \li \link
-/// hpp_tutorial_tutorial_4 Tutorial 4 - inverse kinematics \endlink: how to
-/// plan
-/// end-effector trajectoties
+/// The tutorials are accessible on
+/// github.
diff --git a/include/hpp_tutorial/tutorial_1.hh b/include/hpp_tutorial/tutorial_1.hh
deleted file mode 100644
index 0dbd3b8..0000000
--- a/include/hpp_tutorial/tutorial_1.hh
+++ /dev/null
@@ -1,243 +0,0 @@
-//
-// Copyright (c) 2014 CNRS
-// Authors: Florent Lamiraux
-//
-//
-// This file is part of hpp_tutorial
-// hpp_tutorial 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.
-//
-// hpp_tutorial 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
-// hpp_tutorial If not, see
-// .
-
-/// \page hpp_tutorial_tutorial_1 Tutorial 1 - Python
-///
-/// To run the tutorial, open a terminal and open 3 tabs by typing
-/// \c CTRL+SHIFT+T twice. When the terminal is selected, you can select a tab
-/// by typing \c ALT-[1|2|3].
-///
-/// \section hpp_tutorial_1_starting_hppcorbaserver Starting hppcorbaserver
-///
-/// In the first tab, type
-/// \code
-/// hppcorbaserver
-/// \endcode
-/// See package \c hpp-corbaserver for details.
-///
-/// \section hpp_tutorial_1_starting_gui Starting gepetto-gui
-///
-/// In the second tab, type
-/// \code
-/// gepetto-gui -c basic
-/// \endcode
-/// A window opens and is ready to display the scene containing the robot. The
-/// robot and environment will appear later.
-///
-/// Note that \c gepetto-gui and \c hppcorbaserver executables are
-/// completely independent.
-///
-/// \section hpp_tutorial_1_python Controlling via a python terminal
-///
-/// In the third tab, type
-/// \code
-/// cd script
-/// python -i tutorial_1.py
-/// \endcode
-/// to run the script script/tutorial_1.py in an
-/// interactive python terminal.
-///
-/// To display the scene, type
-/// \code
-/// >>> v = vf.createViewer ()
-/// \endcode
-/// gepetto-gui window should now display a scene containing a PR2 robot in a
-/// kitchen environment.
-///
-/// To display initial and goal configurations type the following commands
-/// \code
-/// >>> v (q_init)
-/// >>> v (q_goal)
-/// \endcode
-///
-/// To solve the path planning problem between those configurations, type
-/// \code
-/// >>> ps.solve ()
-/// \endcode
-///
-/// To display the resulting of RRT, type
-/// \code
-/// >>> from hpp.gepetto import PathPlayer
-/// >>> pp = PathPlayer (v)
-/// >>> pp(0)
-/// \endcode
-///
-/// To display an optimized solutions,
-/// \code
-/// >>> pp(1)
-/// >>> pp(2)
-/// \endcode
-///
-/// \section hpp_tutorial_1_script Detailed explanation
-/// This section presents in more details the content of \c
-/// script/tutorial_1.py.
-///
-/// \code
-/// from hpp.corbaserver.pr2 import Robot
-/// robot = Robot ('pr2')
-/// robot.setJointBounds ("root_joint", [-4, -3, -5, -3])
-/// \endcode
-/// Import class pr2.robot.Robot and create an instance and set bounds of
-/// translation degrees of freedom of the base.
-/// Note that the constructor of the instance calls idl method
-/// hpp::corbaserver::Robot::loadRobotModel. This triggers the loading of the
-/// urdf/srdf model of the PR2 robot in \c hppcorbaserver executable.
-///
-/// \code
-/// from hpp.corbaserver import ProblemSolver
-/// ps = ProblemSolver (robot)
-/// \endcode
-/// Import class hpp.corbaserver.problem_solver.ProblemSolver and create an
-/// instance. This class is a helper class to define and solve path planning
-/// problems.
-///
-/// \code
-/// from hpp.gepetto import ViewerFactory
-/// vf = ViewerFactory (ps)
-/// \endcode
-/// Import class gepetto.viewerFactory.ViewerFactory and create an instance.
-/// This object takes as input the \c ProblemSolver instance that enables the
-/// viewer client to also control \c hppcorbaserver executable
-///
-/// \code
-/// q_init = robot.getCurrentConfig ()
-/// q_goal = q_init [::]
-/// q_init [0:2] = [-3.2, -4]
-/// rank = robot.rankInConfiguration ['torso_lift_joint']
-/// q_init [rank] = 0.2
-/// \endcode
-/// Define initial configuration.
-/// \note Initial configuration is built from configuration of the robot at
-/// construction, and by modification of joints retrieved by name. This method
-/// is more robust than specifying a hard-coded configuration vector since the
-/// ordering of joints in the configuration vector is not unique.
-///
-/// \code
-/// q_goal [0:2] = [-3.2, -4]
-/// rank = robot.rankInConfiguration ['l_shoulder_lift_joint']
-/// q_goal [rank] = 0.5
-/// rank = robot.rankInConfiguration ['l_elbow_flex_joint']
-/// q_goal [rank] = -0.5
-/// rank = robot.rankInConfiguration ['r_shoulder_lift_joint']
-/// q_goal [rank] = 0.5
-/// rank = robot.rankInConfiguration ['r_elbow_flex_joint']
-/// q_goal [rank] = -0.5
-/// \endcode
-/// Define goal configuration.
-///
-/// \code
-/// vf.loadObstacleModel ("package://hpp_tutorial/urdf/kitchen_area.urdf",
-/// "kitchen")
-
-/// \endcode
-/// Load obstacles from urdf file.
-/// \note this method loads the objects defined in the urdf file both in
-/// hppcorbaserver and in \c gepetto-viewer-server.
-///
-/// \code
-/// ps.setInitialConfig (q_init)
-/// ps.addGoalConfig (q_goal)
-/// \endcode
-/// Define initial and goal configurations.
-///
-/// \code
-/// ps.addPathOptimizer ("RandomShortcut")
-/// \endcode
-/// Add a path optimizer (hpp::core::pathOptimization::RandomShortcut).
-///
-/// \code
-/// loaded = ps.client.problem.loadPlugin("spline-gradient-based.so")
-/// if loaded:
-/// ps.addPathOptimizer("SplineGradientBased_bezier1")
-/// else:
-/// print("Could not load spline-gradient-based.so")
-/// \endcode
-/// Load a plugin that implements another path optimizer
-/// (hpp::core::pathOptimization::SplineGradientBasedAbstract) and add the path
-/// optimizer. The two selected path optimizers will be called in sequence.
-/// Note that in this example, the second path optimizer will not improve the
-/// result of the first one.
-///
-/// \code
-/// print (ps.solve ())
-/// \endcode
-/// Solve problem and print the results.
-///
-/// \code
-/// v = vf.createViewer()
-/// from hpp.gepetto import PathPlayer
-/// pp = PathPlayer (v)
-/// \endcode
-/// Create the display window.
-/// Import and create an instance of PathPlayer. This class samples a path in
-/// \c hppcorbaserver and displays it in \c gepetto-viewer-server.
-///
-/// \note Paths can be displayed in \c gepetto-gui after installing \c hpp-gui
-/// package and loading plugin \c hppwidgetsplugin.
-///
-/// \code
-/// pp(0)
-/// \endcode
-/// Display first path, result of RRT.
-///
-/// \code
-/// pp(1)
-/// \endcode
-/// Display second path after optimization by random shortcut algorithm.
-///
-/// \code
-/// pp(2)
-/// \endcode
-/// Display third path after optimization by spline gradient based algorithm.
-
-/// \page hpp_tutorial_tutorial_1_cpp Tutorial 1 - C++
-///
-/// Currently, there is no visualization with the C++ version.
-///
-/// \section hpp_tutorial_tutorial_1_cpp_execution Execute the binary.
-///
-/// Compile the code and run the following command in a terminal, type
-/// \code
-/// build-folder/src/hpp-tutorial-1
-/// \endcode
-///
-/// \section hpp_tutorial_tutorial_1_cpp_source Understanding the source code.
-///
-/// Have a look at the file \c src/tutorial_1.cc. It contains the C++ code that
-/// defines and solves the same path planning problem as \c tutorial_1.py.
-///
-/// \code
-/// ProblemSolverPtr_t ps = ProblemSolver::create();
-/// \endcode
-///
-/// Class hpp::core::ProblemSolver is a container class that stores
-/// \li a robot,
-/// \li objstacles,
-/// \li various types of path planning algorithms (hpp::core::PathPlanner),
-/// \li various types of path optimizers (hpp::core::PathOptimizer),
-/// \li various types of configuration shooter
-/// (hpp::core::ConfigurationShooter),
-/// \li various types of steering methods (hpp::core::SteeringMethod),
-/// \li various types of path validation methods
-/// (hpp::core::PathValidation)
-/// \li various types of path projection algorithms (hpp::core::PathProjector)
-/// \li various types of metrics defined on the configuration space
-/// (hpp::core::Distance).
-///
diff --git a/include/hpp_tutorial/tutorial_2.hh b/include/hpp_tutorial/tutorial_2.hh
deleted file mode 100644
index c2b8aca..0000000
--- a/include/hpp_tutorial/tutorial_2.hh
+++ /dev/null
@@ -1,134 +0,0 @@
-//
-// Copyright (c) 2014 CNRS
-// Authors: Florent Lamiraux
-//
-//
-// This file is part of hpp_tutorial
-// hpp_tutorial 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.
-//
-// hpp_tutorial 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
-// hpp_tutorial If not, see
-// .
-
-/// \page hpp_tutorial_tutorial_2 Tutorial 2 - Plugin
-///
-/// In this tutorial, we are going to implement a new path planning algorithm
-/// within a plugin.
-///
-/// \section hpp_tutorial_tutorial_2_implementation Implementing a new path
-/// planning algorithm in a plugin
-///
-/// The code of this tutorial can be found in \c src/tutorial_2.cc.
-/// The compilation and installation instructions can be found in
-/// \c src/CMakeLists.txt.
-///
-/// \subsection hpp_tutorial_tutorial_2_class_planner Implementation of class
-/// Planner
-///
-/// File \c src/tutorial_2.cc implements \c class
-/// hpp::tutorial::Planner, deriving from abstract class hpp::core::PathPlanner.
-/// In this section, we explain some specific parts of the code.
-///
-/// \code HPP_PREDEF_CLASS (Planner);\endcode
-/// is a macro containing the forward declaration of class \c Planner as well as
-/// \c PlannerWkPtr_t for weak pointer to class \c Planner. See
-/// \c hpp/util/pointer.hh
-/// for details.
-///
-/// \code
-/// static PlannerPtr_t create (const core::Problem& problem,
-/// const core::RoadmapPtr_t& roadmap)
-/// \endcode
-/// As most classes, hpp::core::PathPlanner and any derived class are
-/// manipulated
-/// via shared pointers. Users are not allowed to define variables of the type.
-/// Instead, they are required to call method \c create and to store the
-/// resulting shared pointer. For this reason, the constructors are all
-/// protected.
-/// \note method \c create calls protected method \c init that is explained
-/// later on.
-///
-/// \code
-/// virtual void oneStep ()
-/// \endcode
-/// This method runs one step of our the algorithm. The new algorithm is a
-/// basic version of PRM. Notice the compactness of the code.
-///
-/// \code
-/// void init (const PlannerWkPtr_t& weak)
-/// \endcode
-/// Method \c init takes as input a weak pointer to a new instance and stores
-/// this weak pointer as a private member. This enables any object to
-/// create a shared pointer to itself on demand using the following line of code
-/// \code
-/// weakPtr_.lock ();
-/// \endcode
-/// which is the shared pointer equivalent to \c this when using simple
-/// pointers. \note Method \c init always calls the parent implementation so
-/// that the parent part of the object also stores a weak pointer to itself.
-///
-/// \subsection hpp_tutorial_tutorial_2_plugin Implementation of plugin
-/// tutorial-2.so
-///
-/// Now that the new class \c hpp::tutorial::Planner has been implemented, we
-/// are going to add it via a plugin.
-///
-/// \code
-/// class Plugin : public core::ProblemSolverPlugin {
-/// public:
-/// Plugin() : ProblemSolverPlugin("TutorialPlugin", "0.0") {}
-/// protected:
-/// virtual bool impl_initialize(core::ProblemSolverPtr_t ps) {
-/// ps->pathPlanners.add("TutorialPRM", Planner::create);
-/// return true;
-/// }
-/// }; // class Plugin
-/// \endcode
-/// class \c hpp::tutorial::Plugin derives from abstract class
-/// \c hpp::core::ProblemSolverPlugin. Upon loading of the plugin by
-/// \c hppcorbaserver, method \c impl_initialize is called. This method register
-/// our new path planning class with key "TutorialPRM"
-///
-/// \code
-/// HPP_CORE_DEFINE_PLUGIN(hpp::tutorial::Plugin)
-/// \endcode
-/// This macro register the new plugin.
-///
-/// \section hpp_tutorial_tutorial_2_CMakeLists Compilation and installation
-///
-/// The compilation and installation is done in file \c src/CMakeLists.txt by
-/// the following lines
-/// \code
-/// ## Tutorial 2
-/// include(${HPP_CORE_CMAKE_PLUGIN})
-/// # Create and install the plugin
-/// hpp_add_plugin(tutorial-2 SOURCES tutorial_2.cc LINK_DEPENDENCIES
-/// hpp-corbaserver::hpp-corbaserver)
-/// \endcode
-/// These two lines declare a new plugin the source file of which is
-/// tutorial-2.cc and install this plugin into lib/hppPlugins subdirectory
-/// of the installation prefix.
-///
-/// \section hpp_tutorial_tutorial_2_running Using the plugin and solving a
-/// problem.
-///
-/// To solve a problem with the new path planning
-/// algorithm, we simply need to follow the same steps as in tutorial 1,
-/// except that we should source \c script/tutorial_2.py instead of
-/// \c script/tutorial_1.py
-///
-/// \code
-/// loaded = ps.client.problem.loadPlugin("tutorial-2.so")
-/// assert(loaded)
-///
-/// ps.selectPathPlanner("TutorialPRM")
-/// \endcode
-/// The above lines load the plugin and select the new path planner.
-///
diff --git a/include/hpp_tutorial/tutorial_3.hh b/include/hpp_tutorial/tutorial_3.hh
deleted file mode 100644
index 4fcc446..0000000
--- a/include/hpp_tutorial/tutorial_3.hh
+++ /dev/null
@@ -1,87 +0,0 @@
-//
-// Copyright (c) 2017 CNRS
-// Authors: Florent Lamiraux
-//
-//
-// This file is part of hpp_tutorial
-// hpp_tutorial 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.
-//
-// hpp_tutorial 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
-// hpp_tutorial If not, see
-// .
-
-/// \page hpp_tutorial_tutorial_3 Tutorial 3 - manipulation
-///
-/// To run the tutorial, open a terminal and open 3 tabs by typing
-/// \c CTRL+SHIFT+T twice. When the terminal is selected, you can select a tab
-/// by typing \c ALT-[1|2|3].
-///
-/// \section hpp_tutorial_3_starting_hpp_manipulation_server Starting
-/// hppcorbaserver
-///
-/// In the first tab, type
-/// \code
-/// hppcorbaserver
-/// \endcode
-/// See package \c hpp-manipulation-corba for details.
-///
-/// \section hpp_tutorial_3_python Controlling via a python terminal
-///
-/// In the second tab, type
-/// \code
-/// cd script
-/// python -i tutorial_3.py
-/// \endcode
-/// Script script/tutorial_3.py
-/// defines a manipulation planning problem.
-///
-/// \section hpp_tutorial_3_starting_gui Starting gepetto-gui
-///
-/// In the third tab, type
-/// \code
-/// gepetto-gui
-/// \endcode
-/// A window opens and is ready to display the scene containing the robot. The
-/// robot, environment and object will appear later.
-///
-/// Note that \c gepetto-gui and \c hppcorbaserver executables are
-/// completely independent.
-///
-/// \section hpp_tutorial_3_python Controlling via a python terminal
-///
-/// To display the scene, create a client to the viewer in the python terminal.
-/// \code
-/// >>> v = vf.createViewer ()
-/// \endcode
-/// The robot and environment should appear in the viewer. If the viewer
-/// window is black, select the window and hit space.
-///
-/// To solve the problem, type
-/// \code
-/// >>> ps.solve ()
-/// \endcode
-///
-/// and to display the (non optimized) solution path, type
-/// \code
-/// >>> pp = PathPlayer (v)
-/// >>> pp (0)
-/// \endcode
-///
-/// \section hpp_tutorial_3_optimization Optimizing the solution path
-///
-/// To optimize the solution path, select a path optimizer:
-/// \code
-/// >>> ps.addPathOptimizer('Graph-RandomShortcut')
-/// >>> ps.optimizePath(0)
-/// \endcode
-/// To display the solution:
-/// \code
-/// >>> pp(1)
-/// \endcode
diff --git a/include/hpp_tutorial/tutorial_4.hh b/include/hpp_tutorial/tutorial_4.hh
deleted file mode 100644
index 3c5743c..0000000
--- a/include/hpp_tutorial/tutorial_4.hh
+++ /dev/null
@@ -1,315 +0,0 @@
-//
-// Copyright (c) 2017 CNRS
-// Authors: Florent Lamiraux
-//
-//
-// This file is part of hpp_tutorial
-// hpp_tutorial 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.
-//
-// hpp_tutorial 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
-// hpp_tutorial If not, see
-// .
-
-/// \page hpp_tutorial_tutorial_4 Tutorial 4 - inverse kinematics
-///
-/// To run this tutorial, you need to install package \c ur_description.
-///
-/// To run the tutorial, open a terminal and open 3 tabs by typing
-/// \c CTRL+SHIFT+T twice. When the terminal is selected, you can select a tab
-/// by typing \c ALT-[1|2|3].
-///
-/// \section hpp_tutorial_4_starting_hpp_manipulation_server Starting
-/// hppcorbaserver
-///
-/// In the first tab, type
-/// \code
-/// hppcorbaserver
-/// \endcode
-/// See package \c hpp-manipulation-corba for details.
-///
-/// \section hpp_tutorial_4_python Controlling via a python terminal
-///
-/// In the second tab, type
-/// \code
-/// cd script
-/// python -i tutorial_4.py
-/// \endcode
-/// Script script/tutorial_4.py
-/// defines a path for an UR10 end-effector
-///
-/// \section hpp_tutorial_4_starting_gui Starting gepetto-gui
-///
-/// In the third tab, type
-/// \code
-/// gepetto-gui
-/// \endcode
-/// A window opens and is ready to display the scene containing the robot. The
-/// robot, environment and object will appear later.
-///
-/// \section hpp_tutorial_4_python Controlling via a python terminal
-///
-/// To display the scene, create a client to the viewer in the python terminal.
-/// \code
-/// >>> v = vf.createViewer ()
-/// \endcode
-/// The robot and environment should appear in the viewer. If the viewer
-/// window is black, select the window and hit space.
-///
-/// \section hpp_tutorial_4_explanition Explaining the script
-///
-/// The first part of the script below
-/// \li creates the robot from a xacro file,
-/// \li creates the problem solver and the viewer factory.
-///
-/// \code
-/// ## Load robot from processing of a xacro file
-/// Robot.urdfString = process_xacro\
-/// ("package://hpp_tutorial/urdf/ur10e.urdf.xacro",
-/// "transmission_hw_interface:=hardware_interface/PositionJointInterface")
-/// # Deactivate collision checking between consecutive links
-/// Robot.srdfString = """
-///
-///
-///
-///
-///
-///
-///
-///
-///
-///
-///
-/// """
-/// loadServerPlugin ("corbaserver", "manipulation-corba.so")
-/// newProblem()
-///
-/// robot = Robot('robot', 'ur10e', rootJointType="anchor")
-/// ps = ProblemSolver(robot)
-/// vf = ViewerFactory(ps)
-/// \endcode
-///
-/// The following lines
-/// \li create a gripper attached to the end-effector of the robot,
-/// \li create two handles attached to the base of the robot.
-///
-/// These grippers and handles will ease the creation of pose constraints for
-/// the end-effector.
-///
-/// \code
-/// ## Add a gripper to the robot
-/// robot.client.manipulation.robot.addGripper\
-/// ('ur10e/wrist_3_link', 'ur10e/gripper', [0,0,.1,0.5,0.5,0.5,-0.5], 0.1)
-///
-/// ## Create two handles
-/// robot.client.manipulation.robot.addHandle\
-/// ('ur10e/base_link', 'handle1', [.8, -.4, .5, 0, 0, 0, 1], .1, 6*[True])
-/// robot.client.manipulation.robot.addHandle\
-/// ('ur10e/base_link', 'handle2', [.8, .4, .5, 0, 0, 0, 1], .1, 6*[True])
-/// \endcode
-///
-/// Then two grasp constraints are created to defined initial and goal pose
-/// of the gripper
-///
-/// \code
-/// ## Create grasp constraints
-/// robot.client.manipulation.problem.createGrasp\
-/// ("ur10e/gripper grasps handle1", "ur10e/gripper", "handle1")
-/// robot.client.manipulation.problem.createGrasp\
-/// ("ur10e/gripper grasps handle2", "ur10e/gripper", "handle2")
-/// \endcode
-///
-/// Configurations satisfying the pose constraints are computed by creating
-/// a constraint graph with two nodes and no edge.
-///
-/// \code
-/// ## Create a constraint graph with one node for each grasp
-/// cg = ConstraintGraph(robot, "graph")
-/// cg.createNode(["ur10e/gripper grasps handle1", "ur10e/gripper grasps
-/// handle2"])
-/// cg.addConstraints(node = "ur10e/gripper grasps handle1", constraints = \
-/// Constraints(numConstraints = ["ur10e/gripper grasps handle1"]))
-/// cg.addConstraints(node = "ur10e/gripper grasps handle2", constraints = \
-/// Constraints(numConstraints = ["ur10e/gripper grasps handle2"]))
-/// cg.initialize()
-///\endcode
-///
-/// We compute the initial and goal configurations by numerical inverse
-/// kinematics.
-///
-/// \code
-/// # Generate one configuration satisfying each constraint
-/// found = False
-/// while not found:
-/// q0 = robot.shootRandomConfig()
-/// res, q1, err = cg.applyNodeConstraints("ur10e/gripper grasps handle1",
-/// q0) if not res: continue res, msg = robot.isConfigValid(q1) if not res:
-/// continue res, q2, err = cg.applyNodeConstraints("ur10e/gripper grasps
-/// handle2", q1) if not res: continue res, msg = robot.isConfigValid(q2) if
-/// not res: continue found = True
-///
-/// We create several CORBA objects:
-/// \li the current manipulation planning problem \c cmp,
-/// \li the robot stored in this problem \c crobot,
-/// \li a steering method \c csm of type
-/// hpp::manipulation::steeringMethod::EndEffectorTrajectory
-///
-/// \code
-/// ## Create an EndEffectorTrajectory steering method
-/// cmp = wd(ps.client.basic.problem.getProblem())
-/// crobot = wd(cmp.robot())
-/// cproblem = wd(ps.client.basic.problem.createProblem(crobot))
-/// csm =
-/// wd(ps.client.basic.problem.createSteeringMethod("EndEffectorTrajectory",
-/// cproblem)) \endcode
-///
-/// Then we create a \link hpp::core::ConstraintSet ContraintSet \endlink
-/// containing an empty \link hpp::core::ConfigProjector ConfigProjector
-/// \endlink that we pass to the problem. We set \link
-/// hpp::manipulation::steeringMethod::EndEffectorTrajectory \c csm \endlink as
-/// the steering method of the problem. Note that the last line passes the \link
-/// hpp::core::ConstraintSet ContraintSet \endlink of the problem to the
-/// steering method. The order is important here since at construction the
-/// problem is given an empty \link hpp::core::ConstraintSet ContraintSet
-/// \endlink and setting the steering method of
-/// the problem passes the \link hpp::core::ConstraintSet ContraintSet \endlink
-/// of the problem to the steering method.
-///
-/// \code
-/// cs = wd(ps.client.basic.problem.createConstraintSet(crobot,
-/// "sm-constraints")) cp =
-/// wd(ps.client.basic.problem.createConfigProjector(crobot, "cp", 1e-4, 40))
-/// cs.addConstraint(cp)
-/// cproblem.setConstraints(cs)
-/// cproblem.setSteeringMethod(csm)
-/// \endcode
-///
-/// We need to create a time varying constraint for the end-effector. For that,
-/// we create a new grasp between the gripper and the first handle. Note that
-/// we cannot use the previously created identical grasp, since the comparison
-/// type of this one should be \c Equality.
-///
-/// \code
-/// # Create a new grasp constraint for the steering method right hand side
-/// # The previously created one has EqualToZero as comparison types.
-/// robot.client.manipulation.problem.createGrasp \
-/// ("end-effector-tc", "ur10e/gripper", "handle1")
-/// # Set comparison type to Equality
-/// ps.setConstantRightHandSide("end-effector-tc", False)
-/// \endcode
-///
-/// We insert this constraint into the \link hpp::core::ConfigProjector
-/// ConfigProjector \endlink of the \link hpp::core::Problem problem \endlink
-/// (and thus of the steering method)
-///
-/// \code
-/// tc = wd(ps.client.basic.problem.getConstraint("end-effector-tc"))
-/// cp.add(tc, 0)
-/// \endcode
-///
-/// We pass this constraint to the steering method as the trajectory constraint.
-/// Note that from a mathematical point of view, the trajectory constraint is
-/// a mapping from the robot configuration space \f$\mathcal{C}\f$ to
-/// \f$SE(3)\f$ defined by
-/// \f{equation}
-/// tc(\mathbf{q}) = g^{-1}(\mathbf{q})h_1
-/// \f}
-/// where \f$g(\mathbf{q})\in SE(3)\f$ is the pose of the gripper in
-/// configuration \f$\mathbf{q}\f$ and \f$h_1\in SE(3)\f$ is the pose of
-/// \c handle1.
-///
-/// \code
-/// csm.trajectoryConstraint(tc)
-/// \endcode
-///
-/// We now need to build the right hand side of the constraint as a linear
-/// interpolation between the initial and final values. For that we evaluate
-/// the fonction \f$tc\f$ of the constraint at the initial and goal
-/// configurations,
-/// we create a path in SE(3) linking these two values and we give this path
-/// to the steering method to define the time-varying right hand side.
-///
-/// From a mathematical point of view, \f$\mathbf{p}\f$ is a mapping from an
-/// interval \f$[0,T]\f$ to \f$SE(3)\f$ such that
-/// \f{eqnarray}
-/// \mathbf{p}(0) &=& tc(\mathbf{q}_1) \\
-/// \mathbf{p}(T) &=& tc(\mathbf{q}_2) \\
-/// \f}
-/// The constraint applied along the path computed by the steering method is
-/// thus:
-/// \f{equation}
-/// \forall t\in[0,T],\ \ \mathbf{tc}(\mathbf{q}(t)) = \mathbf{p}(t)
-/// \f}
-///
-/// \code
-/// # Get right hand side for q1 and q2
-/// rhs1 = tc.function().value(q1)
-/// rhs2 = tc.function().value(q2)
-/// # Create linear path for end-effector
-/// p = wd(csm.makePiecewiseLinearTrajectory([rhs1, rhs2], 6*[1.]))
-/// # Set this path as the time-varying right hand side of the constraint
-/// csm.trajectory(p, True)
-///\endcode
-///
-/// We can now call the steering method between the initial and goal
-/// configurations and insert this path in the ProblemSolver in order to
-/// make it visible in \c gepetto-gui.
-///
-/// \code
-/// ## Call steering method
-/// p1 = wd(csm.call(q1,q2))
-/// if p1:
-/// ps.client.basic.problem.addPath(p1.asVector())
-///\endcode
-///
-/// After connecting and refreshing \c gepetto-gui, you should be able to
-/// display the path. Notice that the path might be discontinuous.
-///
-/// To get a continuous path for sure, we need to use the \link
-/// hpp::manipulation::pathPlanner::EndEffectorTrajectory EndEffectorTrajectory
-/// path planner \endlink.
-///
-/// \code
-/// ## Using EndEffectorTrajectory path planner
-/// cdistance = wd(cproblem.getDistance())
-/// croadmap = wd(ps.client.basic.problem.createRoadmap(cdistance, crobot))
-/// cplanner = wd(ps.client.basic.problem.createPathPlanner(
-/// "EndEffectorTrajectory", cproblem, croadmap))
-/// cplanner.setNRandomConfig(0)
-/// cplanner.maxIterations(1)
-/// cplanner.setNDiscreteSteps(20)
-///
-/// cproblem.setInitConfig(q1)
-/// cproblem.addGoalConfig(q2)
-///
-/// p2 = wd(cplanner.solve())
-/// if p2:
-/// ps.client.basic.problem.addPath(p2)
-///\endcode
-///
-/// We set the number of random configurations to 0 in order to force the
-/// planner to start from \c q1. Otherwise, in case of failure to plan a
-/// continuous path starting from \c q1, the planner would generate random
-/// initial configurations that satisfy the constraints at the beginning.
-/// To be consistent, we set the maximal number of iterations to 1 since new
-/// iterations would simply retry to start from \c q1. We set the number of
-/// steps at which a configuration is computed for the corresponding pose of the
-/// end effector to 20.
-///
-/// Notice that the path satisfies the end-effector time-varying constraint, but
-/// does not necessarily end at \f$\mathbf{q}_2\f$ since the final
-/// configuration is completely determined by the initial one.
diff --git a/tutorial_1/Dockerfile b/tutorial_1/Dockerfile
index 7ff4451..c379dc5 100644
--- a/tutorial_1/Dockerfile
+++ b/tutorial_1/Dockerfile
@@ -19,9 +19,7 @@ RUN apt-get update -y && DEBIAN_FRONTEND=noninteractive apt-get install -qqy \
robotpkg-hpp-manipulation-urdf+doc robotpkg-qt5-qgv \
libboost-filesystem1.83-dev libboost-python1.83.0 \
libboost-thread1.83-dev python3-numpy liburdfdom-dev wget python3.12-venv \
- python-is-python3 doxygen
-
-RUN apt-get update -y && DEBIAN_FRONTEND=noninteractive apt-get install -qqy \
+ python-is-python3 doxygen \
libasound2-dev libatk1.0-0 libc6 libcairo-gobject2 libcairo2 libdbus-1-3 libdbus-glib-1-2 \
libffi8 libfontconfig1 libfreetype6 libglib2.0-0 libgtk-3-0 libnspr4 libnss3 libpango-1.0-0 \
libstdc++6 libvpx9 apulse \
diff --git a/tutorial_1/Makefile b/tutorial_1/Makefile
index 3ea90f8..e754a2b 100644
--- a/tutorial_1/Makefile
+++ b/tutorial_1/Makefile
@@ -59,17 +59,29 @@ hpp-plot_extra_flags= -DINSTALL_DOCUMENTATION=OFF
# }}}
##################################
-# {{{ Packages for gepetto-gui
+# {{{ Packages for hpp-plot
qgv_branch=devel
qgv_repository=${HPP_REPO}
qgv_extra_flags=-DBINDINGS_QT5=ON -DBINDINGS_QT4=OFF
+# }}}
+##################################
+# {{{ Packages for toppra
+
+toppra_repository=https://github.com/hungpham2511
+toppra_branch=develop
+toppra_extra_flags= -DBUILD_TESTS=OFF -DPYTHON_BINDINGS=OFF
+
+hpp-toppra_repository=${HPP_REPO}
+hpp-toppra_branch=main
+hpp-toppra_extra_flags=
+
# }}}
##################################
# {{{ High-level targets
-all: hpp-plot.install hpp_tutorial.install
+all: hpp-plot.install hpp_tutorial.install hpp-toppra.install
${MAKE} hpp-doc.install
# }}}
@@ -96,6 +108,8 @@ qgv.configure.dep: qgv.checkout jrl-cmakemodules.install
hpp_tutorial.configure.dep: hpp_tutorial.checkout hpp-gepetto-viewer.install \
hpp-python.install
hpp-gepetto-viewer.configure.dep: hpp-gepetto-viewer.checkout python-venv hpp-python.install
+toppra.configure.dep: toppra.checkout
+hpp-toppra.configure.dep: hpp-toppra.checkout jrl-cmakemodules.install toppra.install
# }}}
##################################
@@ -203,3 +217,20 @@ update:
echo -n "$(@:.log=): "; \
cat .git/refs/heads/${$(@:.log=)_branch}; \
fi
+
+toppra.configure_nodep:toppra.checkout
+ mkdir -p ${SRC_DIR}/$(@:.configure_nodep=)/cpp/${BUILD_FOLDER}; \
+ cd ${SRC_DIR}/$(@:.configure_nodep=)/cpp/${BUILD_FOLDER}; \
+ cmake -DCMAKE_INSTALL_PREFIX=${INSTALL_HPP_DIR} -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_BU\
+ILD_TYPE=${BUILD_TYPE} \
+ -DENFORCE_MINIMAL_CXX_STANDARD=ON \
+ -DINSTALL_DOCUMENTATION=${INSTALL_DOCUMENTATION} \
+ -DCMAKE_CXX_FLAGS_RELWITHDEBINFO="-g -O3 -DNDEBUG" \
+ ${CLANG_FLAGS} \
+ ${$(@:.configure_nodep=)_extra_flags} ..
+
+toppra.install:toppra.configure
+ ${MAKE} -C ${SRC_DIR}/$(@:.install=)/cpp/${BUILD_FOLDER} install
+
+toppra.install_nodep:toppra.configure_nodep
+ ${MAKE} -C ${SRC_DIR}/$(@:.install_nodep=)/cpp/${BUILD_FOLDER} install
diff --git a/tutorial_2/README.md b/tutorial_2/README.md
index 7e76622..2442a44 100644
--- a/tutorial_2/README.md
+++ b/tutorial_2/README.md
@@ -43,7 +43,7 @@ v = Viewer(robot)
v.initViewer(open=False, loadModel=True)
v(q)
```
-Then in midor address bar, type `http://localhost:8080`. You should see the panda robot.
+Then in midori address bar, type `http://localhost:8080`. You should see the panda robot.
You can have a quick look at the script to see the instructions used to define the robot.
diff --git a/tutorial_5/README.md b/tutorial_5/README.md
new file mode 100644
index 0000000..5dcc1e4
--- /dev/null
+++ b/tutorial_5/README.md
@@ -0,0 +1,3 @@
+# How to optimize and time-parameterize paths.
+
+Work in progress, please be patient.
diff --git a/tutorial_6/README.md b/tutorial_6/README.md
new file mode 100644
index 0000000..aded22d
--- /dev/null
+++ b/tutorial_6/README.md
@@ -0,0 +1,3 @@
+# How to execute motions on a real robot.
+
+Work in progress, please be patient.