46 static void fit_cubic_spline(
const int n,
const double dt[],
const double x[],
double x1[],
double x2[]);
47 static void adjust_two_positions(
const int n,
const double dt[],
double x[],
double x1[],
double x2[],
48 const double x2_i,
const double x2_f);
49 static void init_times(
const int n,
double dt[],
const double x[],
const double max_velocity,
const double min_velocity);
51 const double min_velocity,
const double max_acceleration,
52 const double min_acceleration);
68 void globalAdjustment(std::vector<SingleJointTrajectory>& t2,
int num_joints,
const int num_points,
69 std::vector<double>& time_diff);
76 const double max_velocity_scaling_factor,
77 const double max_acceleration_scaling_factor)
const
79 if (trajectory.
empty())
85 ROS_ERROR_NAMED(
"trajectory_processing.iterative_spline_parameterization",
"It looks like the planner did not set "
86 "the group the plan was computed for");
92 double velocity_scaling_factor = 1.0;
93 double acceleration_scaling_factor = 1.0;
98 if (max_velocity_scaling_factor > 0.0 && max_velocity_scaling_factor <= 1.0)
99 velocity_scaling_factor = max_velocity_scaling_factor;
100 else if (max_velocity_scaling_factor == 0.0)
101 ROS_DEBUG_NAMED(
"trajectory_processing.iterative_spline_parameterization",
102 "A max_velocity_scaling_factor of 0.0 was specified, defaulting to %f instead.",
103 velocity_scaling_factor);
105 ROS_WARN_NAMED(
"trajectory_processing.iterative_spline_parameterization",
106 "Invalid max_velocity_scaling_factor %f specified, defaulting to %f instead.",
107 max_velocity_scaling_factor, velocity_scaling_factor);
109 if (max_acceleration_scaling_factor > 0.0 && max_acceleration_scaling_factor <= 1.0)
110 acceleration_scaling_factor = max_acceleration_scaling_factor;
111 else if (max_acceleration_scaling_factor == 0.0)
112 ROS_DEBUG_NAMED(
"trajectory_processing.iterative_spline_parameterization",
113 "A max_acceleration_scaling_factor of 0.0 was specified, defaulting to %f instead.",
114 acceleration_scaling_factor);
116 ROS_WARN_NAMED(
"trajectory_processing.iterative_spline_parameterization",
117 "Invalid max_acceleration_scaling_factor %f specified, defaulting to %f instead.",
118 max_acceleration_scaling_factor, acceleration_scaling_factor);
130 moveit::core::RobotStatePtr p0, p1;
135 for (
unsigned int j = 0; j < num_joints; j++)
137 point.setVariablePosition(idx[j],
138 (9 * p0->getVariablePosition(idx[j]) + 1 * p1->getVariablePosition(idx[j])) / 10);
146 for (
unsigned int j = 0; j < num_joints; j++)
148 point.setVariablePosition(idx[j],
149 (1 * p0->getVariablePosition(idx[j]) + 9 * p1->getVariablePosition(idx[j])) / 10);
160 std::vector<SingleJointTrajectory> t2(num_joints);
162 for (
unsigned int j = 0; j < num_joints; j++)
165 t2[j].positions_.resize(num_points, 0.0);
166 for (
unsigned int i = 0; i < num_points; i++)
168 t2[j].positions_[i] = trajectory.
getWayPointPtr(i)->getVariablePosition(idx[j]);
172 t2[j].velocities_.resize(num_points, 0.0);
175 t2[j].velocities_[0] = trajectory.
getWayPointPtr(0)->getVariableVelocity(idx[j]);
177 t2[j].velocities_[num_points - 1] = trajectory.
getWayPointPtr(num_points - 1)->getVariableVelocity(idx[j]);
180 t2[j].accelerations_.resize(num_points, 0.0);
181 t2[j].initial_acceleration_ = 0.0;
182 t2[j].final_acceleration_ = 0.0;
185 t2[j].initial_acceleration_ = trajectory.
getWayPointPtr(0)->getVariableAcceleration(idx[j]);
186 t2[j].accelerations_[0] = t2[j].initial_acceleration_;
187 if (trajectory.
getWayPointPtr(num_points - 1)->hasAccelerations())
188 t2[j].final_acceleration_ = trajectory.
getWayPointPtr(num_points - 1)->getVariableAcceleration(idx[j]);
189 t2[j].accelerations_[num_points - 1] = t2[j].final_acceleration_;
194 t2[j].min_velocity_ = -
VLIMIT;
199 if (t2[j].min_velocity_ == 0.0)
200 t2[j].min_velocity_ = -t2[j].max_velocity_;
202 t2[j].max_velocity_ *= velocity_scaling_factor;
203 t2[j].min_velocity_ *= velocity_scaling_factor;
205 t2[j].max_acceleration_ =
ALIMIT;
206 t2[j].min_acceleration_ = -
ALIMIT;
211 if (t2[j].min_acceleration_ == 0.0)
212 t2[j].min_acceleration_ = -t2[j].max_acceleration_;
214 t2[j].max_acceleration_ *= acceleration_scaling_factor;
215 t2[j].min_acceleration_ *= acceleration_scaling_factor;
218 if (t2[j].max_velocity_ <= 0.0 || t2[j].max_acceleration_ <= 0.0)
220 ROS_ERROR_NAMED(
"trajectory_processing.iterative_spline_parameterization",
221 "Joint %d max velocity %f and max acceleration %f must be greater than zero "
222 "or a solution won't be found.\n",
223 j, t2[j].max_velocity_, t2[j].max_acceleration_);
226 if (t2[j].min_velocity_ >= 0.0 || t2[j].min_acceleration_ >= 0.0)
228 ROS_ERROR_NAMED(
"trajectory_processing.iterative_spline_parameterization",
229 "Joint %d min velocity %f and min acceleration %f must be less than zero "
230 "or a solution won't be found.\n",
231 j, t2[j].min_velocity_, t2[j].min_acceleration_);
239 ROS_ERROR_NAMED(
"trajectory_processing.iterative_spline_parameterization",
240 "number of waypoints %d, needs to be greater than 3.\n", num_points);
243 for (
unsigned int j = 0; j < num_joints; j++)
245 if (t2[j].velocities_[0] > t2[j].max_velocity_ || t2[j].velocities_[0] < t2[j].min_velocity_)
247 ROS_ERROR_NAMED(
"trajectory_processing.iterative_spline_parameterization",
"Initial velocity %f out of bounds\n",
248 t2[j].velocities_[0]);
251 else if (t2[j].velocities_[num_points - 1] > t2[j].max_velocity_ ||
252 t2[j].velocities_[num_points - 1] < t2[j].min_velocity_)
254 ROS_ERROR_NAMED(
"trajectory_processing.iterative_spline_parameterization",
"Final velocity %f out of bounds\n",
255 t2[j].velocities_[num_points - 1]);
258 else if (t2[j].accelerations_[0] > t2[j].max_acceleration_ || t2[j].accelerations_[0] < t2[j].min_acceleration_)
260 ROS_ERROR_NAMED(
"trajectory_processing.iterative_spline_parameterization",
261 "Initial acceleration %f out of bounds\n", t2[j].accelerations_[0]);
264 else if (t2[j].accelerations_[num_points - 1] > t2[j].max_acceleration_ ||
265 t2[j].accelerations_[num_points - 1] < t2[j].min_acceleration_)
267 ROS_ERROR_NAMED(
"trajectory_processing.iterative_spline_parameterization",
268 "Final acceleration %f out of bounds\n", t2[j].accelerations_[num_points - 1]);
276 std::vector<double> time_diff(trajectory.
getWayPointCount() - 1, std::numeric_limits<double>::epsilon());
277 for (
unsigned int j = 0; j < num_joints; j++)
278 init_times(num_points, &time_diff[0], &t2[j].positions_[0], t2[j].max_velocity_, t2[j].min_velocity_);
286 std::vector<double> time_factor(num_points - 1, 1.00);
287 for (
unsigned j = 0; j < num_joints; j++)
293 &t2[j].accelerations_[0], t2[j].initial_acceleration_, t2[j].final_acceleration_);
296 fit_cubic_spline(num_points, &time_diff[0], &t2[j].positions_[0], &t2[j].velocities_[0], &t2[j].accelerations_[0]);
297 for (
unsigned i = 0; i < num_points; i++)
299 const double acc = t2[j].accelerations_[i];
300 double atfactor = 1.0;
301 if (acc > t2[j].max_acceleration_)
302 atfactor = sqrt(acc / t2[j].max_acceleration_);
303 if (acc < t2[j].min_acceleration_)
304 atfactor = sqrt(acc / t2[j].min_acceleration_);
307 atfactor = (atfactor - 1.0) / 16.0 + 1.0;
309 time_factor[i - 1] = std::max(time_factor[i - 1], atfactor);
310 if (i < num_points - 1)
311 time_factor[i] = std::max(time_factor[i], atfactor);
319 for (
unsigned i = 0; i < num_points - 1; i++)
320 time_diff[i] *= time_factor[i];
327 for (
unsigned int i = 1; i < num_points; i++)
329 for (
unsigned int i = 0; i < num_points; i++)
331 for (
unsigned int j = 0; j < num_joints; j++)
333 trajectory.
getWayPointPtr(i)->setVariableVelocity(idx[j], t2[j].velocities_[i]);
334 trajectory.
getWayPointPtr(i)->setVariableAcceleration(idx[j], t2[j].accelerations_[i]);
338 if (
add_points_ && (i == 1 || i == num_points - 2))
340 for (
unsigned int j = 0; j < num_joints; j++)
341 trajectory.
getWayPointPtr(i)->setVariablePosition(idx[j], t2[j].positions_[i]);
383 static void fit_cubic_spline(
const int n,
const double dt[],
const double x[],
double x1[],
double x2[])
386 const double x1_i = x1[0], x1_f = x1[n - 1];
391 double *c = x1, *
d = x2;
393 d[0] = 3.0 * ((
x[1] -
x[0]) / dt[0] - x1_i) / dt[0];
394 for (i = 1; i <= n - 2; i++)
396 const double dt2 = dt[i - 1] + dt[i];
397 const double a = dt[i - 1] / dt2;
398 const double denom = 2.0 - a * c[i - 1];
399 c[i] = (1.0 - a) / denom;
400 d[i] = 6.0 * ((
x[i + 1] -
x[i]) / dt[i] - (
x[i] -
x[i - 1]) / dt[i - 1]) / dt2;
401 d[i] = (
d[i] - a *
d[i - 1]) / denom;
403 const double denom = dt[n - 2] * (2.0 - c[n - 2]);
404 d[n - 1] = 6.0 * (x1_f - (
x[n - 1] -
x[n - 2]) / dt[n - 2]);
405 d[n - 1] = (
d[n - 1] - dt[n - 2] *
d[n - 2]) / denom;
409 x2[n - 1] =
d[n - 1];
410 for (i = n - 2; i >= 0; i--)
411 x2[i] =
d[i] - c[i] * x2[i + 1];
415 for (i = 1; i < n - 1; i++)
416 x1[i] = (
x[i + 1] -
x[i]) / dt[i] - (2 * x2[i] + x2[i + 1]) * dt[i] / 6.0;
430 const double x2_i,
const double x2_f)
436 double b0 = x2[n - 1];
442 double b2 = x2[n - 1];
446 x[1] =
x[0] + ((
x[2] -
x[0]) / (a2 - a0)) * (x2_i - a0);
448 x[n - 2] =
x[n - 3] + ((
x[n - 1] -
x[n - 3]) / (b2 - b0)) * (x2_f - b0);
456 static void init_times(
const int n,
double dt[],
const double x[],
const double max_velocity,
const double min_velocity)
459 for (i = 0; i < n - 1; i++)
462 double dx =
x[i + 1] -
x[i];
464 time = (dx / max_velocity);
466 time = (dx / min_velocity);
467 time += std::numeric_limits<double>::epsilon();
474 #if 0 // unused function
495 static int fit_spline_and_adjust_times(
const int n,
double dt[],
const double x[],
double x1[],
double x2[],
496 const double max_velocity,
const double min_velocity,
497 const double max_acceleration,
const double min_acceleration,
498 const double tfactor)
505 for (i = 0; i < n - 1; i++)
507 const double vel = x1[i];
508 const double vel2 = x1[i + 1];
509 if (vel > max_velocity || vel < min_velocity || vel2 > max_velocity || vel2 < min_velocity)
518 for (i = 0; i < n - 1; i++)
520 const double acc = x2[i];
521 const double acc2 = x2[i + 1];
522 if (acc > max_acceleration || acc < min_acceleration || acc2 > max_acceleration || acc2 < min_acceleration)
539 const double min_velocity,
const double max_acceleration,
540 const double min_acceleration)
543 double tfactor2 = 1.00;
545 for (i = 0; i < n; i++)
548 tfactor = x1[i] / max_velocity;
549 if (tfactor2 < tfactor)
551 tfactor = x1[i] / min_velocity;
552 if (tfactor2 < tfactor)
557 tfactor = sqrt(fabs(x2[i] / max_acceleration));
558 if (tfactor2 < tfactor)
563 tfactor = sqrt(fabs(x2[i] / min_acceleration));
564 if (tfactor2 < tfactor)
573 void globalAdjustment(std::vector<SingleJointTrajectory>& t2,
int num_joints,
const int num_points,
574 std::vector<double>& time_diff)
576 double gtfactor = 1.0;
577 for (
int j = 0; j < num_joints; j++)
580 tfactor =
global_adjustment_factor(num_points, &t2[j].velocities_[0], &t2[j].accelerations_[0], t2[j].max_velocity_,
581 t2[j].min_velocity_, t2[j].max_acceleration_, t2[j].min_acceleration_);
582 if (tfactor > gtfactor)
587 for (
int i = 0; i < num_points - 1; i++)
588 time_diff[i] *= gtfactor;
590 for (
int j = 0; j < num_joints; j++)
592 fit_cubic_spline(num_points, &time_diff[0], &t2[j].positions_[0], &t2[j].velocities_[0], &t2[j].accelerations_[0]);