Browse Source

add spline segments classes

neozhaoliang 4 years ago
parent
commit
a776bcb802

+ 0 - 122
src/decition/decition_brain/decition/adc_math/coordinate_conversion.h

@@ -1,122 +0,0 @@
-/****************************************
- * Functions:  Convert coordinates between GPS (longitude, latitude) system and UTM system.
- * Purpose:    Vehicle localization
- * Author:     Zhao Liang
- * Last Updated:  2021/01/20
- * Update note:  call third-party lib 'proj4' to do the conversionseee.
-*****************************************
-*
-* Convention: East is the X-axis, North is the Y-axis, Up (sky) is the Z-axis,
-* the pair (longitude, latitude) are in degrees: longitude ~ (-180, 180) and
-* latitude ~(-90, 90).
-*
-* Online tool: https://www.latlong.net/lat-long-utm.html
-*
-* Basically the convertion procedure can be splitted into three steps:
-* 1. Declare two `projPJ` objects for the source system and the target system.
-* 2. Put your projection params in two strings.
-* 3. Call `pj_transform` to do the conversion.
-*
-* String used by Apollo:
-*
-* "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs"
-*
-* 1. +proj=longlat means we are projecting from (longitude, latitude).
-* 2. +ellps=GRS80 means the ellipsoid model is GRS80.
-* 3. +towgs84=0,0,0,0,0,0,0 gives the 7 params for datum transformation.
-* 4. +no_defs means we don't want proj to read the default config file,
-* this option is obsolete since proj 6.x
-*/
-
-#ifndef COORDINATE_CONVERSION_H
-#define COORDINATE_CONVERSION_H
-
-#include <string>
-#include <proj_api.h>
-
-namespace iv {
-namespace math {
-
-/**
- * @brief: Convert (lon, lat) coordinates to UTM coordinates.
- * @param: longitude in degrees, range ~ (-180, 180).
- * @param: latitude in degrees, range ~ (-90, 90).
- * @param: x coordinate (East direction).
- * @param: y coordinate (North direction).
- * @return: Return true if the conversion between the two systems is valid.
-*/
-bool LatLonToUtmXY(double longitude, double latitude, double &x, double &y)
-{
-    projPJ pj_latlon;
-    projPJ pj_utm;
-    int zone = static_cast<int>((longitude + 180) / 6) + 1;
-    std::string latlon_src =
-        "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs";
-    std::string utm_dst =
-        "+proj=utm +zone=" + std::to_string(zone) + " +ellps=GRS80 +units=m +no_defs";
-
-    if (!(pj_latlon = pj_init_plus(latlon_src.c_str())))
-    {
-        return false;
-    }
-
-    if (!(pj_utm = pj_init_plus(utm_dst.c_str())))
-    {
-        return false;
-    }
-
-    // the pj_transform requires the (lon, lat) are in radians
-    double lon = longitude * DEG_TO_RAD;
-    double lat = latitude * DEG_TO_RAD;
-
-    // do the actual conversion
-    pj_transform(pj_latlon, pj_utm, 1, 1, &lon, &lat, nullptr);
-
-    x = lon;
-    y = lat;
-    pj_free(pj_latlon);
-    pj_free(pj_utm);
-    return true;
-}
-
-/**
- * @brief: Convert UTM coordinates to (lon, lat) coordinates.
- * @param: x coordinate (East direction).
- * @param: y coordinate (North direction).
- * @param: zone number.
- * @param: longitude in degrees, range ~ (-180, 180).
- * @param: latitude in degrees, range ~ (-90, 90).
- * @return: Return true if the conversion between the two systems is valid.
-*/
-bool UtmXYToLatLon(double x, double y, int zone, double &longitude, double &latitude)
-{
-    projPJ pj_latlon;
-    projPJ pj_utm;
-    std::string latlon_src =
-        "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs";
-    std::string utm_dst =
-        "+proj=utm +zone=" + std::to_string(zone) + " +ellps=GRS80 +units=m +no_defs";
-
-    if (!(pj_latlon = pj_init_plus(latlon_src.c_str())))
-    {
-        return false;
-    }
-
-    if (!(pj_utm = pj_init_plus(utm_dst.c_str())))
-    {
-        return false;
-    }
-
-    // do the actual conversion
-    pj_transform(pj_utm, pj_latlon, 1, 1, &x, &y, nullptr);
-
-    // the result given by pj_transform are in radians
-    longitude = x * RAD_TO_DEG;
-    latitude = y * RAD_TO_DEG;
-    pj_free(pj_latlon);
-    pj_free(pj_utm);
-    return true;
-}
-}
-}
-#endif // COORDINATE_CONVERSION_H

+ 130 - 0
src/decition/decition_brain/decition/adc_math/core/include/splines/PolynomialXd.h

