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"
26template <TrajectorySample SampleType>
39 std::vector<int>
splits, std::vector<EventMarker>
events)
53 bool mirrorForRedAlliance =
false)
const {
57 return mirrorForRedAlliance ?
samples.front().Flipped() :
samples.front();
68 bool mirrorForRedAlliance =
false)
const {
72 return mirrorForRedAlliance ?
samples.back().Flipped() :
samples.back();
84 template <
int Year = util::kDefaultYear>
85 std::optional<SampleType>
SampleAt(units::second_t timestamp,
86 bool mirrorForRedAlliance =
false)
const {
87 if (
auto state = SampleInternal(timestamp)) {
88 return mirrorForRedAlliance ? state.value().template Flipped<Year>()
102 template <
int Year = util::kDefaultYear>
104 bool mirrorForRedAlliance =
false)
const {
108 if (mirrorForRedAlliance) {
109 return samples.front().template Flipped<Year>().GetPose();
111 return samples.front().GetPose();
122 template <
int Year = util::kDefaultYear>
124 bool mirrorForRedAlliance =
false)
const {
128 if (mirrorForRedAlliance) {
129 return samples.back().template Flipped<Year>().GetPose();
131 return samples.back().GetPose();
150 std::vector<frc::Pose2d> poses;
151 for (
const auto& sample :
samples) {
152 poses.push_back(sample.GetPose());
161 template <
int Year = util::kDefaultYear>
163 std::vector<SampleType> flippedStates;
164 for (
const auto& state :
samples) {
165 flippedStates.push_back(state.template Flipped<Year>());
175 std::vector<EventMarker>
GetEvents(std::string_view eventName)
const {
176 std::vector<EventMarker> matchingEvents;
177 for (
const auto& event :
events) {
178 if (event.event == eventName) {
179 matchingEvents.push_back(event);
182 return matchingEvents;
191 std::optional<Trajectory<SampleType>>
GetSplit(
int splitIndex)
const {
193 if (splitIndex < 0 || splitIndex >=
splits.size()) {
197 int start =
splits[splitIndex];
198 int end = (splitIndex + 1 <
splits.size()) ?
splits[splitIndex + 1] + 1
202 std::vector<SampleType>(
samples.begin() + start,
samples.begin() + end);
205 if (sublist.size() == 0) {
207 name +
"[" + std::to_string(splitIndex) +
"]", {}, {}, {}};
210 units::second_t startTime = sublist.front().GetTimestamp();
211 units::second_t endTime = sublist.back().GetTimestamp();
214 sublist | std::views::transform([startTime](
const SampleType& s) {
215 return s.OffsetBy(-startTime);
218 auto filteredEvents =
219 events | std::views::filter([startTime, endTime](
const auto& e) {
220 return e.timestamp >= startTime && e.timestamp <= endTime;
222 std::views::transform(
223 [startTime](
const auto& e) {
return e.OffsetBy(-startTime); });
226 name +
"[" + std::to_string(splitIndex) +
"]",
227 std::vector<SampleType>(offsetSamples.begin(), offsetSamples.end()),
229 std::vector<EventMarker>(filteredEvents.begin(), filteredEvents.end())};
275 std::optional<SampleType> SampleInternal(units::second_t timestamp)
const {
282 if (timestamp <
samples[0].GetTimestamp()) {
292 while (low != high) {
293 int mid = (low + high) / 2;
294 if (
samples[mid].GetTimestamp() < timestamp) {
305 SampleType behindState =
samples[low - 1];
306 SampleType aheadState =
samples[low];
308 if ((aheadState.GetTimestamp() - behindState.GetTimestamp()) < 1e-6_s) {
312 return behindState.Interpolate(aheadState, timestamp);
316void to_json(wpi::json& json,
const Trajectory<SwerveSample>& trajectory);
317void from_json(
const wpi::json& json, Trajectory<SwerveSample>& trajectory);
319void to_json(wpi::json& json,
const Trajectory<DifferentialSample>& trajectory);
320void from_json(
const wpi::json& json,
321 Trajectory<DifferentialSample>& trajectory);
Definition Trajectory.h:27
std::vector< frc::Pose2d > GetPoses() const
Definition Trajectory.h:149
std::vector< SampleType > samples
The vector of samples in the trajectory.
Definition Trajectory.h:266
std::optional< frc::Pose2d > GetInitialPose(bool mirrorForRedAlliance=false) const
Definition Trajectory.h:103
std::string name
The name of the trajectory.
Definition Trajectory.h:263
std::vector< int > splits
The waypoints indexes where the trajectory is split.
Definition Trajectory.h:269
Trajectory(std::string_view name, std::vector< SampleType > samples, std::vector< int > splits, std::vector< EventMarker > events)
Definition Trajectory.h:38
std::optional< frc::Pose2d > GetFinalPose(bool mirrorForRedAlliance=false) const
Definition Trajectory.h:123
std::optional< SampleType > SampleAt(units::second_t timestamp, bool mirrorForRedAlliance=false) const
Definition Trajectory.h:85
Trajectory< SampleType > Flipped() const
Definition Trajectory.h:162
std::optional< SampleType > GetInitialSample(bool mirrorForRedAlliance=false) const
Definition Trajectory.h:52
Trajectory()=default
Constructs a Trajectory with defaults.
units::second_t GetTotalTime() const
Definition Trajectory.h:139
std::optional< SampleType > GetFinalSample(bool mirrorForRedAlliance=false) const
Definition Trajectory.h:67
bool operator==(const Trajectory< SampleType > &other) const
Definition Trajectory.h:236
std::optional< Trajectory< SampleType > > GetSplit(int splitIndex) const
Definition Trajectory.h:191
std::vector< EventMarker > GetEvents(std::string_view eventName) const
Definition Trajectory.h:175
std::vector< EventMarker > events
A vector of all of the events in the trajectory.
Definition Trajectory.h:272