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) {
100 flipper.FlipX(x),
101 flipper.FlipY(y),
102 flipper.FlipHeading(heading),
103 -vx,
104 vy,
105 -omega,
106 -ax,
107 ay,
108 -alpha,
109 // FL, FR, BL, BR
110 // Mirrored
111 // -FR, -FL, -BR, -BL
114 // FL, FR, BL, BR
115 // Mirrored
116 // -FR, -FL, -BR, -BL
118 moduleForcesY[2]}};
119 } else {
120 return SwerveSample{timestamp,
121 flipper.FlipX(x),
122 flipper.FlipY(y),
123 flipper.FlipHeading(heading),
124 -vx,
125 -vy,
126 omega,
127 -ax,
128 -ay,
129 alpha,
133 -moduleForcesY[2], -moduleForcesY[3]}};
134 }
135 }
136
141 constexpr SwerveSample OffsetBy(units::second_t timeStampOffset) const {
142 return SwerveSample{timestamp + timeStampOffset,
143 x,
144 y,
145 heading,
146 vx,
147 vy,
148 omega,
149 ax,
150 ay,
151 alpha,
154 }
155
161 constexpr SwerveSample Interpolate(const SwerveSample& endValue,
162 units::second_t t) const {
163 units::scalar_t scale = (t - timestamp) / (endValue.timestamp - timestamp);
164
165 std::array<units::newton_t, 4> interpolatedForcesX;
166 std::array<units::newton_t, 4> interpolatedForcesY;
167 for (int i = 0; i < 4; i++) {
168 interpolatedForcesX[i] =
169 wpi::Lerp(moduleForcesX[i], endValue.moduleForcesX[i], scale.value());
170 interpolatedForcesY[i] =
171 wpi::Lerp(moduleForcesY[i], endValue.moduleForcesY[i], scale.value());
172 }
173
174 // Integrate the acceleration to get the rest of the state, since linearly
175 // interpolating the state gives an inaccurate result if the accelerations
176 // are changing between states
177 //
178 // τ = timestamp − tₖ
179 //
180 // x(τ) = xₖ + vₖτ + 1/2 aₖτ²
181 // v(τ) = vₖ + aₖτ
182 auto τ = t - timestamp;
183 auto τ2 = τ * τ;
184 return SwerveSample{wpi::Lerp(timestamp, endValue.timestamp, scale),
185 x + vx * τ + 0.5 * ax * τ2,
186 y + vy * τ + 0.5 * ay * τ2,
187 heading + omega * τ + 0.5 * alpha * τ2,
188 vx + ax * τ,
189 vy + ay * τ,
190 omega + alpha * τ,
191 ax,
192 ay,
193 alpha,
194 interpolatedForcesX,
195 interpolatedForcesY};
196 }
197
202 constexpr bool operator==(const SwerveSample& other) const {
203 constexpr double epsilon = 1e-6;
204
205 auto compare_units = [epsilon](const auto& a, const auto& b) {
206 using UnitType =
207 std::remove_const_t<std::remove_reference_t<decltype(a)>>;
208 return units::math::abs(a - b) < UnitType(epsilon);
209 };
210
211 auto compare_arrays = [&compare_units](const auto& arr1, const auto& arr2) {
212 return std::equal(arr1.begin(), arr1.end(), arr2.begin(), compare_units);
213 };
214
215 return compare_units(timestamp, other.timestamp) &&
216 compare_units(x, other.x) && compare_units(y, other.y) &&
217 compare_units(heading, other.heading) &&
218 compare_units(vx, other.vx) && compare_units(vy, other.vy) &&
219 compare_units(omega, other.omega) && compare_units(ax, other.ax) &&
220 compare_units(ay, other.ay) && compare_units(alpha, other.alpha) &&
221 compare_arrays(moduleForcesX, other.moduleForcesX) &&
222 compare_arrays(moduleForcesY, other.moduleForcesY);
223 }
224
226 units::second_t timestamp = 0_s;
227
229 units::meter_t x = 0_m;
230
232 units::meter_t y = 0_m;
233
235 units::radian_t heading = 0_rad;
236
238 units::meters_per_second_t vx = 0_mps;
239
241 units::meters_per_second_t vy = 0_mps;
242
244 units::radians_per_second_t omega = 0_rad_per_s;
245
247 units::meters_per_second_squared_t ax = 0_mps_sq;
248
250 units::meters_per_second_squared_t ay = 0_mps_sq;
251
253 units::radians_per_second_squared_t alpha = 0_rad_per_s_sq;
254
257 std::array<units::newton_t, 4> moduleForcesX{0_N, 0_N, 0_N, 0_N};
258
261 std::array<units::newton_t, 4> moduleForcesY{0_N, 0_N, 0_N, 0_N};
262};
263
264void to_json(wpi::json& json, const SwerveSample& trajectorySample);
265void from_json(const wpi::json& json, SwerveSample& trajectorySample);
266
267} // namespace choreo
268
269#include "choreo/trajectory/struct/SwerveSampleStruct.h"
A single swerve robot sample in a Trajectory.
Definition SwerveSample.h:26
units::meter_t y
The Y position of the sample relative to the blue alliance wall origin.
Definition SwerveSample.h:232
units::meters_per_second_t vy
The velocity of the sample in the Y direction.
Definition SwerveSample.h:241
constexpr SwerveSample Interpolate(const SwerveSample &endValue, units::second_t t) const
Definition SwerveSample.h:161
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:238
units::radians_per_second_t omega
The angular velocity of the sample.
Definition SwerveSample.h:244
units::meters_per_second_squared_t ax
The acceleration of the in the X direction.
Definition SwerveSample.h:247
units::meter_t x
The X position of the sample relative to the blue alliance wall origin.
Definition SwerveSample.h:229
constexpr SwerveSample OffsetBy(units::second_t timeStampOffset) const
Definition SwerveSample.h:141
constexpr bool operator==(const SwerveSample &other) const
Definition SwerveSample.h:202
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:235
units::second_t timestamp
The timestamp of this sample relative to the beginning of the trajectory.
Definition SwerveSample.h:226
constexpr SwerveSample Flipped() const
Definition SwerveSample.h:96
units::meters_per_second_squared_t ay
The acceleration of the in the Y direction.
Definition SwerveSample.h:250
units::radians_per_second_squared_t alpha
The angular acceleration of the sample.
Definition SwerveSample.h:253
std::array< units::newton_t, 4 > moduleForcesY
Definition SwerveSample.h:261
std::array< units::newton_t, 4 > moduleForcesX
Definition SwerveSample.h:257
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