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
29 public:
31 constexpr DifferentialSample() = default;
32
49 constexpr DifferentialSample(units::second_t timestamp, units::meter_t x,
50 units::meter_t y, units::radian_t heading,
51 units::meters_per_second_t vl,
52 units::meters_per_second_t vr,
53 units::radians_per_second_t omega,
54 units::meters_per_second_squared_t al,
55 units::meters_per_second_squared_t ar,
56 units::radians_per_second_squared_t alpha,
57 units::newton_t fl, units::newton_t fr)
59 x{x},
60 y{y},
62 vl{vl},
63 vr{vr},
64 omega{omega},
65 al{al},
66 ar{ar},
67 alpha{alpha},
68 fl{fl},
69 fr{fr} {}
70
74 units::second_t GetTimestamp() const { return timestamp; }
75
79 constexpr frc::Pose2d GetPose() const {
80 return frc::Pose2d{x, y, frc::Rotation2d{heading}};
81 }
82
86 constexpr frc::ChassisSpeeds GetChassisSpeeds() const {
87 return frc::ChassisSpeeds{(vl + vr) / 2.0, 0_mps, omega};
88 }
89
94 constexpr DifferentialSample OffsetBy(units::second_t timeStampOffset) const {
95 return DifferentialSample{timestamp + timeStampOffset,
96 x,
97 y,
98 heading,
99 vl,
100 vr,
101 omega,
102 al,
103 ar,
104 alpha,
105 fl,
106 fr};
107 }
108
115 units::second_t t) const {
116 units::scalar_t scale = (t - timestamp) / (endValue.timestamp - timestamp);
117
118 // Integrate the acceleration to get the rest of the state, since linearly
119 // interpolating the state gives an inaccurate result if the accelerations
120 // are changing between states
121 Eigen::Vector<double, 6> initialState{x.value(), y.value(),
122 heading.value(), vl.value(),
123 vr.value(), omega.value()};
124
125 // FIXME: this means the function cant be constexpr without c++23
126 std::function<Eigen::Vector<double, 6>(Eigen::Vector<double, 6>,
127 Eigen::Vector<double, 3>)>
128 f = [](Eigen::Vector<double, 6> state, Eigen::Vector<double, 3> input) {
129 // state = [x, y, θ, vₗ, vᵣ, ω]
130 // input = [aₗ, aᵣ, α]
131 //
132 // v = (vₗ + vᵣ)/2
133 //
134 // ẋ = v cosθ
135 // ẏ = v sinθ
136 // θ̇ = ω
137 // v̇ₗ = aₗ
138 // v̇ᵣ = aᵣ
139 // ω̇ = α
140 auto θ = state(2, 0);
141 auto vl = state(3, 0);
142 auto vr = state(4, 0);
143 auto ω = state(5, 0);
144 auto al = input(0, 0);
145 auto ar = input(1, 0);
146 auto α = input(2, 0);
147 auto v = (vl + vr) / 2;
148 return Eigen::Vector<double, 6>{
149 v * std::cos(θ), v * std::sin(θ), ω, al, ar, α};
150 };
151
152 units::second_t τ = t - timestamp;
153 auto sample = frc::RKDP(
154 f, initialState,
155 Eigen::Vector<double, 3>(al.value(), ar.value(), alpha.value()), τ);
156
157 return DifferentialSample{
158 wpi::Lerp(timestamp, endValue.timestamp, scale),
159 units::meter_t{sample(0, 0)},
160 units::meter_t{sample(1, 0)},
161 units::radian_t{sample(2, 0)},
162 units::meters_per_second_t{sample(3, 0)},
163 units::meters_per_second_t{sample(4, 0)},
164 units::radians_per_second_t{sample(5, 0)},
165 al,
166 ar,
167 alpha,
168 wpi::Lerp(fl, endValue.fl, scale),
169 wpi::Lerp(fr, endValue.fr, scale),
170 };
171 }
172
177 template <int Year = util::kDefaultYear>
178 constexpr DifferentialSample Flipped() const {
179 constexpr auto flipper = choreo::util::GetFlipperForYear<Year>();
180 if constexpr (flipper.isMirrored) {
181 return DifferentialSample(timestamp, flipper.FlipX(x), flipper.FlipY(y),
182 flipper.FlipHeading(heading), vr, vl, -omega,
183 ar, al, -alpha, fr, fl);
184 } else {
185 return DifferentialSample(timestamp, flipper.FlipX(x), flipper.FlipY(y),
186 flipper.FlipHeading(heading), vl, vr, omega, al,
187 ar, alpha, fl, fr);
188 }
189 }
190
195 constexpr bool operator==(const DifferentialSample& other) const {
196 constexpr double epsilon = 1e-6;
197
198 auto compare_units = [epsilon](const auto& a, const auto& b) {
199 using UnitType =
200 std::remove_const_t<std::remove_reference_t<decltype(a)>>;
201 return units::math::abs(a - b) < UnitType(epsilon);
202 };
203
204 return compare_units(timestamp, other.timestamp) &&
205 compare_units(x, other.x) && compare_units(y, other.y) &&
206 compare_units(heading, other.heading) &&
207 compare_units(vl, other.vl) && compare_units(vr, other.vr) &&
208 compare_units(omega, other.omega) && compare_units(al, other.al) &&
209 compare_units(ar, other.ar) && compare_units(alpha, other.alpha) &&
210 compare_units(fl, other.fl) && compare_units(fr, other.fr);
211 }
212
214 units::second_t timestamp = 0_s;
215
217 units::meter_t x = 0_m;
218
220 units::meter_t y = 0_m;
221
223 units::radian_t heading = 0_rad;
224
226 units::meters_per_second_t vl = 0_mps;
227
229 units::meters_per_second_t vr = 0_mps;
230
232 units::radians_per_second_t omega = 0_rad_per_s;
233
235 units::meters_per_second_squared_t al = 0_mps_sq;
236
238 units::meters_per_second_squared_t ar = 0_mps_sq;
239
241 units::radians_per_second_squared_t alpha = 0_rad_per_s_sq;
242
244 units::newton_t fl = 0_N;
245
247 units::newton_t fr = 0_N;
248};
249
250void to_json(wpi::json& json, const DifferentialSample& trajectorySample);
251void from_json(const wpi::json& json, DifferentialSample& trajectorySample);
252
253} // namespace choreo
254
255#include "choreo/trajectory/struct/DifferentialSampleStruct.h"
A single differential drive robot sample in a Trajectory.
Definition DifferentialSample.h:28
units::newton_t fl
The force of the left wheels.
Definition DifferentialSample.h:244
units::meter_t y
The Y position of the sample relative to the blue alliance wall origin.
Definition DifferentialSample.h:220
constexpr bool operator==(const DifferentialSample &other) const
Definition DifferentialSample.h:195
units::second_t timestamp
The timestamp of this sample relative to the beginning of the trajectory.
Definition DifferentialSample.h:214
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:49
units::radians_per_second_squared_t alpha
The chassis angular acceleration.
Definition DifferentialSample.h:241
constexpr DifferentialSample Flipped() const
Definition DifferentialSample.h:178
units::radian_t heading
The heading of the sample, with 0 being in the +X direction.
Definition DifferentialSample.h:223
units::newton_t fr
The force of the right wheels.
Definition DifferentialSample.h:247
units::radians_per_second_t omega
The chassis angular velocity.
Definition DifferentialSample.h:232
units::second_t GetTimestamp() const
Definition DifferentialSample.h:74
units::meters_per_second_t vr
The velocity of the right wheels.
Definition DifferentialSample.h:229
constexpr DifferentialSample()=default
Constructs a DifferentialSample that is defaulted.
constexpr frc::Pose2d GetPose() const
Definition DifferentialSample.h:79
constexpr frc::ChassisSpeeds GetChassisSpeeds() const
Definition DifferentialSample.h:86
units::meters_per_second_t vl
The velocity of the left wheels.
Definition DifferentialSample.h:226
units::meters_per_second_squared_t al
The acceleration of the left wheels.
Definition DifferentialSample.h:235
constexpr DifferentialSample OffsetBy(units::second_t timeStampOffset) const
Definition DifferentialSample.h:94
units::meter_t x
The X position of the sample relative to the blue alliance wall origin.
Definition DifferentialSample.h:217
units::meters_per_second_squared_t ar
The acceleration of the right wheels.
Definition DifferentialSample.h:238
DifferentialSample Interpolate(const DifferentialSample &endValue, units::second_t t) const
Definition DifferentialSample.h:114