ChoreoLib
Choreo support library.
Loading...
Searching...
No Matches
DifferentialSample.h
1// Copyright (c) Choreo contributors
2
3#pragma once
4
5#include <functional>
6#include <type_traits>
7
8#include <Eigen/Core>
9#include <frc/geometry/Pose2d.h>
10#include <frc/kinematics/ChassisSpeeds.h>
11#include <frc/system/NumericalIntegration.h>
12#include <units/acceleration.h>
13#include <units/angle.h>
14#include <units/angular_acceleration.h>
15#include <units/angular_velocity.h>
16#include <units/force.h>
17#include <units/length.h>
18#include <units/time.h>
19#include <units/velocity.h>
20#include <wpi/MathExtras.h>
21#include <wpi/json_fwd.h>
22
23#include "choreo/util/AllianceFlipperUtil.h"
24
25namespace choreo {
26
31 public:
35 constexpr DifferentialSample() = default;
36
54 constexpr DifferentialSample(units::second_t timestamp, units::meter_t x,
55 units::meter_t y, units::radian_t heading,
56 units::meters_per_second_t vl,
57 units::meters_per_second_t vr,
58 units::radians_per_second_t omega,
59 units::meters_per_second_squared_t al,
60 units::meters_per_second_squared_t ar,
61 units::radians_per_second_squared_t alpha,
62 units::newton_t fl, units::newton_t fr)
64 x{x},
65 y{y},
67 vl{vl},
68 vr{vr},
69 omega{omega},
70 al{al},
71 ar{ar},
72 alpha{alpha},
73 fl{fl},
74 fr{fr} {}
75
81 units::second_t GetTimestamp() const { return timestamp; }
82
88 constexpr frc::Pose2d GetPose() const {
89 return frc::Pose2d{x, y, frc::Rotation2d{heading}};
90 }
91
97 constexpr frc::ChassisSpeeds GetChassisSpeeds() const {
98 return frc::ChassisSpeeds{(vl + vr) / 2.0, 0_mps, omega};
99 }
100
107 constexpr DifferentialSample OffsetBy(units::second_t timeStampOffset) const {
108 return DifferentialSample{timestamp + timeStampOffset,
109 x,
110 y,
111 heading,
112 vl,
113 vr,
114 omega,
115 al,
116 ar,
117 alpha,
118 fl,
119 fr};
120 }
121
130 units::second_t t) const {
131 units::scalar_t scale = (t - timestamp) / (endValue.timestamp - timestamp);
132
133 // Integrate the acceleration to get the rest of the state, since linearly
134 // interpolating the state gives an inaccurate result if the accelerations
135 // are changing between states
136 Eigen::Vector<double, 6> initialState{x.value(), y.value(),
137 heading.value(), vl.value(),
138 vr.value(), omega.value()};
139
140 // FIXME: this means the function cant be constexpr without c++23
141 std::function<Eigen::Vector<double, 6>(Eigen::Vector<double, 6>,
142 Eigen::Vector<double, 3>)>
143 f = [](Eigen::Vector<double, 6> state, Eigen::Vector<double, 3> input) {
144 // state = [x, y, θ, vₗ, vᵣ, ω]
145 // input = [aₗ, aᵣ, α]
146 //
147 // v = (vₗ + vᵣ)/2
148 //
149 // ẋ = v cosθ
150 // ẏ = v sinθ
151 // θ̇ = ω
152 // v̇ₗ = aₗ
153 // v̇ᵣ = aᵣ
154 // ω̇ = α
155 auto θ = state(2, 0);
156 auto vl = state(3, 0);
157 auto vr = state(4, 0);
158 auto ω = state(5, 0);
159 auto al = input(0, 0);
160 auto ar = input(1, 0);
161 auto α = input(2, 0);
162 auto v = (vl + vr) / 2;
163 return Eigen::Vector<double, 6>{
164 v * std::cos(θ), v * std::sin(θ), ω, al, ar, α};
165 };
166
167 units::second_t τ = t - timestamp;
168 auto sample = frc::RKDP(
169 f, initialState,
170 Eigen::Vector<double, 3>(al.value(), ar.value(), alpha.value()), τ);
171
172 return DifferentialSample{
173 wpi::Lerp(timestamp, endValue.timestamp, scale),
174 units::meter_t{sample(0, 0)},
175 units::meter_t{sample(1, 0)},
176 units::radian_t{sample(2, 0)},
177 units::meters_per_second_t{sample(3, 0)},
178 units::meters_per_second_t{sample(4, 0)},
179 units::radians_per_second_t{sample(5, 0)},
180 al,
181 ar,
182 alpha,
183 wpi::Lerp(fl, endValue.fl, scale),
184 wpi::Lerp(fr, endValue.fr, scale),
185 };
186 }
187
194 template <int Year = util::kDefaultYear>
195 constexpr DifferentialSample Flipped() const {
196 constexpr auto flipper = choreo::util::GetFlipperForYear<Year>();
197 if constexpr (flipper.isMirrored) {
198 return DifferentialSample(timestamp, flipper.FlipX(x), flipper.FlipY(y),
199 flipper.FlipHeading(heading), vr, vl, -omega,
200 ar, al, -alpha, fr, fl);
201 } else {
202 return DifferentialSample(timestamp, flipper.FlipX(x), flipper.FlipY(y),
203 flipper.FlipHeading(heading), vl, vr, omega, al,
204 ar, alpha, fl, fr);
205 }
206 }
207
214 constexpr bool operator==(const DifferentialSample& other) const {
215 constexpr double epsilon = 1e-6;
216
217 auto compare_units = [epsilon](const auto& a, const auto& b) {
218 using UnitType =
219 std::remove_const_t<std::remove_reference_t<decltype(a)>>;
220 return units::math::abs(a - b) < UnitType(epsilon);
221 };
222
223 return compare_units(timestamp, other.timestamp) &&
224 compare_units(x, other.x) && compare_units(y, other.y) &&
225 compare_units(heading, other.heading) &&
226 compare_units(vl, other.vl) && compare_units(vr, other.vr) &&
227 compare_units(omega, other.omega) && compare_units(al, other.al) &&
228 compare_units(ar, other.ar) && compare_units(alpha, other.alpha) &&
229 compare_units(fl, other.fl) && compare_units(fr, other.fr);
230 }
231
233 units::second_t timestamp = 0_s;
234
236 units::meter_t x = 0_m;
237
239 units::meter_t y = 0_m;
240
242 units::radian_t heading = 0_rad;
243
245 units::meters_per_second_t vl = 0_mps;
246
248 units::meters_per_second_t vr = 0_mps;
249
251 units::radians_per_second_t omega = 0_rad_per_s;
252
254 units::meters_per_second_squared_t al = 0_mps_sq;
255
257 units::meters_per_second_squared_t ar = 0_mps_sq;
258
260 units::radians_per_second_squared_t alpha = 0_rad_per_s_sq;
261
263 units::newton_t fl = 0_N;
264
266 units::newton_t fr = 0_N;
267};
268
269void to_json(wpi::json& json, const DifferentialSample& trajectorySample);
270void from_json(const wpi::json& json, DifferentialSample& trajectorySample);
271
272} // namespace choreo
273
274#include "choreo/trajectory/struct/DifferentialSampleStruct.h"
Definition DifferentialSample.h:30
units::newton_t fl
The force of the left wheels.
Definition DifferentialSample.h:263
units::meter_t y
The Y position of the sample relative to the blue alliance wall origin.
Definition DifferentialSample.h:239
constexpr bool operator==(const DifferentialSample &other) const
Definition DifferentialSample.h:214
units::second_t timestamp
The timestamp of this sample relative to the beginning of the trajectory.
Definition DifferentialSample.h:233
constexpr DifferentialSample(units::second_t timestamp, units::meter_t x, units::meter_t y, units::radian_t heading, units::meters_per_second_t vl, units::meters_per_second_t vr, units::radians_per_second_t omega, units::meters_per_second_squared_t al, units::meters_per_second_squared_t ar, units::radians_per_second_squared_t alpha, units::newton_t fl, units::newton_t fr)
Definition DifferentialSample.h:54
units::radians_per_second_squared_t alpha
The chassis angular acceleration.
Definition DifferentialSample.h:260
constexpr DifferentialSample Flipped() const
Definition DifferentialSample.h:195
units::radian_t heading
The heading of the sample, with 0 being in the +X direction.
Definition DifferentialSample.h:242
units::newton_t fr
The force of the right wheels.
Definition DifferentialSample.h:266
units::radians_per_second_t omega
The chassis angular velocity.
Definition DifferentialSample.h:251
units::second_t GetTimestamp() const
Definition DifferentialSample.h:81
units::meters_per_second_t vr
The velocity of the right wheels.
Definition DifferentialSample.h:248
constexpr DifferentialSample()=default
constexpr frc::Pose2d GetPose() const
Definition DifferentialSample.h:88
constexpr frc::ChassisSpeeds GetChassisSpeeds() const
Definition DifferentialSample.h:97
units::meters_per_second_t vl
The velocity of the left wheels.
Definition DifferentialSample.h:245
units::meters_per_second_squared_t al
The acceleration of the left wheels.
Definition DifferentialSample.h:254
constexpr DifferentialSample OffsetBy(units::second_t timeStampOffset) const
Definition DifferentialSample.h:107
units::meter_t x
The X position of the sample relative to the blue alliance wall origin.
Definition DifferentialSample.h:236
units::meters_per_second_squared_t ar
The acceleration of the right wheels.
Definition DifferentialSample.h:257
DifferentialSample Interpolate(const DifferentialSample &endValue, units::second_t t) const
Definition DifferentialSample.h:129