ChoreoLib
Choreo support library.
Loading...
Searching...
No Matches
SwerveSample.h
1// Copyright (c) Choreo contributors
2
3#pragma once
4
5#include <algorithm>
6#include <array>
7#include <type_traits>
8
9#include <frc/kinematics/ChassisSpeeds.h>
10#include <units/acceleration.h>
11#include <units/angle.h>
12#include <units/angular_acceleration.h>
13#include <units/angular_velocity.h>
14#include <units/force.h>
15#include <units/length.h>
16#include <units/time.h>
17#include <units/velocity.h>
18#include <wpi/MathExtras.h>
19#include <wpi/json_fwd.h>
20
21#include "choreo/util/AllianceFlipperUtil.h"
22
23namespace choreo {
24
27 public:
29 constexpr SwerveSample() = default;
30
49 constexpr SwerveSample(units::second_t timestamp, units::meter_t x,
50 units::meter_t y, units::radian_t heading,
51 units::meters_per_second_t vx,
52 units::meters_per_second_t vy,
53 units::radians_per_second_t omega,
54 units::meters_per_second_squared_t ax,
55 units::meters_per_second_squared_t ay,
56 units::radians_per_second_squared_t alpha,
57 std::array<units::newton_t, 4> moduleForcesX,
58 std::array<units::newton_t, 4> moduleForcesY)
60 x{x},
61 y{y},
63 vx{vx},
64 vy{vy},
65 omega{omega},
66 ax{ax},
67 ay{ay},
68 alpha{alpha},
71
75 constexpr units::second_t GetTimestamp() const { return timestamp; }
76
80 constexpr frc::Pose2d GetPose() const {
81 return frc::Pose2d{x, y, frc::Rotation2d{heading}};
82 }
83
87 constexpr frc::ChassisSpeeds GetChassisSpeeds() const {
88 return frc::ChassisSpeeds{vx, vy, omega};
89 }
90
95 template <int Year = util::kDefaultYear>
96 constexpr SwerveSample Flipped() const {
97 constexpr auto flipper = choreo::util::GetFlipperForYear<Year>();
98 if constexpr (flipper.isMirrored) {
99 return MirrorX();
100 } else {
101 return RotateAround();
102 }
103 }
104
108 constexpr SwerveSample MirrorX() const {
109 return SwerveSample{timestamp,
113 -vx,
114 vy,
115 -omega,
116 -ax,
117 ay,
118 -alpha,
119 // FL, FR, BL, BR
120 // Mirrored
121 // -FR, -FL, -BR, -BL
124 // FL, FR, BL, BR
125 // Mirrored
126 // FR, FL, BR, BL
128 moduleForcesY[2]}};
129 }
130
134 constexpr SwerveSample MirrorY() const {
135 return SwerveSample{timestamp,
139 vx,
140 -vy,
141 -omega,
142 ax,
143 -ay,
144 -alpha,
145 // FL, FR, BL, BR
146 // Mirrored
147 // FR, FL, BR, BL
149 moduleForcesX[2]},
150 // FL, FR, BL, BR
151 // Mirrored
152 // -FR, -FL, -BR, -BL
154 -moduleForcesY[3], -moduleForcesY[2]}};
155 }
156
176
181 constexpr SwerveSample OffsetBy(units::second_t timeStampOffset) const {
182 return SwerveSample{timestamp + timeStampOffset,
183 x,
184 y,
185 heading,
186 vx,
187 vy,
188 omega,
189 ax,
190 ay,
191 alpha,
194 }
195
201 constexpr SwerveSample Interpolate(const SwerveSample& endValue,
202 units::second_t t) const {
203 units::scalar_t scale = (t - timestamp) / (endValue.timestamp - timestamp);
204
205 std::array<units::newton_t, 4> interpolatedForcesX;
206 std::array<units::newton_t, 4> interpolatedForcesY;
207 for (int i = 0; i < 4; i++) {
208 interpolatedForcesX[i] =
209 wpi::Lerp(moduleForcesX[i], endValue.moduleForcesX[i], scale.value());
210 interpolatedForcesY[i] =
211 wpi::Lerp(moduleForcesY[i], endValue.moduleForcesY[i], scale.value());
212 }
213
214 // Integrate the acceleration to get the rest of the state, since linearly
215 // interpolating the state gives an inaccurate result if the accelerations
216 // are changing between states
217 //
218 // τ = timestamp − tₖ
219 //
220 // x(τ) = xₖ + vₖτ + 1/2 aₖτ²
221 // v(τ) = vₖ + aₖτ
222 auto τ = t - timestamp;
223 auto τ2 = τ * τ;
224 return SwerveSample{wpi::Lerp(timestamp, endValue.timestamp, scale),
225 x + vx * τ + 0.5 * ax * τ2,
226 y + vy * τ + 0.5 * ay * τ2,
227 heading + omega * τ + 0.5 * alpha * τ2,
228 vx + ax * τ,
229 vy + ay * τ,
230 omega + alpha * τ,
231 ax,
232 ay,
233 alpha,
234 interpolatedForcesX,
235 interpolatedForcesY};
236 }
237
242 constexpr bool operator==(const SwerveSample& other) const {
243 constexpr double epsilon = 1e-6;
244
245 auto compare_units = [epsilon](const auto& a, const auto& b) {
246 using UnitType =
247 std::remove_const_t<std::remove_reference_t<decltype(a)>>;
248 return units::math::abs(a - b) < UnitType(epsilon);
249 };
250
251 auto compare_arrays = [&compare_units](const auto& arr1, const auto& arr2) {
252 return std::equal(arr1.begin(), arr1.end(), arr2.begin(), compare_units);
253 };
254
255 return compare_units(timestamp, other.timestamp) &&
256 compare_units(x, other.x) && compare_units(y, other.y) &&
257 compare_units(heading, other.heading) &&
258 compare_units(vx, other.vx) && compare_units(vy, other.vy) &&
259 compare_units(omega, other.omega) && compare_units(ax, other.ax) &&
260 compare_units(ay, other.ay) && compare_units(alpha, other.alpha) &&
261 compare_arrays(moduleForcesX, other.moduleForcesX) &&
262 compare_arrays(moduleForcesY, other.moduleForcesY);
263 }
264
266 units::second_t timestamp = 0_s;
267
269 units::meter_t x = 0_m;
270
272 units::meter_t y = 0_m;
273
275 units::radian_t heading = 0_rad;
276
278 units::meters_per_second_t vx = 0_mps;
279
281 units::meters_per_second_t vy = 0_mps;
282
284 units::radians_per_second_t omega = 0_rad_per_s;
285
287 units::meters_per_second_squared_t ax = 0_mps_sq;
288
290 units::meters_per_second_squared_t ay = 0_mps_sq;
291
293 units::radians_per_second_squared_t alpha = 0_rad_per_s_sq;
294
297 std::array<units::newton_t, 4> moduleForcesX{0_N, 0_N, 0_N, 0_N};
298
301 std::array<units::newton_t, 4> moduleForcesY{0_N, 0_N, 0_N, 0_N};
302};
303
304void to_json(wpi::json& json, const SwerveSample& trajectorySample);
305void from_json(const wpi::json& json, SwerveSample& trajectorySample);
306
307} // namespace choreo
308
309#include "choreo/trajectory/struct/SwerveSampleStruct.h"
A single swerve robot sample in a Trajectory.
Definition SwerveSample.h:26
constexpr SwerveSample RotateAround() const
Definition SwerveSample.h:160
units::meter_t y
The Y position of the sample relative to the blue alliance wall origin.
Definition SwerveSample.h:272
units::meters_per_second_t vy
The velocity of the sample in the Y direction.
Definition SwerveSample.h:281
constexpr SwerveSample Interpolate(const SwerveSample &endValue, units::second_t t) const
Definition SwerveSample.h:201
constexpr SwerveSample MirrorY() const
Definition SwerveSample.h:134
constexpr units::second_t GetTimestamp() const
Definition SwerveSample.h:75
units::meters_per_second_t vx
The velocity of the sample in the X direction.
Definition SwerveSample.h:278
units::radians_per_second_t omega
The angular velocity of the sample.
Definition SwerveSample.h:284
units::meters_per_second_squared_t ax
The acceleration of the in the X direction.
Definition SwerveSample.h:287
units::meter_t x
The X position of the sample relative to the blue alliance wall origin.
Definition SwerveSample.h:269
constexpr SwerveSample OffsetBy(units::second_t timeStampOffset) const
Definition SwerveSample.h:181
constexpr bool operator==(const SwerveSample &other) const
Definition SwerveSample.h:242
constexpr frc::ChassisSpeeds GetChassisSpeeds() const
Definition SwerveSample.h:87
constexpr frc::Pose2d GetPose() const
Definition SwerveSample.h:80
constexpr SwerveSample()=default
Constructs a SwerveSample that is defaulted.
units::radian_t heading
The heading of the sample, with 0 being in the +X direction.
Definition SwerveSample.h:275
units::second_t timestamp
The timestamp of this sample relative to the beginning of the trajectory.
Definition SwerveSample.h:266
constexpr SwerveSample Flipped() const
Definition SwerveSample.h:96
constexpr SwerveSample MirrorX() const
Definition SwerveSample.h:108
units::meters_per_second_squared_t ay
The acceleration of the in the Y direction.
Definition SwerveSample.h:290
units::radians_per_second_squared_t alpha
The angular acceleration of the sample.
Definition SwerveSample.h:293
std::array< units::newton_t, 4 > moduleForcesY
Definition SwerveSample.h:301
std::array< units::newton_t, 4 > moduleForcesX
Definition SwerveSample.h:297
constexpr SwerveSample(units::second_t timestamp, units::meter_t x, units::meter_t y, units::radian_t heading, units::meters_per_second_t vx, units::meters_per_second_t vy, units::radians_per_second_t omega, units::meters_per_second_squared_t ax, units::meters_per_second_squared_t ay, units::radians_per_second_squared_t alpha, std::array< units::newton_t, 4 > moduleForcesX, std::array< units::newton_t, 4 > moduleForcesY)
Definition SwerveSample.h:49
static constexpr units::radian_t FlipHeading(units::radian_t heading)
Definition AllianceFlipperUtil.h:43
static constexpr units::meter_t FlipX(units::meter_t x)
Definition AllianceFlipperUtil.h:29
static constexpr units::meter_t FlipY(units::meter_t y)
Definition AllianceFlipperUtil.h:37
static constexpr units::radian_t FlipHeading(units::radian_t heading)
Definition AllianceFlipperUtil.h:72
static constexpr units::meter_t FlipX(units::meter_t x)
Definition AllianceFlipperUtil.h:58
static constexpr units::meter_t FlipY(units::meter_t y)
Definition AllianceFlipperUtil.h:64
static constexpr units::meter_t FlipY(units::meter_t y)
Definition AllianceFlipperUtil.h:95
static constexpr units::radian_t FlipHeading(units::radian_t heading)
Definition AllianceFlipperUtil.h:103
static constexpr units::meter_t FlipX(units::meter_t x)
Definition AllianceFlipperUtil.h:87