59 T min_value = std::numeric_limits<T>::quiet_NaN(),
60 T max_value = std::numeric_limits<T>::quiet_NaN(),
61 T min_first_derivative_neg = std::numeric_limits<T>::quiet_NaN(),
62 T max_first_derivative_pos = std::numeric_limits<T>::quiet_NaN(),
63 T min_first_derivative_pos = std::numeric_limits<T>::quiet_NaN(),
64 T max_first_derivative_neg = std::numeric_limits<T>::quiet_NaN(),
65 T min_second_derivative = std::numeric_limits<T>::quiet_NaN(),
66 T max_second_derivative = std::numeric_limits<T>::quiet_NaN());
76 T
limit(T & v, T v0, T v1, T dt);
126 T min_value = std::numeric_limits<T>::quiet_NaN(),
127 T max_value = std::numeric_limits<T>::quiet_NaN(),
128 T min_first_derivative_neg = std::numeric_limits<T>::quiet_NaN(),
129 T max_first_derivative_pos = std::numeric_limits<T>::quiet_NaN(),
130 T min_first_derivative_pos = std::numeric_limits<T>::quiet_NaN(),
131 T max_first_derivative_neg = std::numeric_limits<T>::quiet_NaN(),
132 T min_second_derivative = std::numeric_limits<T>::quiet_NaN(),
133 T max_second_derivative = std::numeric_limits<T>::quiet_NaN());
137 bool has_value_limits_ =
true;
138 bool has_first_derivative_limits_ =
true;
139 bool has_second_derivative_limits_ =
true;
142 T min_value_ = std::numeric_limits<T>::quiet_NaN();
143 T max_value_ = std::numeric_limits<T>::quiet_NaN();
146 T min_first_derivative_neg_ = std::numeric_limits<T>::quiet_NaN();
147 T max_first_derivative_pos_ = std::numeric_limits<T>::quiet_NaN();
148 T min_first_derivative_pos_ = std::numeric_limits<T>::quiet_NaN();
149 T max_first_derivative_neg_ = std::numeric_limits<T>::quiet_NaN();
152 T min_second_derivative_ = std::numeric_limits<T>::quiet_NaN();
153 T max_second_derivative_ = std::numeric_limits<T>::quiet_NaN();
158 T min_value, T max_value,
159 T min_first_derivative_neg, T max_first_derivative_pos,
160 T min_first_derivative_pos, T max_first_derivative_neg,
161 T min_second_derivative, T max_second_derivative)
164 min_value, max_value,
165 min_first_derivative_neg, max_first_derivative_pos,
166 min_first_derivative_pos, max_first_derivative_neg,
167 min_second_derivative, max_second_derivative
174 T min_value, T max_value,
175 T min_first_derivative_neg, T max_first_derivative_pos,
176 T min_first_derivative_pos, T max_first_derivative_neg,
177 T min_second_derivative, T max_second_derivative)
179 min_value_ = min_value;
180 max_value_ = max_value;
181 min_first_derivative_neg_ = min_first_derivative_neg;
182 max_first_derivative_pos_ = max_first_derivative_pos;
183 min_first_derivative_pos_ = min_first_derivative_pos;
184 max_first_derivative_neg_ = max_first_derivative_neg;
185 min_second_derivative_ = min_second_derivative;
186 max_second_derivative_ = max_second_derivative;
188 if (std::isnan(max_value_))
190 has_value_limits_ =
false;
192 if (std::isnan(min_value_))
194 min_value_ = -max_value_;
196 if (has_value_limits_ && min_value_ > max_value_)
198 throw std::invalid_argument(
"Invalid value limits");
201 if (std::isnan(max_first_derivative_pos_))
203 has_first_derivative_limits_ =
false;
205 if (std::isnan(min_first_derivative_neg_))
207 min_first_derivative_neg_ = -max_first_derivative_pos_;
209 if (has_first_derivative_limits_ && min_first_derivative_neg_ > max_first_derivative_pos_)
211 throw std::invalid_argument(
"Invalid first derivative limits");
213 if (has_first_derivative_limits_)
215 if (std::isnan(max_first_derivative_neg_))
217 max_first_derivative_neg_ = max_first_derivative_pos_;
219 if (std::isnan(min_first_derivative_pos_))
221 min_first_derivative_pos_ = min_first_derivative_neg_;
223 if (has_first_derivative_limits_ && min_first_derivative_pos_ > max_first_derivative_neg_)
225 throw std::invalid_argument(
"Invalid first derivative limits");
229 if (std::isnan(max_second_derivative_))
231 has_second_derivative_limits_ =
false;
233 if (std::isnan(min_second_derivative_))
235 min_second_derivative_ = -max_second_derivative_;
237 if (has_second_derivative_limits_ && min_second_derivative_ > max_second_derivative_)
239 throw std::invalid_argument(
"Invalid second derivative limits");
248 limit_second_derivative(v, v0, v1, dt);
249 limit_first_derivative(v, v0, dt);
252 return tmp !=
static_cast<T
>(0.0) ? v / tmp :
static_cast<T
>(1.0);
273 if (has_first_derivative_limits_)
275 T dv_max, dv_min = 0;
276 if (v0 >
static_cast<T
>(0.0))
278 dv_max = max_first_derivative_pos_ * dt;
279 dv_min = min_first_derivative_pos_ * dt;
281 else if (v0 <
static_cast<T
>(0.0))
283 dv_min = min_first_derivative_neg_ * dt;
284 dv_max = max_first_derivative_neg_ * dt;
288 dv_min = min_first_derivative_neg_ * dt;
289 dv_max = max_first_derivative_pos_ * dt;
291 const T dv = std::clamp(v - v0, dv_min, dv_max);
296 return tmp !=
static_cast<T
>(0.0) ? v / tmp :
static_cast<T
>(1.0);
304 if (has_second_derivative_limits_)
307 const T dv0 = v0 - v1;
312 if ((dv - dv0) * (v - v0) > 0)
314 const T dt2 = dt * dt;
316 const T da_min = min_second_derivative_ * dt2;
317 const T da_max = max_second_derivative_ * dt2;
319 const T da = std::clamp(dv - dv0, da_min, da_max);
325 return tmp !=
static_cast<T
>(0.0) ? v / tmp :
static_cast<T
>(1.0);