Commit 88ffc79b authored by Guilhem Saurel's avatar Guilhem Saurel
Browse files

[Format]

parent 0e28b340
Pipeline #11481 failed with stage
in 4 minutes and 5 seconds
/**
* \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.
*/
* \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
......@@ -20,23 +20,20 @@
#include <vector>
#include <utility>
namespace curves{
//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);
}
namespace curves {
// 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 curves
#endif //_SPLINEMATH
pinvmat = (svd.matrixV() * m_sigma_inv * svd.matrixU().transpose());
}
} // namespace curves
#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
*/
* \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
......@@ -18,72 +17,62 @@
#include <vector>
#include <stdexcept>
namespace curves
{
/// \brief Computes a binomial coefficient .
/// \param n : an unsigned integer.
/// \param k : an unsigned integer.
/// \return \f$\binom{n}{k}f$
///
inline unsigned int bin(const unsigned int n, const unsigned int k)
{
if(k > n) throw std::runtime_error("binomial coefficient higher than degree");
if(k == 0) return 1;
if(k > n/2) return bin(n,n-k);
return n * bin(n-1,k-1) / k;
}
namespace curves {
/// \brief Computes a binomial coefficient .
/// \param n : an unsigned integer.
/// \param k : an unsigned integer.
/// \return \f$\binom{n}{k}f$
///
inline unsigned int bin(const unsigned int n, const unsigned int k) {
if (k > n) throw std::runtime_error("binomial coefficient higher than degree");
if (k == 0) return 1;
if (k > n / 2) return bin(n, n - k);
return n * bin(n - 1, k - 1) / k;
}
/// \class Bernstein.
/// \brief Computes a Bernstein polynome.
///
template <typename Numeric = double>
struct Bern {
Bern(){}
Bern(const unsigned int m, const unsigned int i)
:m_minus_i(m - i),
i_(i),
bin_m_i_(bin(m,i))
{}
/// \class Bernstein.
/// \brief Computes a Bernstein polynome.
///
template <typename Numeric = double>
struct Bern {
Bern() {}
Bern(const unsigned int m, const unsigned int i) : m_minus_i(m - i), i_(i), bin_m_i_(bin(m, i)) {}
~Bern(){}
~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 operator()(const Numeric u) const {
assert(u >= 0. && u <= 1.);
return bin_m_i_ * (pow(u, i_)) * pow((1 - u), m_minus_i);
}
/* Attributes */
Numeric m_minus_i;
Numeric i_;
Numeric bin_m_i_;
/* Attributes */
/* Attributes */
Numeric m_minus_i;
Numeric i_;
Numeric bin_m_i_;
/* Attributes */
// Serialization of the class
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version){
if (version) {
// Serialization of the class
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int version) {
if (version) {
// Do something depending on version ?
}
ar & boost::serialization::make_nvp("m_minus_i", m_minus_i);
ar & boost::serialization::make_nvp("i", i_);
ar & boost::serialization::make_nvp("bin_m_i", bin_m_i_);
}
}; // End struct Bern
/// \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;
ar& boost::serialization::make_nvp("m_minus_i", m_minus_i);
ar& boost::serialization::make_nvp("i", i_);
ar& boost::serialization::make_nvp("bin_m_i", bin_m_i_);
}
} // namespace curves
#endif //_CLASS_BERNSTEIN
}; // End struct Bern
/// \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 curves
#endif //_CLASS_BERNSTEIN
This diff is collapsed.
This diff is collapsed.
/**
* \file cubic_spline.h
* \brief Definition of a cubic spline.
* \author Steve T.
* \version 0.1
* \date 06/17/2013
*
* This file contains definitions for the CubicFunction struct.
* It allows the creation and evaluation of natural
* smooth cubic splines of arbitrary dimension
*/
* \file cubic_spline.h
* \brief Definition of a cubic spline.
* \author Steve T.
* \version 0.1
* \date 06/17/2013
*
* This file contains definitions for the CubicFunction struct.
* It allows the creation and evaluation of natural
* smooth cubic splines of arbitrary dimension
*/
#ifndef _STRUCT_CUBICSPLINE
#define _STRUCT_CUBICSPLINE
......@@ -20,28 +19,27 @@
#include <stdexcept>
namespace curves
{
/// \brief Creates coefficient vector of a cubic spline defined on the interval
/// \f$[t_{min}, t_{max}]\f$. It follows the equation : <br>
/// \f$ x(t) = a + b(t - t_{min}) + c(t - t_{min})^2 + d(t - t_{min})^3 \f$ where \f$ t \in [t_{min}, t_{max}] \f$
/// with a, b, c and d the control points.
///
template<typename Point, typename T_Point>
T_Point make_cubic_vector(Point const& a, Point const& b, Point const& c, Point const &d)
{
T_Point res;
res.push_back(a);res.push_back(b);res.push_back(c);res.push_back(d);
return res;
}
template<typename Time, typename Numeric, bool Safe, typename Point, typename T_Point>
polynomial<Time,Numeric,Safe,Point,T_Point> create_cubic(Point const& a, Point const& b, Point const& c, Point const &d,
const Time t_min, const Time t_max)
{
T_Point coeffs = make_cubic_vector<Point, T_Point>(a,b,c,d);
return polynomial<Time,Numeric,Safe,Point,T_Point>(coeffs.begin(),coeffs.end(), t_min, t_max);
}
} // namespace curves
#endif //_STRUCT_CUBICSPLINE
namespace curves {
/// \brief Creates coefficient vector of a cubic spline defined on the interval
/// \f$[t_{min}, t_{max}]\f$. It follows the equation : <br>
/// \f$ x(t) = a + b(t - t_{min}) + c(t - t_{min})^2 + d(t - t_{min})^3 \f$ where \f$ t \in [t_{min}, t_{max}] \f$
/// with a, b, c and d the control points.
///
template <typename Point, typename T_Point>
T_Point make_cubic_vector(Point const& a, Point const& b, Point const& c, Point const& d) {
T_Point res;
res.push_back(a);
res.push_back(b);
res.push_back(c);
res.push_back(d);
return res;
}
template <typename Time, typename Numeric, bool Safe, typename Point, typename T_Point>
polynomial<Time, Numeric, Safe, Point, T_Point> create_cubic(Point const& a, Point const& b, Point const& c,
Point const& d, const Time t_min, const Time t_max) {
T_Point coeffs = make_cubic_vector<Point, T_Point>(a, b, c, d);
return polynomial<Time, Numeric, Safe, Point, T_Point>(coeffs.begin(), coeffs.end(), t_min, t_max);
}
} // namespace curves
#endif //_STRUCT_CUBICSPLINE
/**
* \file curve_abc.h
* \brief interface for a Curve of arbitrary dimension.
* \author Steve T.
* \version 0.1
* \date 06/17/2013
*
* Interface for a curve
*/
* \file curve_abc.h
* \brief interface for a Curve of arbitrary dimension.
* \author Steve T.
* \version 0.1
* \date 06/17/2013
*
* Interface for a curve
*/
#ifndef _STRUCT_CURVE_ABC
#define _STRUCT_CURVE_ABC
......@@ -18,63 +17,59 @@
#include <functional>
namespace curves
{
/// \struct curve_abc.
/// \brief Represents a curve of dimension Dim.
/// If value of parameter Safe is false, no verification is made on the evaluation of the curve.
template<typename Time= double, typename Numeric=Time, bool Safe=false,
typename Point= Eigen::Matrix<Numeric, Eigen::Dynamic, 1> >
struct curve_abc : std::unary_function<Time, Point>,
public serialization::Serializable
{
typedef Point point_t;
typedef Time time_t;
/* Constructors - destructors */
public:
/// \brief Constructor.
curve_abc(){}
namespace curves {
/// \struct curve_abc.
/// \brief Represents a curve of dimension Dim.
/// If value of parameter Safe is false, no verification is made on the evaluation of the curve.
template <typename Time = double, typename Numeric = Time, bool Safe = false,
typename Point = Eigen::Matrix<Numeric, Eigen::Dynamic, 1> >
struct curve_abc : std::unary_function<Time, Point>, public serialization::Serializable {
typedef Point point_t;
typedef Time time_t;
/// \brief Destructor.
virtual ~curve_abc(){}
/* Constructors - destructors */
/* Constructors - destructors */
public:
/// \brief Constructor.
curve_abc() {}
/*Operations*/
/// \brief Evaluation of the cubic spline at time t.
/// \param t : time when to evaluate the spine
/// \return \f$x(t)\f$, point corresponding on curve at time t.
virtual point_t operator()(const time_t t) const = 0;
/// \brief Destructor.
virtual ~curve_abc() {}
/* Constructors - destructors */
/// \brief Evaluate the derivative of order N of curve at time t.
/// \param t : time when to evaluate the spline.
/// \param order : order of derivative.
/// \return \f$\frac{d^Nx(t)}{dt^N}\f$, point corresponding on derivative curve of order N at time t.
virtual point_t derivate(const time_t t, const std::size_t order) const = 0;
/*Operations*/
/*Operations*/
/// \brief Evaluation of the cubic spline at time t.
/// \param t : time when to evaluate the spine
/// \return \f$x(t)\f$, point corresponding on curve at time t.
virtual point_t operator()(const time_t t) const = 0;
/*Helpers*/
/// \brief Get dimension of curve.
/// \return dimension of curve.
virtual std::size_t dim() const = 0;
/// \brief Get the minimum time for which the curve is defined.
/// \return \f$t_{min}\f$, lower bound of time range.
virtual time_t min() const = 0;
/// \brief Get the maximum time for which the curve is defined.
/// \return \f$t_{max}\f$, upper bound of time range.
virtual time_t max() const = 0;
std::pair<time_t, time_t> timeRange() {return std::make_pair(min(), max());}
/*Helpers*/
/// \brief Evaluate the derivative of order N of curve at time t.
/// \param t : time when to evaluate the spline.
/// \param order : order of derivative.
/// \return \f$\frac{d^Nx(t)}{dt^N}\f$, point corresponding on derivative curve of order N at time t.
virtual point_t derivate(const time_t t, const std::size_t order) const = 0;
/*Operations*/
// Serialization of the class
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version){
if (version) {
// Do something depending on version ?
}
}
};
} // namespace curves
#endif //_STRUCT_CURVE_ABC
/*Helpers*/
/// \brief Get dimension of curve.
/// \return dimension of curve.
virtual std::size_t dim() const = 0;
/// \brief Get the minimum time for which the curve is defined.
/// \return \f$t_{min}\f$, lower bound of time range.
virtual time_t min() const = 0;
/// \brief Get the maximum time for which the curve is defined.
/// \return \f$t_{max}\f$, upper bound of time range.
virtual time_t max() const = 0;
std::pair<time_t, time_t> timeRange() { return std::make_pair(min(), max()); }
/*Helpers*/
// Serialization of the class
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int version) {
if (version) {
// Do something depending on version ?
}
}
};
} // namespace curves
#endif //_STRUCT_CURVE_ABC
/**
* \file curve_constraint.h
* \brief struct to define constraints on start / end velocities and acceleration
* on a curve
* \author Steve T.
* \version 0.1
* \date 04/05/2017
*
*/
* \file curve_constraint.h
* \brief struct to define constraints on start / end velocities and acceleration
* on a curve
* \author Steve T.
* \version 0.1
* \date 04/05/2017
*
*/
#ifndef _CLASS_CURVE_CONSTRAINT
#define _CLASS_CURVE_CONSTRAINT
......@@ -17,20 +16,18 @@
#include <functional>
#include <vector>
namespace curves
{
template <typename Point>
struct curve_constraints
{
typedef Point point_t;
curve_constraints(){}
namespace curves {
template <typename Point>
struct curve_constraints {
typedef Point point_t;
curve_constraints() {}
~curve_constraints(){}
~curve_constraints() {}
point_t init_vel;
point_t init_acc;
point_t end_vel;
point_t end_acc;
};
} // namespace curves
#endif //_CLASS_CUBICZEROVELACC
point_t init_vel;
point_t init_acc;
point_t end_vel;
point_t end_acc;
};
} // namespace curves
#endif //_CLASS_CUBICZEROVELACC
......@@ -12,93 +12,88 @@
#include <iostream>
namespace curves
{
/// \brief Converts a cubic hermite spline or a bezier curve to a polynomial.
/// \param curve : the bezier curve/cubic hermite spline defined between [Tmin,Tmax] to convert.
/// \return the equivalent polynomial.
template<typename Polynomial, typename curveTypeToConvert>
Polynomial polynomial_from_curve(const curveTypeToConvert& curve)
{
typedef typename Polynomial::t_point_t t_point_t;
typedef typename Polynomial::num_t num_t;
t_point_t coefficients;
curveTypeToConvert current (curve);
coefficients.push_back(curve(curve.min()));
num_t T = curve.max()-curve.min();
num_t T_div = 1.0;
num_t fact = 1;
for(std::size_t i = 1; i<= curve.degree_; ++i)
{
fact *= (num_t)i;
coefficients.push_back(current.derivate(current.min(),i)/fact);
}
return Polynomial(coefficients,curve.min(),curve.max());
namespace curves {
/// \brief Converts a cubic hermite spline or a bezier curve to a polynomial.
/// \param curve : the bezier curve/cubic hermite spline defined between [Tmin,Tmax] to convert.
/// \return the equivalent polynomial.
template <typename Polynomial, typename curveTypeToConvert>
Polynomial polynomial_from_curve(const curveTypeToConvert& curve) {
typedef typename Polynomial::t_point_t t_point_t;
typedef typename Polynomial::num_t num_t;
t_point_t coefficients;
curveTypeToConvert current(curve);
coefficients.push_back(curve(curve.min()));
num_t T = curve.max() - curve.min();
num_t T_div = 1.0;
num_t fact = 1;
for (std::size_t i = 1; i <= curve.degree_; ++i) {
fact *= (num_t)i;
coefficients.push_back(current.derivate(current.min(), i) / fact);
}
return Polynomial(coefficients, curve.min(), curve.max());
}
/// \brief Converts a cubic hermite spline or polynomial of order 3 or less to a cubic bezier curve.
/// \param curve : the polynomial of order 3 or less/cubic hermite spline defined between [Tmin,Tmax] to convert.
/// \return the equivalent cubic bezier curve.
template<typename Bezier, typename curveTypeToConvert>
Bezier bezier_from_curve(const curveTypeToConvert& curve)
{
typedef typename Bezier::point_t point_t;
typedef typename Bezier::t_point_t t_point_t;
typedef typename Bezier::num_t num_t;
curveTypeToConvert current (curve);
num_t T_min = current.min();
num_t T_max = current.max();
num_t T = T_max-T_min;
// Positions and derivatives
point_t p0 = current(T_min);
point_t p1 = current(T_max);
point_t m0 = current.derivate(T_min,1);
point_t m1 = current.derivate(T_max,1);
// Convert to bezier control points
// for t in [Tmin,Tmax] and T=Tmax-Tmin : x'(0)=3(b_p1-b_p0)/T and x'(1)=3(b_p3-b_p2)/T
// so : m0=3(b_p1-b_p0)/T and m1=3(b_p3-b_p2)/T
// <=> b_p1=T(m0/3)+b_p0 and b_p2=-T(m1/3)+b_p3
point_t b_p0 = p0;
point_t b_p3 = p1;
point_t b_p1 = T*m0/3+b_p0;
point_t b_p2 = -T*m1/3+b_p3;
t_point_t control_points;
control_points.push_back(b_p0);
control_points.push_back(b_p1);
control_points.push_back(b_p2);
control_points.push_back(b_p3);
return Bezier(control_points.begin(), control_points.end(), current.min(), current.max());
}
/// \brief Converts a cubic hermite spline or polynomial of order 3 or less to a cubic bezier curve.
/// \param curve : the polynomial of order 3 or less/cubic hermite spline defined between [Tmin,Tmax] to convert.
/// \return the equivalent cubic bezier curve.
template <typename Bezier, typename curveTypeToConvert>
Bezier bezier_from_curve(const curveTypeToConvert& curve) {
typedef typename Bezier::point_t point_t;
typedef typename Bezier::t_point_t t_point_t;
typedef typename Bezier::num_t num_t;
curveTypeToConvert current(curve);
num_t T_min = current.min();
num_t T_max = current.max();
num_t T = T_max - T_min;
// Positions and derivatives
point_t p0 = current(T_min);
point_t p1 = current(T_max);
point_t m0 = current.derivate(T_min, 1);
point_t m1 = current.derivate(T_max, 1);
// Convert to bezier control points
// for t in [Tmin,Tmax] and T=Tmax-Tmin : x'(0)=3(b_p1-b_p0)/T and x'(1)=3(b_p3-b_p2)/T
// so : m0=3(b_p1-b_p0)/T and m1=3(b_p3-b_p2)/T
// <=> b_p1=T(m0/3)+b_p0 and b_p2=-T(m1/3)+b_p3
point_t b_p0 = p0;
point_t b_p3 = p1;
point_t b_p1 = T * m0 / 3 + b_p0;
point_t b_p2 = -T * m1 / 3 + b_p3;
t_point_t control_points;
control_points.push_back(b_p0);
control_points.push_back(b_p1);
control_points.push_back(b_p2);
control_points.push_back(b_p3);
return Bezier(control_points.begin(), control_points.end(), current.min(), current.max());
}
/// \brief Converts a polynomial of order 3 or less/cubic bezier curve to a cubic hermite spline.
/// \param curve : the polynomial of order 3 or less/cubic bezier curve defined between [Tmin,Tmax] to convert.
/// \return the equivalent cubic hermite spline.
template<typename Hermite, typename curveTypeToConvert>
Hermite hermite_from_curve(const curveTypeToConvert& curve)
{
typedef typename Hermite::pair_point_tangent_t pair_point_tangent_t;
typedef typename Hermite::t_pair_point_tangent_t t_pair_point_tangent_t;
typedef typename Hermite::point_t point_t;
typedef typename Hermite::num_t num_t;
curveTypeToConvert current (curve);
num_t T_min = current.min();
num_t T_max = current.max();
num_t T = T_max-T_min;
// Positions and derivatives