moveCommand.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *   http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 
00018 // standard includes
00019 #include <math.h>
00020 #include <stddef.h>
00021 
00022 // own includes
00023 #include <schunk_powercube_chain/moveCommand.h>
00024 
00025 // ToDo : ? Funktion
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     // RampCommand::RampCommand(double x0, double v0, double xtarget, double amax, double vmax)
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;  // x = x0 + v0t + a/2*t^2
00214     }
00215     else
00216     {
00217       // std::cout << "in getPos(double)\n";
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;  // x = x0 + v0t + a/2*t^2
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);  // x = x1 + v2*t
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       // x = x2 + v2t + a/2*t^2
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   // std::cout << "getTotalTime()\n";
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   // std::ostream& out(debug);
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     // double d2 = 0.5 * TG * v0;
00319     double d3 = 0.5 * v0 * v0 / amax;
00320     // out << "d1:\t" << d1 << "\n";
00321     // out << "d2h:\t" << d2h << "\n";
00322     // out << "d2l:\t" << d2l << "\n";
00323     // out << "d3:\t" << d3 << "\n";
00324     // out << "delta:\t" << delta << "\n";
00325 
00326     if (T3 > 0)
00327     {
00329       if (fabs(delta) >= d1)
00330       {
00331         /* out << "  Case 1\n"; */
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         // out << "  a=" << a << " | b=" << b << " | c=" << c << endl;
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         /* out << "  Case 2\n"; */
00354         /*          \                           */
00355         /*       ----------             */
00356         /*                 \    */
00358         double a = TG;
00359         double b = -delta - T3 * v0;
00360         double c = 0.5 * v0 * v0 * T3;
00361         // out << "  a=" << a << " | b=" << b << " | c=" << c << endl;
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             // delta>0 (-> a>0), v0 < 0:
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             // delta<0 (-> a<0), v0 > 0:
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 }


schunk_powercube_chain
Author(s): Florian Weisshardt
autogenerated on Sat Jun 8 2019 20:25:18