BSplineND.h
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 #ifndef BSPLINE_ND_H
19 #define BSPLINE_ND_H
20 //-----------------------------------------------
21 
22 #include <vector>
23 #include <cmath>
24 #include <assert.h>
25 
26 #define BSPLINE_TINY 1e-20
27 
28 
36 template <class PointND>
37 class BSplineND
38 {
39 public:
40  //----------------------- Interface
41  BSplineND();
42 
43  ~BSplineND();
44 
45  void setCtrlPoints(const std::vector<PointND>& ctrlPointVec );
46 
47  // main functions
48  bool ipoWithConstSampleDist(double dIpoDist, std::vector<PointND>& ipoVec);
49 
50  bool ipoWithNumSamples(int iNumPts, std::vector<PointND>& ipoVec);
51 
52  void eval(double dPos, PointND& point);
53 
54  double getMaxdPos() const { return m_dLength; }
55 
56 private:
57  //----------------------- Parameters
58  double m_iGrad;
59 
60  //----------------------- Variables
61  std::vector<PointND> m_CtrlPointVec;
62 
63  std::vector<double> m_KnotVec;
64 
65  double m_dLength;
66 
67  //----------------------- Member functions
68  double evalBasis(double t, unsigned int i, int n);
69 
70 };
71 
72 
73 /*****************************************************************************
74  * *
75  * Implementierung bei TemplateKlassen im Headerfile *
76  * *
77  *****************************************************************************/
78 
79 template <class PointND>
81 {
82  m_iGrad = 3;
83  m_dLength = 0;
84 }
85 
86 //-----------------------------------------------
87 template <class PointND>
89 {
90 }
91 
92 //-----------------------------------------------
93 template <class PointND>
94 void BSplineND<PointND>::setCtrlPoints(const std::vector<PointND>& ctrlPointVec )
95 {
96  int iNumCtrlPoint;
97  int i;
98  double d;
99 
100  m_CtrlPointVec = ctrlPointVec;
101  iNumCtrlPoint = m_CtrlPointVec.size();
102 
103  if (iNumCtrlPoint < m_iGrad)
104  {
105  return;
106  }
107 
108  m_KnotVec.resize( iNumCtrlPoint + m_iGrad );
109 
110  // Calculate knots
111  for(i = 0; i< m_iGrad; i++)
112  {
113  m_KnotVec[i] = 0;
114  }
115 
116  int iNumInternalKnots = iNumCtrlPoint - m_iGrad;
117  for(i=0; i<iNumInternalKnots; i++)
118  {
119  double Distance1 = 0.0;
120  for(unsigned int k = 0; k < m_CtrlPointVec[i+1].size(); k++)
121  {
122  Distance1 += (m_CtrlPointVec[i+1].at(k) - m_CtrlPointVec[i+2].at(k)) * (m_CtrlPointVec[i+1].at(k) - m_CtrlPointVec[i+2].at(k));
123  }
124  d= m_KnotVec[i+m_iGrad-1] + sqrt(Distance1);
125  // OLD WITH JOINTD d= m_KnotVec[i+m_iGrad-1] + Distance( m_CtrlPointVec[i+1], m_CtrlPointVec[i+2] );
126  m_KnotVec[i+m_iGrad] = d;
127  }
128  double Distance2 = 0.0;
129  for(unsigned int k = 0; k < m_CtrlPointVec[iNumInternalKnots+1].size(); k++)
130  {
131  Distance2 += ( m_CtrlPointVec[iNumInternalKnots+1].at(k) - m_CtrlPointVec[iNumInternalKnots+2].at(k)) * ( m_CtrlPointVec[iNumInternalKnots+1].at(k) - m_CtrlPointVec[iNumInternalKnots+2].at(k));
132  }
133  d = m_KnotVec[iNumCtrlPoint-1] + sqrt(Distance2);
134  // OLD WITH JOINTD d = m_KnotVec[iNumCtrlPoint-1] + Distance( m_CtrlPointVec[iNumInternalKnots+1], m_CtrlPointVec[iNumInternalKnots+2] );
135 
136  for(i = 0; i< m_iGrad; i++)
137  {
138  m_KnotVec[i+iNumCtrlPoint] = d;
139  }
140 
141  // This is not the arc-length but the maximum of the spline parameter.
142  // eval(m_dLength, Point) should return the last point of the spline
143  m_dLength = d;
144 
145 }
146 
147 
148 //-----------------------------------------------
149 template <class PointND>
150 void BSplineND<PointND>::eval(double dPos, PointND& point)
151 {
152  double dFak;
153 
154  for(unsigned int i = 0; i<point.size(); i++)
155  point.at(i) = 0.0;
156  for(unsigned int i = 0; i < m_CtrlPointVec.size(); i++)
157  {
158  dFak = evalBasis(dPos, i, m_iGrad);
159  for(unsigned int j = 0; j<point.size(); j++)
160  point.at(j) += m_CtrlPointVec[i][j] * dFak; // !!!! TODO this might be wrong due to change from JointD to std::vector
161  }
162 }
163 
164 
165 //-----------------------------------------------
166 template <class PointND>
167 bool BSplineND<PointND>::ipoWithConstSampleDist(double dIpoDist, std::vector<PointND >& ipoVec)
168 {
169  PointND buf = m_CtrlPointVec.front();
170  int iNumOfPoints;
171  double dPos;
172  //int iStart, iNextStart;
173 
174  if (m_CtrlPointVec.size() < m_iGrad)
175  {
176  ipoVec = m_CtrlPointVec;
177  return false;
178  }
179 
180  // Felix: Dies ist falsch? m_KnotVec.back() enthält nicht die tatsächliche
181  // Bogenlänge entlang des Splines. Folge: Ergebnisvektor ist am Ende abge-
182  // schnitten.
183  iNumOfPoints = m_KnotVec.back() / dIpoDist + 2;
184  ipoVec.resize(iNumOfPoints);
185 
186  // Calculate x- and y-coordinates
187  dPos = 0;
188  for(int i=0; i < iNumOfPoints -1 ; i++)
189  {
190  eval(dPos, buf);
191  ipoVec[i] = buf;
192  dPos += dIpoDist;
193  }
194 
195  ipoVec.back() = m_CtrlPointVec.back();
196 
197  return true;
198 }
199 
200 /*
201 //-----------------------------------------------
202 //Florian
203 bool BSplineND<PointND>::ipoWithConstSampleDist(double dIpoDist, OmniPath& ipoVec)
204 {
205  Neo::Vector2D buf;
206  int iNumOfPoints;
207  int iNumOfCtrlPoints;
208  double dPos, viewang;
209  double dx, dy, da;
210  int i;
211  bool bRet = true;
212  int iStart, iNextStart;
213 
214  iNumOfCtrlPoints = m_OmniCtrlPointVec.getSize();
215 
216  if ( iNumOfCtrlPoints < m_iGrad )
217  {
218  bRet = false;
219 
220  iNumOfPoints = m_OmniCtrlPointVec.getSize();
221  ipoVec.clearVec();
222  for(i=0; i<iNumOfPoints; i++)
223  {
224  ipoVec.addFrame(m_OmniCtrlPointVec.m_VecPathPnt[i].Frm,m_OmniCtrlPointVec.m_VecPathPnt[i].ViewAng);
225  }
226 
227  if ( iNumOfCtrlPoints < 2 )
228  {
229  return bRet;
230  }
231  }
232  else
233  {
234  iNumOfPoints = m_KnotVec.back() / dIpoDist + 2;
235  ipoVec.m_VecPathPnt.resize(iNumOfPoints);
236 
237  // Calculate x- and y-coordinates
238  dPos = 0;
239  iStart = 0;
240  for(i=0; i < iNumOfPoints -1 ; i++)
241  {
242 // eval(dPos, buf);
243  eval(dPos, buf, iStart, iNextStart, viewang);
244  iStart = iNextStart;
245 
246  ipoVec.m_VecPathPnt[i].Frm.x() = buf.x();
247  ipoVec.m_VecPathPnt[i].Frm.y() = buf.y();
248  ipoVec.m_VecPathPnt[i].ViewAng=viewang;
249  dPos += dIpoDist;
250  }
251 
252  ipoVec.m_VecPathPnt.back().Frm.x() = m_OmniCtrlPointVec.m_VecPathPnt.back().Frm.x();
253  ipoVec.m_VecPathPnt.back().Frm.y() = m_OmniCtrlPointVec.m_VecPathPnt.back().Frm.y();
254  ipoVec.m_VecPathPnt.back().ViewAng = m_OmniCtrlPointVec.m_VecPathPnt.back().ViewAng;
255  }
256 
257  // Calculate angle
258  for(i=0; i < iNumOfPoints-1; i++)
259  {
260  dx = ipoVec.m_VecPathPnt[i+1].Frm.x() - ipoVec.m_VecPathPnt[i].Frm.x();
261  dy = ipoVec.m_VecPathPnt[i+1].Frm.y() - ipoVec.m_VecPathPnt[i].Frm.y();
262  da = atan2(dy, dx);
263  MathSup::normalizePi(da);
264  ipoVec.m_VecPathPnt[i].Frm.a() = da;
265  }
266  ipoVec.m_VecPathPnt.back().Frm.a() = da;
267 
268  return bRet;
269 }
270 */
271 
272 //-----------------------------------------------
273 template <class PointND>
274 bool BSplineND<PointND>::ipoWithNumSamples(int iNumOfPoints, std::vector<PointND >& ipoVec)
275 {
276  PointND buf;
277  double dPos, dInc;
278 
279  if (m_CtrlPointVec.size() < m_iGrad)
280  {
281  ipoVec = m_CtrlPointVec;
282  return false;
283  }
284 
285  dInc = m_KnotVec.back() / (double)(iNumOfPoints-1);
286  ipoVec.resize(iNumOfPoints);
287 
288  // Calculate x- and y-coordinates
289  dPos = 0;
290  for(int i=0; i < iNumOfPoints -1 ; i++)
291  {
292  eval(dPos, buf);
293 
294  ipoVec[i] = buf;
295  dPos += dInc;
296  }
297 
298  ipoVec.back() = m_CtrlPointVec.back();
299  return true;
300 }
301 
302 
303 template <class PointND>
304 double BSplineND<PointND>::evalBasis(double u, unsigned int i, int n)
305 {
306  assert(i >= 0);
307  assert(i < m_KnotVec.size() - 1 );
308 
309  if (n==1)
310  {
311  if ( (m_KnotVec[i]<=u) && ( u<m_KnotVec[i+1]) )
312  {
313  return 1.0;
314  }
315  else
316  {
317  return 0.0;
318  }
319  }
320  else
321  {
322  double N;
323  double dNum1, dNum2;
324  double dDen1, dDen2;
325 
326  dDen1 = u - m_KnotVec[i];
327  dNum1 = m_KnotVec[i+n-1] - m_KnotVec[i];
328 
329  dDen2 = m_KnotVec[i+n] - u;
330  dNum2 = m_KnotVec[i+n] - m_KnotVec[i+1];
331 
332  if ( (fabs(dNum1) > BSPLINE_TINY)&&(fabs(dNum2) > BSPLINE_TINY) )
333  {
334  N = dDen1 / dNum1 * evalBasis(u, i , n-1);
335  N += dDen2 / dNum2 * evalBasis(u, i+1 , n-1);
336  }
337  else if ( (fabs(dNum1) < BSPLINE_TINY)&&(fabs(dNum2) > BSPLINE_TINY) )
338  {
339  N = dDen2 / dNum2 * evalBasis(u, i+1 , n-1);
340  }
341  else if ((fabs(dNum1) > BSPLINE_TINY)&&(fabs(dNum2) < BSPLINE_TINY))
342  {
343  N = dDen1 / dNum1 * evalBasis(u, i , n-1);
344  }
345  else
346  {
347  N = 0;
348  }
349 
350  return N;
351  }
352 }
353 
354 
355 
356 #endif
d
#define BSPLINE_TINY
Definition: BSplineND.h:26
void setCtrlPoints(const std::vector< PointND > &ctrlPointVec)
Definition: BSplineND.h:94
double evalBasis(double t, unsigned int i, int n)
Definition: BSplineND.h:304
void eval(double dPos, PointND &point)
Definition: BSplineND.h:150
bool ipoWithConstSampleDist(double dIpoDist, std::vector< PointND > &ipoVec)
Definition: BSplineND.h:167
double m_iGrad
Definition: BSplineND.h:58
std::vector< double > m_KnotVec
Definition: BSplineND.h:63
BSplineND()
Definition: BSplineND.h:80
std::vector< PointND > m_CtrlPointVec
Definition: BSplineND.h:61
bool ipoWithNumSamples(int iNumPts, std::vector< PointND > &ipoVec)
Definition: BSplineND.h:274
~BSplineND()
Definition: BSplineND.h:88
double getMaxdPos() const
Definition: BSplineND.h:54
double m_dLength
Definition: BSplineND.h:65


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