1 #ifndef ORG_EEROS_CONTROL_PATHPLANNER_TRAPEZOID_HPP_ 2 #define ORG_EEROS_CONTROL_PATHPLANNER_TRAPEZOID_HPP_ 19 template <
typename T = eeros::math::Matrix<1,1,
double> >
22 PathPlannerTrapezoid(T velMax, T accMax, T decMax,
double dt) : velMax(velMax), accMax(accMax), decMax(decMax), dt(dt), posOut(this), velOut(this), accOut(this), jerkOut(this), log(
'F') {
25 posOut.getSignal().clear();
26 velOut.getSignal().clear();
27 accOut.getSignal().clear();
28 jerkOut.getSignal().clear();
41 std::vector<T> r = std::vector<T>(4);
51 virtual bool move(T pos,
bool jerkLimit =
false) {
52 if (!finished)
return false;
55 this->jerkLimit = jerkLimit;
57 if (calculateCoefficients_fromPosition()) {
59 finish_segment =
false;
65 finish_segment =
true;
73 virtual bool move(std::vector<T> pos,
bool jerkLimit =
false) {
74 if (!finished)
return false;
77 this->jerkLimit = jerkLimit;
84 for (
int i = 0; i < pos.size(); i++) {
85 if (pos[i] < zero) i = pos.size();
else nofPoints++;
93 this->nofPoints = nofPoints;
95 if (calculateCoefficients_fromPosition()){
97 finish_segment =
false;
103 finish_segment =
true;
111 virtual bool move(std::string filename,
double timeTot = 1.0, T end_position = 1.0) {
112 if(!finished)
return false;
117 file.open(filename, std::fstream::in);
118 if (!file.is_open())
throw Fault(
"Path planner cannot open path file");
120 std::vector<double> input_time = std::vector<double>(100);
121 std::vector<double> input_jerk = std::vector<double>(100);
125 for(
int j = 0; j < input_time.size(); j++){
126 file >> input_time[j];
127 file >> input_jerk[j];
128 if (input_time[j] < 0.0) j = input_time.size();
else nofPoints++;
131 this->nofPoints = nofPoints;
134 for(
int j = 0; j < nofPoints; j++){
135 input_time[j] = input_time[j] * timeTot;
136 input_jerk[j] = input_jerk[j] * end_position[0] / (timeTot*timeTot*timeTot);
142 double rounded_points_nr = 0;
148 std::vector<double> rounded_input_time = std::vector<double>(100);
149 std::vector<double> rounded_input_jerk = std::vector<double>(100);
150 std::vector<double> dT = std::vector<double>(100);
151 std::vector<double> rest = std::vector<double>(100);
152 std::vector<int> rest2 = std::vector<int>(100);
154 double timePrev = 0.0;
155 for(
int j = 0; j < nofPoints; j++){
157 if(j == 0) {dT[j] = input_time[j]; }
158 else {dT[j] = dT[j-1] + input_time[j];}
160 rest[j] = dT[j] / dt;
161 rest2[j] =
static_cast<int>(std::floor(rest[j]));
165 if(rest[j] != rest2[j]) {
167 roundDown = rest2[j]*dt - timePrev;
168 rounded_input_time[rounded_points_nr] = roundDown;
169 rounded_input_jerk[rounded_points_nr] = input_jerk[j];
171 double t1 = dT[j]-timePrev-roundDown;
173 if(j < nofPoints -1) {
174 rounded_input_time[rounded_points_nr+1] = dt;
175 rounded_input_jerk[rounded_points_nr+1] = (input_jerk[j] * t1 + input_jerk[j+1] * t2)/ dt;
179 timePrev = dT[j] + t2;
180 if(j < nofPoints -1) rounded_points_nr = rounded_points_nr + 2;
181 else rounded_points_nr = rounded_points_nr + 1;
184 rounded_input_time[rounded_points_nr] = dT[j] - timePrev;
185 rounded_input_jerk[rounded_points_nr] = input_jerk[j];
188 timePrev = timePrev + rounded_input_time[rounded_points_nr];
189 rounded_points_nr = rounded_points_nr + 1;
192 nofPoints = rounded_points_nr;
195 for(
int j = 0; j < nofPoints; j++){
196 input_time[j] = rounded_input_time[j];
197 input_jerk[j] = rounded_input_jerk[j];
204 while (j < nofPoints) {
205 coefficients(j,0) = input_time[j];
206 coefficients(j,1) = input_jerk[j];
211 calculateCoefficients_fromJerk();
213 finish_segment =
false;
233 std::vector<T> y = this->last;
237 if (k < segments_nr) {
239 if (segment_set ==
false) {
240 dT = coefficients(k,0)(0);
241 j_prev = coefficients(k,1);
242 a_prev = coefficients(k,2);
243 v_prev = coefficients(k,3);
244 p_prev = coefficients(k,4);
245 for (
int i=0; i<j_prev.size() ;i++) {
246 j0 = 6.0 * coefficients(k,2)(i) / coefficients(k,0)(i);
247 s0 = -12.0 * coefficients(k,2)(i) / (coefficients(k,0)(i)*coefficients(k,0)(i));
253 if (t >= dTold && t < dT + dTold) { }
255 finish_segment =
true;
261 y[0] = p_prev + v_prev * dt + (a_prev/2.0) * pow(dt,2) + (j_prev/6.0) * pow(dt,3);
262 y[1] = v_prev + a_prev * dt + (j_prev/2.0) * pow(dt,2);
263 y[2] = a_prev + j_prev * dt;
266 y[2] = (s0 / 2.0) * (t-dTold) * (t-dTold) + j0 * (t-dTold);
268 y[2] = a_prev + j_prev * dt;
277 if (finish_segment ==
true && k == segments_nr) finished =
true;
280 this->last[0] = y[0];
281 this->last[1] = y[1];
282 this->last[2] = y[2];
283 this->last[3] = y[3];
285 posOut.getSignal().setValue( y[0]);
286 velOut.getSignal().setValue( y[1]);
287 accOut.getSignal().setValue( y[2]);
288 jerkOut.getSignal().setValue(y[3]);
291 posOut.getSignal().setTimestamp( time);
292 velOut.getSignal().setTimestamp( time);
293 accOut.getSignal().setTimestamp( time);
294 jerkOut.getSignal().setTimestamp(time);
298 virtual bool calculateCoefficients_fromPosition() {
301 for (
int k = 0; k < nofPoints; k++) {
302 std::vector<T> start = std::vector<T>(4);
303 if (k == 0) start = last;
304 else start = {positions[k-1], zero, zero, zero};
306 std::vector<T> end = std::vector<T>{positions[k], zero, zero, zero};
308 T calcVelNorm, calcAccNorm, calcDecNorm;
309 double velNorm, accNorm, decNorm, squareNormVel;
310 T distance = end[0] - start[0];
312 if (distance == zero)
return false;
315 for(
unsigned int i = 0; i < calcVelNorm.size(); i++) {
316 calcVelNorm[i] = fabs(velMax[i] / distance[i]);
317 calcAccNorm[i] = fabs(accMax[i] / distance[i]);
318 calcDecNorm[i] = fabs(decMax[i] / distance[i]);
322 velNorm = calcVelNorm[0]; accNorm = calcAccNorm[0]; decNorm = calcDecNorm[0];
323 for(
unsigned int i = 0; i < calcVelNorm.size(); i++) {
324 if(calcVelNorm[i] < velNorm) velNorm = calcVelNorm[i];
325 if(calcAccNorm[i] < accNorm) accNorm = calcAccNorm[i];
326 if(calcDecNorm[i] < decNorm) decNorm = calcDecNorm[i];
330 squareNormVel = sqrt(2 * (accNorm * decNorm) / (accNorm + decNorm));
331 if(velNorm > squareNormVel) velNorm = squareNormVel;
334 double dT1 = velNorm / accNorm;
335 double dT3 = velNorm / decNorm;
336 double dT2 = 1 / velNorm - (dT1 + dT3) * 0.5;
337 if (dT2 < 0) dT2 = 0;
340 dT1 = ceil(dT1 / dt) * dt;
341 dT2 = ceil(dT2 / dt) * dt;
342 dT3 = ceil(dT3 / dt) * dt;
344 velNorm = 1/((dT2 + (dT1 + dT3)*0.5)*dt);
350 T ca1 = velNorm * dt / dT1 * distance;
352 T ca3 = velNorm * dt / dT3 * distance * (-1);
356 T cv3 = ca1 * dT1 + ca2 * dT2;
359 if (k == 0) cp1 = last[0];
else cp1 = positions[k-1];
360 T cp2 = cp1 + cv1 * dT1 + ca1 * dT1 * dT1 / 2.0;
361 T cp3 = cp2 + cv2 * dT2 + ca2 * dT2 * dT2 / 2.0;
363 coefficients(0+k*3,0) = dT1; coefficients(0+k*3,1) = cj1; coefficients(0+k*3,2) = ca1;
364 coefficients(0+k*3,3) = cv1; coefficients(0+k*3,4) = cp1;
366 coefficients(1+k*3,0) = dT2; coefficients(1+k*3,1) = cj2; coefficients(1+k*3,2) = ca2;
367 coefficients(1+k*3,3) = cv2; coefficients(1+k*3,4) = cp2;
369 coefficients(2+k*3,0) = dT3; coefficients(2+k*3,1) = cj3; coefficients(2+k*3,2) = ca3;
370 coefficients(2+k*3,3) = cv3; coefficients(2+k*3,4) = cp3;
373 segments_nr = nofPoints * 3.0;
377 virtual bool calculateCoefficients_fromJerk() {
378 for (
int k = 0; k < nofPoints; k++) {
379 T cj1, ca1, cv1, cp1;
381 cj1 = coefficients(k,1);
387 T t_old = coefficients(k-1,0);
388 T j_old = coefficients(k-1,1);
389 T a_old = coefficients(k-1,2);
390 T v_old = coefficients(k-1,3);
391 T p_old = coefficients(k-1,4);
393 cj1 = coefficients(k,1);
395 for(
int i=0; i<ca1.size(); i++){
396 ca1(i) = a_old(i) + j_old(i) * t_old(i);
397 cv1(i) = v_old(i) + a_old(i) * t_old(i) + j_old(i) / 2.0 * t_old(i) * t_old(i);
398 cp1(i) = p_old(i) + v_old(i) * t_old(i) + a_old(i) / 2.0 * t_old(i) * t_old(i) + j_old(i) / 6.0 * t_old(i) * t_old(i) * t_old(i);
401 coefficients(k,2) = ca1;
402 coefficients(k,3) = cv1;
403 coefficients(k,4) = cp1;
405 segments_nr = nofPoints;
422 std::atomic<bool> finished;
423 bool finish_segment =
true;
424 bool segment_set =
false;
425 bool jerkLimit =
false;
427 T velMax, accMax, decMax;
428 T a_prev, v_prev, p_prev, j_prev;
431 std::vector<T> last = std::vector<T>(4);
432 std::vector<T> positions = std::vector<T>(100);
Definition: Logger.hpp:15
Matrix< N, M, T > transpose() const
Definition: Matrix.hpp:428
virtual void reset()
Definition: PathPlannerTrapezoid.hpp:226
PathPlannerTrapezoid(T velMax, T accMax, T decMax, double dt)
Definition: PathPlannerTrapezoid.hpp:22
virtual bool move(std::vector< T > pos, bool jerkLimit=false)
Definition: PathPlannerTrapezoid.hpp:73
Definition: Config.hpp:14
static uint64_t getTimeNs()
Definition: System_POSIX.cpp:41
virtual eeros::control::Output< T > & getVelOut()
Definition: PathPlannerTrapezoid.hpp:34
virtual eeros::control::Output< T > & getAccOut()
Definition: PathPlannerTrapezoid.hpp:35
Definition: PathPlannerTrapezoid.hpp:20
~PathPlannerTrapezoid()
Definition: PathPlannerTrapezoid.hpp:31
virtual bool move(T pos, bool jerkLimit=false)
Definition: PathPlannerTrapezoid.hpp:51
Definition: Output.hpp:11
virtual void setInitPos(T initPos)
Definition: PathPlannerTrapezoid.hpp:38
virtual eeros::control::Output< T > & getPosOut()
Definition: PathPlannerTrapezoid.hpp:33
virtual void setMaxSpeed(T speed)
Definition: PathPlannerTrapezoid.hpp:222
virtual void run()
Definition: PathPlannerTrapezoid.hpp:232
virtual void setMaxDec(T dec)
Definition: PathPlannerTrapezoid.hpp:224
void zero()
Definition: Matrix.hpp:52
virtual void setMaxAcc(T acc)
Definition: PathPlannerTrapezoid.hpp:223
virtual bool endReached()
Definition: PathPlannerTrapezoid.hpp:220
virtual bool move(std::string filename, double timeTot=1.0, T end_position=1.0)
Definition: PathPlannerTrapezoid.hpp:111
uint64_t timestamp_t
Definition: types.hpp:12
virtual eeros::control::Output< T > & getJerkOut()
Definition: PathPlannerTrapezoid.hpp:36