@@ -0,0 +1,130 @@
+#ifndef POLYNOMIALXD_H
+#define POLYNOMIALXD_H
+
+#pragma once
+
+#include <vector>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_join.h"
+
+namespace adtoolbox {
+namespace core {
+
+class PolynomialXd
+{
+public:
+    PolynomialXd() = default;
+    explicit PolynomialXd(const size_t order);
+    explicit PolynomialXd(const std::vector<double> &params);
+    double operator()(const double value) const;
+    double operator[](const size_t index) const;
+    void setParams(const std::vector<double> &params);
+
+    static PolynomialXd derivedFrom(const PolynomialXd &other);
+    static PolynomialXd integratedFrom(const PolynomialXd &other, const double c);
+
+    size_t order() const;
+    const std::vector<double> &params() const;
+    std::string toString() const;
+
+private:
+    std::vector<double> params_;
+};
+
+// ----------------------------------------
+
+PolynomialXd::PolynomialXd(const size_t order)
+    : params_(order + 1, 0.0) {}
+
+// ----------------------------------------
+
+PolynomialXd::PolynomialXd(const std::vector<double> &params)
+    : params_(params) {}
+
+// ----------------------------------------
+
+size_t PolynomialXd::order() const
+{
+    return params_.size() - 1;
+}
+
+// ----------------------------------------
+
+void PolynomialXd::setParams(const std::vector<double> &params)
+{
+    params_ = params;
+}
+
+// ----------------------------------------
+
+const std::vector<double> &PolynomialXd::params() const
+{
+    return params_;
+}
+
+// ----------------------------------------
+
+double PolynomialXd::operator()(const double value) const
+{
+    double result = 0.0;
+    for (auto rit = params_.rbegin(); rit != params_.rend(); ++rit)
+    {
+        result = result * value + (*rit);
+    }
+    return result;
+}
+
+// ----------------------------------------
+
+double PolynomialXd::operator[](const size_t index) const
+{
+    return index >= params_.size() ? 0.0 : params_[index];
+}
+
+// ----------------------------------------
+
+PolynomialXd PolynomialXd::derivedFrom(const PolynomialXd &other)
+{
+    std::vector<double> params;
+    if (other.order() <= 0)
+    {
+        params.clear();
+    }
+    else
+    {
+        params.resize(other.params().size() - 1);
+        for (size_t i = 1; i < other.order() + 1; i++)
+        {
+            params[i - 1] = other[i] * i;
+        }
+    }
+    return PolynomialXd(params);
+}
+
+// ----------------------------------------
+
+PolynomialXd PolynomialXd::integratedFrom(const PolynomialXd &other, const double c)
+{
+    std::vector<double> params;
+    params.resize(other.params().size() + 1);
+    params[0] = c;
+    for (size_t i = 0; i < other.params().size(); i++)
+    {
+        params[i + 1] = other[i] / (i + 1);
+    }
+    return PolynomialXd(params);
+}
+
+// ----------------------------------------
+
+std::string PolynomialXd::toString() const
+{
+    return absl::StrCat("PolynomailXd(", absl::StrJoin(params_, ", "), ")");
+}
+// ----------------------------------------
+// Ends class PolynomialXd
+}
+}
+
+#endif // POLYNOMIALXD_H

+ 78 - 29
src/decition/decition_brain/decition/adc_math/quartic_polynomail.cpp → src/decition/decition_brain/decition/adc_math/core/include/splines/QuarticPolynomial.h

@@ -1,9 +1,47 @@
-#include "quartic_polynomial.h"
+#ifndef QUARTICPOLYNOMIAL_H
+#define QUARTICPOLYNOMIAL_H
+
+#pragma once
+
+#include <array>
 #include "absl/strings/str_cat.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/str_join.h"
 #include "absl/strings/str_join.h"
 
 
