Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • pfernbac/curves
  • stonneau/curves
  • jchemin/curves
  • gsaurel/ndcurves
4 results
Show changes
Commits on Source (838)
Showing with 2057 additions and 607 deletions
# pre-commit run -a (Guilhem Saurel, 2022-07-27)
ffb995161cba59619cec1b70088eb1dd7c527b37
# format (Guilhem Saurel, 2022-04-04)
1f1525de5b2ae9daef224cc8b0c4f6e12edccc12
# Format: yapf 0.32 (Guilhem Saurel, 2022-01-28)
906e28c6bbae602474778823dc2fd934dfd2c479
# format (Guilhem Saurel, 2022-01-07)
631b1a618da82af020e7b1fb2fe5662d49a32c13
# python tests: format (Guilhem Saurel, 2022-01-07)
d6a87cf82c953e89e403e2cd1ce057a768697a8c
# [Tests][Python] clean formatting (Pierre Fernbach, 2020-05-04)
810ba652943b272a3e86eb888e1fec89959fc2a3
# remove StringIO, not available in Python 3 (Guilhem Saurel, 2019-08-06)
2c88bfbe0b9775f9da51d550c352e493430d3e60
name: Build ndcurves for Mac OS X/Linux via pip
on: [push, pull_request]
env:
CTEST_OUTPUT_ON_FAILURE: 1
CTEST_PARALLEL_LEVEL: 4
jobs:
ndcurves-pip:
name: "CI on ${{ matrix.os }} / python ${{ matrix.python-version }} with pip"
runs-on: "${{ matrix.os }}"
strategy:
matrix:
os: ["ubuntu-latest"] # , "macos-latest"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
with:
submodules: 'true'
- uses: actions/setup-python@v5
with:
python-version: "${{ matrix.python-version }}"
- run: python -m pip install -U pip
- run: python -m pip install pin[build]
- run: echo "CMAKE_PREFIX_PATH=$(python -m cmeel cmake)" >> $GITHUB_ENV
- run: echo "LD_LIBRARY_PATH=$(python -m cmeel lib)" >> $GITHUB_ENV
- run: cmake -B build -S .
- run: cmake --build build
- run: cmake --build build -t test
name: "CI - Nix"
on:
push:
jobs:
nix:
runs-on: "${{ matrix.os }}-latest"
strategy:
matrix:
os: [ubuntu, macos]
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v27
- uses: cachix/cachix-action@v15
with:
name: gepetto
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
- run: nix build -L
......@@ -6,3 +6,4 @@ build-rel/
.*~
*.user
*.pyc
*.ipynb_checkpoints
include: http://rainboard.laas.fr/project/ndcurves/.gitlab-ci.yml
pull_request_rules:
- name: merge automatically when CI passes and PR is approved
conditions:
- check-success = "CI on ubuntu-latest / python 3.8 with pip"
- check-success = "CI on ubuntu-latest / python 3.9 with pip"
- check-success = "CI on ubuntu-latest / python 3.10 with pip"
- check-success = "CI on ubuntu-latest / python 3.11 with pip"
- check-success = "CI on ubuntu-latest / python 3.12 with pip"
- check-success = "gitlab-ci"
- check-success = "nix (macos)"
- check-success = "nix (ubuntu)"
- check-success = "pre-commit.ci - pr"
- or:
- author = pre-commit-ci[bot]
- author = dependabot[bot]
actions:
merge:
ci:
autoupdate_branch: devel
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.2
hooks:
- id: ruff
args:
- --fix
- --exit-non-zero-on-fix
- id: ruff-format
- repo: https://github.com/cheshirekow/cmake-format-precommit
rev: v0.6.13
hooks:
- id: cmake-format
- repo: https://github.com/pappasam/toml-sort
rev: v0.24.2
hooks:
- id: toml-sort-fix
exclude: poetry.lock
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v19.1.4
hooks:
- id: clang-format
args:
- --style=Google
exclude: python/test/sandbox/test.ipynb
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: check-added-large-files
- id: check-ast
- id: check-executables-have-shebangs
- id: check-json
- id: check-merge-conflict
- id: check-symlinks
- id: check-toml
- id: check-yaml
- id: debug-statements
- id: destroyed-symlinks
- id: detect-private-key
- id: end-of-file-fixer
- id: fix-byte-order-marker
- id: mixed-line-ending
- id: trailing-whitespace
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [2.0.0] - 2024-12-05
- :warning: BREAKING: switch from boost smart pointers to std ones
- setup nix
- setup mergify
## [1.4.1] - 2024-04-12
- tests: fix use of np.random in tests
- CMake: enable python bindings by default
## [1.4.0] - 2024-04-12
- Add a SO3 curves which is C2. It's called S03Smooth
- Add some typedef on using 3D curves.
- Fix typos around the package
- Add some tests on polynomials and the new structs.
- update tooling
- update packaging
- add pip CI
## [1.3.1] - 2023-11-29
### Changed
- ⚠️ require CMake 3.10 ⚠️
### Added
- python: define CopyableVisitor, fix SerializableVisitor and use them
### Fixed
- cmake generation on macosx
- Supporting pinocchio installed with cppad (#108)
- fix E721
## [1.3.0] - 2023-07-19
- add stubs support
- fix RPATH for OSX
## [1.2.0] - 2023-05-13
- [python] Enabled support to copy and deepcopy
- [python] Removed deprecated macros in eigenpy
- update for eigenpy v3
- pre-commit update
- sync submodule
- CMake: fetch submodule, set default build type, bump standard
## [1.1.6] - 2023-01-24
- don't build python bindings by default, to be more gentle with PAL robotics buildfarm.
## [1.1.5] - 2022-08-29
- fix allocator
- modernize cmake
## [1.1.4] - 2022-06-29
- remove unary function, deprecated since C++11 and removed in C++17
## [1.1.3] - 2022-05-31
## [1.1.2] - 2022-02-09
- [cmake] Improve Eigen detection/usage
- fix format
## [1.1.1] - 2022-01-06
- fix virtual functions
- fix optional dependency to pinocchio
- primitive now accept initial value\n
## [1.1.0] - 2021-05-03
- make dependency on pinocchio not mandatory
- fix link to Boost::serialization
- use eigen matrix serialization from pinocchio >= 2.6.0 if available
- export -DCURVES_WITH_PINOCCHIO_SUPPORT
## [1.0.0] - 2021-03-18
- ⚠️ library renamed from curves to ndcurves ⚠️
- added arithmetic operations on curves
## [0.5.2] - 2020-09-24
- fix CMake for fedora
## [0.5.1] - 2020-07-27
- fix serialization versioning
## [0.5.0] - 2020-07-25
- Add piecewise::load_from_text_file
- New curves type required by sot-talos-balance
- Use Bezier formulation for cubic hermite
- Check input degree before converting curve to bezier or hermite
- remove cubic and quintic classes
## [0.4.1] - 2020-04-02
Changes since v0.4.0:
- [CMake] fix pinocchio detection
- [CMake] export CURVES_WITH_PINOCCHIO_SUPPORT
## [0.4.0] - 2020-03-30
Changes since v0.3.3:
- [Python] Add pickle support
- Add serialization/curves header
## [0.3.3] - 2020-03-11
Changes since v0.3.2:
- CMake Exports
## [0.3.2] - 2020-02-13
Changes since v0.3.1:
- [Python] Fix binding of Piecewise.curve_at_index
- Replace several critical asserts with exceptions
- Install the header python_definitions.h in include/python
- Add python API to retrieve bezier waypoints as 2D array
- Add C++ and python API to retrieve the translation or rotation curve contained in a SE3 curve
- Correctly specify the corresponding shared_pointer to all python class
- Fix SO3 constructors when t_min == t_max
- Correctly check and raise error when trying to use polynomial constructors from boundary condition when t_min == t_max
- Reworking of the exposition of the abstract class in Python (fix https://gepgitlab.laas.fr/loco-3d/curves/issues/32)
- Correctly register the shared_pointer of the base abstract classes in boost::Python
## [0.3.1] - 2020-02-13
Changes since v0.3.0:
- [CMake] add INSTALL_PYTHON_INTERFACE_ONLY option
- Update README
## [0.3.0] - 2020-01-10
Changes since v0.2.0:
- [CMake] update minimal eigenpy version
- Add operator == and != for all curves
- Add methods isApprox() and isEquivalent() to all curves
- Fix optional dependency to pinocchio for python bindings
- [Python][Tests] remove all unecessary reshape(-1,1) in python
- Rework the class piecewise_curve to make it generic and remove the need to specify the type of curve used as a template argument, can now mix any kind of curves inside
- Rework the methods convert_to_X_from_Y to convert_to_X and remove the need to specify the input type as template argument
- Add compute_derivate_ptr() method to curve_abc and implement it in all child classes
- Add degree() method to curve_abc and implement it in all child class
- Factorize the most commonly used typedef with template argument in fwd.h
- [Python] correctly define eigenpy matrix type for point3 and point6
- [CMake] fix hardcoded path
- [CMake] fix install path of optimization files
- [Tests][Python] use Quaternion.isApprox to test equality instead of ==
- Add SE3 with pinocchio
- Add conversion functions from piecewise curve to python bindings
- Optimization
- Fix all compiler warnings
- Export plot
## [0.2.0] - 2019-10-04
- Initial release
[Unreleased]: https://github.com/loco-3d/ndcurves/compare/v2.0.0...HEAD
[2.0.0]: https://github.com/loco-3d/ndcurves/compare/v1.4.1...v2.0.0
[1.4.1]: https://github.com/loco-3d/ndcurves/compare/v1.4.0...v1.4.1
[1.4.0]: https://github.com/loco-3d/ndcurves/compare/v1.3.1...v1.4.0
[1.3.1]: https://github.com/loco-3d/ndcurves/compare/v1.3.0...v1.3.1
[1.3.0]: https://github.com/loco-3d/ndcurves/compare/v1.2.0...v1.3.0
[1.2.0]: https://github.com/loco-3d/ndcurves/compare/v1.1.6...v1.2.0
[1.1.6]: https://github.com/loco-3d/ndcurves/compare/v1.1.5...v1.1.6
[1.1.5]: https://github.com/loco-3d/ndcurves/compare/v1.1.4...v1.1.5
[1.1.4]: https://github.com/loco-3d/ndcurves/compare/v1.1.3...v1.1.4
[1.1.3]: https://github.com/loco-3d/ndcurves/compare/v1.1.2...v1.1.3
[1.1.2]: https://github.com/loco-3d/ndcurves/compare/v1.1.1...v1.1.2
[1.1.1]: https://github.com/loco-3d/ndcurves/compare/v1.1.0...v1.1.1
[1.1.0]: https://github.com/loco-3d/ndcurves/compare/v1.0.0...v1.1.0
[1.0.0]: https://github.com/loco-3d/ndcurves/compare/v0.5.2...v1.0.0
[0.5.2]: https://github.com/loco-3d/ndcurves/compare/v0.5.1...v0.5.2
[0.5.1]: https://github.com/loco-3d/ndcurves/compare/v0.5.0...v0.5.1
[0.5.0]: https://github.com/loco-3d/ndcurves/compare/v0.4.1...v0.5.0
[0.4.1]: https://github.com/loco-3d/ndcurves/compare/v0.4.0...v0.4.1
[0.4.0]: https://github.com/loco-3d/ndcurves/compare/v0.3.3...v0.4.0
[0.3.3]: https://github.com/loco-3d/ndcurves/compare/v0.3.2...v0.3.3
[0.3.2]: https://github.com/loco-3d/ndcurves/compare/v0.3.1...v0.3.2
[0.3.1]: https://github.com/loco-3d/ndcurves/compare/v0.3.0...v0.3.1
[0.3.0]: https://github.com/loco-3d/ndcurves/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/loco-3d/ndcurves/releases/tag/v0.2.0
cmake_minimum_required(VERSION 2.6)
project(spline)
INCLUDE(cmake/base.cmake)
INCLUDE(cmake/test.cmake)
INCLUDE(cmake/python.cmake)
cmake_minimum_required(VERSION 3.10)
SET(PROJECT_ORG humanoid-path-planner)
SET(PROJECT_NAME curves)
SET(PROJECT_DESCRIPTION
"template based classes for creating and manipulating spline and bezier curves. Comes with extra options specific to end-effector trajectories in robotics."
)
SET(PROJECT_URL "https://github.com/${PROJECT_ORG}/${PROJECT_NAME}")
# Project properties
set(PROJECT_ORG loco-3d)
set(PROJECT_NAME ndcurves)
set(PROJECT_DESCRIPTION "creatie and manipulate spline and bezier curves.")
set(PROJECT_URL "https://github.com/${PROJECT_ORG}/${PROJECT_NAME}")
# Disable -Werror on Unix for now.
SET(CXX_DISABLE_WERROR True)
SET(CMAKE_VERBOSE_MAKEFILE True)
# Project options
option(BUILD_PYTHON_INTERFACE "Build the python bindings" ON)
option(INSTALL_PYTHON_INTERFACE_ONLY "Install *ONLY* the python bindings" OFF)
option(SUFFIX_SO_VERSION "Suffix library name with its version" ON)
find_package(Eigen3 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIR})
# Project configuration
if(NOT INSTALL_PYTHON_INTERFACE_ONLY)
set(PROJECT_USE_CMAKE_EXPORT TRUE)
endif(NOT INSTALL_PYTHON_INTERFACE_ONLY)
set(CXX_DISABLE_WERROR TRUE)
SETUP_PROJECT()
# JRL-cmakemodule setup
set(JRL_CMAKE_MODULES "${CMAKE_CURRENT_LIST_DIR}/cmake")
if(EXISTS "${JRL_CMAKE_MODULES}/base.cmake")
message(STATUS "JRL cmakemodules found in 'cmake/' git submodule")
else()
find_package(jrl-cmakemodules QUIET CONFIG)
if(jrl-cmakemodules_FOUND)
get_property(
JRL_CMAKE_MODULES
TARGET jrl-cmakemodules::jrl-cmakemodules
PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
message(STATUS "JRL cmakemodules found on system at ${JRL_CMAKE_MODULES}")
elseif(${CMAKE_VERSION} VERSION_LESS "3.14.0")
message(
FATAL_ERROR
"\nCan't find jrl-cmakemodules. Please either:\n"
" - use git submodule: 'git submodule update --init'\n"
" - or install https://github.com/jrl-umi3218/jrl-cmakemodules\n"
" - or upgrade your CMake version to >= 3.14 to allow automatic fetching\n"
)
else()
message(STATUS "JRL cmakemodules not found. Let's fetch it.")
include(FetchContent)
FetchContent_Declare(
"jrl-cmakemodules"
GIT_REPOSITORY "https://github.com/jrl-umi3218/jrl-cmakemodules.git")
FetchContent_MakeAvailable("jrl-cmakemodules")
FetchContent_GetProperties("jrl-cmakemodules" SOURCE_DIR JRL_CMAKE_MODULES)
endif()
endif()
OPTION (BUILD_PYTHON_INTERFACE "Build the python binding" ON)
IF(BUILD_PYTHON_INTERFACE)
# search for python
FINDPYTHON(2.7 REQUIRED)
find_package( PythonLibs 2.7 REQUIRED )
include_directories( ${PYTHON_INCLUDE_DIRS} )
include("${JRL_CMAKE_MODULES}/base.cmake")
include("${JRL_CMAKE_MODULES}/boost.cmake")
include(CMakeDependentOption)
find_package( Boost COMPONENTS python REQUIRED )
include_directories( ${Boost_INCLUDE_DIR} )
cmake_dependent_option(
GENERATE_PYTHON_STUBS
"Generate the Python stubs associated to the Python library" OFF
BUILD_PYTHON_INTERFACE ON)
add_subdirectory (python)
set_default_cmake_build_type("Release")
ENDIF(BUILD_PYTHON_INTERFACE)
# Project definition
compute_project_args(PROJECT_ARGS LANGUAGES CXX)
project(${PROJECT_NAME} ${PROJECT_ARGS})
check_minimal_cxx_standard(14 ENFORCE)
# Project dependencies
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/find-external/CppAD/"
${CMAKE_MODULE_PATH})
find_package(Eigen3 QUIET NO_CMAKE_PACKAGE_REGISTRY)
if(Eigen3_FOUND)
add_project_dependency(Eigen3 REQUIRED NO_CMAKE_PACKAGE_REGISTRY
PKG_CONFIG_REQUIRES eigen3)
else(Eigen3_FOUND)
add_project_dependency(Eigen3 MODULE REQUIRED PKG_CONFIG_REQUIRES eigen3)
endif(Eigen3_FOUND)
find_package(pinocchio QUIET)
option(CURVES_WITH_PINOCCHIO_SUPPORT "Build with pinocchio support"
${pinocchio_FOUND})
if(CURVES_WITH_PINOCCHIO_SUPPORT)
if(NOT pinocchio_FOUND)
message(
FATAL_ERROR
"CURVES_WITH_PINOCCHIO_SUPPORT selected, but pinocchio has not been found"
)
endif(NOT pinocchio_FOUND)
add_project_dependency(pinocchio REQUIRED PKG_CONFIG_REQUIRES)
pkg_config_append_cflags("-DCURVES_WITH_PINOCCHIO_SUPPORT")
endif(CURVES_WITH_PINOCCHIO_SUPPORT)
set(PACKAGE_EXTRA_MACROS
"SET(CURVES_WITH_PINOCCHIO_SUPPORT ${CURVES_WITH_PINOCCHIO_SUPPORT})")
ADD_SUBDIRECTORY(include/curve)
ADD_SUBDIRECTORY(tests)
add_project_dependency(Boost REQUIRED COMPONENTS serialization)
SETUP_PROJECT_FINALIZE()
if(BUILD_PYTHON_INTERFACE)
add_project_dependency(eigenpy 3.0.0 REQUIRED PKG_CONFIG_REQUIRES
"eigenpy >= 3.0.0")
endif(BUILD_PYTHON_INTERFACE)
# Main Library
set(${PROJECT_NAME}_HEADERS
include/${PROJECT_NAME}/bernstein.h
include/${PROJECT_NAME}/bezier_curve.h
include/${PROJECT_NAME}/constant_curve.h
include/${PROJECT_NAME}/cross_implementation.h
include/${PROJECT_NAME}/cubic_hermite_spline.h
include/${PROJECT_NAME}/curve_abc.h
include/${PROJECT_NAME}/curve_constraint.h
include/${PROJECT_NAME}/curve_conversion.h
include/${PROJECT_NAME}/exact_cubic.h
include/${PROJECT_NAME}/fwd.h
include/${PROJECT_NAME}/helpers/effector_spline.h
include/${PROJECT_NAME}/helpers/effector_spline_rotation.h
include/${PROJECT_NAME}/linear_variable.h
include/${PROJECT_NAME}/MathDefs.h
include/${PROJECT_NAME}/optimization/definitions.h
include/${PROJECT_NAME}/optimization/details.h
include/${PROJECT_NAME}/optimization/integral_cost.h
include/${PROJECT_NAME}/optimization/quadratic_problem.h
include/${PROJECT_NAME}/piecewise_curve.h
include/${PROJECT_NAME}/polynomial.h
include/${PROJECT_NAME}/python/python_definitions.h
include/${PROJECT_NAME}/quadratic_variable.h
include/${PROJECT_NAME}/se3_curve.h
include/${PROJECT_NAME}/serialization/archive.hpp
include/${PROJECT_NAME}/serialization/curves.hpp
include/${PROJECT_NAME}/serialization/eigen-matrix.hpp
include/${PROJECT_NAME}/serialization/registeration.hpp
include/${PROJECT_NAME}/sinusoidal.h
include/${PROJECT_NAME}/so3_linear.h
include/${PROJECT_NAME}/so3_smooth.h)
add_library(${PROJECT_NAME} INTERFACE)
modernize_target_link_libraries(
${PROJECT_NAME}
SCOPE
INTERFACE
TARGETS
Eigen3::Eigen
INCLUDE_DIRS
${EIGEN3_INCLUDE_DIR})
target_include_directories(
${PROJECT_NAME} INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
target_link_libraries(${PROJECT_NAME} INTERFACE Boost::serialization)
if(CURVES_WITH_PINOCCHIO_SUPPORT)
target_link_libraries(${PROJECT_NAME} INTERFACE pinocchio::pinocchio)
target_compile_definitions(${PROJECT_NAME}
INTERFACE -DCURVES_WITH_PINOCCHIO_SUPPORT)
endif(CURVES_WITH_PINOCCHIO_SUPPORT)
if(NOT INSTALL_PYTHON_INTERFACE_ONLY)
install(
TARGETS ${PROJECT_NAME}
EXPORT ${TARGETS_EXPORT_NAME}
DESTINATION lib)
install(FILES package.xml DESTINATION share/${PROJECT_NAME})
endif(NOT INSTALL_PYTHON_INTERFACE_ONLY)
if(BUILD_PYTHON_INTERFACE)
add_subdirectory(python)
endif(BUILD_PYTHON_INTERFACE)
add_subdirectory(tests)
Spline
===================
# NDCurves
[![Pipeline status](https://gitlab.laas.fr/loco-3d/ndcurves/badges/master/pipeline.svg)](https://gitlab.laas.fr/loco-3d/ndcurves/commits/master)
[![Coverage report](https://gitlab.laas.fr/loco-3d/ndcurves/badges/master/coverage.svg?job=doc-coverage)](https://gepettoweb.laas.fr/doc/loco-3d/ndcurves/master/coverage/)
[![PyPI version](https://badge.fury.io/py/ndcurves.svg)](https://pypi.org/project/ndcurves)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/loco-3d/ndcurves/master.svg)](https://results.pre-commit.ci/latest/github/loco-3d/ndcurves)
A template-based Library for creating curves of arbitrary order and dimension, eventually subject to derivative constraints. The main use of the library is the creation of end-effector trajectories for legged robots.
To do so, tools are provided to:
> - create **exact** splines of arbitrary order (that pass exactly by an arbitrary number waypoints)
> - constrain initial / end velocities and acceleration for the spline.
> - constrain take-off and landing phases to follow a straight line along a given normal (to avoid undesired collisions between the effector and the contact surface)
> - automatically handle 3d rotation of the effector.
- create **exact** splines of arbitrary order (that pass exactly by an arbitrary number waypoints)
- constrain initial / end velocities and acceleration for the spline.
- constrain take-off and landing phases to follow a straight line along a given normal (to avoid undesired collisions between the effector and the contact surface)
- automatically handle 3d rotation of the effector.
- create curves in SO3
- support partial symbolic differentiation of curves. You can represent control points as linear variables, and integrate / differentiate those variable curves. You can also compute the cross product of two curves, which is relevant for centroidal dynamics.
Several type of formulation are provided:
- Polynomials
- Bezier
- Hermite (only cubic hermite for now)
The library is template-based, thus generic: the curves can be of any dimension, and can be implemented in double or float and can work with kind variables like Vector, Transform, Matrix, ...
## Installation
### Installation through robotpkg
The library is template-based, thus generic: the curves can be of any dimension, and can be implemented in double, float ...
You can install this package through robotpkg. robotpkg is a package manager tailored for robotics softwares.
It greatly simplifies the release of new versions along with the management of their dependencies.
You just need to add the robotpkg apt repository to your sources.list and then use `sudo apt install robotpkg-py3\*-ndcurves`.
While a Bezier curve implementation is provided, the main interest
of this library is to create spline curves of arbitrary order
If you have never added robotpkg as a softwares repository, please follow first the instructions from 1 to 3; otherwise, go directly to instruction 4.
Those instructions are similar to the installation procedures presented in [http://robotpkg.openrobots.org/debian.html](http://robotpkg.openrobots.org/debian.html).
----------
Example of use for and end-effector trajectory
-------------
The library comes with an helper class to automatically generate end-effector trajectories.
For instance, to create a 2 second long trajectory from the point (0,0,0) to (1,1,0), with a waypoint
at (0.5,0.5,0.5), one can use the following code:
1. Add robotpkg as source repository to apt:
```bash
sudo tee /etc/apt/sources.list.d/robotpkg.list <<EOF
deb [arch=amd64] http://robotpkg.openrobots.org/wip/packages/debian/pub $(lsb_release -sc) robotpkg
deb [arch=amd64] http://robotpkg.openrobots.org/packages/debian/pub $(lsb_release -sc) robotpkg
EOF
```
typedef std::pair<double, Eigen::Vector3d> Waypoint;
typedef std::vector<Waypoint> T_Waypoint;
// loading helper class namespace
using namespace spline::helpers;
2. Register the authentication certificate of robotpkg:
// Create waypoints
waypoints.push_back(std::make_pair(0., Eigen::Vector3d(0,0,0)));
waypoints.push_back(std::make_pair(1., Eigen::Vector3d(0.5,0.5,0.5)));
waypoints.push_back(std::make_pair(2., Eigen::Vector3d(1,1,0)));
```bash
curl http://robotpkg.openrobots.org/packages/debian/robotpkg.key | sudo apt-key add -
```
exact_cubic_t* eff_traj = effector_spline(waypoints.begin(),waypoints.end());
3. You need to run at least once apt update to fetch the package descriptions:
// evaluate spline
(*eff_traj)(0.); // (0,0,0)
(*eff_traj)(2.); // (1,1,0)
```bash
sudo apt-get update
```
If rotation of the effector must be considered, the code is almost the same:
4. The installation of nd-curves:
```bash
sudo apt install robotpkg-py3\*-ndcurves # for Python 3
sudo apt install robotpkg-py27-ndcurves # for Python 2
```
// initial rotation is 0, end rotation is a rotation by Pi around x axis
quat_t init_rot(0,0,0,1), end_rot(1,0,0,0);
effector_spline_rotation eff_traj_rot(waypoints.begin(),waypoints.end(), init_quat, end_quat);
// evaluate spline
eff_traj_rot(0.); // (0,0,0,0,0,0,1)
eff_traj_rot(1.); // (0.5,0.5,0.5,0.707107,0,0,0.707107) // Pi/2 around x axis
eff_traj_rot(2.); // (0,0,0,1,0,0,0)
Finally you will need to configure your environment variables, e.g.:
```bash
export PATH=/opt/openrobots/bin:$PATH
export PKG_CONFIG_PATH=/opt/openrobots/lib/pkgconfig:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=/opt/openrobots/lib:$LD_LIBRARY_PATH
export PYTHONPATH=/opt/openrobots/lib/python2.7/site-packages:$PYTHONPATH
```
Additional parameters for the same methods an be used to specify parameters for the take off and
landing phases: height and duration of the phase, and along which normal.
Please refer to the Main.cpp files to see all the unit tests and possibilities offered by the library
### Installation from source
Installation
-------------
## Dependencies
#### Dependencies
* [Eigen (version >= 3.2.2)](http://eigen.tuxfamily.org/index.php?title=Main_Page)
## Additional dependencies for python bindings
#### Additional dependencies for python bindings
* [Boost.Python](http://www.boost.org/doc/libs/1_63_0/libs/python/doc/html/index.html)
* [eigenpy](https://github.com/stack-of-tasks/eigenpy)
To handle this with cmake, use the recursive option to clone the repository.
For instance, using http:
```
git clone --recursive https://github.com/stonneau/spline.git $SPLINE_DIR
git clone --recursive https://github.com/loco-3d/ndcurves $NDCURVES_DIR
```
Where $NDCURVES_DIR is to be replaced to your selected source folder.
The library is header only, so the build only serves to build the tests and python bindings:
```sh
cd $NDCURVES_DIR && mkdir build && cd build
cmake -DBUILD_PYTHON_INTERFACE=ON .. && make && make test
```
cd $SPLINE_DIR && mkdir build && cd build
cmake .. && make
../bin/tests
```
Switch the BUILD_PYTHON argument to OFF if you don't want to use the python bindings of the package.
If everything went fine you should obtain the following output:
```sh
100% tests passed, 0 tests failed out of 3
```
performing tests...
no errors found
```
### Optional: Python bindings installation
To install the Python bindings, in the CMakeLists.txt file, first enable the BUILD_PYTHON_INTERFACE option:
#### Optional: Python bindings installation
To install the Python bindings first enable the `BUILD_PYTHON_INTERFACE` option:
```
OPTION (BUILD_PYTHON_INTERFACE "Build the python binding" ON)
cmake -DBUILD_PYTHON_INTERFACE=ON ..
```
Then rebuild the library:
```
cd $SPLINE_DIR/build
cmake -DCMAKE_INSTALL_PREFIX=${DEVEL_DIR}/install ..
make install
cd ${NDCURVES_DIR}/build
make && make test
```
The python bindings should then be accessible through the package centroidal_dynamics.
To see example of use, you can refer to the [test file](https://github.com/stonneau/spline/blob/master/python/test/test.py)
To see example of use, you can refer to the [test file](https://github.com/loco-3d/ndcurves/blob/master/python/test/test.py)
which is rather self explanatory:
In spite of an exhaustive documentation, please refer to the C++ documentation, which mostly applies
to python. For the moment, only bezier curves are binded.
In spite of an exhaustive documentation, please refer to the C++ documentation, which mostly applies to python.
## Documentation and tutorial
For the C++ / Python detailed documentation, you can consult [this pdf](https://github.com/loco-3d/ndcurves/blob/devel/doc/curves.pdf) available in the doc folder
For a python tutorial, you can refer to the [jupyter notebook](https://github.com/loco-3d/ndcurves/blob/master/python/test/sandbox/test.ipynb).
The [test file](https://github.com/loco-3d/ndcurves/blob/master/python/test/test.py) is more exhaustive and rather self explanatory.
## Citation
If you wish to cite this work please use the bibtex below:
```bib
@software{ndcurves,
author = {Tonneau, Steve and Chemin, Jason and Fernbach, Pierre and Saurel, Guilhem},
title = {ndcurves},
url = {https://github.com/loco-3d/ndcurves},
year = {2013}
}
```
Subproject commit cea261e3da7d383844530070356bca76d20197a8
Subproject commit 29c0eb4e659304f44d55a0389e2749812d858659
File added
This diff is collapsed.
doc/source/images/De_Casteljau_construction.png

34.7 KiB

{
"nodes": {
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1733312601,
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1733380312,
"narHash": "sha256-ywntxT10Om755wkB9tYgJwEwELQZKYAO5WcNuHv1vjI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a772498086eac57d97065a980a21fc0f304e3192",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1733096140,
"narHash": "sha256-1qRH7uAUsyQI7R1Uwl4T+XvdNv778H0Nb5njNrqvylY=",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz"
}
},
"root": {
"inputs": {
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}
{
description = "Library for creating smooth cubic splines";
inputs = {
flake-parts.url = "github:hercules-ci/flake-parts";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs =
inputs:
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
systems = inputs.nixpkgs.lib.systems.flakeExposed;
perSystem =
{ pkgs, self', ... }:
{
apps.default = {
type = "app";
program = pkgs.python3.withPackages (_: [ self'.packages.default ]);
};
devShells.default = pkgs.mkShell { inputsFrom = [ self'.packages.default ]; };
packages = {
default = self'.packages.ndcurves;
ndcurves = pkgs.python3Packages.ndcurves.overrideAttrs (_: {
src = pkgs.lib.fileset.toSource {
root = ./.;
fileset = pkgs.lib.fileset.unions [
./CMakeLists.txt
./doc
./include
./package.xml
./python
./tests
];
};
});
};
};
};
}
SET(${PROJECT_NAME}_HEADERS
bernstein.h
bezier_polynom_conversion.h
curve_abc.h
exact_cubic.h
MathDefs.h
polynom.h
spline_deriv_constraint.h
bezier_curve.h
cubic_spline.h
curve_constraint.h
quintic_spline.h
linear_variable.h
)
INSTALL(FILES
${${PROJECT_NAME}_HEADERS}
DESTINATION include/curve
)
ADD_SUBDIRECTORY(helpers)
/**
* \file Math.h
* \brief Linear algebra and other maths definitions. Based on Eigen 3 or more
* \author Steve T.
* \version 0.1
* \date 06/17/2013
*
* This file contains math definitions used
* used throughout the library.
* Preprocessors definition are used to use eitheir float
* or double values, and 3 dimensional vectors for
* the Point structure.
*/
#ifndef _SPLINEMATH
#define _SPLINEMATH
#include <Eigen/Dense>
#include <Eigen/SVD>
#include <vector>
#include <utility>
namespace curve{
//REF: boulic et al An inverse kinematics architecture enforcing an arbitrary number of strict priority levels
template<typename _Matrix_Type_>
void PseudoInverse(_Matrix_Type_& pinvmat)
{
Eigen::JacobiSVD<_Matrix_Type_> svd(pinvmat, Eigen::ComputeFullU | Eigen::ComputeFullV);
_Matrix_Type_ m_sigma = svd.singularValues();
double pinvtoler= 1.e-6; // choose your tolerance widely!
_Matrix_Type_ m_sigma_inv = _Matrix_Type_::Zero(pinvmat.cols(),pinvmat.rows());
for (long i=0; i<m_sigma.rows(); ++i)
{
if (m_sigma(i) > pinvtoler)
m_sigma_inv(i,i)=1.0/m_sigma(i);
}
pinvmat = (svd.matrixV()*m_sigma_inv*svd.matrixU().transpose());
}
} // namespace curve
#endif //_SPLINEMATH
/**
* \file bezier_curve.h
* \brief class allowing to create a Bezier curve of dimension 1 <= n <= 3.
* \author Steve T.
* \version 0.1
* \date 06/17/2013
*/
#ifndef _CLASS_BERNSTEIN
#define _CLASS_BERNSTEIN
#include "curve_abc.h"
#include "MathDefs.h"
#include <math.h>
#include <vector>
#include <stdexcept>
namespace curve
{
///
/// \brief Computes factorial of a number
///
inline unsigned int fact(const unsigned int n)
{
unsigned int res = 1;
for (unsigned int i=2 ; i <= n ; ++i)
res *= i;
return res;
}
///
/// \brief Computes a binomal coefficient
///
inline unsigned int bin(const unsigned int n, const unsigned int k)
{
return fact(n) / (fact(k) * fact(n - k));
}
/// \class Bernstein
/// \brief Computes a Bernstein polynome
///
template <typename Numeric = double>
struct Bern{
Bern(const unsigned int m, const unsigned int i)
:m_minus_i(m - i)
,i_(i)
,bin_m_i_(bin(m,i)) {}
~Bern(){}
Numeric operator()(const Numeric u) const
{
assert(u >= 0. && u <= 1.);
return bin_m_i_*(pow(u, i_)) *pow((1-u),m_minus_i);
}
Numeric m_minus_i;
Numeric i_;
Numeric bin_m_i_;
};
///
/// \brief Computes all Bernstein polynomes for a certain degree
///
template <typename Numeric>
std::vector<Bern<Numeric> > makeBernstein(const unsigned int n)
{
std::vector<Bern<Numeric> > res;
for(unsigned int i = 0; i<= n; ++i)
res.push_back(Bern<Numeric>(n, i));
return res;
}
} // namespace curve
#endif //_CLASS_BERNSTEIN
/**
* \file bezier_curve.h
* \brief class allowing to create a Bezier curve of dimension 1 <= n <= 3.
* \author Steve T.
* \version 0.1
* \date 06/17/2013
*/
#ifndef _CLASS_BEZIERCURVE
#define _CLASS_BEZIERCURVE
#include "curve_abc.h"
#include "bernstein.h"
#include "curve_constraint.h"
#include "MathDefs.h"
#include <vector>
#include <stdexcept>
#include <iostream>
namespace curve
{
/// \class BezierCurve
/// \brief Represents a Bezier curve of arbitrary dimension and order.
/// For degree lesser than 4, the evaluation is analitycal.Otherwise
/// the bernstein polynoms are used to evaluate the spline at a given location.
///
template<typename Time= double, typename Numeric=Time, std::size_t Dim=3, bool Safe=false
, typename Point= Eigen::Matrix<Numeric, Dim, 1> >
struct bezier_curve : public curve_abc<Time, Numeric, Dim, Safe, Point>
{
typedef Point point_t;
typedef Time time_t;
typedef Numeric num_t;
typedef curve_constraints<point_t> curve_constraints_t;
typedef std::vector<point_t,Eigen::aligned_allocator<point_t> > t_point_t;
typedef typename t_point_t::const_iterator cit_point_t;
typedef bezier_curve<Time, Numeric, Dim, Safe, Point > bezier_curve_t;
/* Constructors - destructors */
public:
///\brief Constructor
///\param PointsBegin, PointsEnd : the points parametering the Bezier curve
///
template<typename In>
bezier_curve(In PointsBegin, In PointsEnd)
: T_(1.)
, mult_T_(1.)
, size_(std::distance(PointsBegin, PointsEnd))
, degree_(size_-1)
, bernstein_(curve::makeBernstein<num_t>((unsigned int)degree_))
{
assert(bernstein_.size() == size_);
In it(PointsBegin);
if(Safe && (size_<1 || T_ <= 0.))
throw std::out_of_range("can't create bezier min bound is higher than max bound"); // TODO
for(; it != PointsEnd; ++it)
pts_.push_back(*it);
}
///\brief Constructor
///\param PointsBegin, PointsEnd : the points parametering the Bezier curve
///
template<typename In>
bezier_curve(In PointsBegin, In PointsEnd, const time_t T)
: T_(T)
, mult_T_(1.)
, size_(std::distance(PointsBegin, PointsEnd))
, degree_(size_-1)
, bernstein_(curve::makeBernstein<num_t>((unsigned int)degree_))
{
assert(bernstein_.size() == size_);
In it(PointsBegin);
if(Safe && (size_<1 || T_ <= 0.))
throw std::out_of_range("can't create bezier min bound is higher than max bound"); // TODO
for(; it != PointsEnd; ++it)
pts_.push_back(*it);
}
///\brief Constructor
///\param PointsBegin, PointsEnd : the points parametering the Bezier curve
///
template<typename In>
bezier_curve(In PointsBegin, In PointsEnd, const time_t T, const time_t mult_T)
: T_(T)
, mult_T_(mult_T)
, size_(std::distance(PointsBegin, PointsEnd))
, degree_(size_-1)
, bernstein_(curve::makeBernstein<num_t>((unsigned int)degree_))
{
assert(bernstein_.size() == size_);
In it(PointsBegin);
if(Safe && (size_<1 || T_ <= 0.))
throw std::out_of_range("can't create bezier min bound is higher than max bound"); // TODO
for(; it != PointsEnd; ++it)
pts_.push_back(*it);
}
///\brief Constructor
/// This constructor will add 4 points (2 after the first one, 2 before the last one)
/// to ensure that velocity and acceleration constraints are respected
///\param PointsBegin, PointsEnd : the points parametering the Bezier curve
///\param constraints : constraints applying on start / end velocities and acceleration
///
template<typename In>
bezier_curve(In PointsBegin, In PointsEnd, const curve_constraints_t& constraints, const time_t T=1.)
: T_(T)
, mult_T_(1.)
, size_(std::distance(PointsBegin, PointsEnd)+4)
, degree_(size_-1)
, bernstein_(curve::makeBernstein<num_t>((unsigned int)degree_))
{
if(Safe && (size_<1 || T_ <= 0.))
throw std::out_of_range("can't create bezier min bound is higher than max bound");
t_point_t updatedList = add_constraints<In>(PointsBegin, PointsEnd, constraints);
for(cit_point_t cit = updatedList.begin(); cit != updatedList.end(); ++cit)
pts_.push_back(*cit);
}
///\brief Destructor
~bezier_curve()
{
// NOTHING
}
private:
// bezier_curve(const bezier_curve&);
// bezier_curve& operator=(const bezier_curve&);
/* Constructors - destructors */
/*Operations*/
public:
/// \brief Evaluation of the cubic spline at time t.
/// \param t : the time when to evaluate the spine
/// \param return : the value x(t)
virtual point_t operator()(const time_t t) const
{
if(Safe &! (0 <= t && t <= T_))
throw std::out_of_range("can't evaluate bezier curve, out of range"); // TODO
return evalHorner(t);
}
/// \brief Computes the derivative curve at order N.
/// \param order : order of the derivative
/// \param return : the value x(t)
bezier_curve_t compute_derivate(const std::size_t order) const
{
if(order == 0) return *this;
t_point_t derived_wp;
for(typename t_point_t::const_iterator pit = pts_.begin(); pit != pts_.end()-1; ++pit)
derived_wp.push_back((num_t)degree_ * (*(pit+1) - (*pit)));
if(derived_wp.empty())
derived_wp.push_back(point_t::Zero(Dim));
bezier_curve_t deriv(derived_wp.begin(), derived_wp.end(),T_, mult_T_ * (1./T_) );
return deriv.compute_derivate(order-1);
}
/// \brief Computes the primitive of the curve at order N.
/// \param constant : value of the primitive at t = 0
/// \param return : the curve x_1(t) such that d/dt(x_1(t)) = x_1(t)
bezier_curve_t compute_primitive(const std::size_t order) const
{
if(order == 0) return *this;
num_t new_degree = (num_t)(degree_+1);
t_point_t n_wp;
point_t current_sum = point_t::Zero(Dim);
// recomputing waypoints q_i from derivative waypoints p_i. q_0 is the given constant.
// then q_i = (sum( j = 0 -> j = i-1) p_j) /n+1
n_wp.push_back(current_sum);
for(typename t_point_t::const_iterator pit = pts_.begin(); pit != pts_.end(); ++pit)
{
current_sum += *pit;
n_wp.push_back(current_sum / new_degree);
}
bezier_curve_t integ(n_wp.begin(), n_wp.end(),T_, mult_T_*T_);
return integ.compute_primitive(order-1);
}
/// \brief Evaluates the derivative at order N of the curve.
/// If the derivative is to be evaluated several times, it is
/// rather recommended to compute the derivative curve using compute_derivate
/// \param order : order of the derivative
/// \param t : the time when to evaluate the spine
/// \param return : the value x(t)
virtual point_t derivate(const time_t t, const std::size_t order) const
{
bezier_curve_t deriv =compute_derivate(order);
return deriv(t);
}
///
/// \brief Evaluates all Bernstein polynomes for a certain degree
/// Warning: the horner scheme is about 100 times faster than this method.
/// This method will probably be removed in the future
///
point_t evalBernstein(const Numeric t) const
{
const Numeric u = t/T_;
point_t res = point_t::Zero(Dim);
typename t_point_t::const_iterator pts_it = pts_.begin();
for(typename std::vector<Bern<Numeric> >::const_iterator cit = bernstein_.begin();
cit !=bernstein_.end(); ++cit, ++pts_it)
res += cit->operator()(u) * (*pts_it);
return res*mult_T_;
}
///
/// \brief Evaluates all Bernstein polynomes for a certain degree using horner's scheme
///
point_t evalHorner(const Numeric t) const
{
const Numeric u = t/T_;
typename t_point_t::const_iterator pts_it = pts_.begin();
Numeric u_op, bc, tn;
u_op = 1.0 - u;
bc = 1;
tn = 1;
point_t tmp =(*pts_it)*u_op; ++pts_it;
for(unsigned int i=1; i<degree_; i++, ++pts_it)
{
tn = tn*u;
bc = bc*((num_t)(degree_-i+1))/i;
tmp = (tmp + tn*bc*(*pts_it))*u_op;
}
return (tmp + tn*u*(*pts_it))*mult_T_;
}
const t_point_t& waypoints() const {return pts_;}
/**
* @brief evalDeCasteljau evaluate the curve value at time t using deCasteljau algorithm
* @param t unNormalized time
* @return the point at time t
*/
point_t evalDeCasteljau(const Numeric t) const {
// normalize time :
const Numeric u = t/T_;
t_point_t pts = deCasteljauReduction(waypoints(),u);
while(pts.size() > 1){
pts = deCasteljauReduction(pts,u);
}
return pts[0]*mult_T_;
}
t_point_t deCasteljauReduction(const Numeric t) const{
return deCasteljauReduction(waypoints(),t/T_);
}
/**
* @brief deCasteljauReduction compute the de Casteljau's reduction of the given list of points at time t
* @param pts the original list of points
* @param u the NORMALIZED time
* @return the reduced list of point (size of pts - 1)
*/
t_point_t deCasteljauReduction(const t_point_t& pts, const Numeric u) const{
if(u < 0 || u > 1)
throw std::out_of_range("In deCasteljau reduction : u is not in [0;1]");
if(pts.size() == 1)
return pts;
t_point_t new_pts;
for(cit_point_t cit = pts.begin() ; cit != (pts.end() - 1) ; ++cit){
new_pts.push_back((1-u) * (*cit) + u*(*(cit+1)));
}
return new_pts;
}
/**
* @brief split split the curve in 2 at time t
* @param t
* @return
*/
std::pair<bezier_curve_t,bezier_curve_t> split(const Numeric t){
if (t == T_)
throw std::runtime_error("can't split curve, interval range is equal to original curve");
t_point_t wps_first(size_),wps_second(size_);
const double u = t/T_;
wps_first[0] = pts_.front();
wps_second[degree_] = pts_.back();
t_point_t casteljau_pts = waypoints();
size_t id = 1;
while(casteljau_pts.size() > 1){
casteljau_pts = deCasteljauReduction(casteljau_pts,u);
wps_first[id] = casteljau_pts.front();
wps_second[degree_-id] = casteljau_pts.back();
++id;
}
bezier_curve_t c_first(wps_first.begin(), wps_first.end(), t,mult_T_);
bezier_curve_t c_second(wps_second.begin(), wps_second.end(), T_-t,mult_T_);
return std::make_pair(c_first,c_second);
}
bezier_curve_t extract(const Numeric t1, const Numeric t2){
if(t1 < 0. || t1 > T_ || t2 < 0. || t2 > T_)
throw std::out_of_range("In Extract curve : times out of bounds");
if(t1 == 0. && t2 == T_)
return bezier_curve_t(waypoints().begin(), waypoints().end(), T_,mult_T_);
if(t1 == 0.)
return split(t2).first;
if(t2 == T_)
return split(t1).second;
std::pair<bezier_curve_t,bezier_curve_t> c_split = this->split(t1);
return c_split.second.split(t2-t1).first;
}
private:
template<typename In>
t_point_t add_constraints(In PointsBegin, In PointsEnd, const curve_constraints_t& constraints)
{
t_point_t res;
point_t P0, P1, P2, P_n_2, P_n_1, PN;
P0 = *PointsBegin; PN = *(PointsEnd-1);
P1 = P0+ constraints.init_vel / (num_t)degree_;
P_n_1 = PN -constraints.end_vel / (num_t)degree_;
P2 = constraints.init_acc / (num_t)(degree_ * (degree_-1)) + 2* P1 - P0;
P_n_2 = constraints.end_acc / (num_t)(degree_ * (degree_-1)) + 2* P_n_1 - PN;
res.push_back(P0);
res.push_back(P1);
res.push_back(P2);
for(In it = PointsBegin+1; it != PointsEnd-1; ++it)
res.push_back(*it);
res.push_back(P_n_2);
res.push_back(P_n_1);
res.push_back(PN);
return res;
}
/*Operations*/
/*Helpers*/
public:
virtual time_t min() const{return 0.;}
virtual time_t max() const{return T_;}
/*Helpers*/
public:
/*const*/ time_t T_;
/*const*/ time_t mult_T_;
/*const*/ std::size_t size_;
/*const*/ std::size_t degree_;
/*const*/ std::vector<Bern<Numeric> > bernstein_;
private:
t_point_t pts_;
public:
static bezier_curve_t zero(const time_t T=1.)
{
std::vector<point_t> ts;
ts.push_back(point_t::Zero(Dim));
return bezier_curve_t(ts.begin(), ts.end(),T);
}
};
} // namespace curve
#endif //_CLASS_BEZIERCURVE