31 #ifndef TRAJECTORY_INTERFACE_QUINTIC_SPLINE_SEGMENT_H 32 #define TRAJECTORY_INTERFACE_QUINTIC_SPLINE_SEGMENT_H 37 #include <boost/array.hpp> 38 #include <boost/foreach.hpp> 50 template<
class ScalarType>
77 const State& start_state,
79 const State& end_state)
81 init(start_time, start_state, end_time, end_state);
104 void init(
const Time& start_time,
105 const State& start_state,
106 const Time& end_time,
107 const State& end_state);
118 void sample(
const Time& time, State& state)
const 126 typedef typename std::vector<SplineCoefficients>::const_iterator ConstIterator;
127 for(ConstIterator coefs_it =
coefs_.begin(); coefs_it !=
coefs_.end(); ++coefs_it)
129 const typename std::vector<Scalar>::size_type
id = std::distance(
coefs_.begin(), coefs_it);
158 static void generatePowers(
int n,
const Scalar& x, Scalar* powers);
161 const Scalar& end_pos,
163 SplineCoefficients& coefficients);
166 const Scalar& end_pos,
const Scalar& end_vel,
168 SplineCoefficients& coefficients);
170 static void computeCoefficients(
const Scalar& start_pos,
const Scalar& start_vel,
const Scalar& start_acc,
171 const Scalar& end_pos,
const Scalar& end_vel,
const Scalar& end_acc,
173 SplineCoefficients& coefficients);
175 static void sample(
const SplineCoefficients& coefficients,
const Scalar& time,
176 Scalar& position, Scalar& velocity, Scalar& acceleration);
178 static void sampleWithTimeBounds(
const SplineCoefficients& coefficients,
const Scalar& duration,
const Scalar& time,
179 Scalar& position, Scalar& velocity, Scalar& acceleration);
182 template<
class ScalarType>
184 const State& start_state,
185 const Time& end_time,
186 const State& end_state)
189 if (end_time < start_time)
191 throw(std::invalid_argument(
"Quintic spline segment can't be constructed: end_time < start_time."));
195 throw(std::invalid_argument(
"Quintic spline segment can't be constructed: Endpoint positions can't be empty."));
199 throw(std::invalid_argument(
"Quintic spline segment can't be constructed: Endpoint positions size mismatch."));
202 const unsigned int dim = start_state.
position.size();
203 const bool has_velocity = !start_state.
velocity.empty() && !end_state.
velocity.empty();
206 if (has_velocity && dim != start_state.
velocity.size())
208 throw(std::invalid_argument(
"Quintic spline segment can't be constructed: Start state velocity size mismatch."));
210 if (has_velocity && dim != end_state.
velocity.size())
212 throw(std::invalid_argument(
"Quintic spline segment can't be constructed: End state velocity size mismatch."));
214 if (has_acceleration && dim!= start_state.
acceleration.size())
216 throw(std::invalid_argument(
"Quintic spline segment can't be constructed: Start state acceleration size mismatch."));
218 if (has_acceleration && dim != end_state.
acceleration.size())
220 throw(std::invalid_argument(
"Quintic spline segment can't be constructed: End state acceleratios size mismatch."));
230 typedef typename std::vector<SplineCoefficients>::iterator Iterator;
234 for(Iterator coefs_it =
coefs_.begin(); coefs_it !=
coefs_.end(); ++coefs_it)
236 const typename std::vector<Scalar>::size_type
id = std::distance(
coefs_.begin(), coefs_it);
244 else if (!has_acceleration)
247 for(Iterator coefs_it =
coefs_.begin(); coefs_it !=
coefs_.end(); ++coefs_it)
249 const typename std::vector<Scalar>::size_type
id = std::distance(
coefs_.begin(), coefs_it);
260 for(Iterator coefs_it =
coefs_.begin(); coefs_it !=
coefs_.end(); ++coefs_it)
262 const typename std::vector<Scalar>::size_type
id = std::distance(
coefs_.begin(), coefs_it);
272 template<
class ScalarType>
276 for (
int i=1; i<=n; ++i)
278 powers[i] = powers[i-1]*x;
282 template<
class ScalarType>
289 coefficients[0] = start_pos;
290 coefficients[1] = (time == 0.0) ? 0.0 : (end_pos - start_pos) / time;
291 coefficients[2] = 0.0;
292 coefficients[3] = 0.0;
293 coefficients[4] = 0.0;
294 coefficients[5] = 0.0;
297 template<
class ScalarType>
306 coefficients[0] = start_pos;
307 coefficients[1] = start_vel;
308 coefficients[2] = 0.0;
309 coefficients[3] = 0.0;
316 coefficients[0] = start_pos;
317 coefficients[1] = start_vel;
318 coefficients[2] = (-3.0*start_pos + 3.0*end_pos - 2.0*start_vel*T[1] - end_vel*T[1]) / T[2];
319 coefficients[3] = (2.0*start_pos - 2.0*end_pos + start_vel*T[1] + end_vel*T[1]) / T[3];
321 coefficients[4] = 0.0;
322 coefficients[5] = 0.0;
325 template<
class ScalarType>
334 coefficients[0] = start_pos;
335 coefficients[1] = start_vel;
336 coefficients[2] = 0.5*start_acc;
337 coefficients[3] = 0.0;
338 coefficients[4] = 0.0;
339 coefficients[5] = 0.0;
346 coefficients[0] = start_pos;
347 coefficients[1] = start_vel;
348 coefficients[2] = 0.5*start_acc;
349 coefficients[3] = (-20.0*start_pos + 20.0*end_pos - 3.0*start_acc*T[2] + end_acc*T[2] -
350 12.0*start_vel*T[1] - 8.0*end_vel*T[1]) / (2.0*T[3]);
351 coefficients[4] = (30.0*start_pos - 30.0*end_pos + 3.0*start_acc*T[2] - 2.0*end_acc*T[2] +
352 16.0*start_vel*T[1] + 14.0*end_vel*T[1]) / (2.0*T[4]);
353 coefficients[5] = (-12.0*start_pos + 12.0*end_pos - start_acc*T[2] + end_acc*T[2] -
354 6.0*start_vel*T[1] - 6.0*end_vel*T[1]) / (2.0*T[5]);
358 template<
class ScalarType>
367 position = t[0]*coefficients[0] +
368 t[1]*coefficients[1] +
369 t[2]*coefficients[2] +
370 t[3]*coefficients[3] +
371 t[4]*coefficients[4] +
372 t[5]*coefficients[5];
374 velocity = t[0]*coefficients[1] +
375 2.0*t[1]*coefficients[2] +
376 3.0*t[2]*coefficients[3] +
377 4.0*t[3]*coefficients[4] +
378 5.0*t[4]*coefficients[5];
380 acceleration = 2.0*t[0]*coefficients[2] +
381 6.0*t[1]*coefficients[3] +
382 12.0*t[2]*coefficients[4] +
383 20.0*t[3]*coefficients[5];
386 template<
class ScalarType>
394 sample(coefficients, 0.0, position, _, _);
398 else if (time > duration)
401 sample(coefficients, duration, position, _, _);
407 sample(coefficients, time,
408 position, velocity, acceleration);
414 #endif // header guard static void generatePowers(int n, const Scalar &x, Scalar *powers)
std::vector< Scalar > acceleration
Class representing a multi-dimensional quintic spline segment with a start and end time...
QuinticSplineSegment()
Creates an empty segment.
std::vector< SplineCoefficients > coefs_
static void sampleWithTimeBounds(const SplineCoefficients &coefficients, const Scalar &duration, const Scalar &time, Scalar &position, Scalar &velocity, Scalar &acceleration)
QuinticSplineSegment(const Time &start_time, const State &start_state, const Time &end_time, const State &end_state)
Construct segment from start and end states (boundary conditions).
void init(const Time &start_time, const State &start_state, const Time &end_time, const State &end_state)
Initialize segment from start and end states (boundary conditions).
static void computeCoefficients(const Scalar &start_pos, const Scalar &end_pos, const Scalar &time, SplineCoefficients &coefficients)
PosVelAccState< Scalar > State
void sample(const Time &time, State &state) const
Sample the segment at a specified time.
std::vector< Scalar > position
Multi-dof trajectory state containing position, velocity and acceleration data.
unsigned int size() const
boost::array< Scalar, 6 > SplineCoefficients
std::vector< Scalar > velocity