Refactor TrajectoryGenerator (#1972)

This commit is contained in:
Prateek Machiraju
2019-10-26 12:39:47 -04:00
committed by Peter Johnson
parent 73a30182c3
commit 9440edf2b5
23 changed files with 825 additions and 629 deletions

View File

@@ -11,39 +11,22 @@
using namespace frc;
std::vector<CubicHermiteSpline> SplineHelper::CubicSplinesFromWaypoints(
const Pose2d& start, std::vector<Translation2d> waypoints,
const Pose2d& end) {
std::vector<CubicHermiteSpline> SplineHelper::CubicSplinesFromControlVectors(
const Spline<3>::ControlVector& start, std::vector<Translation2d> waypoints,
const Spline<3>::ControlVector& end) {
std::vector<CubicHermiteSpline> splines;
double scalar;
// This just makes the splines look better.
if (waypoints.empty()) {
scalar = 1.2 * start.Translation().Distance(end.Translation()).to<double>();
} else {
scalar = 1.2 * start.Translation().Distance(waypoints.front()).to<double>();
}
std::array<double, 2> startXControlVector{
start.Translation().X().to<double>(), start.Rotation().Cos() * scalar};
std::array<double, 2> startYControlVector{
start.Translation().Y().to<double>(), start.Rotation().Sin() * scalar};
// This just makes the splines look better.
if (!waypoints.empty()) {
scalar = 1.2 * end.Translation().Distance(waypoints.back()).to<double>();
}
std::array<double, 2> endXControlVector{end.Translation().X().to<double>(),
end.Rotation().Cos() * scalar};
std::array<double, 2> endYControlVector{end.Translation().Y().to<double>(),
end.Rotation().Sin() * scalar};
std::array<double, 2> xInitial = start.x;
std::array<double, 2> yInitial = start.y;
std::array<double, 2> xFinal = end.x;
std::array<double, 2> yFinal = end.y;
if (waypoints.size() > 1) {
waypoints.emplace(waypoints.begin(), start.Translation());
waypoints.emplace_back(end.Translation());
waypoints.emplace(waypoints.begin(),
Translation2d{units::meter_t(xInitial[0]),
units::meter_t(yInitial[0])});
waypoints.emplace_back(
Translation2d{units::meter_t(xFinal[0]), units::meter_t(yFinal[0])});
std::vector<double> a;
std::vector<double> b(waypoints.size() - 2, 4.0);
@@ -53,7 +36,7 @@ std::vector<CubicHermiteSpline> SplineHelper::CubicSplinesFromWaypoints(
fy(waypoints.size() - 2, 0.0);
a.emplace_back(0);
for (unsigned int i = 0; i < waypoints.size() - 3; i++) {
for (size_t i = 0; i < waypoints.size() - 3; ++i) {
a.emplace_back(1);
c.emplace_back(1);
}
@@ -61,12 +44,12 @@ std::vector<CubicHermiteSpline> SplineHelper::CubicSplinesFromWaypoints(
dx.emplace_back(
3 * (waypoints[2].X().to<double>() - waypoints[0].X().to<double>()) -
startXControlVector[1]);
xInitial[1]);
dy.emplace_back(
3 * (waypoints[2].Y().to<double>() - waypoints[0].Y().to<double>()) -
startYControlVector[1]);
yInitial[1]);
if (waypoints.size() > 4) {
for (unsigned int i = 1; i <= waypoints.size() - 4; i++) {
for (size_t i = 1; i <= waypoints.size() - 4; ++i) {
dx.emplace_back(3 * (waypoints[i + 1].X().to<double>() -
waypoints[i - 1].X().to<double>()));
dy.emplace_back(3 * (waypoints[i + 1].Y().to<double>() -
@@ -75,20 +58,20 @@ std::vector<CubicHermiteSpline> SplineHelper::CubicSplinesFromWaypoints(
}
dx.emplace_back(3 * (waypoints[waypoints.size() - 1].X().to<double>() -
waypoints[waypoints.size() - 3].X().to<double>()) -
endXControlVector[1]);
xFinal[1]);
dy.emplace_back(3 * (waypoints[waypoints.size() - 1].Y().to<double>() -
waypoints[waypoints.size() - 3].Y().to<double>()) -
endYControlVector[1]);
yFinal[1]);
ThomasAlgorithm(a, b, c, dx, &fx);
ThomasAlgorithm(a, b, c, dy, &fy);
fx.emplace(fx.begin(), startXControlVector[1]);
fx.emplace_back(endXControlVector[1]);
fy.emplace(fy.begin(), startYControlVector[1]);
fy.emplace_back(endYControlVector[1]);
fx.emplace(fx.begin(), xInitial[1]);
fx.emplace_back(xFinal[1]);
fy.emplace(fy.begin(), yInitial[1]);
fy.emplace_back(yFinal[1]);
for (unsigned int i = 0; i < fx.size() - 1; i++) {
for (size_t i = 0; i < fx.size() - 1; ++i) {
// Create the spline.
const CubicHermiteSpline spline{
{waypoints[i].X().to<double>(), fx[i]},
@@ -99,39 +82,69 @@ std::vector<CubicHermiteSpline> SplineHelper::CubicSplinesFromWaypoints(
splines.push_back(spline);
}
} else if (waypoints.size() == 1) {
const double xDeriv = (3 * (end.Translation().X().to<double>() -
start.Translation().X().to<double>()) -
endXControlVector[1] - startXControlVector[1]) /
4.0;
const double yDeriv = (3 * (end.Translation().Y().to<double>() -
start.Translation().Y().to<double>()) -
endYControlVector[1] - startYControlVector[1]) /
4.0;
const double xDeriv =
(3 * (xFinal[0] - xInitial[0]) - xFinal[1] - xInitial[1]) / 4.0;
const double yDeriv =
(3 * (yFinal[0] - yInitial[0]) - yFinal[1] - yInitial[1]) / 4.0;
std::array<double, 2> midXControlVector{waypoints[0].X().to<double>(),
xDeriv};
std::array<double, 2> midYControlVector{waypoints[0].Y().to<double>(),
yDeriv};
splines.emplace_back(startXControlVector, midXControlVector,
startYControlVector, midYControlVector);
splines.emplace_back(midXControlVector, endXControlVector,
midYControlVector, endYControlVector);
splines.emplace_back(xInitial, midXControlVector, yInitial,
midYControlVector);
splines.emplace_back(midXControlVector, xFinal, midYControlVector, yFinal);
} else {
// Create the spline.
const CubicHermiteSpline spline{startXControlVector, endXControlVector,
startYControlVector, endYControlVector};
const CubicHermiteSpline spline{xInitial, xFinal, yInitial, yFinal};
splines.push_back(spline);
}
return splines;
}
std::vector<QuinticHermiteSpline> SplineHelper::QuinticSplinesFromWaypoints(
const std::vector<Pose2d>& waypoints) {
std::vector<QuinticHermiteSpline>
SplineHelper::QuinticSplinesFromControlVectors(
const std::vector<Spline<5>::ControlVector>& controlVectors) {
std::vector<QuinticHermiteSpline> splines;
for (unsigned int i = 0; i < waypoints.size() - 1; i++) {
for (size_t i = 0; i < controlVectors.size() - 1; ++i) {
auto& xInitial = controlVectors[i].x;
auto& yInitial = controlVectors[i].y;
auto& xFinal = controlVectors[i + 1].x;
auto& yFinal = controlVectors[i + 1].y;
splines.emplace_back(xInitial, xFinal, yInitial, yFinal);
}
return splines;
}
std::array<Spline<3>::ControlVector, 2>
SplineHelper::CubicControlVectorsFromWaypoints(
const Pose2d& start, const std::vector<Translation2d>& interiorWaypoints,
const Pose2d& end) {
double scalar;
if (interiorWaypoints.empty()) {
scalar = 1.2 * start.Translation().Distance(end.Translation()).to<double>();
} else {
scalar =
1.2 *
start.Translation().Distance(interiorWaypoints.front()).to<double>();
}
const auto initialCV = CubicControlVector(scalar, start);
if (!interiorWaypoints.empty()) {
scalar =
1.2 * end.Translation().Distance(interiorWaypoints.back()).to<double>();
}
const auto finalCV = CubicControlVector(scalar, end);
return {initialCV, finalCV};
}
std::vector<Spline<5>::ControlVector>
SplineHelper::QuinticControlVectorsFromWaypoints(
const std::vector<Pose2d>& waypoints) {
std::vector<Spline<5>::ControlVector> vectors;
for (size_t i = 0; i < waypoints.size() - 1; ++i) {
auto& p0 = waypoints[i];
auto& p1 = waypoints[i + 1];
@@ -139,19 +152,10 @@ std::vector<QuinticHermiteSpline> SplineHelper::QuinticSplinesFromWaypoints(
const auto scalar =
1.2 * p0.Translation().Distance(p1.Translation()).to<double>();
const std::array<double, 3> xInitialControlVector{
p0.Translation().X().to<double>(), p0.Rotation().Cos() * scalar, 0.0};
const std::array<double, 3> xFinalControlVector{
p1.Translation().X().to<double>(), p1.Rotation().Cos() * scalar, 0.0};
const std::array<double, 3> yInitialControlVector{
p0.Translation().Y().to<double>(), p0.Rotation().Sin() * scalar, 0.0};
const std::array<double, 3> yFinalControlVector{
p1.Translation().Y().to<double>(), p1.Rotation().Sin() * scalar, 0.0};
splines.emplace_back(xInitialControlVector, xFinalControlVector,
yInitialControlVector, yFinalControlVector);
vectors.push_back(QuinticControlVector(scalar, p0));
vectors.push_back(QuinticControlVector(scalar, p1));
}
return splines;
return vectors;
}
void SplineHelper::ThomasAlgorithm(const std::vector<double>& a,
@@ -176,7 +180,7 @@ void SplineHelper::ThomasAlgorithm(const std::vector<double>& a,
d_star[0] = d[0] / b[0];
// Create the c_star and d_star coefficients in the forward sweep
for (unsigned int i = 1; i < N; i++) {
for (size_t i = 1; i < N; ++i) {
double m = 1.0 / (b[i] - a[i] * c_star[i - 1]);
c_star[i] = c[i] * m;
d_star[i] = (d[i] - a[i] * d_star[i - 1]) * m;

View File

@@ -15,98 +15,78 @@
using namespace frc;
Trajectory TrajectoryGenerator::GenerateTrajectory(
const std::vector<Pose2d>& waypoints,
std::vector<std::unique_ptr<TrajectoryConstraint>>&& constraints,
units::meters_per_second_t startVelocity,
units::meters_per_second_t endVelocity,
units::meters_per_second_t maxVelocity,
units::meters_per_second_squared_t maxAcceleration, bool reversed) {
Spline<3>::ControlVector initial,
const std::vector<Translation2d>& interiorWaypoints,
Spline<3>::ControlVector end, const TrajectoryConfig& config) {
const Transform2d flip{Translation2d(), Rotation2d(180_deg)};
// Make theta normal for trajectory generation if path is reversed.
std::vector<Pose2d> newWaypoints;
newWaypoints.reserve(waypoints.size());
for (auto&& point : waypoints) {
newWaypoints.push_back(reversed ? point + flip : point);
// Flip the headings.
if (config.IsReversed()) {
initial.x[1] *= -1;
initial.y[1] *= -1;
end.x[1] *= -1;
end.y[1] *= -1;
}
auto points = SplinePointsFromSplines(
SplineHelper::QuinticSplinesFromWaypoints(newWaypoints));
auto points =
SplinePointsFromSplines(SplineHelper::CubicSplinesFromControlVectors(
initial, interiorWaypoints, end));
// After trajectory generation, flip theta back so it's relative to the
// field. Also fix curvature.
if (reversed) {
if (config.IsReversed()) {
for (auto& point : points) {
point = {point.first + flip, -point.second};
}
}
return TrajectoryParameterizer::TimeParameterizeTrajectory(
points, std::move(constraints), startVelocity, endVelocity, maxVelocity,
maxAcceleration, reversed);
points, config.Constraints(), config.StartVelocity(),
config.EndVelocity(), config.MaxVelocity(), config.MaxAcceleration(),
config.IsReversed());
}
Trajectory TrajectoryGenerator::GenerateTrajectory(
const Pose2d& start, const std::vector<Translation2d>& waypoints,
const Pose2d& end,
std::vector<std::unique_ptr<TrajectoryConstraint>>&& constraints,
units::meters_per_second_t startVelocity,
units::meters_per_second_t endVelocity,
units::meters_per_second_t maxVelocity,
units::meters_per_second_squared_t maxAcceleration, bool reversed) {
const Pose2d& start, const std::vector<Translation2d>& interiorWaypoints,
const Pose2d& end, const TrajectoryConfig& config) {
auto [startCV, endCV] = SplineHelper::CubicControlVectorsFromWaypoints(
start, interiorWaypoints, end);
return GenerateTrajectory(startCV, interiorWaypoints, endCV, config);
}
Trajectory TrajectoryGenerator::GenerateTrajectory(
std::vector<Spline<5>::ControlVector> controlVectors,
const TrajectoryConfig& config) {
const Transform2d flip{Translation2d(), Rotation2d(180_deg)};
// Make theta normal for trajectory generation if path is reversed.
const Pose2d newStart = reversed ? start + flip : start;
const Pose2d newEnd = reversed ? end + flip : end;
if (config.IsReversed()) {
for (auto& vector : controlVectors) {
// Flip the headings.
vector.x[1] *= -1;
vector.y[1] *= -1;
}
}
auto points = SplinePointsFromSplines(
SplineHelper::CubicSplinesFromWaypoints(newStart, waypoints, newEnd));
SplineHelper::QuinticSplinesFromControlVectors(controlVectors));
// After trajectory generation, flip theta back so it's relative to the
// field. Also fix curvature.
if (reversed) {
if (config.IsReversed()) {
for (auto& point : points) {
point = {point.first + flip, -point.second};
}
}
return TrajectoryParameterizer::TimeParameterizeTrajectory(
points, std::move(constraints), startVelocity, endVelocity, maxVelocity,
maxAcceleration, reversed);
points, config.Constraints(), config.StartVelocity(),
config.EndVelocity(), config.MaxVelocity(), config.MaxAcceleration(),
config.IsReversed());
}
Trajectory TrajectoryGenerator::GenerateTrajectory(
const std::vector<Pose2d>& waypoints,
const DifferentialDriveKinematics& differentialDriveKinematics,
units::meters_per_second_t startVelocity,
units::meters_per_second_t endVelocity,
units::meters_per_second_t maxVelocity,
units::meters_per_second_squared_t maxAcceleration, bool reversed) {
std::vector<std::unique_ptr<TrajectoryConstraint>> constraints;
constraints.emplace_back(
std::make_unique<DifferentialDriveKinematicsConstraint>(
differentialDriveKinematics, maxVelocity));
return GenerateTrajectory(waypoints, std::move(constraints), startVelocity,
endVelocity, maxVelocity, maxAcceleration,
reversed);
}
Trajectory TrajectoryGenerator::GenerateTrajectory(
const Pose2d& start, const std::vector<Translation2d>& waypoints,
const Pose2d& end,
const DifferentialDriveKinematics& differentialDriveKinematics,
units::meters_per_second_t startVelocity,
units::meters_per_second_t endVelocity,
units::meters_per_second_t maxVelocity,
units::meters_per_second_squared_t maxAcceleration, bool reversed) {
std::vector<std::unique_ptr<TrajectoryConstraint>> constraints;
constraints.emplace_back(
std::make_unique<DifferentialDriveKinematicsConstraint>(
differentialDriveKinematics, maxVelocity));
return GenerateTrajectory(start, waypoints, end, std::move(constraints),
startVelocity, endVelocity, maxVelocity,
maxAcceleration, reversed);
const std::vector<Pose2d>& waypoints, const TrajectoryConfig& config) {
return GenerateTrajectory(
SplineHelper::QuinticControlVectorsFromWaypoints(waypoints), config);
}

View File

@@ -35,7 +35,7 @@ using namespace frc;
Trajectory TrajectoryParameterizer::TimeParameterizeTrajectory(
const std::vector<PoseWithCurvature>& points,
std::vector<std::unique_ptr<TrajectoryConstraint>>&& constraints,
const std::vector<std::unique_ptr<TrajectoryConstraint>>& constraints,
units::meters_per_second_t startVelocity,
units::meters_per_second_t endVelocity,
units::meters_per_second_t maxVelocity,

View File

@@ -7,6 +7,7 @@
#pragma once
#include <array>
#include <utility>
#include <vector>
@@ -43,6 +44,18 @@ class Spline {
virtual ~Spline() = default;
/**
* Represents a control vector for a spline.
*
* Each element in each array represents the value of the derivative at the
* index. For example, the value of x[2] is the second derivative in the x
* dimension.
*/
struct ControlVector {
std::array<double, (Degree + 1) / 2> x;
std::array<double, (Degree + 1) / 2> y;
};
/**
* Gets the pose and curvature at some point t on the spline.
*

View File

@@ -7,6 +7,8 @@
#pragma once
#include <array>
#include <utility>
#include <vector>
#include "frc/spline/CubicHermiteSpline.h"
@@ -20,39 +22,79 @@ namespace frc {
class SplineHelper {
public:
/**
* Returns a set of cubic splines corresponding to the provided waypoints. 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.
* 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<Spline<3>::ControlVector, 2>
CubicControlVectorsFromWaypoints(
const Pose2d& start, const std::vector<Translation2d>& interiorWaypoints,
const Pose2d& end);
/**
* Returns quintic control vectors from a set of waypoints.
*
* @param waypoints The waypoints
* @return List of control vectors
*/
static std::vector<Spline<5>::ControlVector>
QuinticControlVectorsFromWaypoints(const std::vector<Pose2d>& 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:
* <https://www.uio.no/studier/emner/matnat/ifi/nedlagte-emner/INF-MAT4350/h08/undervisningsmateriale/chap7alecture.pdf>
*
* @param start The starting waypoint.
* @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 waypoint.
* @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<CubicHermiteSpline> CubicSplinesFromWaypoints(
const Pose2d& start, std::vector<Translation2d> waypoints,
const Pose2d& end);
static std::vector<CubicHermiteSpline> CubicSplinesFromControlVectors(
const Spline<3>::ControlVector& start,
std::vector<Translation2d> waypoints,
const Spline<3>::ControlVector& end);
/**
* Returns a set of quintic splines corresponding to the provided waypoints.
* The user is free to set the direction of all waypoints. Continuous
* 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 waypoints The waypoints.
* @param controlVectors The control vectors.
* @return A vector of quintic hermite splines that interpolate through the
* provided waypoints.
*/
static std::vector<QuinticHermiteSpline> QuinticSplinesFromWaypoints(
const std::vector<Pose2d>& waypoints);
static std::vector<QuinticHermiteSpline> QuinticSplinesFromControlVectors(
const std::vector<Spline<5>::ControlVector>& controlVectors);
private:
static Spline<3>::ControlVector CubicControlVector(double scalar,
const Pose2d& point) {
return {
{point.Translation().X().to<double>(), scalar * point.Rotation().Cos()},
{point.Translation().Y().to<double>(),
scalar * point.Rotation().Sin()}};
}
static Spline<5>::ControlVector QuinticControlVector(double scalar,
const Pose2d& point) {
return {{point.Translation().X().to<double>(),
scalar * point.Rotation().Cos(), 0.0},
{point.Translation().Y().to<double>(),
scalar * point.Rotation().Sin(), 0.0}};
}
/**
* Thomas algorithm for solving tridiagonal systems Af = d.
*

View File

@@ -0,0 +1,140 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2019 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 <memory>
#include <utility>
#include <vector>
#include <units/units.h>
#include "frc/kinematics/DifferentialDriveKinematics.h"
#include "frc/trajectory/constraint/DifferentialDriveKinematicsConstraint.h"
#include "frc/trajectory/constraint/TrajectoryConstraint.h"
namespace frc {
/**
* Represents the configuration for generating a trajectory. This class stores
* the start velocity, end velocity, max velocity, max acceleration, custom
* constraints, and the reversed flag.
*
* The class must be constructed with a max velocity and max acceleration.
* The other parameters (start velocity, end velocity, constraints, reversed)
* have been defaulted to reasonable values (0, 0, {}, false). These values can
* be changed via the SetXXX methods.
*/
class TrajectoryConfig {
public:
/**
* Constructs a config object.
* @param maxVelocity The max velocity of the trajectory.
* @param maxAcceleration The max acceleration of the trajectory.
*/
TrajectoryConfig(units::meters_per_second_t maxVelocity,
units::meters_per_second_squared_t maxAcceleration)
: m_maxVelocity(maxVelocity), m_maxAcceleration(maxAcceleration) {}
TrajectoryConfig(const TrajectoryConfig&) = delete;
TrajectoryConfig& operator=(const TrajectoryConfig&) = delete;
TrajectoryConfig(TrajectoryConfig&&) = default;
TrajectoryConfig& operator=(TrajectoryConfig&&) = default;
/**
* Sets the start velocity of the trajectory.
* @param startVelocity The start velocity of the trajectory.
*/
void SetStartVelocity(units::meters_per_second_t startVelocity) {
m_startVelocity = startVelocity;
}
/**
* Sets the end velocity of the trajectory.
* @param endVelocity The end velocity of the trajectory.
*/
void SetEndVelocity(units::meters_per_second_t endVelocity) {
m_endVelocity = endVelocity;
}
/**
* Sets the reversed flag of the trajectory.
* @param reversed Whether the trajectory should be reversed or not.
*/
void SetReversed(bool reversed) { m_reversed = reversed; }
/**
* Adds a user-defined constraint to the trajectory.
* @param constraint The user-defined constraint.
*/
template <typename Constraint, typename = std::enable_if_t<std::is_base_of_v<
TrajectoryConstraint, Constraint>>>
void AddConstraint(Constraint constraint) {
m_constraints.emplace_back(std::make_unique<Constraint>(constraint));
}
/**
* Adds a differential drive kinematics constraint to ensure that
* no wheel velocity of a differential drive goes above the max velocity.
*
* @param kinematics The differential drive kinematics.
*/
void SetKinematics(const DifferentialDriveKinematics& kinematics) {
AddConstraint(
DifferentialDriveKinematicsConstraint(kinematics, m_maxVelocity));
}
/**
* Returns the starting velocity of the trajectory.
* @return The starting velocity of the trajectory.
*/
units::meters_per_second_t StartVelocity() const { return m_startVelocity; }
/**
* Returns the ending velocity of the trajectory.
* @return The ending velocity of the trajectory.
*/
units::meters_per_second_t EndVelocity() const { return m_endVelocity; }
/**
* Returns the maximum velocity of the trajectory.
* @return The maximum velocity of the trajectory.
*/
units::meters_per_second_t MaxVelocity() const { return m_maxVelocity; }
/**
* Returns the maximum acceleration of the trajectory.
* @return The maximum acceleration of the trajectory.
*/
units::meters_per_second_squared_t MaxAcceleration() const {
return m_maxAcceleration;
}
/**
* Returns the user-defined constraints of the trajectory.
* @return The user-defined constraints of the trajectory.
*/
const std::vector<std::unique_ptr<TrajectoryConstraint>>& Constraints()
const {
return m_constraints;
}
/**
* Returns whether the trajectory is reversed or not.
* @return whether the trajectory is reversed or not.
*/
bool IsReversed() const { return m_reversed; }
private:
units::meters_per_second_t m_startVelocity = 0_mps;
units::meters_per_second_t m_endVelocity = 0_mps;
units::meters_per_second_t m_maxVelocity;
units::meters_per_second_squared_t m_maxAcceleration;
std::vector<std::unique_ptr<TrajectoryConstraint>> m_constraints;
bool m_reversed = false;
};
} // namespace frc

View File

@@ -13,6 +13,7 @@
#include "frc/spline/SplineParameterizer.h"
#include "frc/trajectory/Trajectory.h"
#include "frc/trajectory/TrajectoryConfig.h"
#include "frc/trajectory/constraint/DifferentialDriveKinematicsConstraint.h"
#include "frc/trajectory/constraint/TrajectoryConstraint.h"
@@ -25,114 +26,63 @@ class TrajectoryGenerator {
using PoseWithCurvature = std::pair<Pose2d, curvature_t>;
/**
* Generates a trajectory with the given waypoints and constraints.
* Generates a trajectory from the given control vectors and config. This
* method uses clamped cubic splines -- a method in which the exterior control
* vectors and interior waypoints are provided. The headings are automatically
* determined at the interior points to ensure continuous curvature.
*
* @param waypoints A vector of points that the trajectory must go through.
* @param constraints A vector of various velocity and acceleration
* constraints.
* @param startVelocity The start velocity for the trajectory.
* @param endVelocity The end velocity for the trajectory.
* @param maxVelocity The max velocity for the trajectory.
* @param maxAcceleration The max acceleration for the trajectory.
* @param reversed Whether the robot should move backwards. Note that the
* robot will still move from a -> b -> ... -> z as defined in the waypoints.
*
* @return The trajectory.
* @param initial The initial control vector.
* @param interiorWaypoints The interior waypoints.
* @param end The ending control vector.
* @param config The configuration for the trajectory.
* @return The generated trajectory.
*/
static Trajectory GenerateTrajectory(
const std::vector<Pose2d>& waypoints,
std::vector<std::unique_ptr<TrajectoryConstraint>>&& constraints,
units::meters_per_second_t startVelocity,
units::meters_per_second_t endVelocity,
units::meters_per_second_t maxVelocity,
units::meters_per_second_squared_t maxAcceleration,
bool reversed = false);
Spline<3>::ControlVector initial,
const std::vector<Translation2d>& interiorWaypoints,
Spline<3>::ControlVector end, const TrajectoryConfig& config);
/**
* Generates a trajectory with the given waypoints and constraints.
* Generates a trajectory from the given waypoints and config. This method
* uses clamped cubic splines -- a method in which the initial pose, final
* pose, and interior waypoints are provided. The headings are automatically
* determined at the interior points to ensure continuous curvature.
*
* @param start The starting pose for the trajectory.
* @param waypoints The interior waypoints for the trajectory. The headings
* will be determined automatically to ensure continuous curvature.
* @param end The ending pose for the trajectory.
* @param constraints A vector of various velocity and acceleration
* constraints.
* @param startVelocity The start velocity for the trajectory.
* @param endVelocity The end velocity for the trajectory.
* @param maxVelocity The max velocity for the trajectory.
* @param maxAcceleration The max acceleration for the trajectory.
* @param reversed Whether the robot should move backwards. Note that the
* robot will still move from a -> b -> ... -> z as defined in the waypoints.
*
* @return The trajectory.
* @param start The starting pose.
* @param interiorWaypoints The interior waypoints.
* @param end The ending pose.
* @param config The configuration for the trajectory.
* @return The generated trajectory.
*/
static Trajectory GenerateTrajectory(
const Pose2d& start, const std::vector<Translation2d>& waypoints,
const Pose2d& end,
std::vector<std::unique_ptr<TrajectoryConstraint>>&& constraints,
units::meters_per_second_t startVelocity,
units::meters_per_second_t endVelocity,
units::meters_per_second_t maxVelocity,
units::meters_per_second_squared_t maxAcceleration,
bool reversed = false);
const Pose2d& start, const std::vector<Translation2d>& interiorWaypoints,
const Pose2d& end, const TrajectoryConfig& config);
/**
* Generates a trajectory with the given waypoints and differential drive
* constraints. Use this method if you just want a constraint such that none
* of the wheels on your differential drive exceed the specified max velocity.
* If you desire to impose more constraints, please use the other overloads.
* Generates a trajectory from the given quintic control vectors and config.
* This method uses quintic hermite splines -- therefore, all points must be
* represented by control vectors. Continuous curvature is guaranteed in this
* method.
*
* @param waypoints A vector of points that the trajectory must go through.
* @param differentialDriveKinematics The DifferentialDriveKinematics
* object that represents your drivetrain.
* @param startVelocity The start velocity for the trajectory.
* @param endVelocity The end velocity for the trajectory.
* @param maxVelocity The max velocity for the trajectory.
* @param maxAcceleration The max acceleration for the trajectory.
* @param reversed Whether the robot should move backwards. Note that the
* robot will still move from a -> b -> ... -> z as defined in the waypoints.
*
* @return The trajectory.
* @param controlVectors List of quintic control vectors.
* @param config The configuration for the trajectory.
* @return The generated trajectory.
*/
static Trajectory GenerateTrajectory(
const std::vector<Pose2d>& waypoints,
const DifferentialDriveKinematics& differentialDriveKinematics,
units::meters_per_second_t startVelocity,
units::meters_per_second_t endVelocity,
units::meters_per_second_t maxVelocity,
units::meters_per_second_squared_t maxAcceleration,
bool reversed = false);
std::vector<Spline<5>::ControlVector> controlVectors,
const TrajectoryConfig& config);
/**
* Generates a trajectory with the given waypoints and differential drive
* constraints. Use this method if you just want a constraint such that none
* of the wheels on your differential drive exceed the specified max velocity.
* If you desire to impose more constraints, please use the other overloads.
* Generates a trajectory from the given waypoints and config. This method
* uses quintic hermite splines -- therefore, all points must be represented
* by Pose2d objects. Continuous curvature is guaranteed in this method.
*
* @param start The starting pose for the trajectory.
* @param waypoints The interior waypoints for the trajectory. The headings
* will be determined automatically to ensure continuous curvature.
* @param end The ending pose for the trajectory.
* @param differentialDriveKinematics The DifferentialDriveKinematics
* object that represents your drivetrain.
* @param startVelocity The start velocity for the trajectory.
* @param endVelocity The end velocity for the trajectory.
* @param maxVelocity The max velocity for the trajectory.
* @param maxAcceleration The max acceleration for the trajectory.
* @param reversed Whether the robot should move backwards. Note that the
* robot will still move from a -> b -> ... -> z as defined in the waypoints.
*
* @return The trajectory.
* @param waypoints List of waypoints..
* @param config The configuration for the trajectory.
* @return The generated trajectory.
*/
static Trajectory GenerateTrajectory(
const Pose2d& start, const std::vector<Translation2d>& waypoints,
const Pose2d& end,
const DifferentialDriveKinematics& differentialDriveKinematics,
units::meters_per_second_t startVelocity,
units::meters_per_second_t endVelocity,
units::meters_per_second_t maxVelocity,
units::meters_per_second_squared_t maxAcceleration,
bool reversed = false);
static Trajectory GenerateTrajectory(const std::vector<Pose2d>& waypoints,
const TrajectoryConfig& config);
/**
* Generate spline points from a vector of splines by parameterizing the

View File

@@ -67,7 +67,7 @@ class TrajectoryParameterizer {
*/
static Trajectory TimeParameterizeTrajectory(
const std::vector<PoseWithCurvature>& points,
std::vector<std::unique_ptr<TrajectoryConstraint>>&& constraints,
const std::vector<std::unique_ptr<TrajectoryConstraint>>& constraints,
units::meters_per_second_t startVelocity,
units::meters_per_second_t endVelocity,
units::meters_per_second_t maxVelocity,