RefValJS_PTP_Trajectory.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 
19 #include <stdexcept>
20 #include <algorithm>
21 #include <vector>
22 
23 //#define PTP_TRAJ_DEBUG
24 
25 const double RefValJS_PTP_Trajectory::weigths[] = { 1.5, 1.5, 1.0, 1.0, 0.8, 0.8, 0.7 };
26 
27 
28 inline double sqr(double x)
29 {
30  return x*x;
31 }
32 
33 RefValJS_PTP_Trajectory::RefValJS_PTP_Trajectory(const trajectory_msgs::JointTrajectory& trajectory, double v_rad_s, double a_rad_s2, bool smooth)
34 {
35  m_trajectory = trajectory;
36  m_length = 0;
37  //m_stepSize = 0.4;
38  m_stepSize = 0.0175; // 0.0175 rad = 1°
39  m_length_parts.clear();
40  m_s_parts.clear();
41 
42  if ( m_trajectory.points.size() < 1 )
43  {
44  throw std::runtime_error("Tried to create reference values for empty trajectory!");
45  }
46 
47  std::vector<std::vector<double> > zwischenPunkte;
48 
49  if (smooth == false)
50  {
51  // Maß dafür, wo groß die Rundung wird
52 // double between_stepsize = 2.5; // 0.2 rad = 11.5°
53  //uhr-messmerf:
54  //double between_stepsize = 0.1; //verkleinert wegen Exception (s.u.)
55  double between_stepsize = 0.8; //AUB
56  for (unsigned int i=0; i < m_trajectory.points.size()-1; i++)
57  {
58  std::vector<double> direction;
59  direction.resize( m_trajectory.points[i+1].positions.size());
60  double len = 0;
61  for(unsigned int j = 0; j < m_trajectory.points[i+1].positions.size(); j++)
62  {
63  direction.at(j) = m_trajectory.points[i+1].positions.at(j)-m_trajectory.points[i].positions.at(j);
64  len += direction.at(j) * direction.at(j);
65  }
66  double dist = sqrt(len);
67  int num_segs = ceil(dist/between_stepsize);
68  zwischenPunkte.resize(num_segs);
69  for (int j=0; j < num_segs; j++)
70  {
71  std::vector<double> betw_joint;
72  betw_joint.resize(direction.size());
73  for(unsigned int d=0; d < direction.size(); d++)
74  {
75  betw_joint.at(d) = m_trajectory.points[i].positions.at(d) + direction.at(d) * ( (double)j / (double)num_segs );
76  }
77  zwischenPunkte.at(j) = betw_joint;
78  }
79  }
80  zwischenPunkte.push_back( m_trajectory.points.back().positions );
81  } else
82  {
83  zwischenPunkte.resize(trajectory.points.size());
84  for(unsigned int i = 0; i < trajectory.points.size(); i++)
85  {
86  zwischenPunkte.at(i) = trajectory.points.at(i).positions;
87  }
88  }
89  ROS_INFO("Calculated %lu zwischenPunkte", zwischenPunkte.size());
90 
91  m_TrajectorySpline.setCtrlPoints(zwischenPunkte);
92 
93  // Note: unlike the name of the function suggests, the distance between any two neigbouring points
94  // is not always the same!
96  {
97  //uhr-messmerf: diese exception wird geworfen, wenn nicht genügend Stützpunkte vorhanden sind (kleiner m_iGrad=3)
98  //uhr-messmerf: dies tritt auf, wenn die Punkte der Trajectory pfad zu nah beieinander liegen (dist < between_stepsize=2.5)
99  throw std::runtime_error("Error in BSplineND::ipoWithConstSampleDist!");
100  }
101  m_SplinePoints = zwischenPunkte;
102  ROS_INFO("Calculated %lu splinepoints", m_SplinePoints.size());
103 
104  m_length_cumulated.clear();
105  m_length_cumulated.push_back(0.0);
106 
107  for (unsigned int i=0; i < m_SplinePoints.size()-1; i++)
108  {
109  std::vector<double> dist;
110  dist.resize(m_SplinePoints[i].size());
111  for(unsigned int j=0; j < m_SplinePoints[i].size(); j++)
112  {
113  dist.at(j) = m_SplinePoints[i+1].at(j) - m_SplinePoints[i].at(j);
114  }
115  //double max = fabs(direction.getMax());
116  //double min = fabs(direction.getMin());
117  m_length_parts.push_back( norm(dist) );
118  m_length += norm(dist);
119  m_length_cumulated.push_back(m_length);
120  }
121 
123 
124  for (unsigned int i=0; i < m_length_parts.size(); i++)
125  {
126  m_s_parts.push_back( m_length_parts[i] / m_length );
127  }
128 
129  m_v_rad_s = v_rad_s;
130  m_a_rad_s2 = a_rad_s2;
131 
132  /* Parameter für Beschl.begrenzte Fahrt: */
133  double a = fabs(m_a_rad_s2);
134  double v = fabs(m_v_rad_s);
135 
136  if (m_length > v*v/a)
137  {
138  // Phase mit konst. Geschw. wird erreicht:
139  m_T1 = m_T3 = v / a;
140  m_T2 = (m_length - v*v/a) / v;
141 
142  // Wegparameter s immer positiv, deswegen keine weitere Fallunterscheidung nötig:
143  m_sv2 = 1.0 / (m_T1 + m_T2);
144  m_sa1 = m_sv2 / m_T1;
145  m_sa3 = -m_sa1;
146  }
147  else {
148  // Phase konst. Geschw. wird nicht erreicht:
149  m_T2 = 0.0;
150  m_T1 = m_T3 = sqrt(m_length / a);
151 
152  m_sv2 = 1.0 / m_T1;
153  m_sa1 = m_sv2 / m_T1;
154  m_sa3 = -m_sa1;
155 
156  }
157  // Bewegung vollständig charakterisiert.
158 
159 }
160 
161 std::vector<double> RefValJS_PTP_Trajectory::r(double s) const
162 {
163  //printw("Line %d\ts: %f\n", __LINE__, s);
164  std::vector<double> soll;
165  if (s <= 0)
166  {
167  soll = m_trajectory.points.front().positions;
168  } else
169  if (s < 1)
170  {
171  // since the Distances between the points of m_SplinePoints are not equal,
172  // we first need to find the last i where m_length_cumulated[i] is smaller than s*m_length
173 
174  // return the first index i, where m_length_cumulated[i] is not smaller s * m_length
175  // more information under: http://www.cplusplus.com/reference/algorithm/lower_bound/
176  //typedef std::vector<double> dvec;
177 
178 
179  vecd_it start = m_length_cumulated.begin();
180  vecd_it end = m_length_cumulated.end();
181  vecd_it it = upper_bound(start, end, s * m_length);
182 
183  int i = int(it-start) - 1;
184  double frac = (s * m_length - m_length_cumulated[i]) / m_length_parts[i];
185 
186 
187  /*
188  int i = floor( s * m_param_length / m_stepSize);
189  double frac = s * m_param_length / m_stepSize - (double) i;
190  */
191  // interpolate
192  soll.resize(m_SplinePoints[i].size());
193  for(unsigned int j = 0; j < m_SplinePoints[i].size(); j++)
194  {
195  soll.at(j) = m_SplinePoints[i].at(j) + (m_SplinePoints[i+1].at(j)-m_SplinePoints[i].at(j))*frac;
196  }
197  }
198  else
199  {
200  soll = m_trajectory.points.back().positions;
201  }
202  return soll;
203 }
204 
205 double RefValJS_PTP_Trajectory::s(double t) const
206 {
207  if (t >= m_T1 + m_T2 + m_T3)
208  return 1.0;
209  else if (t >= m_T1 + m_T2)
210  {
211  return 0.5*m_sa1*m_T1*m_T1 + m_sv2*m_T2 + m_sv2*(t-m_T1-m_T2) + 0.5*m_sa3*sqr(t-m_T1-m_T2);
212  }
213  else if (t >= m_T1)
214  {
215  return 0.5*m_sa1*m_T1*m_T1 + m_sv2*(t-m_T1);
216  }
217  else if (t > 0.0)
218  {
219  return 0.5*m_sa1*t*t;
220  }
221  else return 0.0;
222 }
223 
224 double RefValJS_PTP_Trajectory::ds_dt(double t) const
225 {
226  if (t >= m_T1 + m_T2 + m_T3)
227  return 0.0;
228  else if (t >= m_T1 + m_T2)
229  {
230  return m_sv2 + m_sa3*(t-m_T1-m_T2);
231  }
232  else if (t >= m_T1)
233  {
234  return m_sv2;
235  }
236  else if (t > 0.0)
237  {
238  return m_sa1*t;
239  }
240  else return 0.0;
241 }
242 
243 
244 std::vector<double> RefValJS_PTP_Trajectory::dr_ds(double s) const
245 {
246  //printw("Line %d\ts: %f\n", __LINE__, s);
247  std::vector<double> result = m_trajectory.points.front().positions;
248  if (s < 0.0 || s >= 1.0)
249  {
250  for(unsigned int j=0; j < result.size(); j++)
251  result.at(j) = 0.0;
252  }
253  else
254  {
255 
256  vecd_it start = m_length_cumulated.begin();
257  vecd_it end = m_length_cumulated.end();
258  vecd_it it = upper_bound(start, end, s * m_length);
259 
260  int i = int(it-start) - 1;
261  double frac = (s * m_length - m_length_cumulated[i]) / m_length_parts[i];
262 
263 
264  /*
265  int i = floor( s * m_param_length / m_stepSize);
266  double frac = s * m_param_length / m_stepSize - (double) i;
267  */
268 
269  std::vector<double> vi; // vi
270  std::vector<double> vii;// vi+1
271 
272  double step_s = m_stepSize / m_param_length;
273 
274  if ( i == 0 )
275  {
276  // vi rechtsseitig approximieren
277  step_s = m_length_parts[0] / m_length;
278  vi.resize(m_SplinePoints[i].size());
279  for(unsigned int k = 0; k < m_SplinePoints[i].size(); k++)
280  {
281  vi.at(k) = (m_SplinePoints[1].at(k) - m_SplinePoints[0].at(k)) / step_s;
282  }
283  vii = vi;
284  // vi+1 zentrisch approximieren
285  //step_s = (m_length_parts[i]+m_length_parts[i+1]) / m_length;
286  //vii = (m_SplinePoints[i+2] - m_SplinePoints[i]) / (2.0 * step_s);
287  } else
288  if ( i == (int) m_SplinePoints.size() - 2 )
289  {
290  // vi zentrisch:
291  //step_s = (m_length_parts[i]+m_length_parts[i-1]) / m_length;
292  //vi = (m_SplinePoints[i+1] - m_SplinePoints[i-1]) / (2.0 * step_s);
293  // vi+1 linksseitig:
294  step_s = (m_length_parts[i]) / m_length;
295  vii.resize(m_SplinePoints[i].size());
296  for(unsigned int k = 0; k < m_SplinePoints[i].size(); k++)
297  vii.at(k) = (m_SplinePoints[i+1].at(k) - m_SplinePoints[i].at(k)) / step_s;
298  vi = vii;
299  } else
300  {
301  // beide zentrisch:
302  step_s = (m_length_parts[i]+m_length_parts[i-1]) / m_length;
303  vi.resize(m_SplinePoints[i].size());
304  for(unsigned int k = 0; k < m_SplinePoints[i].size(); k++)
305  vi.at(k) = (m_SplinePoints[i+1].at(k) - m_SplinePoints[i-1].at(k)) / step_s;
306  step_s = (m_length_parts[i]+m_length_parts[i+1]) / m_length;
307  vii.resize(m_SplinePoints[i].size());
308  for(unsigned int k = 0; k < m_SplinePoints[i].size(); k++)
309  vii.at(k) = (m_SplinePoints[i+2].at(k) - m_SplinePoints[i].at(k)) / step_s;
310  }
311 
312  // linear interpolieren:
313  result.resize(m_SplinePoints[i].size());
314  for(unsigned int k = 0; k < m_SplinePoints[i].size(); k++)
315  result.at(k) = vi.at(k) + (vii.at(k)-vi.at(k))*frac;
316  }
317 
318  return result;
319 }
320 
321 
322 
323 
d
double sqr(double x)
RefValJS_PTP_Trajectory(const trajectory_msgs::JointTrajectory &trajectory, double v_rad_s, double a_rad_s2, bool smooth=false)
ROSCPP_DECL void start()
BSplineND< std::vector< double > > m_TrajectorySpline
double norm(const std::vector< double > &j)
std::vector< double >::const_iterator vecd_it
void setCtrlPoints(const std::vector< PointND > &ctrlPointVec)
Definition: BSplineND.h:94
trajectory_msgs::JointTrajectory m_trajectory
bool ipoWithConstSampleDist(double dIpoDist, std::vector< PointND > &ipoVec)
Definition: BSplineND.h:167
double ds_dt(double t) const
#define ROS_INFO(...)
static const double weigths[]
std::vector< double > r(double s) const
double getMaxdPos() const
Definition: BSplineND.h:54
std::vector< double > dr_ds(double s) const
std::vector< std::vector< double > > m_SplinePoints


cob_trajectory_controller
Author(s): Alexander Bubeck
autogenerated on Thu Apr 8 2021 02:39:55