blob: 6ea23c64a51ecb63752e3df2ab07fd9662d6a736 [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(
124 spline, ::y2020::control_loops::drivetrain::GetDrivetrainConfig(), vmax,
125 num_distance);
126}
127
128void deleteTrajectory(Trajectory *t) { delete t; }
129
130void TrajectorySetLongitudinalAcceleration(Trajectory *t, double accel) {
131 t->set_longitudinal_acceleration(accel);
132}
133
134void TrajectorySetLateralAcceleration(Trajectory *t, double accel) {
135 t->set_lateral_acceleration(accel);
136}
137
138void TrajectorySetVoltageLimit(Trajectory *t, double limit) {
139 t->set_voltage_limit(limit);
140}
141
142void TrajectoryLimitVelocity(Trajectory *t, double start, double end,
143 double max) {
144 t->LimitVelocity(start, end, max);
145}
146
147void TrajectoryPlan(Trajectory *t) { t->Plan(); }
148
149void TrajectoryVoltage(Trajectory *t, double distance, double *res) {
150 const Eigen::Vector2d ff_voltage = t->FFVoltage(distance);
151 res[0] = ff_voltage.x();
152 res[1] = ff_voltage.y();
153}
154
155double TrajectoryLength(Trajectory *t) { return t->length(); }
156
157int TrajectoryGetPathLength(Trajectory *t) { return t->plan().size(); }
158
159// This assumes that res is created in python to be getPathLength() long.
160// Likely to SEGFAULT otherwise.
161void TrajectoryDistances(Trajectory *t, double *res) {
162 const ::std::vector<double> &distances = t->Distances();
163 ::std::memcpy(res, distances.data(), sizeof(double) * distances.size());
164}
165
166double TrajectoryDistance(Trajectory *t, int index) {
167 return t->Distance(index);
168}
169
170// This assumes that res is created in python to be getPathLength() long.
171// Likely to SEGFAULT otherwise.
172void TrajectoryGetPlan(Trajectory *t, double *res) {
173 const ::std::vector<double> &velocities = t->plan();
174 ::std::memcpy(res, velocities.data(), sizeof(double) * velocities.size());
175}
176
177// Time in in nanoseconds.
178::std::vector<::Eigen::Matrix<double, 3, 1>> *TrajectoryGetPlanXVAPtr(
179 Trajectory *t, int dt) {
180 return new ::std::vector<::Eigen::Matrix<double, 3, 1>>(
181 t->PlanXVA(::std::chrono::nanoseconds(dt)));
182}
183
184void TrajectoryDeleteVector(::std::vector<::Eigen::Matrix<double, 3, 1>> *vec) {
185 delete vec;
186}
187
188int TrajectoryGetVectorLength(
189 ::std::vector<::Eigen::Matrix<double, 3, 1>> *vec) {
190 return vec->size();
191}
192
193void TrajectoryGetPlanXVA(::std::vector<::Eigen::Matrix<double, 3, 1>> *vec,
194 double *X, double *V, double *A) {
195 for (size_t i = 0; i < vec->size(); ++i) {
196 X[i] = (*vec)[i][0];
197 V[i] = (*vec)[i][1];
198 A[i] = (*vec)[i][2];
Alex Perry20762632019-01-21 17:48:02 -0500199 }
Austin Schuhd749d932020-12-30 21:38:40 -0800200}
Alex Perry20762632019-01-21 17:48:02 -0500201
Austin Schuhd749d932020-12-30 21:38:40 -0800202// Util
203void SetUpLogging() { ::aos::network::OverrideTeamNumber(971); }
Alex Perry20762632019-01-21 17:48:02 -0500204}
205
206} // namespace drivetrain
207} // namespace control_loops
208} // namespace frc971