blob: f275c17f959d0eaeafe820002c9e15d9579db921 [file] [log] [blame]
Alex Perry0603b542019-01-25 20:29:51 -08001#include <string>
Austin Schuhd749d932020-12-30 21:38:40 -08002#include <vector>
Alex Perry20762632019-01-21 17:48:02 -05003
4#include "Eigen/Dense"
5
Alex Perry0603b542019-01-25 20:29:51 -08006#include "aos/logging/implementations.h"
7#include "aos/network/team_number.h"
Alex Perrya60da442019-01-21 19:00:27 -05008#include "frc971/control_loops/drivetrain/distance_spline.h"
Alex Perry20762632019-01-21 17:48:02 -05009#include "frc971/control_loops/drivetrain/spline.h"
Alex Perry0603b542019-01-25 20:29:51 -080010#include "frc971/control_loops/drivetrain/trajectory.h"
James Kuszmaul8aa37cb2020-03-01 10:27:58 -080011#include "y2020/control_loops/drivetrain/drivetrain_base.h"
Alex Perry20762632019-01-21 17:48:02 -050012
13namespace frc971 {
14namespace control_loops {
15namespace drivetrain {
16
17extern "C" {
Austin Schuhd749d932020-12-30 21:38:40 -080018// Based on spline.h
19NSpline<6> *NewSpline(double x[6], double y[6]) {
20 return new NSpline<6>((::Eigen::Matrix<double, 2, 6>() << x[0], x[1], x[2],
21 x[3], x[4], x[5], y[0], y[1], y[2], y[3], y[4], y[5])
22 .finished());
23}
24
25void deleteSpline(NSpline<6> *spline) { delete spline; }
26
27void SplinePoint(NSpline<6> *spline, double alpha, double *res) {
28 const Eigen::Vector2d xy = spline->Point(alpha);
29 res[0] = xy.x();
30 res[1] = xy.y();
31}
32
33void SplineDPoint(NSpline<6> *spline, double alpha, double *res) {
34 const Eigen::Vector2d dxy = spline->DPoint(alpha);
35 res[0] = dxy.x();
36 res[1] = dxy.y();
37}
38
39void SplineDDPoint(NSpline<6> *spline, double alpha, double *res) {
40 const Eigen::Vector2d ddxy = spline->DDPoint(alpha);
41 res[0] = ddxy.x();
42 res[1] = ddxy.y();
43}
44
45void SplineDDDPoint(NSpline<6> *spline, double alpha, double *res) {
46 const Eigen::Vector2d dddxy = spline->DDDPoint(alpha);
47 res[0] = dddxy.x();
48 res[1] = dddxy.y();
49}
50
51double SplineTheta(NSpline<6> *spline, double alpha) {
52 return spline->Theta(alpha);
53}
54
55double SplineDTheta(NSpline<6> *spline, double alpha) {
56 return spline->DTheta(alpha);
57}
58
59double SplineDDTheta(NSpline<6> *spline, double alpha) {
60 return spline->DDTheta(alpha);
61}
62
63void SplineControlPoints(NSpline<6> *spline, double *x, double *y) {
64 auto points = spline->control_points();
65 // Deal with incorrectly strided matrix.
66 for (int i = 0; i < 6; ++i) {
67 x[i] = points(0, i);
68 y[i] = points(1, i);
Alex Perry20762632019-01-21 17:48:02 -050069 }
Austin Schuhd749d932020-12-30 21:38:40 -080070}
Alex Perry20762632019-01-21 17:48:02 -050071
Austin Schuhd749d932020-12-30 21:38:40 -080072// Based on distance_spline.h
73DistanceSpline *NewDistanceSpline(Spline **splines, int count) {
74 ::std::vector<Spline> splines_;
75 for (int i = 0; i < count; ++i) {
76 splines_.push_back(*splines[i]);
Alex Perry20762632019-01-21 17:48:02 -050077 }
Austin Schuhd749d932020-12-30 21:38:40 -080078 return new DistanceSpline(::std::vector<Spline>(splines_));
79}
Alex Perry20762632019-01-21 17:48:02 -050080
Austin Schuhd749d932020-12-30 21:38:40 -080081void deleteDistanceSpline(DistanceSpline *spline) { delete spline; }
82
83void DistanceSplineXY(DistanceSpline *spline, double distance, double *res) {
84 const Eigen::Vector2d xy = spline->XY(distance);
85 res[0] = xy.x();
86 res[1] = xy.y();
87}
88
89void DistanceSplineDXY(DistanceSpline *spline, double distance, double *res) {
90 const Eigen::Vector2d dxy = spline->DXY(distance);
91 res[0] = dxy.x();
92 res[1] = dxy.y();
93}
94
95void DistanceSplineDDXY(DistanceSpline *spline, double distance, double *res) {
96 const Eigen::Vector2d ddxy = spline->DDXY(distance);
97 res[0] = ddxy.x();
98 res[1] = ddxy.y();
99}
100
101double DistanceSplineTheta(DistanceSpline *spline, double distance) {
102 return spline->Theta(distance);
103}
104
105double DistanceSplineDTheta(DistanceSpline *spline, double distance) {
106 return spline->DTheta(distance);
107}
108
109double DistanceSplineDThetaDt(DistanceSpline *spline, double distance,
110 double velocity) {
111 return spline->DThetaDt(distance, velocity);
112}
113
114double DistanceSplineDDTheta(DistanceSpline *spline, double distance) {
115 return spline->DDTheta(distance);
116}
117
118double DistanceSplineLength(DistanceSpline *spline) { return spline->length(); }
119
120// Based on trajectory.h
121Trajectory *NewTrajectory(DistanceSpline *spline, double vmax,
122 int num_distance) {
123 return new Trajectory(
James Kuszmaul75a18c52021-03-10 22:02:07 -0800124 DistanceSpline(*spline),
125 ::y2020::control_loops::drivetrain::GetDrivetrainConfig(), nullptr, -1,
126 vmax, num_distance);
Austin Schuhd749d932020-12-30 21:38:40 -0800127}
128
129void deleteTrajectory(Trajectory *t) { delete t; }
130
131void TrajectorySetLongitudinalAcceleration(Trajectory *t, double accel) {
132 t->set_longitudinal_acceleration(accel);
133}
134
135void TrajectorySetLateralAcceleration(Trajectory *t, double accel) {
136 t->set_lateral_acceleration(accel);
137}
138
139void TrajectorySetVoltageLimit(Trajectory *t, double limit) {
140 t->set_voltage_limit(limit);
141}
142
143void TrajectoryLimitVelocity(Trajectory *t, double start, double end,
144 double max) {
145 t->LimitVelocity(start, end, max);
146}
147
148void TrajectoryPlan(Trajectory *t) { t->Plan(); }
149
150void TrajectoryVoltage(Trajectory *t, double distance, double *res) {
151 const Eigen::Vector2d ff_voltage = t->FFVoltage(distance);
152 res[0] = ff_voltage.x();
153 res[1] = ff_voltage.y();
154}
155
156double TrajectoryLength(Trajectory *t) { return t->length(); }
157
158int TrajectoryGetPathLength(Trajectory *t) { return t->plan().size(); }
159
160// This assumes that res is created in python to be getPathLength() long.
161// Likely to SEGFAULT otherwise.
162void TrajectoryDistances(Trajectory *t, double *res) {
163 const ::std::vector<double> &distances = t->Distances();
164 ::std::memcpy(res, distances.data(), sizeof(double) * distances.size());
165}
166
167double TrajectoryDistance(Trajectory *t, int index) {
168 return t->Distance(index);
169}
170
171// This assumes that res is created in python to be getPathLength() long.
172// Likely to SEGFAULT otherwise.
173void TrajectoryGetPlan(Trajectory *t, double *res) {
174 const ::std::vector<double> &velocities = t->plan();
175 ::std::memcpy(res, velocities.data(), sizeof(double) * velocities.size());
176}
177
178// Time in in nanoseconds.
179::std::vector<::Eigen::Matrix<double, 3, 1>> *TrajectoryGetPlanXVAPtr(
180 Trajectory *t, int dt) {
181 return new ::std::vector<::Eigen::Matrix<double, 3, 1>>(
182 t->PlanXVA(::std::chrono::nanoseconds(dt)));
183}
184
185void TrajectoryDeleteVector(::std::vector<::Eigen::Matrix<double, 3, 1>> *vec) {
186 delete vec;
187}
188
189int TrajectoryGetVectorLength(
190 ::std::vector<::Eigen::Matrix<double, 3, 1>> *vec) {
191 return vec->size();
192}
193
194void TrajectoryGetPlanXVA(::std::vector<::Eigen::Matrix<double, 3, 1>> *vec,
195 double *X, double *V, double *A) {
196 for (size_t i = 0; i < vec->size(); ++i) {
197 X[i] = (*vec)[i][0];
198 V[i] = (*vec)[i][1];
199 A[i] = (*vec)[i][2];
Alex Perry20762632019-01-21 17:48:02 -0500200 }
Austin Schuhd749d932020-12-30 21:38:40 -0800201}
Alex Perry20762632019-01-21 17:48:02 -0500202
Austin Schuhd749d932020-12-30 21:38:40 -0800203// Util
204void SetUpLogging() { ::aos::network::OverrideTeamNumber(971); }
Alex Perry20762632019-01-21 17:48:02 -0500205}
206
207} // namespace drivetrain
208} // namespace control_loops
209} // namespace frc971