WPILibC++ 2024.1.1-beta-4
ExponentialProfile.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include "units/time.h"
9
10namespace frc {
11
12/**
13 * A Exponential-shaped velocity profile.
14 *
15 * While this class can be used for a profiled movement from start to finish,
16 * the intended usage is to filter a reference's dynamics based on
17 * ExponentialProfile velocity constraints. To compute the reference obeying
18 * this constraint, do the following.
19 *
20 * Initialization:
21 * @code{.cpp}
22 * ExponentialProfile::Constraints constraints{kMaxV, kV, kA};
23 * State previousProfiledReference = {initialReference, 0_mps};
24 * @endcode
25 *
26 * Run on update:
27 * @code{.cpp}
28 * previousProfiledReference = profile.Calculate(timeSincePreviousUpdate,
29 * previousProfiledReference, unprofiledReference);
30 * @endcode
31 *
32 * where `unprofiledReference` is free to change between calls. Note that when
33 * the unprofiled reference is within the constraints, `Calculate()` returns the
34 * unprofiled reference unchanged.
35 *
36 * Otherwise, a timer can be started to provide monotonic values for
37 * `Calculate()` and to determine when the profile has completed via
38 * `IsFinished()`.
39 */
40template <class Distance, class Input>
42 public:
44 using Velocity =
51 using B_t =
57
59 public:
61 : maxInput{maxInput}, A{A}, B{B} {}
63 : maxInput{maxInput}, A{-kV / kA}, B{1 / kA} {}
64 Velocity_t MaxVelocity() const { return -maxInput * B / A; }
65
67 A_t A{0};
68 B_t B{0};
69 };
70
71 class State {
72 public:
75 bool operator==(const State&) const = default;
76 };
77
79 public:
80 units::second_t inflectionTime;
81 units::second_t totalTime;
82
83 bool IsFinished(const units::second_t& time) const {
84 return time > totalTime;
85 }
86 };
87
88 /**
89 * Construct a ExponentialProfile.
90 *
91 * @param constraints The constraints on the profile, like maximum input.
92 */
93 explicit ExponentialProfile(Constraints constraints);
94
99
100 /**
101 * Calculate the correct position and velocity for the profile at a time t
102 * where the current state is at time t = 0.
103 */
104 State Calculate(const units::second_t& t, const State& current,
105 const State& goal) const;
106
107 /**
108 * Calculate the point after which the fastest way to reach the goal state is
109 * to apply input in the opposite direction.
110 */
111 State CalculateInflectionPoint(const State& current, const State& goal) const;
112
113 /**
114 * Calculate the time it will take for this profile to reach the goal state.
115 */
116 units::second_t TimeLeftUntil(const State& current, const State& goal) const;
117
118 /**
119 * Calculate the time it will take for this profile to reach the inflection
120 * point, and the time it will take for this profile to reach the goal state.
121 */
123 const State& goal) const;
124
125 private:
126 /**
127 * Calculate the point after which the fastest way to reach the goal state is
128 * to apply input in the opposite direction.
129 */
130 State CalculateInflectionPoint(const State& current, const State& goal,
131 const Input_t& input) const;
132
133 /**
134 * Calculate the time it will take for this profile to reach the inflection
135 * point, and the time it will take for this profile to reach the goal state.
136 */
138 const State& inflectionPoint,
139 const State& goal,
140 const Input_t& input) const;
141
142 /**
143 * Calculate the velocity reached after t seconds when applying an input from
144 * the initial state.
145 */
146 Velocity_t ComputeVelocityFromTime(const units::second_t& time,
147 const Input_t& input,
148 const State& initial) const;
149
150 /**
151 * Calculate the position reached after t seconds when applying an input from
152 * the initial state.
153 */
154 Distance_t ComputeDistanceFromTime(const units::second_t& time,
155 const Input_t& input,
156 const State& initial) const;
157
158 /**
159 * Calculate the distance reached at the same time as the given velocity when
160 * applying the given input from the initial state.
161 */
162 Distance_t ComputeDistanceFromVelocity(const Velocity_t& velocity,
163 const Input_t& input,
164 const State& initial) const;
165
166 /**
167 * Calculate the time required to reach a specified velocity given the initial
168 * velocity.
169 */
170 units::second_t ComputeTimeFromVelocity(const Velocity_t& velocity,
171 const Input_t& input,
172 const Velocity_t& initial) const;
173
174 /**
175 * Calculate the velocity at which input should be reversed in order to reach
176 * the goal state from the current state.
177 */
178 Velocity_t SolveForInflectionVelocity(const Input_t& input,
179 const State& current,
180 const State& goal) const;
181
182 /**
183 * Returns true if the profile should be inverted.
184 *
185 * <p>The profile is inverted if we should first apply negative input in order
186 * to reach the goal state.
187 */
188 bool ShouldFlipInput(const State& current, const State& goal) const;
189
190 Constraints m_constraints;
191};
192} // namespace frc
193
194#include "ExponentialProfile.inc"
Definition: ExponentialProfile.h:58
Input_t maxInput
Definition: ExponentialProfile.h:66
A_t A
Definition: ExponentialProfile.h:67
Constraints(Input_t maxInput, A_t A, B_t B)
Definition: ExponentialProfile.h:60
Constraints(Input_t maxInput, kV_t kV, kA_t kA)
Definition: ExponentialProfile.h:62
Velocity_t MaxVelocity() const
Definition: ExponentialProfile.h:64
B_t B
Definition: ExponentialProfile.h:68
Definition: ExponentialProfile.h:78
units::second_t totalTime
Definition: ExponentialProfile.h:81
units::second_t inflectionTime
Definition: ExponentialProfile.h:80
bool IsFinished(const units::second_t &time) const
Definition: ExponentialProfile.h:83
Definition: ExponentialProfile.h:71
bool operator==(const State &) const =default
Distance_t position
Definition: ExponentialProfile.h:73
Velocity_t velocity
Definition: ExponentialProfile.h:74
A Exponential-shaped velocity profile.
Definition: ExponentialProfile.h:41
units::second_t TimeLeftUntil(const State &current, const State &goal) const
Calculate the time it will take for this profile to reach the goal state.
Definition: ExponentialProfile.inc:71
ExponentialProfile(const ExponentialProfile &)=default
State Calculate(const units::second_t &t, const State &current, const State &goal) const
Calculate the correct position and velocity for the profile at a time t where the current state is at...
Definition: ExponentialProfile.inc:21
ProfileTiming CalculateProfileTiming(const State &current, const State &goal) const
Calculate the time it will take for this profile to reach the inflection point, and the time it will ...
Definition: ExponentialProfile.inc:80
units::compound_unit< Distance, units::inverse< units::seconds > > Velocity
Definition: ExponentialProfile.h:45
ExponentialProfile & operator=(ExponentialProfile &&)=default
units::compound_unit< Input, units::inverse< Acceleration > > KA
Definition: ExponentialProfile.h:55
ExponentialProfile & operator=(const ExponentialProfile &)=default
ExponentialProfile(ExponentialProfile &&)=default
ExponentialProfile(Constraints constraints)
Construct a ExponentialProfile.
Definition: ExponentialProfile.inc:16
units::compound_unit< Input, units::inverse< Velocity > > KV
Definition: ExponentialProfile.h:53
units::compound_unit< Velocity, units::inverse< units::seconds > > Acceleration
Definition: ExponentialProfile.h:48
State CalculateInflectionPoint(const State &current, const State &goal) const
Calculate the point after which the fastest way to reach the goal state is to apply input in the oppo...
Definition: ExponentialProfile.inc:45
typename units::detail::compound_impl< U, Us... >::type compound_unit
Represents a unit type made up from other units.
Definition: base.h:1446
Definition: AprilTagPoseEstimator.h:15