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