RIT VEXU Core API
Loading...
Searching...
No Matches
math/trajectories/trapezoid_profile.h
1#pragma once
2
3#include <cmath>
4
5// Struct representing a state along the motion profile containing position, velocity and acceleration.
6typedef struct {
7 double pos; // 1D position
8 double vel; // 1D velocity
9 double acc; // 1D acceleration
10} motion_t;
11
15typedef struct {
16 double v_max = 1.0; // Maximum velocity
17 double accel = 1.0; // Acceleration
18 double decel = 1.0; // Deceleration (typically equal to accel)
20
33class TrapezoidProfile {
34 public:
44 TrapezoidProfile::TrapezoidProfile(const double& x_initial,
45 const double& x_target,
46 const double& v_max, const double& accel,
47 const double& decel)
48 : x_initial_(x_initial),
49 x_target_(x_target),
50 v_max_(v_max),
51 accel_(accel),
52 decel_(decel),
53 distance_(x_target - x_initial) {
54 direction_ = distance_ > 0 ? 1 : -1;
55 dist_accel_ = 0.5 * (v_max_ * v_max_) / accel_;
56 dist_decel_ = 0.5 * (v_max_ * v_max_) / decel_;
57 dist_full_ = dist_accel_ + dist_decel_;
58
59 if (std::abs(distance_) > dist_full_) {
60 // if the velocity graph is trapezoidal we use max velocity and set cruise time and distance
61 triangular_ = false;
62 time_accel_ = v_max_ / accel_;
63 time_decel_ = v_max_ / decel_;
64 dist_cruise_ = std::abs(distance_) - dist_full_;
65 time_cruise_ = dist_cruise_ / v_max_;
66 time_total_ = time_accel_ + time_cruise_ + time_decel_;
67 } else {
68 // if the velocity graph is triangular we compute the peak velocity, and don't use cruise time or distance
69 triangular_ = true;
70 v_peak_ = sqrt((2 * std::abs(distance_) * accel_ * decel_) /
71 (accel_ + decel_));
72 time_accel_ = v_peak_ / accel_;
73 time_decel_ = v_peak_ / decel_;
74 time_cruise_ = 0.0;
75 time_total_ = time_accel_ + time_decel_;
76 }
77 }
78
86 motion_t TrapezoidProfile::calculate(double t) {
87 // clamp the input time to within the timeframe of the motion profile
88 if (t < 0) {
89 t = 0;
90 } else if (t > time_total_) {
91 t = time_total_;
92 }
93
94 double pos_local;
95 double vel_local;
96 double acc_local;
97
98 // acceleration phase
99 if (t < time_accel_) {
100 pos_local = 0.5 * accel_ * (t * t);
101 vel_local = accel_ * t;
102 acc_local = accel_;
103 // cruise phase only if it's not triangular
104 } else if (!triangular_ && (t < time_accel_ + time_cruise_)) {
105 pos_local = dist_accel_ + v_max_ * (t - time_accel_);
106 vel_local = v_max_;
107 acc_local = 0.0;
108 // deceleration phase
109 } else {
110 double time_deceled;
111 if (triangular_) {
112 time_deceled = t - time_accel_;
113 pos_local = (0.5 * accel_ * (time_accel_ * time_accel_)) +
114 (v_peak_ * time_deceled) -
115 (0.5 * decel_ * (time_deceled * time_deceled));
116 vel_local = v_peak_ - (decel_ * time_deceled);
117 acc_local = -decel_;
118 } else {
119 time_deceled = t - (time_accel_ + time_cruise_);
120 pos_local = dist_accel_ +
121 (v_max_ * (time_cruise_ + time_deceled)) -
122 (0.5 * decel_ * (time_deceled * time_deceled));
123 vel_local = v_max_ - (decel_ * time_deceled);
124 acc_local = -decel_;
125 }
126 }
127
128 double pos = x_initial_ + (direction_ * pos_local);
129 double vel = direction_ * vel_local;
130 double acc = direction_ * acc_local;
131 return motion_t{pos, vel, acc};
132 }
133
139 double TrapezoidProfile::total_time() { return time_total_; }
140
141 private:
142 double x_initial_;
143 double x_target_;
144 double v_max_;
145 double v_peak_;
146 double accel_;
147 double decel_;
148 double distance_;
149 double dist_accel_;
150 double dist_decel_;
151 double dist_cruise_;
152 double dist_full_;
153
154 double time_accel_;
155 double time_decel_;
156 double time_cruise_;
157 double time_total_;
158
159 bool triangular_;
160
161 // 1 if positive, -1 if negative
162 int direction_;
163};
Definition core/utils/controls/trapezoid_profile.h:25
TrapezoidProfile(const double &x_initial, const double &x_target, const double &v_max, const double &accel, const double &decel)
Definition trapezoid_profile.cpp:14
double total_time()
Definition trapezoid_profile.cpp:99
motion_t calculate(double t)
Definition trapezoid_profile.cpp:48
Definition math/trajectories/trapezoid_profile.h:15