moveCommand.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 // standard includes
19 #include <math.h>
20 #include <stddef.h>
21 
22 // own includes
24 
25 // ToDo : ? Funktion
26 RampCommand::RampCommand(double x0, double v0, double xtarget, double amax, double vmax)
27  : moveCommand(), m_x0(x0), m_v0(v0), m_xtarget(xtarget), m_amax(amax), m_vmax(vmax)
28 {
29  m_umkehr = false;
30  m_nachumkehr = NULL;
32  m_vmax = fabs(m_vmax);
33  m_amax = fabs(m_amax);
35  double delta = m_xtarget - m_x0;
36  if (delta < 0)
37  {
38  m_vmax = -m_vmax;
39  m_amax = -m_amax;
40  }
41 
43  if (m_v0 * m_vmax >= 0)
44  {
46  if (fabs(m_vmax) >= fabs(m_v0))
47  {
49  double delta1 = (m_vmax * m_vmax - 0.5 * m_v0 * m_v0) / m_amax;
50  double delta2 = 0.5 * m_v0 * m_v0 / m_amax;
51 
52  if (fabs(delta) >= fabs(delta1))
53  {
54  m_T1 = (m_vmax - m_v0) / m_amax;
55  m_a1 = m_amax;
56  m_T3 = m_vmax / m_amax;
57  m_a3 = -m_amax;
58  m_T2 = (delta - delta1) / m_vmax;
59  m_v2 = m_vmax;
60  }
61  else if (fabs(delta) >= fabs(delta2))
62  {
63  m_v2 = sqrt(delta * m_amax + 0.5 * m_v0 * m_v0);
64  m_v2 = (delta < 0) ? -m_v2 : m_v2;
65  m_T1 = (m_v2 - m_v0) / m_amax;
66  m_a1 = m_amax;
67  m_T2 = 0.0;
68  m_T3 = m_v2 / m_amax;
69  m_a3 = -m_amax;
70  }
71  else if (fabs(delta) > 0)
72  {
73  m_v2 = -sqrt(0.5 * m_v0 * m_v0 - m_amax * delta);
74  m_v2 = (delta < 0) ? -m_v2 : m_v2;
75  m_T2 = 0.0;
76  m_T1 = (m_v0 - m_v2) / m_amax;
77  m_a1 = -m_amax;
78  m_T3 = -m_v2 / m_amax;
79  m_a3 = m_amax;
80  }
82  else
83  {
84  m_T1 = 0;
85  m_T2 = 0;
86  m_T3 = 0;
87  m_a1 = 0;
88  m_v2 = 0;
89  m_a3 = 0;
90  }
92  }
93  else
94  {
96  double delta1 = 0.5 * m_v0 * m_v0 / m_amax;
98  double vstern = m_v0 * 0.707106781;
99 
100  if (fabs(delta) >= fabs(delta1))
101  {
102  m_T1 = (m_v0 - m_vmax) / m_amax;
103  m_a1 = -m_amax;
104  m_T3 = m_vmax / m_amax;
105  m_a3 = -m_amax;
106  m_T2 = (delta - delta1) / m_vmax;
107  m_v2 = m_vmax;
108  }
109  else if (fabs(m_vmax) >= fabs(vstern))
110  {
111  m_v2 = -sqrt(0.5 * m_v0 * m_v0 - m_amax * delta);
112  m_v2 = (delta < 0) ? -m_v2 : m_v2;
113  m_T2 = 0.0;
114  m_T1 = (m_v0 - m_v2) / m_amax;
115  m_a1 = -m_amax;
116  m_T3 = -m_v2 / m_amax;
117  m_a3 = m_amax;
118  }
120  else
121  {
122  m_T1 = (m_v0 + m_vmax) / m_amax;
123  m_a1 = -m_amax;
124  m_T2 = (delta - (0.5 * m_v0 * m_v0 / m_amax - m_vmax * m_vmax / m_amax)) / m_vmax;
125  m_v2 = -m_vmax;
126  m_T3 = m_vmax / m_amax;
127  m_a3 = m_amax;
128  }
129  }
130  }
133  else
134  {
136  m_a1 = m_amax;
137  m_T1 = -m_v0 / m_amax;
138  m_umkehr = true;
139  // RampCommand::RampCommand(double x0, double v0, double xtarget, double amax, double vmax)
140  m_nachumkehr = new RampCommand(m_x0 + 0.5 * m_v0 * m_T1, 0.0, m_xtarget, m_amax, m_vmax);
141  m_T2 = 0;
142  m_T3 = 0;
143  m_v2 = 0;
144  m_a3 = 0;
145  }
147 }
148 
150 {
151  m_x0 = rc.m_x0;
152  m_v0 = rc.m_v0;
153  m_xtarget = rc.m_xtarget;
154  m_amax = rc.m_amax;
155  m_vmax = rc.m_vmax;
156 
157  m_T1 = rc.m_T1;
158  m_T2 = rc.m_T2;
159  m_T3 = rc.m_T3;
160  m_a1 = rc.m_a1;
161  m_v2 = rc.m_v2;
162  m_a3 = rc.m_a3;
163 
164  m_umkehr = rc.m_umkehr;
168  if (rc.m_umkehr)
170  else
171  m_nachumkehr = NULL;
172 }
173 
175 {
176  if (m_nachumkehr)
177  delete m_nachumkehr;
178 
179  m_x0 = rc.m_x0;
180  m_v0 = rc.m_v0;
181  m_xtarget = rc.m_xtarget;
182  m_amax = rc.m_amax;
183  m_vmax = rc.m_vmax;
184 
185  m_T1 = rc.m_T1;
186  m_T2 = rc.m_T2;
187  m_T3 = rc.m_T3;
188  m_a1 = rc.m_a1;
189  m_v2 = rc.m_v2;
190  m_a3 = rc.m_a3;
191 
192  m_umkehr = rc.m_umkehr;
196  if (rc.m_umkehr)
198  else
199  m_nachumkehr = NULL;
200 
201  return *this;
202 }
203 
207 double RampCommand::getPos(double TimeElapsed)
208 {
209  if (m_umkehr)
210  {
211  if (TimeElapsed <= m_T1)
212  {
213  return m_x0 + m_v0 * TimeElapsed + 0.5 * m_a1 * TimeElapsed * TimeElapsed; // x = x0 + v0t + a/2*t^2
214  }
215  else
216  {
217  // std::cout << "in getPos(double)\n";
218  return m_nachumkehr->getPos(TimeElapsed - m_T1);
219  }
220  }
221  else
222  {
223  if (TimeElapsed <= m_T1)
224  {
225  return m_x0 + m_v0 * TimeElapsed + 0.5 * m_a1 * TimeElapsed * TimeElapsed; // x = x0 + v0t + a/2*t^2
226  }
227  else if (TimeElapsed <= m_T1 + m_T2)
228  {
229  return m_x0 + m_v0 * m_T1 + 0.5 * m_a1 * m_T1 * m_T1 + m_v2 * (TimeElapsed - m_T1); // x = x1 + v2*t
230  }
231  else if (TimeElapsed <= m_T1 + m_T2 + m_T3)
232  {
233  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) +
234  0.5 * m_a3 * (TimeElapsed - m_T1 - m_T2) * (TimeElapsed - m_T1 - m_T2);
235  // x = x2 + v2t + a/2*t^2
236  }
238  else
239  return m_xtarget;
240  }
241 }
242 
246 double RampCommand::getVel(double TimeElapsed)
247 {
248  if (m_umkehr)
249  {
250  if (TimeElapsed <= m_T1)
251  {
252  return m_v0 + m_a1 * TimeElapsed;
253  }
254  else
255  {
256  return m_nachumkehr->getVel(TimeElapsed - m_T1);
257  }
258  }
259  else
260  {
261  if (TimeElapsed <= m_T1)
262  {
263  return m_v0 + m_a1 * TimeElapsed;
264  }
265  else if (TimeElapsed <= m_T1 + m_T2)
266  {
267  return m_v2;
268  }
269  else if (TimeElapsed <= m_T1 + m_T2 + m_T3)
270  {
271  return m_v2 + m_a3 * (TimeElapsed - m_T1 - m_T2);
272  }
274  else
275  return 0.0;
276  }
277 }
278 
283 {
284  // std::cout << "getTotalTime()\n";
285  if (m_umkehr)
286  return m_T1 + m_nachumkehr->getTotalTime();
287  else
288  return m_T1 + m_T2 + m_T3;
289 }
290 
296 void RampCommand::calculateAV(double x0, double v0, double xtarget, double time, double T3, double amax, double vmax,
297  double& acc, double& vel)
298 {
299  // std::ostream& out(debug);
300 
301  double TG = time;
302 
303  if (TG <= 0)
304  {
305  acc = 0;
306  vel = 0;
307  }
308  else
309  {
310  double delta = xtarget - x0;
312  amax = fabs(amax);
313  amax = (delta >= 0) ? amax : -amax;
314 
315  double d1 = fabs(v0) * TG - 0.5 * T3 * fabs(v0);
316  double d2h = (v0 > 0) ? -T3 * v0 + v0 * sqrt(2 * T3 * TG) : -T3 * v0 - v0 * sqrt(2 * T3 * TG);
317  double d2l = (v0 > 0) ? -T3 * v0 - v0 * sqrt(2 * T3 * TG) : -T3 * v0 + v0 * sqrt(2 * T3 * TG);
318  // double d2 = 0.5 * TG * v0;
319  double d3 = 0.5 * v0 * v0 / amax;
320  // out << "d1:\t" << d1 << "\n";
321  // out << "d2h:\t" << d2h << "\n";
322  // out << "d2l:\t" << d2l << "\n";
323  // out << "d3:\t" << d3 << "\n";
324  // out << "delta:\t" << delta << "\n";
325 
326  if (T3 > 0)
327  {
329  if (fabs(delta) >= d1)
330  {
331  /* out << " Case 1\n"; */
332  /* ---------- */
333  /* / \ */
334  /* \ */
335 
337  double a = (TG / T3 - 1.0);
338  double b = v0 - delta / T3;
339  double c = -0.5 * v0 * v0;
340  // out << " a=" << a << " | b=" << b << " | c=" << c << endl;
342  if (delta >= 0)
343  vel = (-b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a);
344  else
345  vel = (-b - sqrt(b * b - 4.0 * a * c)) / (2.0 * a);
346 
348  acc = vel / T3;
349  }
350  else if (delta >= d2h || delta <= d2l)
352  {
353  /* out << " Case 2\n"; */
354  /* \ */
355  /* ---------- */
356  /* \ */
358  double a = TG;
359  double b = -delta - T3 * v0;
360  double c = 0.5 * v0 * v0 * T3;
361  // out << " a=" << a << " | b=" << b << " | c=" << c << endl;
363  if (delta >= 0)
364  vel = (-b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a);
365  else
366  vel = (-b - sqrt(b * b - 4.0 * a * c)) / (2.0 * a);
367 
369  acc = vel / T3;
370  }
371  else if (fabs(delta) >= d3)
372  {
374 
382 
383  acc = amax;
384 
385  if (delta * v0 > 0)
386  vel = (2 * acc * delta - v0 * v0) / (2 * acc * TG - 2 * v0);
387  else if (-4 * acc * delta + acc * acc * TG * TG + 2 * acc * TG * v0 - v0 * v0 >= 0)
388  if (delta > 0)
389  {
390  // delta>0 (-> a>0), v0 < 0:
391  vel = 0.5 * (acc * TG + v0 - sqrt(-4 * acc * delta + acc * acc * TG * TG + 2 * acc * TG * v0 - v0 * v0));
392  }
393  else
394  {
395  // delta<0 (-> a<0), v0 > 0:
396  vel = 0.5 * (acc * TG + v0 + sqrt(-4 * acc * delta + acc * acc * TG * TG + 2 * acc * TG * v0 - v0 * v0));
397  }
398  else
399  {
403 
406  vel = vmax;
407  }
408  }
409  else
410  {
414 
418  if (4 * delta * delta - 4 * delta * TG * v0 + 2 * TG * TG * v0 * v0 >= 0)
420  if (delta * v0 > 0)
421  acc = (-2.0 * delta + TG * v0 + sqrt(4 * delta * delta - 4 * delta * TG * v0 + 2 * TG * TG * v0 * v0)) / (TG * TG);
422  else
423  acc = (-2.0 * delta + TG * v0 - sqrt(4 * delta * delta - 4 * delta * TG * v0 + 2 * TG * TG * v0 * v0)) / (TG * TG);
424  else
426  acc = amax;
427 
428  vel = vmax;
429  }
430  }
431  else if (T3 == 0)
432  {
436  acc = amax;
437  vel = vmax;
438  }
439  else
440  {
442  acc = 0;
443  vel = 0;
444  }
445  }
449 }
virtual double getPos(double TimeElapsed)
returns the planned position for TimeElapsed (seconds)
RampCommand * m_nachumkehr
Definition: moveCommand.h:184
double m_T1
Definition: moveCommand.h:181
double m_vmax
Definition: moveCommand.h:179
RampCommand(double x0, double v0, double xtarget, double amax, double vmax)
Definition: moveCommand.cpp:26
virtual double T3()
Definition: moveCommand.h:163
virtual double getTotalTime()
returns the planned total time for the movement (in seconds)
static void calculateAV(double x0, double v0, double xtarget, double time, double T3, double amax, double vmax, double &a, double &v)
Calculate the necessary a and v of a rampmove, so that the move will take the desired time...
double getVel()
Definition: moveCommand.h:131
double m_a3
Definition: moveCommand.h:182
double m_T3
Definition: moveCommand.h:181
double getPos()
Definition: moveCommand.h:122
double m_x0
Definition: moveCommand.h:177
virtual double vel()
returns the planned velocity at time of function call (desired velocitys)
Definition: moveCommand.h:84
double m_xtarget
Definition: moveCommand.h:178
double m_amax
Definition: moveCommand.h:179
double m_v0
Definition: moveCommand.h:177
virtual double getVel(double TimeElapsed)
returns the planned velocity for TimeElapsed (seconds)
double m_v2
Definition: moveCommand.h:182
double m_a1
Definition: moveCommand.h:182
virtual RampCommand & operator=(const RampCommand &rc)
double m_T2
Definition: moveCommand.h:181


schunk_powercube_chain
Author(s): Florian Weisshardt
autogenerated on Mon Nov 25 2019 03:48:21