13 #include <Eigen/Eigen> 31 typedef Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 10> Vector;
40 double initial_acceleration,
41 double initial_velocity,
42 double initial_position)
45 initial_acceleration_ = initial_acceleration;
46 initial_velocity_ = initial_velocity;
47 initial_position_= initial_position;
52 initial_acceleration_;
56 return jerk_ * 0.5 * t * t +
57 initial_acceleration_ * t +
62 return jerk_ * 0.5 * 1./3. * t * t * t +
63 initial_acceleration_ * 0.5 * t * t +
64 initial_velocity_ * t +
68 Vector find_t_given_velocity(
double velocity)
const 70 double a = jerk_ * 0.5;
71 double b = initial_acceleration_;
72 double c = initial_velocity_ - velocity;
74 double determinant = b * b - 4 * a * c;
76 Vector solutions(Vector::Index(0));
82 solutions[0] = - c / b;
86 else if(determinant == 0)
89 solutions[0] = -b / 2 / a;
91 else if(determinant > 0)
93 double determinant_sqrt = std::sqrt(determinant);
95 solutions[0] = (-b + determinant_sqrt) / 2 / a;
96 solutions[1] = (-b - determinant_sqrt) / 2 / a;
99 Vector positive_solutions(Vector::Index(0));
100 for(
size_t i = 0; i < solutions.size(); i++)
102 if(solutions[i] >= 0)
104 mct::append_to_vector(positive_solutions, solutions[i]);
108 return positive_solutions;
113 double initial_acceleration_;
114 double initial_velocity_;
115 double initial_position_;
127 void print_parameters()
const 129 std::cout <<
"-------------------------------------------" << std::endl;
130 std::cout <<
"jerk: " << jerk_ << std::endl
131 <<
"initial_acceleration: " << initial_acceleration_ << std::endl
132 <<
"initial_velocity: " << initial_velocity_ << std::endl
133 <<
"initial_position: " << initial_position_ << std::endl
134 <<
"acceleration_limit: " << acceleration_limit_ << std::endl
135 <<
"jerk_duration: " << jerk_duration_ << std::endl;
136 std::cout <<
"-------------------------------------------" << std::endl;
139 typedef LinearDynamics::Vector Vector;
141 typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 0, 10, 10>
153 double initial_acceleration,
154 double initial_velocity,
155 double initial_position,
158 initial_acceleration,
163 acceleration_limit_ = abs_acceleration_limit;
165 acceleration_limit_ = -abs_acceleration_limit;
167 set_initial_acceleration(initial_acceleration);
171 void set_initial_acceleration(
double initial_acceleration)
173 if(std::fabs(initial_acceleration) > std::fabs(acceleration_limit_))
174 throw std::invalid_argument(
"expected " 175 "std::fabs(initial_acceleration) > " 176 "abs_acceleration_limit");
177 initial_acceleration_ = initial_acceleration;
179 (acceleration_limit_ - initial_acceleration_) / jerk_;
184 if(t < jerk_duration_)
186 return LinearDynamics::get_acceleration(t);
190 return acceleration_limit_;
195 if(t < jerk_duration_)
197 return LinearDynamics::get_velocity(t);
201 return LinearDynamics::get_velocity(jerk_duration_) +
202 acceleration_limit_ * (t - jerk_duration_);
207 if(t < jerk_duration_)
209 return LinearDynamics::get_position(t);
213 return LinearDynamics::get_position(jerk_duration_) +
214 LinearDynamics::get_velocity(jerk_duration_) * (t - jerk_duration_) +
215 acceleration_limit_ * 0.5 * (t - jerk_duration_) * (t - jerk_duration_);
219 template<
typename Array>
220 Array get_positions(
const Array& times)
const 222 Array positions(times.size());
223 for(
size_t i = 0; i < times.size(); i++)
225 positions[i] = get_position(times[i]);
230 Vector find_t_given_velocity(
double velocity)
const 232 Vector potential_solutions =
233 LinearDynamics::find_t_given_velocity(velocity);
235 Vector solutions(Vector::Index(0));
236 for(
size_t i = 0; i < potential_solutions.size(); i++)
238 if(potential_solutions[i] <= jerk_duration_)
240 mct::append_to_vector(solutions, potential_solutions[i]);
244 double potential_solution = jerk_duration_
245 + (velocity - LinearDynamics::get_velocity(jerk_duration_))
246 / acceleration_limit_;
247 if(potential_solution > jerk_duration_ &&
248 !(mct::contains(solutions, jerk_duration_) &&
249 mct::approx_equal(potential_solution, jerk_duration_)))
251 mct::append_to_vector(solutions, potential_solution);
256 if(solutions.size() > 2)
258 std::cout <<
"too many solutions, something went wrong!!!" 262 std::cout <<
"potential_solutions[0]: " << potential_solutions[0] << std::endl;
264 std::cout <<
"potential_solutions size: " << potential_solutions.size() <<
" content: " << potential_solutions.transpose() << std::endl;
267 std::cout <<
"solutions size: " << solutions.size() <<
" content: " << solutions.transpose() << std::endl;
273 bool will_exceed_jointly(
const double& max_velocity,
274 const double& max_position)
const 276 double certificate_time;
277 return will_exceed_jointly(max_velocity, max_position, certificate_time);
282 const double& max_position,
283 double& certificate_time)
const 285 if(max_velocity == std::numeric_limits<double>::infinity() ||
286 max_position == std::numeric_limits<double>::infinity())
292 certificate_time = std::numeric_limits<double>::infinity();
297 throw std::domain_error(
"not implemented for jerk == 0");
311 if(initial_velocity_ > max_velocity &&
312 initial_position_ > max_position)
314 certificate_time = 0;
318 Vector t_given_zero_velocity = find_t_given_velocity(0);
319 if(t_given_zero_velocity.size() > 0)
321 Vector position_given_zero_velocity =
322 get_positions(t_given_zero_velocity);
324 Vector::Index max_index;
325 double max_achieved_position =
326 position_given_zero_velocity.maxCoeff(&max_index);
327 if(max_achieved_position < max_position)
333 certificate_time = t_given_zero_velocity[max_index];
338 Vector t_given_max_velocity =
339 find_t_given_velocity(max_velocity);
340 Vector position_given_max_velocity =
341 get_positions(t_given_max_velocity);
343 for(
size_t i = 0; i < position_given_max_velocity.size(); i++)
345 if(position_given_max_velocity[i] > max_position)
347 certificate_time = t_given_max_velocity[i];
356 bool will_deceed_jointly(
const double& min_velocity,
357 const double& min_position)
const 359 double certificate_time;
360 return will_deceed_jointly(min_velocity, min_position, certificate_time);
363 bool will_deceed_jointly(
const double& min_velocity,
364 const double& min_position,
365 double& certificate_time)
const 368 flipped_dynamics(-jerk_,
369 -initial_acceleration_,
372 std::fabs(acceleration_limit_));
374 return flipped_dynamics.will_exceed_jointly(-min_velocity,
381 double acceleration_limit_;
388 const double& initial_velocity,
389 const double& initial_position,
390 const double& max_velocity,
391 const double& max_position,
395 double lower = -abs_acceleration_limit;
396 double upper = abs_acceleration_limit;
403 abs_acceleration_limit);
406 if(dynamics.will_exceed_jointly(max_velocity, max_position))
412 dynamics.set_initial_acceleration(upper);
413 if(!dynamics.will_exceed_jointly(max_velocity, max_position))
418 for(
size_t i = 0; i < 20; i++)
420 double middle = (lower + upper) / 2.0;
422 dynamics.set_initial_acceleration(middle);
423 if(dynamics.will_exceed_jointly(max_velocity, max_position))
437 double find_min_admissible_acceleration(
438 const double& initial_velocity,
439 const double& initial_position,
440 const double& min_velocity,
441 const double& min_position,
450 abs_acceleration_limit);
460 min_velocity_ = -std::numeric_limits<double>::infinity();
461 min_position_ = -std::numeric_limits<double>::infinity();
462 max_velocity_ = std::numeric_limits<double>::infinity();
463 max_position_ = std::numeric_limits<double>::infinity();
477 min_velocity_ = min_velocity;
478 min_position_ = min_position;
479 max_velocity_ = max_velocity;
480 max_position_ = max_position;
481 max_torque_ = max_torque;
482 max_jerk_ = max_jerk;
487 double get_safe_torque(
const double& torque,
488 const double& velocity,
489 const double& position)
491 double safe_torque = mct::clamp(torque, -max_torque_, max_torque_);
501 double max_admissible_acc =
508 double max_admissible_torque = max_admissible_acc * inertia_;
530 double min_admissible_acc =
531 find_min_admissible_acceleration(velocity,
537 double min_admissible_torque = min_admissible_acc * inertia_;
544 if(min_admissible_torque > max_admissible_torque)
546 std::cout <<
"min_admissible_torque > max_admissible_torque!!!!" 551 safe_torque = mct::clamp(safe_torque,
552 min_admissible_torque, max_admissible_torque);
555 if(safe_torque > max_torque_ || safe_torque < -max_torque_)
557 std::cout <<
"something went horribly horribly wrong " << std::endl;
564 double min_velocity_;
565 double min_position_;
566 double max_velocity_;
567 double max_position_;
Definition: basic_tools.hpp:14
double find_max_admissible_acceleration(const double &initial_velocity, const double &initial_position, const double &max_velocity, const double &max_position, const mct::NonnegDouble &abs_jerk_limit, const mct::NonnegDouble &abs_acceleration_limit)
Definition: dynamical_systems.hpp:387
Definition: dynamical_systems.hpp:28
bool will_exceed_jointly(const double &max_velocity, const double &max_position, double &certificate_time) const
Definition: dynamical_systems.hpp:281
Definition: basic_tools.hpp:17
Definition: dynamical_systems.hpp:455
Definition: dynamical_systems.hpp:123