00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #include <cob_powercube_chain/moveCommand.h>
00055 #include <math.h>
00056 #include <stddef.h>
00057
00058 RampCommand::RampCommand(double x0, double v0, double xtarget, double amax, double vmax)
00059 : moveCommand(),
00060 m_x0(x0),
00061 m_v0(v0),
00062 m_xtarget(xtarget),
00063 m_amax(amax),
00064 m_vmax(vmax)
00065 {
00066 m_umkehr = false;
00067 m_nachumkehr = NULL;
00068
00069 m_vmax = fabs(m_vmax);
00070 m_amax = fabs(m_amax);
00071
00072 double delta = m_xtarget - m_x0;
00073 if (delta < 0)
00074 {
00075 m_vmax = -m_vmax;
00076 m_amax = -m_amax;
00077 }
00078
00079 if (m_v0 * m_vmax >= 0)
00080 {
00081 if (fabs(m_vmax) >= fabs(m_v0))
00082 {
00083
00084 double delta1 = (m_vmax*m_vmax - 0.5 * m_v0*m_v0) / m_amax;
00085 double delta2 = 0.5 * m_v0*m_v0 / m_amax;
00086
00087 if (fabs(delta) >= fabs(delta1)) {
00088 m_T1 = (m_vmax-m_v0) / m_amax;
00089 m_a1 = m_amax;
00090 m_T3 = m_vmax / m_amax;
00091 m_a3 = -m_amax;
00092 m_T2 = (delta - delta1) / m_vmax;
00093 m_v2 = m_vmax;
00094 }
00095 else if (fabs(delta) >= fabs(delta2)) {
00096 m_v2 = sqrt( delta*m_amax + 0.5*m_v0*m_v0 );
00097 m_v2 = (delta < 0)?-m_v2:m_v2;
00098 m_T1 = (m_v2-m_v0) / m_amax;
00099 m_a1 = m_amax;
00100 m_T2 = 0.0;
00101 m_T3 = m_v2 / m_amax;
00102 m_a3 = -m_amax;
00103 }
00104 else if (fabs(delta) > 0)
00105 {
00106 m_v2 = -sqrt( 0.5*m_v0*m_v0 - m_amax*delta );
00107 m_v2 = (delta < 0)?-m_v2:m_v2;
00108 m_T2 = 0.0;
00109 m_T1 = (m_v0 - m_v2) / m_amax;
00110 m_a1 = -m_amax;
00111 m_T3 = - m_v2 / m_amax;
00112 m_a3 = m_amax;
00113 }
00114 else
00115 {
00116 m_T1 = 0;
00117 m_T2 = 0;
00118 m_T3 = 0;
00119 m_a1 = 0;
00120 m_v2 = 0;
00121 m_a3 = 0;
00122 }
00123 } else
00124 {
00125
00126 double delta1 = 0.5 * m_v0*m_v0 / m_amax;
00127 double vstern = m_v0 * 0.707106781;
00128
00129 if (fabs(delta) >= fabs(delta1))
00130 {
00131 m_T1 = (m_v0-m_vmax) / m_amax;
00132 m_a1 = -m_amax;
00133 m_T3 = m_vmax / m_amax;
00134 m_a3 = -m_amax;
00135 m_T2 = (delta - delta1) / m_vmax;
00136 m_v2 = m_vmax;
00137 }
00138 else if (fabs(m_vmax) >= fabs(vstern))
00139 {
00140 m_v2 = -sqrt( 0.5*m_v0*m_v0 - m_amax*delta );
00141 m_v2 = (delta < 0)?-m_v2:m_v2;
00142 m_T2 = 0.0;
00143 m_T1 = (m_v0 - m_v2) / m_amax;
00144 m_a1 = -m_amax;
00145 m_T3 = - m_v2 / m_amax;
00146 m_a3 = m_amax;
00147 }
00148 else
00149 {
00150 m_T1 = (m_v0 + m_vmax) / m_amax;
00151 m_a1 = -m_amax;
00152 m_T2 = ( delta - (0.5*m_v0*m_v0/m_amax - m_vmax*m_vmax/m_amax) ) / m_vmax;
00153 m_v2 = -m_vmax;
00154 m_T3 = m_vmax / m_amax;
00155 m_a3 = m_amax;
00156 }
00157 }
00158 }
00159 else
00160 {
00161
00162
00163 m_a1 = m_amax;
00164 m_T1 = -m_v0 / m_amax;
00165 m_umkehr = true;
00166
00167 m_nachumkehr = new RampCommand( m_x0 + 0.5*m_v0*m_T1, 0.0, m_xtarget, m_amax, m_vmax);
00168
00169
00170
00171 m_T2 = 0;
00172 m_T3 = 0;
00173 m_v2 = 0;
00174 m_a3 = 0;
00175 }
00176
00177 }
00178
00179 RampCommand::RampCommand(const RampCommand& rc)
00180 {
00181
00182
00183 m_x0 = rc.m_x0;
00184 m_v0 = rc.m_v0;
00185 m_xtarget = rc.m_xtarget;
00186 m_amax = rc.m_amax;
00187 m_vmax = rc.m_vmax;
00188
00189 m_T1 = rc.m_T1;
00190 m_T2 = rc.m_T2;
00191 m_T3 = rc.m_T3;
00192 m_a1 = rc.m_a1;
00193 m_v2 = rc.m_v2;
00194 m_a3 = rc.m_a3;
00195
00196 m_umkehr = rc.m_umkehr;
00197
00198
00199
00200 if (rc.m_umkehr)
00201 m_nachumkehr = new RampCommand(*rc.m_nachumkehr);
00202 else
00203 m_nachumkehr = NULL;
00204 }
00205
00206 RampCommand& RampCommand::operator=(const RampCommand& rc)
00207 {
00208
00209
00210
00211 if (m_nachumkehr)
00212 delete m_nachumkehr;
00213
00214 m_x0 = rc.m_x0;
00215 m_v0 = rc.m_v0;
00216 m_xtarget = rc.m_xtarget;
00217 m_amax = rc.m_amax;
00218 m_vmax = rc.m_vmax;
00219
00220 m_T1 = rc.m_T1;
00221 m_T2 = rc.m_T2;
00222 m_T3 = rc.m_T3;
00223 m_a1 = rc.m_a1;
00224 m_v2 = rc.m_v2;
00225 m_a3 = rc.m_a3;
00226
00227 m_umkehr = rc.m_umkehr;
00228
00229
00230
00231 if (rc.m_umkehr)
00232 m_nachumkehr = new RampCommand(*rc.m_nachumkehr);
00233 else
00234 m_nachumkehr = NULL;
00235
00236 return *this;
00237 }
00238
00239
00241 double RampCommand::getPos(double TimeElapsed)
00242 {
00243 if (m_umkehr)
00244 {
00245 if (TimeElapsed <= m_T1)
00246 {
00247 return m_x0 + m_v0 * TimeElapsed + 0.5 * m_a1 * TimeElapsed * TimeElapsed;
00248 } else {
00249
00250 return m_nachumkehr->getPos(TimeElapsed-m_T1);
00251 }
00252 } else
00253 {
00254 if (TimeElapsed <= m_T1)
00255 {
00256 return m_x0 + m_v0 * TimeElapsed + 0.5 * m_a1 * TimeElapsed * TimeElapsed;
00257 }
00258 else if (TimeElapsed <= m_T1 + m_T2)
00259 {
00260 return m_x0 + m_v0*m_T1 + 0.5*m_a1*m_T1*m_T1 + m_v2 * (TimeElapsed-m_T1);
00261 }
00262 else if (TimeElapsed <= m_T1 + m_T2 + m_T3)
00263 {
00264 return m_x0 + m_v0*m_T1 + 0.5*m_a1*m_T1*m_T1 + m_v2*m_T2 +
00265 m_v2*(TimeElapsed-m_T1-m_T2) + 0.5*m_a3*(TimeElapsed-m_T1-m_T2)*(TimeElapsed-m_T1-m_T2);
00266
00267 }
00268 else
00269 return m_xtarget;
00270 }
00271 }
00272
00274 double RampCommand::getVel(double TimeElapsed)
00275 {
00276 if (m_umkehr)
00277 {
00278 if (TimeElapsed <= m_T1)
00279 {
00280 return m_v0 + m_a1 * TimeElapsed;
00281 } else {
00282 return m_nachumkehr->getVel(TimeElapsed-m_T1);
00283 }
00284 } else
00285 {
00286 if (TimeElapsed <= m_T1)
00287 {
00288 return m_v0 + m_a1 * TimeElapsed;
00289 }
00290 else if (TimeElapsed <= m_T1 + m_T2)
00291 {
00292 return m_v2;
00293 }
00294 else if (TimeElapsed <= m_T1 + m_T2 + m_T3)
00295 {
00296 return m_v2 + m_a3 * (TimeElapsed - m_T1 - m_T2);
00297 }
00298 else
00299 return 0.0;
00300 }
00301 }
00302
00304 double RampCommand::getTotalTime()
00305 {
00306
00307 if (m_umkehr)
00308 return m_T1 + m_nachumkehr->getTotalTime();
00309 else
00310 return m_T1 + m_T2 + m_T3;
00311 }
00312
00315 void RampCommand::calculateAV(double x0, double v0, double xtarget, double time, double T3, double amax, double vmax, double& acc, double& vel)
00316 {
00317
00318
00319
00320 double TG = time;
00321
00322 if (TG <= 0)
00323 {
00324
00325 acc = 0;
00326 vel = 0;
00327 } else
00328 {
00329 double delta = xtarget - x0;
00330
00331 amax = fabs(amax);
00332 amax = (delta>=0)?amax:-amax;
00333
00334 double d1 = fabs(v0)*TG - 0.5 * T3 * fabs(v0);
00335 double d2h = (v0>0)?-T3*v0 + v0*sqrt(2*T3*TG):-T3*v0 - v0*sqrt(2*T3*TG);
00336 double d2l = (v0>0)?-T3*v0 - v0*sqrt(2*T3*TG):-T3*v0 + v0*sqrt(2*T3*TG);
00337
00338 double d3 = 0.5 * v0 * v0 / amax;
00339
00340
00341
00342
00343
00344
00345 if (T3 > 0)
00346 {
00348
00350 if (fabs(delta) >= d1)
00351 {
00352
00353
00354
00355
00356
00357
00358 double a = (TG / T3 - 1.0);
00359 double b = v0 - delta/T3;
00360 double c = - 0.5 * v0 * v0;
00361
00362
00363 if (delta >= 0)
00364 vel = (-b + sqrt(b*b - 4.0*a*c)) / (2.0 * a);
00365 else
00366 vel = (-b - sqrt(b*b - 4.0*a*c)) / (2.0 * a);
00367
00368
00369 acc = vel / T3;
00370 }
00371 else if (delta >= d2h || delta <= d2l)
00372
00373 {
00374
00375
00376
00377
00378
00379
00380 double a = TG;
00381 double b = - delta - T3*v0;
00382 double c = 0.5 * v0 * v0 * T3;
00383
00384
00385 if (delta >= 0)
00386 vel = (-b + sqrt(b*b - 4.0*a*c)) / (2.0 * a);
00387 else
00388 vel = (-b - sqrt(b*b - 4.0*a*c)) / (2.0 * a);
00389
00390
00391 acc = vel / T3;
00392 }
00393 else if (fabs(delta) >= d3)
00394 {
00395
00396
00397
00398
00399
00400
00401
00402
00403 acc = amax;
00404
00405 if (delta*v0 > 0)
00406 vel = (2*acc*delta - v0*v0) / (2*acc*TG - 2*v0);
00407 else
00408 if (-4*acc*delta + acc*acc*TG*TG + 2*acc*TG*v0 - v0*v0 >= 0)
00409 if (delta>0)
00410 {
00411
00412 vel = 0.5 * (acc*TG+v0 - sqrt(-4*acc*delta + acc*acc*TG*TG + 2*acc*TG*v0 - v0*v0));
00413 } else
00414 {
00415
00416 vel = 0.5 * (acc*TG+v0 + sqrt(-4*acc*delta + acc*acc*TG*TG + 2*acc*TG*v0 - v0*v0));
00417 }
00418 else
00419 {
00420
00421
00422 vel = vmax;
00423 }
00424
00425 }
00426 else
00427 {
00428
00429
00430
00431 if (4*delta*delta - 4*delta*TG*v0 + 2*TG*TG*v0*v0 >=0)
00432
00433 if (delta*v0 > 0)
00434 acc = ( -2.0*delta + TG*v0 + sqrt(4*delta*delta - 4*delta*TG*v0 + 2*TG*TG*v0*v0) ) / (TG*TG);
00435 else
00436 acc = ( -2.0*delta + TG*v0 - sqrt(4*delta*delta - 4*delta*TG*v0 + 2*TG*TG*v0*v0) ) / (TG*TG);
00437 else
00438
00439 acc = amax;
00440
00441 vel = vmax;
00442 }
00443 }
00444 else if (T3 == 0)
00445 {
00446
00447
00448
00449 acc = amax;
00450 vel = vmax;
00451 } else
00452 {
00453
00454 acc = 0;
00455 vel = 0;
00456 }
00457 }
00458
00459
00460
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537