13#include <units/time.h>
14#include <wpi/json_fwd.h>
16#include "choreo/trajectory/DifferentialSample.h"
17#include "choreo/trajectory/EventMarker.h"
18#include "choreo/trajectory/SwerveSample.h"
19#include "choreo/trajectory/TrajectorySample.h"
28template <TrajectorySample SampleType>
45 std::vector<int>
splits, std::vector<EventMarker>
events)
61 bool mirrorForRedAlliance =
false)
const {
65 return mirrorForRedAlliance ?
samples.front().Flipped() :
samples.front();
78 bool mirrorForRedAlliance =
false)
const {
82 return mirrorForRedAlliance ?
samples.back().Flipped() :
samples.back();
96 template <
int Year = util::kDefaultYear>
97 std::optional<SampleType>
SampleAt(units::second_t timestamp,
98 bool mirrorForRedAlliance =
false)
const {
99 if (
auto state = SampleInternal(timestamp)) {
100 return mirrorForRedAlliance ? state.value().template Flipped<Year>()
116 template <
int Year = util::kDefaultYear>
118 bool mirrorForRedAlliance =
false)
const {
122 if (mirrorForRedAlliance) {
123 return samples.front().template Flipped<Year>().GetPose();
125 return samples.front().GetPose();
138 template <
int Year = util::kDefaultYear>
140 bool mirrorForRedAlliance =
false)
const {
144 if (mirrorForRedAlliance) {
145 return samples.back().template Flipped<Year>().GetPose();
147 return samples.back().GetPose();
170 std::vector<frc::Pose2d> poses;
171 for (
const auto& sample :
samples) {
172 poses.push_back(sample.GetPose());
183 template <
int Year = util::kDefaultYear>
185 std::vector<SampleType> flippedStates;
186 for (
const auto& state :
samples) {
187 flippedStates.push_back(state.template Flipped<Year>());
199 std::vector<EventMarker>
GetEvents(std::string_view eventName)
const {
200 std::vector<EventMarker> matchingEvents;
201 for (
const auto& event :
events) {
202 if (event.event == eventName) {
203 matchingEvents.push_back(event);
206 return matchingEvents;
217 std::optional<Trajectory<SampleType>>
GetSplit(
int splitIndex)
const {
219 if (splitIndex < 0 || splitIndex >=
splits.size()) {
223 int start =
splits[splitIndex];
224 int end = (splitIndex + 1 <
splits.size()) ?
splits[splitIndex + 1] + 1
228 std::vector<SampleType>(
samples.begin() + start,
samples.begin() + end);
231 if (sublist.size() == 0) {
233 name +
"[" + std::to_string(splitIndex) +
"]", {}, {}, {}};
236 units::second_t startTime = sublist.front().GetTimestamp();
237 units::second_t endTime = sublist.back().GetTimestamp();
240 sublist | std::views::transform([startTime](
const SampleType& s) {
241 return s.OffsetBy(-startTime);
244 auto filteredEvents =
245 events | std::views::filter([startTime, endTime](
const auto& e) {
246 return e.timestamp >= startTime && e.timestamp <= endTime;
248 std::views::transform(
249 [startTime](
const auto& e) {
return e.OffsetBy(-startTime); });
252 name +
"[" + std::to_string(splitIndex) +
"]",
253 std::vector<SampleType>(offsetSamples.begin(), offsetSamples.end()),
255 std::vector<EventMarker>(filteredEvents.begin(), filteredEvents.end())};
303 std::optional<SampleType> SampleInternal(units::second_t timestamp)
const {
310 if (timestamp <
samples[0].GetTimestamp()) {
320 while (low != high) {
321 int mid = (low + high) / 2;
322 if (
samples[mid].GetTimestamp() < timestamp) {
333 SampleType behindState =
samples[low - 1];
334 SampleType aheadState =
samples[low];
336 if ((aheadState.GetTimestamp() - behindState.GetTimestamp()) < 1e-6_s) {
340 return behindState.Interpolate(aheadState, timestamp);
344void to_json(wpi::json& json,
const Trajectory<SwerveSample>& trajectory);
345void from_json(
const wpi::json& json, Trajectory<SwerveSample>& trajectory);
347void to_json(wpi::json& json,
const Trajectory<DifferentialSample>& trajectory);
348void from_json(
const wpi::json& json,
349 Trajectory<DifferentialSample>& trajectory);
Definition Trajectory.h:29
std::vector< frc::Pose2d > GetPoses() const
Definition Trajectory.h:169
std::vector< SampleType > samples
The vector of samples in the trajectory.
Definition Trajectory.h:294
std::optional< frc::Pose2d > GetInitialPose(bool mirrorForRedAlliance=false) const
Definition Trajectory.h:117
std::string name
The name of the trajectory.
Definition Trajectory.h:291
std::vector< int > splits
The waypoints indexes where the trajectory is split.
Definition Trajectory.h:297
Trajectory(std::string_view name, std::vector< SampleType > samples, std::vector< int > splits, std::vector< EventMarker > events)
Definition Trajectory.h:44
std::optional< frc::Pose2d > GetFinalPose(bool mirrorForRedAlliance=false) const
Definition Trajectory.h:139
std::optional< SampleType > SampleAt(units::second_t timestamp, bool mirrorForRedAlliance=false) const
Definition Trajectory.h:97
Trajectory< SampleType > Flipped() const
Definition Trajectory.h:184
std::optional< SampleType > GetInitialSample(bool mirrorForRedAlliance=false) const
Definition Trajectory.h:60
units::second_t GetTotalTime() const
Definition Trajectory.h:157
std::optional< SampleType > GetFinalSample(bool mirrorForRedAlliance=false) const
Definition Trajectory.h:77
bool operator==(const Trajectory< SampleType > &other) const
Definition Trajectory.h:264
std::optional< Trajectory< SampleType > > GetSplit(int splitIndex) const
Definition Trajectory.h:217
std::vector< EventMarker > GetEvents(std::string_view eventName) const
Definition Trajectory.h:199
std::vector< EventMarker > events
A vector of all of the events in the trajectory.
Definition Trajectory.h:300