-namespace iv {
-namespace math {
+namespace adtoolbox {
+namespace core {
+
+class QuarticPolynomial
+{
+public:
+    QuarticPolynomial() = default;
+    virtual ~QuarticPolynomial() = default;
+
+    QuarticPolynomial(const double x0, const double dx0, const double ddx0,
+                      const double dx1, const double ddx1,
+                      const double t);
+
+    QuarticPolynomial(const std::array<double, 3> &start,
+                      const std::array<double, 2> &end,
+                      const double t);
+
+    double evaluate(const size_t order, const double t) const;
+    size_t order() const;
+    double paramLength() const;
+    double coef(const size_t order) const;
+    std::string toString() const;
+
+private:
+    void computeCoefficients(const double x0, const double dx0, const double ddx0,
+                             const double dx1, const double ddx1,
+                             const double t);
+
+    double t_;
+    std::array<double, 3> start_condition_;
+    std::array<double, 2> end_condition_;
+    std::array<double, 5> coef_;
+};
+
+// ----------------------------------------
 
 
 QuarticPolynomial::QuarticPolynomial(const double x0, const double dx0, const double ddx0,
 QuarticPolynomial::QuarticPolynomial(const double x0, const double dx0, const double ddx0,
                                      const double dx1, const double ddx1,
                                      const double dx1, const double ddx1,
@@ -18,30 +56,15 @@ QuarticPolynomial::QuarticPolynomial(const double x0, const double dx0, const do
     computeCoefficients(x0, dx0, ddx0, dx1, ddx1, t);
     computeCoefficients(x0, dx0, ddx0, dx1, ddx1, t);
 }
 }
 
 
+// ----------------------------------------
+
 QuarticPolynomial::QuarticPolynomial(const std::array<double, 3> &start,
 QuarticPolynomial::QuarticPolynomial(const std::array<double, 3> &start,
                                      const std::array<double, 2> &end,
                                      const std::array<double, 2> &end,
                                      const double t)
                                      const double t)
     : QuarticPolynomial::QuarticPolynomial(start[0], start[1], start[2],
     : QuarticPolynomial::QuarticPolynomial(start[0], start[1], start[2],
                                            end[0], end[1], t) {}
                                            end[0], end[1], t) {}
 
 
-void QuarticPolynomial::computeCoefficients(const double x0, const double dx0, const double ddx0,
-                                            const double dx1, const double ddx1,
-                                            const double t)
-{
-    coef_[0] = x0;
-    coef_[1] = dx0;
-    coef_[2] = ddx0 * 0.5;
-
-    double b0 = dx1 - ddx0 * t - dx0;
-    double b1 = ddx1 - ddx0;
-    double t2 = t * t;
-    double t3 = t2 * t;
-
-    coef_[3] = (3 * b0 - b1 * t) / (3 * t2);
-    coef_[4] = (-2 * b0 + b1 * t) / (4 * t3);
-}
-
-double QuarticPolynomial::evaluate(const std::uint32_t order, const double p) const
+double QuarticPolynomial::evaluate(const size_t order, const double p) const
 {
 {
     switch (order)
     switch (order)
     {
     {
@@ -60,19 +83,45 @@ double QuarticPolynomial::evaluate(const std::uint32_t order, const double p) co
     }
     }
 }
 }
 
 
-double QuarticPolynomial::coef(const size_t order) const
-{
-    return coef_[order];
-}
+// ----------------------------------------
+
+size_t QuarticPolynomial::order() const { return 4; }
+
+// ----------------------------------------
+
+double QuarticPolynomial::coef(const size_t order) const { return coef_[order];}
+
+// ----------------------------------------
 
 
-const std::array<double, 5> &QuarticPolynomial::coef() const
+double QuarticPolynomial::paramLength() const { return t_; }
+
+// ----------------------------------------
+
+std::string QuarticPolynomial::toString() const
 {
 {
-    return coef_;
+    return absl::StrCat("QuarticPoly(", absl::StrJoin(coef_, ", "), ")");
 }
 }
 
 
-std::string QuarticPolynomial::toString() const
+// ----------------------------------------
+
+void QuarticPolynomial::computeCoefficients(const double x0, const double dx0, const double ddx0,
+                                            const double dx1, const double ddx1,
+                                            const double t)
 {
 {
-    return absl::StrCat("QuarticPolynomial(", absl::StrJoin(coef_, ", "), ")");
+    coef_[0] = x0;
+    coef_[1] = dx0;
+    coef_[2] = ddx0 * 0.5;
+
+    double b0 = dx1 - ddx0 * t - dx0;
+    double b1 = ddx1 - ddx0;
+    double t2 = t * t;
+    double t3 = t2 * t;
+
+    coef_[3] = (3 * b0 - b1 * t) / (3 * t2);
+    coef_[4] = (-2 * b0 + b1 * t) / (4 * t3);
 }
 }
+// ----------------------------------------
+// Ends class QuarticPolynomial
 }
 }
 }
 }
+#endif // QUARTICPOLYNOMIAL_H

+ 86 - 22
src/decition/decition_brain/decition/adc_math/quintic_polynomial.cpp → src/decition/decition_brain/decition/adc_math/core/include/splines/QuinticPolynomial.h

@@ -1,9 +1,51 @@
-#include "quintic_polynomial.h"
+#ifndef QUINTICPOLYNOMIAL_H
+#define QUINTICPOLYNOMIAL_H
+
+#pragma once
+
+#include <array>
 #include "absl/strings/str_cat.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/str_join.h"
 #include "absl/strings/str_join.h"
 
 
-namespace iv {
-namespace math {
+namespace adtoolbox {
+namespace core {
+
+class QuinticPolynomial
+{
+public:
+    QuinticPolynomial() = default;
+    virtual ~QuinticPolynomial() = default;
+
+    QuinticPolynomial(const double x0, const double dx0, const double ddx0,
+                      const double x1, const double dx1, const double ddx1,
+                      const double t);
+
+    QuinticPolynomial(const std::array<double, 3> &start,
+                      const std::array<double, 3> &end,
+                      const double t);
+
+    void fitBoundaryConditions(const double x0, const double dx0, const double ddx0,
+                               const double x1, const double dx1, const double ddx1,
+                               const double t);
+
+    double evaluate(const size_t order, const double t) const;
+    size_t order() const;
+    double paramLength() const;
+    double coef(const size_t order) const;
+    std::string toString() const;
+
+private:
+    void computeCoefficients(const double x0, const double dx0, const double ddx0,
+                             const double x1, const double dx1, const double ddx1,
+                             const double t);
+
+    double t_;
+    std::array<double, 3> start_condition_;
+    std::array<double, 3> end_condition_;
+    std::array<double, 6> coef_;
+};
+
+// ----------------------------------------
 
 
 QuinticPolynomial::QuinticPolynomial(const double x0, const double dx0, const double ddx0,
 QuinticPolynomial::QuinticPolynomial(const double x0, const double dx0, const double ddx0,
                                      const double x1, const double dx1, const double ddx1,
                                      const double x1, const double dx1, const double ddx1,
@@ -19,13 +61,31 @@ QuinticPolynomial::QuinticPolynomial(const double x0, const double dx0, const do
     computeCoefficients(x0, dx0, ddx0, x1, dx1, ddx1, t);
     computeCoefficients(x0, dx0, ddx0, x1, dx1, ddx1, t);
 }
 }
 
 
+// ----------------------------------------
+
 QuinticPolynomial::QuinticPolynomial(const std::array<double, 3> &start,
 QuinticPolynomial::QuinticPolynomial(const std::array<double, 3> &start,
                                      const std::array<double, 3> &end,
                                      const std::array<double, 3> &end,
                                      const double t)
                                      const double t)
     : QuinticPolynomial::QuinticPolynomial(start[0], start[1], start[2],
     : QuinticPolynomial::QuinticPolynomial(start[0], start[1], start[2],
                                            end[0], end[1], end[2], t) {}
                                            end[0], end[1], end[2], t) {}
 
 
-double QuinticPolynomial::evaluate(std::uint32_t order, const double p) const
+void QuinticPolynomial::fitBoundaryConditions(const double x0, const double dx0, const double ddx0,
+                                              const double x1, const double dx1, const double ddx1,
+                                              const double t)
+{
+    t_ = t;
+    start_condition_[0] = x0;
+    start_condition_[1] = dx0;
+    start_condition_[2] = ddx0;
+    end_condition_[0] = x1;
+    end_condition_[1] = dx1;
+    end_condition_[2] = ddx1;
+    computeCoefficients(x0, dx0, ddx0, x1, dx1, ddx1, t);
+}
+
+// ----------------------------------------
+
+double QuinticPolynomial::evaluate(const size_t order, const double p) const
 {
 {
     switch (order)
     switch (order)
     {
     {
@@ -46,30 +106,36 @@ double QuinticPolynomial::evaluate(std::uint32_t order, const double p) const
     }
     }
 }
 }
 
 
-void QuinticPolynomial::fitByBoundaryConditions(const double x0, const double dx0, const double ddx0,
-                                                const double x1, const double dx1, const double ddx1,
-                                                const double t)
+// ----------------------------------------
+
+size_t QuinticPolynomial::order() const
 {
 {
-    t_ = t;
-    start_condition_[0] = x0;
-    start_condition_[1] = dx0;
-    start_condition_[2] = ddx0;
-    end_condition_[0] = x1;
-    end_condition_[1] = dx1;
-    end_condition_[2] = ddx1;
-    computeCoefficients(x0, dx0, ddx0, x1, dx1, ddx1, t);
+    return 5;
 }
 }
 
 
+// ----------------------------------------
+
 double QuinticPolynomial::coef(const size_t order) const
 double QuinticPolynomial::coef(const size_t order) const
 {
 {
     return coef_[order];
     return coef_[order];
 }
 }
 
 
-const std::array<double, 6> &QuinticPolynomial::coef() const
+// ----------------------------------------
+
+double QuinticPolynomial::paramLength() const
+{
+    return t_;
+}
+
+// ----------------------------------------
+
+std::string QuinticPolynomial::toString() const
 {
 {
-    return coef_;
+    return absl::StrCat("QuinticPoly(", absl::StrJoin(coef_, ", "), ")");
 }
 }
 
 
+// ----------------------------------------
+
 void QuinticPolynomial::computeCoefficients(const double x0, const double dx0, const double ddx0,
 void QuinticPolynomial::computeCoefficients(const double x0, const double dx0, const double ddx0,
                                             const double x1, const double dx1, const double ddx1,
                                             const double x1, const double dx1, const double ddx1,
                                             const double t)
                                             const double t)
@@ -89,10 +155,8 @@ void QuinticPolynomial::computeCoefficients(const double x0, const double dx0, c
     coef_[4] = (-15.0 * c0 + 7.0 * c1 - c2) / t;
     coef_[4] = (-15.0 * c0 + 7.0 * c1 - c2) / t;
     coef_[5] = (6.0 * c0 - 3.0 * c1 + 0.5 * c2) / t2;
     coef_[5] = (6.0 * c0 - 3.0 * c1 + 0.5 * c2) / t2;
 }
 }
-
-std::string QuinticPolynomial::toString() const
-{
-    return absl::StrCat("QuinticPolynomial(", absl::StrJoin(coef_, ", "), ")");
-}
+// ----------------------------------------
+// Ends class QuinticPolynomial
 }
 }
 }
 }
+#endif // QUINTICPOLYNOMIAL_H

+ 120 - 0
src/decition/decition_brain/decition/adc_math/core/include/splines/Spline1dSegment.h

@@ -0,0 +1,120 @@
+#ifndef SPLINE1DSEGMENT_H
+#define SPLINE1DSEGMENT_H
+
+#pragma once
+
+#include <vector>
+#include <eigen3/Eigen/Core>
+
+#include "core/include/splines/PolynomialXd.h"
+
+namespace adtoolbox {
+namespace core {
+
+class Spline1dSegment
+{
+public:
+    explicit Spline1dSegment(const size_t order);
+    explicit Spline1dSegment(const std::vector<double> &params);
+    ~Spline1dSegment() = default;
+
+    void setParams(const std::vector<double> &params);
+    double operator()(const double x) const;
+    double derivative(const double x) const;
+    double secondOrderDerivative(const double x) const;
+    double thirdOrderDerivative(const double x) const;
+
+    const PolynomialXd &splineFunc() const;
+    const PolynomialXd &derivativeFunc() const;
+    const PolynomialXd &secondOrderDerivativeFunc() const;
+    const PolynomialXd &thirdOrderDerivativeFunc() const;
+
+private:
+    void setSplineFunc(const PolynomialXd &spline_func);
+
+    PolynomialXd f_;
+    PolynomialXd df_;
+    PolynomialXd ddf_;
+    PolynomialXd dddf_;
+};
+
+// ----------------------------------------
+
+Spline1dSegment::Spline1dSegment(const size_t order)
+{
+    setSplineFunc(PolynomialXd(order));
+}
+
+// ----------------------------------------
+
+Spline1dSegment::Spline1dSegment(const std::vector<double> &params)
+{
+    setSplineFunc(PolynomialXd(params));
+}
+
+// ----------------------------------------
+
+void Spline1dSegment::setParams(const std::vector<double> &params)
+{
+    setSplineFunc(PolynomialXd(params));
+}
+
+// ----------------------------------------
+
+void Spline1dSegment::setSplineFunc(const PolynomialXd &spline_func)
+{
+    f_ = spline_func;
+    df_ = PolynomialXd::derivedFrom(f_);
+    ddf_ = PolynomialXd::derivedFrom(df_);
+    dddf_ = PolynomialXd::derivedFrom(ddf_);
+}
+
+// ----------------------------------------
+
+double Spline1dSegment::operator()(const double x) const
+{
+    return f_(x);
+}
+
+double Spline1dSegment::derivative(const double x) const
+{
+    return df_(x);
+}
+
+double Spline1dSegment::secondOrderDerivative(const double x) const
+{
+    return ddf_(x);
+}
+
+double Spline1dSegment::thirdOrderDerivative(const double x) const
+{
+    return dddf_(x);
+}
+
+// ----------------------------------------
+
+const PolynomialXd& Spline1dSegment::splineFunc() const
+{
+    return f_;
+}
+
+const PolynomialXd& Spline1dSegment::derivativeFunc() const
+{
+    return df_;
+}
+
+const PolynomialXd& Spline1dSegment::secondOrderDerivativeFunc() const
+{
+    return ddf_;
+}
+
+const PolynomialXd& Spline1dSegment::thirdOrderDerivativeFunc() const
+{
+    return dddf_;
+}
+// ----------------------------------------
+// Ends class Spline1dSegment
+}
+}
+
+#endif // SPLINE1DSEGMENT_H

+ 133 - 0
src/decition/decition_brain/decition/adc_math/core/include/splines/Spline2dSegment.h

@@ -0,0 +1,133 @@
+#ifndef SPLINE2DSEGMENT_H
+#define SPLINE2DSEGMENT_H
+
+#pragma once
+
+#include <vector>
+#include <eigen3/Eigen/Core>
+
+#include "core/include/splines/PolynomialXd.h"
+
+namespace adtoolbox {
+namespace core {
+
+class Spline2dSegment
+{
+public:
+    explicit Spline2dSegment(const size_t order);
+    Spline2dSegment(const std::vector<double> &x_param,
+                    const std::vector<double> &y_param);
+    ~Spline2dSegment() = default;
+
+    bool setParams(const std::vector<double> &x_param,
+                   const std::vector<double> &y_param);
+
+    std::pair<double, double> operator()(const double t) const;
+    double x(const double t) const;
+    double y(const double t) const;
+    double derivativeX(const double t) const;
+    double derivativeY(const double t) const;
+    double secondOrderDerivativeX(const double t) const;
+    double secondOrderDerivativeY(const double t) const;
+    double thirdOrderDerivativeX(const double t) const;
+    double thirdOrderDerivativeY(const double t) const;
+
+    const PolynomialXd& splineFuncX() const;
+    const PolynomialXd& splineFuncY() const;
+    const PolynomialXd& derivativeFuncX() const;
+    const PolynomialXd& derivativeFuncY() const;
+    const PolynomialXd& secondOrderDerivativeFuncX() const;
+    const PolynomialXd& secondOrderDerivativeFuncY() const;
+    const PolynomialXd& thirdOrderDerivativeFuncX() const;
+    const PolynomialXd& thirdOrderDerivativeFuncY() const;
+
+private:
+    PolynomialXd fx_;
+    PolynomialXd fy_;
+    PolynomialXd dfx_;
+    PolynomialXd dfy_;
+    PolynomialXd ddfx_;
+    PolynomialXd ddfy_;
+    PolynomialXd dddfx_;
+    PolynomialXd dddfy_;
+};
+
+// ----------------------------------------
+
+Spline2dSegment::Spline2dSegment(const size_t order)
+    : fx_(order), fy_(order)
+{
+    dfx_ = PolynomialXd::derivedFrom(fx_);
+    dfy_ = PolynomialXd::derivedFrom(fy_);
+    ddfx_ = PolynomialXd::derivedFrom(dfx_);
+    ddfy_ = PolynomialXd::derivedFrom(dfy_);
+    dddfx_ = PolynomialXd::derivedFrom(ddfx_);
+    dddfy_ = PolynomialXd::derivedFrom(ddfy_);
+}
+
+// ----------------------------------------
+
+Spline2dSegment::Spline2dSegment(const std::vector<double>& x_param,
+                                 const std::vector<double>& y_param)
+    : fx_(x_param), fy_(y_param)
+{
+    dfx_ = PolynomialXd::derivedFrom(fx_);
+    dfy_ = PolynomialXd::derivedFrom(fy_);
+    ddfx_ = PolynomialXd::derivedFrom(dfx_);
+    ddfy_ = PolynomialXd::derivedFrom(dfy_);
+    dddfx_ = PolynomialXd::derivedFrom(ddfx_);
+    dddfy_ = PolynomialXd::derivedFrom(ddfy_);
+}
+
+// ----------------------------------------
+
+bool Spline2dSegment::setParams(const std::vector<double> &x_param,
+                                const std::vector<double> &y_param)
+{
+    if (x_param.size() != y_param.size())
+        return false;
+
+    fx_ = PolynomialXd(x_param);
+    fy_ = PolynomialXd(y_param);
+    dfx_ = PolynomialXd::derivedFrom(fx_);
+    dfy_ = PolynomialXd::derivedFrom(fy_);
+    ddfx_ = PolynomialXd::derivedFrom(dfx_);
+    ddfy_ = PolynomialXd::derivedFrom(dfy_);
+    dddfx_ = PolynomialXd::derivedFrom(ddfx_);
+    dddfy_ = PolynomialXd::derivedFrom(ddfy_);
+    return true;
+}
+
+// ----------------------------------------
+
+std::pair<double, double> Spline2dSegment::operator()(const double t) const
+{
+    return std::make_pair(fx_(t), fy_(t));
+}
+
+// ----------------------------------------
+
+double Spline2dSegment::x(const double t) const { return fx_(t); }
+double Spline2dSegment::y(const double t) const { return fy_(t); }
+double Spline2dSegment::derivativeX(const double t) const { return dfx_(t); }
+double Spline2dSegment::derivativeY(const double t) const { return dfy_(t); }
+double Spline2dSegment::secondOrderDerivativeX(const double t) const { return ddfx_(t); }
+double Spline2dSegment::secondOrderDerivativeY(const double t) const { return ddfy_(t); }
+double Spline2dSegment::thirdOrderDerivativeX(const double t) const { return dddfx_(t); }
+double Spline2dSegment::thirdOrderDerivativeY(const double t) const { return dddfy_(t); }
+
+// ----------------------------------------
+
+const PolynomialXd& Spline2dSegment::splineFuncX() const { return fx_; }
+const PolynomialXd& Spline2dSegment::splineFuncY() const { return fy_; }
+const PolynomialXd& Spline2dSegment::derivativeFuncX() const { return dfx_; }
+const PolynomialXd& Spline2dSegment::derivativeFuncY() const { return dfy_; }
+const PolynomialXd& Spline2dSegment::secondOrderDerivativeFuncX() const { return ddfx_; }
+const PolynomialXd& Spline2dSegment::secondOrderDerivativeFuncY() const { return ddfy_; }
+const PolynomialXd& Spline2dSegment::thirdOrderDerivativeFuncX() const { return dddfx_; }
+const PolynomialXd& Spline2dSegment::thirdOrderDerivativeFuncY() const { return dddfy_; }
+// ----------------------------------------
+// Ends class Spline2dSegment
+}
+}
+#endif // SPLINE2DSEGMENT_H

+ 0 - 100
src/decition/decition_brain/decition/adc_math/quartic_polynomial.h

@@ -1,100 +0,0 @@
-/****************************************
- * Class:    Quartic Polynomial class
- * Purpose:  Fitting a quartic polynomial on interval [0, t] by given
- *     boundary conditions.
- * Author:   Zhao Liang
- * Last Updated:  2021/02/23
-*****************************************
-*
-* Note: The polynomial is defined on interval [0, t] and has form
-*
-*     f(t) = a0 + a1*t + a2*t^2 + a3*t^3 + a4*t^4
-*
-* Boundary conditions are given by:
-* 1. x0=f(0), dx0=f'(0), ddx0=f''(0)
-* 2. dx1=f'(t), ddx1=f''(t)
-*/
-
-#ifndef QUARTIC_POLYNOMIAL_H
-#define QUARTIC_POLYNOMIAL_H
-
-#pragma once
-
-#include <array>
-
-namespace iv {
-namespace math {
-
-class QuarticPolynomial
-{
-public:
-    QuarticPolynomial() = default;
-    ~QuarticPolynomial() = default;
-
-    /**
-    * @brief Initialize a quartic polynomial by given boundary conditions.
-    * @param x0: start point at x=0
-    * @param dx0: first order derivative at the start point
-    * @param ddx0: second order derivative at the start point
-    * @param dx1: first order derivative at the end point x=t.
-    * @param ddx1: second order derivative at the end point x=t.
-    * @param t: parameter length.
-    */
-    QuarticPolynomial(const double x0, const double dx0, const double ddx0,
-                      const double dx1, const double ddx1,
-                      const double t);
-
-    /**
-    * @brief You can also pack the boundary conditions into two arrays.
-    */
-    QuarticPolynomial(const std::array<double, 3> &start,
-                      const std::array<double, 2> &end,
-                      const double t);
-
-    /**
-    * @brief Evaluate the n-th derivative of this polynomial at a given point p.
-    * @param order: the order of the derivative to be evaluated.
-    * @param p: the point to be evaluated.
-    */
-    double evaluate(const std::uint32_t order, const double p) const;
-
-    /**
-    * @brief Return the coefficient of the k-th term.
-    */
-    double coef(const size_t order) const;
-
-    /**
-    * @brief Return all coefficients as a std::array.
-    */
-    const std::array<double, 5> &coef() const;
-
-    /**
-    * @brief Return a pretty string representation of this polynomial
-    */
-    std::string toString() const;
-
-    size_t order() const { return 4; }
-
-    /**
-    * @brief Return the length of the fitting interval [0, t]
-    */
-    double paramLength() const { return t_; }
-
-private:
-
-    /**
-    * @brief Compute the coefficients array.
-    */
-    void computeCoefficients(const double x0, const double dx0, const double ddx0,
-                             const double dx1, const double ddx1,
-                             const double t);
-
-    double t_;
-    std::array<double, 3> start_condition_;
-    std::array<double, 2> end_condition_;
-    std::array<double, 5> coef_;
-};
-}
-}
-
-#endif // QUARTIC_POLYNOMIAL_H

+ 0 - 93
src/decition/decition_brain/decition/adc_math/quintic_polynomial.h

@@ -1,93 +0,0 @@
-/****************************************
- * Class:    Quintic Polynomial class
- * Purpose:  Fitting a quinticc polynomial on interval [0, t] by given
- *     boundary conditions.
- * Author:   Zhao Liang
- * Last Updated:  2021/02/24
-*****************************************
-*
-* Note: The polynomial is defined on interval [0, t] and has form
-*
-*     f(t) = a0 + a1*t + a2*t^2 + a3*t^3 + a4*t^4 + a5*t^5
-*
-* Boundary conditions are given by:
-* 1. x0=f(0), dx0=f'(0), ddx0=f''(0)
-* 2. x1=f(t), dx1=f'(t), ddx1=f''(t)
-*/
-#ifndef QUINTIC_POLYNOMIAL_H
-#define QUINTIC_POLYNOMIAL_H
-
-#pragma once
-
-#include <array>
-
-namespace iv {
-namespace math {
-
-class QuinticPolynomial
-{
-public:
-    QuinticPolynomial() = default;
-    ~QuinticPolynomial() = default;
-
-    /**
-    * @brief Initialize a quintic polynomial by given boundary conditions.
-    * @param x0: start point at x=0
-    * @param dx0: first order derivative at the start point
-    * @param ddx0: second order derivative at the start point
-    * @param x1: end point at x=t
-    * @param dx1: first order derivative at the end point x=t.
-    * @param ddx1: second order derivative at the end point x=t.
-    * @param t: parameter length.
-    */
-    QuinticPolynomial(const double x0, const double dx0, const double ddx0,
-                      const double x1, const double dx1, const double ddx1,
-                      const double t);
-
-    QuinticPolynomial(const std::array<double, 3> &start,
-                      const std::array<double, 3> &end,
-                      const double t);
-
-    void fitByBoundaryConditions(const double x0, const double dx0, const double ddx0,
-                                 const double x1, const double dx1, const double ddx1,
-                                 const double t);
-
-    /**
-    * @brief Evaluate the n-th derivative of this polynomial at a given point p.
-    * @param order: the order of the derivative to be evaluated.
-    * @param p: the point to be evaluated.
-    */
-    double evaluate(const std::uint32_t order, const double p) const;
-
-    /**
-    * @brief Return the coefficient of the k-th term.
-    */
-    double coef(const size_t order) const;
-
-    /**
-    * @brief Return all coefficients as a std::array.
-    */
-    const std::array<double, 6> &coef() const;
-
-    /**
-    * @brief Return a pretty string representation of this polynomial
-    */
-    std::string toString() const;
-
-    size_t order() const { return 5; }
-    double paramLength() const { return t_; }
-
-private:
-    void computeCoefficients(const double x0, const double dx0, const double ddx0,
-                             const double x1, const double dx1, const double ddx1,
-                             const double t);
-
-    double t_;
-    std::array<double, 3> start_condition_;
-    std::array<double, 3> end_condition_;
-    std::array<double, 6> coef_;
-};
-}
-}
-
-#endif // QUINTIC_POLYNOMIAL_H

+ 0 - 289
src/decition/decition_brain/decition/adc_math/vec2.h

@@ -1,289 +0,0 @@
-/****************************************
-* Class:    2D vector class
-* Purpose:  A single header file handling 2D vector computations.
-* Author:   Zhao Liang
-* Last Updated:  2021/01/20
-*****************************************
-*
-* Note: Need to add error handling procedures in divisions.
-*
-*/
-
-#ifndef VEC2_H
-#define VEC2_H
-
-#pragma once
-
-#include <cmath>
-#include <iostream>
-
-namespace iv {
-namespace math {
-
-constexpr double _EPSILON = 1e-12;
-
-class Vec2
-{
-public:
-
-    // ----------------------------------------
-
-    /*
-     * Constructors.
-    */
-
-    Vec2() : x_(0), y_(0) {}
-
-    explicit Vec2(double a) : x_(a), y_(a) {}
-
-    Vec2(double a, double b) : x_(a), y_(b) {}
-
-    // ----------------------------------------
-
-    // Compare to another vector
-    bool operator == (const Vec2 &v) const
-    {
-        return (std::abs(x_ - v.x()) < _EPSILON &&
-                std::abs(y_ - v.y()) < _EPSILON);
-    }
-
-    // ----------------------------------------
-
-    /*
-     * Return the unit vector Vec2(cos(angle), sin(angle)),
-     * The param 'angle' should be in radians.
-    */
-    static Vec2 unitVec2(const double angle)
-    {
-        return Vec2(cos(angle), sin(angle));
-    }
-
-    // ----------------------------------------
-
-    /*
-     * Access x and y components
-    */
-    double x() const { return x_; }
-    double y() const { return y_; }
-
-    // ----------------------------------------
-
-    /*
-     * Set x and y components
-    */
-    void set_x(const double x) { x_ = x; }
-    void set_y(const double y) { y_ = y; }
-
-    // ----------------------------------------
-
-    /*
-     * Operations with other scalars,
-     * vec2 is the left operand, scalar is the right operand.
-    */
-
-    // ----------------------------------------
-
-    // add a scalar
-    Vec2 operator + (double c) const { return Vec2(x() + c, y() + c); }
-    // subtract a scalar
-    Vec2 operator - (double c) const { return Vec2(x() - c, y() - c); }
-    // multiply a scalar
-    Vec2 operator * (double c) const { return Vec2(x() * c, y() * c); }
-    // divide by a scalar
-    Vec2 operator / (double c) const { return Vec2(x() / c, y() / c); }
-    // in-place add a scalar
-    Vec2 operator += (double c) { x_ += c; y_ += c; return (*this); }
-    // in-place subtract a scalar
-    Vec2 operator -= (double c) { x_ -= c; y_ -= c; return (*this); }
-    // in-place multiply a scalar
-    Vec2 operator *= (double c) { x_ *= c; y_ *= c; return (*this); }
-    // in-place divide by a scalar
-    Vec2 operator /= (double c) { x_ /= c; y_ /= c; return (*this); }
-
-    // ----------------------------------------
-
-    /*
-     * Operations with other vec2
-    */
-
-    // ----------------------------------------
-
-    // add two vectors
-    Vec2 operator + (const Vec2 &v) const { return Vec2(x() + v.x(), y() + v.y()); }
-    // subtract another vector
-    Vec2 operator - (const Vec2 &v) const { return Vec2(x() - v.x(), y() - v.y()); }
-    // multiply two vectors as complex numbers
-    Vec2 operator * (const Vec2 &v) const
-    {
-        double x1 = x() * v.x() - y() * v.y();
-        double y1 = x() * v.y() + y() * v.x();
-        return Vec2(x1, y1);
-    }
-    // division as complex numbers
-    Vec2 operator / (const Vec2 &v) const
-    {
-        double snorm = v.squared_norm();
-        return Vec2(this->dot(v) / snorm, -this->cross(v) / snorm);
-    }
-    // in-place vector addition
-    Vec2 operator += (const Vec2 &v) { x_ += v.x(); y_ += v.y(); return (*this); }
-    // in-place vector subtraction
-    Vec2 operator -= (const Vec2 &v) { x_ -= v.x(); y_ -= v.y(); return (*this); }
-    // in-place vector multiplication as complex numbers
-    Vec2 operator *= (const Vec2 &v)
-    {
-        double x1 = x() * v.x() - y() * v.y();
-        double y1 = x() * v.y() + y() * v.x();
-        x_ = x1;
-        y_ = y1;
-        return (*this);
-    }
-    // in-place vector division as complex numbers
-    Vec2 operator /= (const Vec2 &v)
-    {
-        double snorm = v.squared_norm();
-        double x1 = this->dot(v) / snorm;
-        double y1 = -this->cross(v) / snorm;
-        x_ = x1;
-        y_ = y1;
-        return (*this);
-    }
-
-    // ----------------------------------------
-
-    /*
-     * Vector util functions
-    */
-
-    // ----------------------------------------
-
-    // Return squared norm
-    double squared_norm() const { return x() * x() + y() * y(); }
-
-    // Return the usual Euclidean norm
-    double norm() const { return sqrt(x() * x() + y() * y()); }
-
-    // Inner product of two vectors
-    double dot(const Vec2 &v) const { return x() * v.x() + y() * v.y(); }
-
-    // Angle with the positive x-axis in radians
-    double angle() const { return atan2(y(), x()); }
-
-    // Angle between two vectors
-    double angle(const Vec2 &v) const
-    {
-        return acos(this->dot(v) / (norm() * v.norm()));
-    }
-
-    // Distance between two vectors
-    double dist(const Vec2 &v) const { return (*this - v).norm(); }
-
-    // Squared distance between two vectors
-    double squared_dist(const Vec2 &v) const { return (*this - v).squared_norm(); }
-
-    // Cross product of two vectors
-    double cross(const Vec2 &v) const { return x() * v.y() - y() * v.x(); }
-
-    // Return a normalized version of this vector
-    Vec2 normalize() const
-    {
-        double s = norm();
-        return (*this) / s;
-    }
-
-    // Translate a vector
-    Vec2 translate(double tx, double ty) const { return Vec2(x() + tx, y() + ty); }
-
-    // Rotate a vector by angle
-    Vec2 rotate(const double theta) const
-    {
-        double ct = cos(theta), st = sin(theta);
-        double x1 = x() * ct - y() * st;
-        double y1 = x() * ct + y() * st;
-        return Vec2(x1, y1);
-    }
-
-    // return a perpendicular vector to this one
-    Vec2 perp() const { return Vec2(-y(), x()); }
-
-private:
-    double x_;
-    double y_;
-};
-
-// ----------------------------------------
-
-/*
- * Vec2 operations as right operand
-*/
-
-// ----------------------------------------
-
-// print formatting
-std::ostream & operator << (std::ostream &out, const Vec2 &v)
-{
-    out << "Vec2(" << v.x() << ", " << v.y() << ")";
-    return out;
-}
-
-// add another scalar
-Vec2 operator + (double c, const Vec2 &v) { return Vec2(v.x() + c, v.y() + c); }
-// subtract another scalar
-Vec2 operator - (double c, const Vec2 &v) { return Vec2(c - v.x(), c - v.y()); }
-// multiply another scalar
-Vec2 operator * (double c, const Vec2 &v) { return Vec2(v.x() * c, v.y() * c); }
-// divide another scalar
-Vec2 operator / (double c, const Vec2 &v)
-{
-    double snorm = v.squared_norm();
-    return Vec2(v.x() * c / snorm, -v.y() * c / snorm);
-}
-
-// ----------------------------------------
-
-/*
- * Vector util functions
-*/
-
-// ----------------------------------------
-
-// Inner product
-double vdot(const Vec2 &v1, const Vec2 &v2) { return v1.dot(v2); }
-
-// Cross
-double vcross(const Vec2 &v1, const Vec2 &v2) { return v1.cross(v2); }
-
-// Vector length
-double vlength(const Vec2 &v) { return v.norm(); }
-
-// Angle with positive x-axis
-double vangle(const Vec2 &v) { return v.angle(); }
-
-// Angle between two vectors
-double vangle(const Vec2 &v1, const Vec2 &v2) { return v1.angle(v2); }
-
-// distance between two vectors
-double vdist(const Vec2 &v1, const Vec2 &v2) { return v1.dist(v2); }
-
-// squared distance between two vectors
-double vsquared_dist(const Vec2 &v1, const Vec2 &v2) { return v1.squared_dist(v2); }
-
-// normalize a vector
-Vec2 vnormalize(const Vec2 &v) { return v.normalize(); }
-
-// return a perpendicular one
-Vec2 vperp(const Vec2 &v) { return v.perp(); }
-
-// rotate a vector
-Vec2 vrotate(const Vec2 &v, double theta) { return v.rotate(theta); }
-
-// return a unit vector of given direction
-Vec2 vdir(const double angle) { return Vec2::unitVec2(angle); }
-
-// return a linear combination of two vectors
-Vec2 vinterp(const Vec2 &v1, const Vec2 &v2, double t) { return v1 * (1 - t) + v2 * t; }
-
-}
-}
-
-#endif // VEC2_H