Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <math.h>
00020 #include <stddef.h>
00021
00022
00023 #include <schunk_powercube_chain/moveCommand.h>
00024
00025
00026 RampCommand::RampCommand(double x0, double v0, double xtarget, double amax, double vmax)
00027 : moveCommand(), m_x0(x0), m_v0(v0), m_xtarget(xtarget), m_amax(amax), m_vmax(vmax)
00028 {
00029 m_umkehr = false;
00030 m_nachumkehr = NULL;
00032 m_vmax = fabs(m_vmax);
00033 m_amax = fabs(m_amax);
00035 double delta = m_xtarget - m_x0;
00036 if (delta < 0)
00037 {
00038 m_vmax = -m_vmax;
00039 m_amax = -m_amax;
00040 }
00041
00043 if (m_v0 * m_vmax >= 0)
00044 {
00046 if (fabs(m_vmax) >= fabs(m_v0))
00047 {
00049 double delta1 = (m_vmax * m_vmax - 0.5 * m_v0 * m_v0) / m_amax;
00050 double delta2 = 0.5 * m_v0 * m_v0 / m_amax;
00051
00052 if (fabs(delta) >= fabs(delta1))
00053 {
00054 m_T1 = (m_vmax - m_v0) / m_amax;
00055 m_a1 = m_amax;
00056 m_T3 = m_vmax / m_amax;
00057 m_a3 = -m_amax;
00058 m_T2 = (delta - delta1) / m_vmax;
00059 m_v2 = m_vmax;
00060 }
00061 else if (fabs(delta) >= fabs(delta2))
00062 {
00063 m_v2 = sqrt(delta * m_amax + 0.5 * m_v0 * m_v0);
00064 m_v2 = (delta < 0) ? -m_v2 : m_v2;
00065 m_T1 = (m_v2 - m_v0) / m_amax;
00066 m_a1 = m_amax;
00067 m_T2 = 0.0;
00068 m_T3 = m_v2 / m_amax;
00069 m_a3 = -m_amax;
00070 }
00071 else if (fabs(delta) > 0)
00072 {
00073 m_v2 = -sqrt(0.5 * m_v0 * m_v0 - m_amax * delta);
00074 m_v2 = (delta < 0) ? -m_v2 : m_v2;
00075 m_T2 = 0.0;
00076 m_T1 = (m_v0 - m_v2) / m_amax;
00077 m_a1 = -m_amax;
00078 m_T3 = -m_v2 / m_amax;
00079 m_a3 = m_amax;
00080 }
00082 else
00083 {
00084 m_T1 = 0;
00085 m_T2 = 0;
00086 m_T3 = 0;
00087 m_a1 = 0;
00088 m_v2 = 0;
00089 m_a3 = 0;
00090 }
00092 }
00093 else
00094 {
00096 double delta1 = 0.5 * m_v0 * m_v0 / m_amax;
00098 double vstern = m_v0 * 0.707106781;
00099
00100 if (fabs(delta) >= fabs(delta1))
00101 {
00102 m_T1 = (m_v0 - m_vmax) / m_amax;
00103 m_a1 = -m_amax;
00104 m_T3 = m_vmax / m_amax;
00105 m_a3 = -m_amax;
00106 m_T2 = (delta - delta1) / m_vmax;
00107 m_v2 = m_vmax;
00108 }
00109 else if (fabs(m_vmax) >= fabs(vstern))
00110 {
00111 m_v2 = -sqrt(0.5 * m_v0 * m_v0 - m_amax * delta);
00112 m_v2 = (delta < 0) ? -m_v2 : m_v2;
00113 m_T2 = 0.0;
00114 m_T1 = (m_v0 - m_v2) / m_amax;
00115 m_a1 = -m_amax;
00116 m_T3 = -m_v2 / m_amax;
00117 m_a3 = m_amax;
00118 }
00120 else
00121 {
00122 m_T1 = (m_v0 + m_vmax) / m_amax;
00123 m_a1 = -m_amax;
00124 m_T2 = (delta - (0.5 * m_v0 * m_v0 / m_amax - m_vmax * m_vmax / m_amax)) / m_vmax;
00125 m_v2 = -m_vmax;
00126 m_T3 = m_vmax / m_amax;
00127 m_a3 = m_amax;
00128 }
00129 }
00130 }
00133 else
00134 {
00136 m_a1 = m_amax;
00137 m_T1 = -m_v0 / m_amax;
00138 m_umkehr = true;
00139
00140 m_nachumkehr = new RampCommand(m_x0 + 0.5 * m_v0 * m_T1, 0.0, m_xtarget, m_amax, m_vmax);
00141 m_T2 = 0;
00142 m_T3 = 0;
00143 m_v2 = 0;
00144 m_a3 = 0;
00145 }
00147 }
00148
00149 RampCommand::RampCommand(const RampCommand& rc)
00150 {
00151 m_x0 = rc.m_x0;
00152 m_v0 = rc.m_v0;
00153 m_xtarget = rc.m_xtarget;
00154 m_amax = rc.m_amax;
00155 m_vmax = rc.m_vmax;
00156
00157 m_T1 = rc.m_T1;
00158 m_T2 = rc.m_T2;
00159 m_T3 = rc.m_T3;
00160 m_a1 = rc.m_a1;
00161 m_v2 = rc.m_v2;
00162 m_a3 = rc.m_a3;
00163
00164 m_umkehr = rc.m_umkehr;
00168 if (rc.m_umkehr)
00169 m_nachumkehr = new RampCommand(*rc.m_nachumkehr);
00170 else
00171 m_nachumkehr = NULL;
00172 }
00173
00174 RampCommand& RampCommand::operator=(const RampCommand& rc)
00175 {
00176 if (m_nachumkehr)
00177 delete m_nachumkehr;
00178
00179 m_x0 = rc.m_x0;
00180 m_v0 = rc.m_v0;
00181 m_xtarget = rc.m_xtarget;
00182 m_amax = rc.m_amax;
00183 m_vmax = rc.m_vmax;
00184
00185 m_T1 = rc.m_T1;
00186 m_T2 = rc.m_T2;
00187 m_T3 = rc.m_T3;
00188 m_a1 = rc.m_a1;
00189 m_v2 = rc.m_v2;
00190 m_a3 = rc.m_a3;
00191
00192 m_umkehr = rc.m_umkehr;
00196 if (rc.m_umkehr)
00197 m_nachumkehr = new RampCommand(*rc.m_nachumkehr);
00198 else
00199 m_nachumkehr = NULL;
00200
00201 return *this;
00202 }
00203
00207 double RampCommand::getPos(double TimeElapsed)
00208 {
00209 if (m_umkehr)
00210 {
00211 if (TimeElapsed <= m_T1)
00212 {
00213 return m_x0 + m_v0 * TimeElapsed + 0.5 * m_a1 * TimeElapsed * TimeElapsed;
00214 }
00215 else
00216 {
00217
00218 return m_nachumkehr->getPos(TimeElapsed - m_T1);
00219 }
00220 }
00221 else
00222 {
00223 if (TimeElapsed <= m_T1)
00224 {
00225 return m_x0 + m_v0 * TimeElapsed + 0.5 * m_a1 * TimeElapsed * TimeElapsed;
00226 }
00227 else if (TimeElapsed <= m_T1 + m_T2)
00228 {
00229 return m_x0 + m_v0 * m_T1 + 0.5 * m_a1 * m_T1 * m_T1 + m_v2 * (TimeElapsed - m_T1);
00230 }
00231 else if (TimeElapsed <= m_T1 + m_T2 + m_T3)
00232 {
00233 return m_x0 + m_v0 * m_T1 + 0.5 * m_a1 * m_T1 * m_T1 + m_v2 * m_T2 + m_v2 * (TimeElapsed - m_T1 - m_T2) +
00234 0.5 * m_a3 * (TimeElapsed - m_T1 - m_T2) * (TimeElapsed - m_T1 - m_T2);
00235
00236 }
00238 else
00239 return m_xtarget;
00240 }
00241 }
00242
00246 double RampCommand::getVel(double TimeElapsed)
00247 {
00248 if (m_umkehr)
00249 {
00250 if (TimeElapsed <= m_T1)
00251 {
00252 return m_v0 + m_a1 * TimeElapsed;
00253 }
00254 else
00255 {
00256 return m_nachumkehr->getVel(TimeElapsed - m_T1);
00257 }
00258 }
00259 else
00260 {
00261 if (TimeElapsed <= m_T1)
00262 {
00263 return m_v0 + m_a1 * TimeElapsed;
00264 }
00265 else if (TimeElapsed <= m_T1 + m_T2)
00266 {
00267 return m_v2;
00268 }
00269 else if (TimeElapsed <= m_T1 + m_T2 + m_T3)
00270 {
00271 return m_v2 + m_a3 * (TimeElapsed - m_T1 - m_T2);
00272 }
00274 else
00275 return 0.0;
00276 }
00277 }
00278
00282 double RampCommand::getTotalTime()
00283 {
00284
00285 if (m_umkehr)
00286 return m_T1 + m_nachumkehr->getTotalTime();
00287 else
00288 return m_T1 + m_T2 + m_T3;
00289 }
00290
00296 void RampCommand::calculateAV(double x0, double v0, double xtarget, double time, double T3, double amax, double vmax,
00297 double& acc, double& vel)
00298 {
00299
00300
00301 double TG = time;
00302
00303 if (TG <= 0)
00304 {
00305 acc = 0;
00306 vel = 0;
00307 }
00308 else
00309 {
00310 double delta = xtarget - x0;
00312 amax = fabs(amax);
00313 amax = (delta >= 0) ? amax : -amax;
00314
00315 double d1 = fabs(v0) * TG - 0.5 * T3 * fabs(v0);
00316 double d2h = (v0 > 0) ? -T3 * v0 + v0 * sqrt(2 * T3 * TG) : -T3 * v0 - v0 * sqrt(2 * T3 * TG);
00317 double d2l = (v0 > 0) ? -T3 * v0 - v0 * sqrt(2 * T3 * TG) : -T3 * v0 + v0 * sqrt(2 * T3 * TG);
00318
00319 double d3 = 0.5 * v0 * v0 / amax;
00320
00321
00322
00323
00324
00325
00326 if (T3 > 0)
00327 {
00329 if (fabs(delta) >= d1)
00330 {
00331
00332
00333
00334
00335
00337 double a = (TG / T3 - 1.0);
00338 double b = v0 - delta / T3;
00339 double c = -0.5 * v0 * v0;
00340
00342 if (delta >= 0)
00343 vel = (-b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a);
00344 else
00345 vel = (-b - sqrt(b * b - 4.0 * a * c)) / (2.0 * a);
00346
00348 acc = vel / T3;
00349 }
00350 else if (delta >= d2h || delta <= d2l)
00352 {
00353
00354
00355
00356
00358 double a = TG;
00359 double b = -delta - T3 * v0;
00360 double c = 0.5 * v0 * v0 * T3;
00361
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
00369 acc = vel / T3;
00370 }
00371 else if (fabs(delta) >= d3)
00372 {
00374
00382
00383 acc = amax;
00384
00385 if (delta * v0 > 0)
00386 vel = (2 * acc * delta - v0 * v0) / (2 * acc * TG - 2 * v0);
00387 else if (-4 * acc * delta + acc * acc * TG * TG + 2 * acc * TG * v0 - v0 * v0 >= 0)
00388 if (delta > 0)
00389 {
00390
00391 vel = 0.5 * (acc * TG + v0 - sqrt(-4 * acc * delta + acc * acc * TG * TG + 2 * acc * TG * v0 - v0 * v0));
00392 }
00393 else
00394 {
00395
00396 vel = 0.5 * (acc * TG + v0 + sqrt(-4 * acc * delta + acc * acc * TG * TG + 2 * acc * TG * v0 - v0 * v0));
00397 }
00398 else
00399 {
00403
00406 vel = vmax;
00407 }
00408 }
00409 else
00410 {
00414
00418 if (4 * delta * delta - 4 * delta * TG * v0 + 2 * TG * TG * v0 * v0 >= 0)
00420 if (delta * v0 > 0)
00421 acc = (-2.0 * delta + TG * v0 + sqrt(4 * delta * delta - 4 * delta * TG * v0 + 2 * TG * TG * v0 * v0)) / (TG * TG);
00422 else
00423 acc = (-2.0 * delta + TG * v0 - sqrt(4 * delta * delta - 4 * delta * TG * v0 + 2 * TG * TG * v0 * v0)) / (TG * TG);
00424 else
00426 acc = amax;
00427
00428 vel = vmax;
00429 }
00430 }
00431 else if (T3 == 0)
00432 {
00436 acc = amax;
00437 vel = vmax;
00438 }
00439 else
00440 {
00442 acc = 0;
00443 vel = 0;
00444 }
00445 }
00449 }