/*----------------------------------------------------------------------------*/ /* Copyright (c) 2019-2020 FIRST. All Rights Reserved. */ /* Open Source Software - may be modified and shared by FRC teams. The code */ /* must be accompanied by the FIRST BSD license file in the root directory of */ /* the project. */ /*----------------------------------------------------------------------------*/ #pragma once #include #include #include #include "frc/spline/CubicHermiteSpline.h" #include "frc/spline/QuinticHermiteSpline.h" namespace frc { /** * Helper class that is used to generate cubic and quintic splines from user * provided waypoints. */ class SplineHelper { public: /** * Returns 2 cubic control vectors from a set of exterior waypoints and * interior translations. * * @param start The starting pose. * @param interiorWaypoints The interior waypoints. * @param end The ending pose. * @return 2 cubic control vectors. */ static std::array::ControlVector, 2> CubicControlVectorsFromWaypoints( const Pose2d& start, const std::vector& interiorWaypoints, const Pose2d& end); /** * Returns quintic splines from a set of waypoints. * * @param waypoints The waypoints * @return List of quintic splines. */ static std::vector QuinticSplinesFromWaypoints( const std::vector& waypoints); /** * Returns a set of cubic splines corresponding to the provided control * vectors. The user is free to set the direction of the start and end * point. The directions for the middle waypoints are determined * automatically to ensure continuous curvature throughout the path. * * The derivation for the algorithm used can be found here: * * * @param start The starting control vector. * @param waypoints The middle waypoints. This can be left blank if you * only wish to create a path with two waypoints. * @param end The ending control vector. * * @return A vector of cubic hermite splines that interpolate through the * provided waypoints. */ static std::vector CubicSplinesFromControlVectors( const Spline<3>::ControlVector& start, std::vector waypoints, const Spline<3>::ControlVector& end); /** * Returns a set of quintic splines corresponding to the provided control * vectors. The user is free to set the direction of all waypoints. Continuous * curvature is guaranteed throughout the path. * * @param controlVectors The control vectors. * @return A vector of quintic hermite splines that interpolate through the * provided waypoints. */ static std::vector QuinticSplinesFromControlVectors( const std::vector::ControlVector>& controlVectors); private: static Spline<3>::ControlVector CubicControlVector(double scalar, const Pose2d& point) { return {{point.X().to(), scalar * point.Rotation().Cos()}, {point.Y().to(), scalar * point.Rotation().Sin()}}; } static Spline<5>::ControlVector QuinticControlVector(double scalar, const Pose2d& point) { return {{point.X().to(), scalar * point.Rotation().Cos(), 0.0}, {point.Y().to(), scalar * point.Rotation().Sin(), 0.0}}; } /** * Thomas algorithm for solving tridiagonal systems Af = d. * * @param a the values of A above the diagonal * @param b the values of A on the diagonal * @param c the values of A below the diagonal * @param d the vector on the rhs * @param solutionVector the unknown (solution) vector, modified in-place */ static void ThomasAlgorithm(const std::vector& a, const std::vector& b, const std::vector& c, const std::vector& d, std::vector* solutionVector); }; } // namespace frc