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 }
RampCommand::m_T2
double m_T2
Definition: moveCommand.h:181
RampCommand::m_nachumkehr
RampCommand * m_nachumkehr
Definition: moveCommand.h:184
RampCommand::m_T1
double m_T1
Definition: moveCommand.h:181
RampCommand::m_umkehr
bool m_umkehr
Definition: moveCommand.h:183
RampCommand::m_vmax
double m_vmax
Definition: moveCommand.h:179
RampCommand::T3
virtual double T3()
Definition: moveCommand.h:163
RampCommand
Definition: moveCommand.h:104
RampCommand::getTotalTime
virtual double getTotalTime()
returns the planned total time for the movement (in seconds)
Definition: moveCommand.cpp:282
RampCommand::RampCommand
RampCommand(double x0, double v0, double xtarget, double amax, double vmax)
Definition: moveCommand.cpp:26
moveCommand
Definition: moveCommand.h:24
RampCommand::m_T3
double m_T3
Definition: moveCommand.h:181
moveCommand::vel
virtual double vel()
returns the planned velocity at time of function call (desired velocitys)
Definition: moveCommand.h:84
RampCommand::calculateAV
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.
Definition: moveCommand.cpp:296
RampCommand::getVel
double getVel()
Definition: moveCommand.h:131
RampCommand::m_a3
double m_a3
Definition: moveCommand.h:182
RampCommand::getPos
double getPos()
Definition: moveCommand.h:122
RampCommand::m_amax
double m_amax
Definition: moveCommand.h:179
RampCommand::m_v0
double m_v0
Definition: moveCommand.h:177
RampCommand::m_x0
double m_x0
Definition: moveCommand.h:177
RampCommand::getVel
virtual double getVel(double TimeElapsed)
returns the planned velocity for TimeElapsed (seconds)
Definition: moveCommand.cpp:246
RampCommand::m_xtarget
double m_xtarget
Definition: moveCommand.h:178
moveCommand.h
RampCommand::operator=
virtual RampCommand & operator=(const RampCommand &rc)
Definition: moveCommand.cpp:174
RampCommand::m_v2
double m_v2
Definition: moveCommand.h:182
RampCommand::m_a1
double m_a1
Definition: moveCommand.h:182
RampCommand::getPos
virtual double getPos(double TimeElapsed)
returns the planned position for TimeElapsed (seconds)
Definition: moveCommand.cpp:207


schunk_powercube_chain
Author(s): Florian Weisshardt
autogenerated on Sat May 7 2022 02:17:15