transformer
Transformer.hpp
Go to the documentation of this file.
1 #ifndef TRANSFORMER_H
2 #define TRANSFORMER_H
3 
4 #include <Eigen/Geometry>
5 #include <string>
6 #include <base/Time.hpp>
7 #include <aggregator/StreamAligner.hpp>
8 #include <map>
9 #include <boost/bind.hpp>
10 #include <base/samples/RigidBodyState.hpp>
11 #include "TransformationStatus.hpp"
12 
13 namespace transformer {
14 
15 typedef base::samples::RigidBodyState TransformationType;
17 
19 {
20  friend class Transformer;
21  private:
22  Transformation(const std::string &sourceFrame, const std::string &targetFrame)
23  : valid(false)
24  , sourceFrame(sourceFrame)
25  , targetFrame(targetFrame)
26  , generatedTransformations(0)
27  , failedNoChain(0)
28  , failedNoSample(0)
29  , failedInterpolationImpossible(0) {};
30  bool valid;
31 
32  std::string sourceFrame;
33  std::string targetFrame;
34  std::string sourceFrameMapped;
35  std::string targetFrameMapped;
36  std::vector<TransformationElement *> transformationChain;
37 
38  mutable base::Time lastGeneratedValue;
39  mutable uint64_t generatedTransformations;
40  mutable uint64_t failedNoChain;
41  mutable uint64_t failedNoSample;
42  mutable uint64_t failedInterpolationImpossible;
43  boost::function<void (const base::Time &ts)> transformationChangedCallback;
44 
45  void setFrameMapping(const std::string &frameName, const std::string &newName);
46 
56  void setTransformationChain(const std::vector<TransformationElement *> &chain);
57 
58  Transformation(const Transformation &other)
59  {
60  }
61 
62  public:
67 
71  void updateStatus(TransformationStatus& status) const;
72 
76  const std::string &getSourceFrame() const
77  {
78  if(sourceFrameMapped.empty())
79  return sourceFrame;
80 
81  return sourceFrameMapped;
82  }
83 
87  const std::string &getTargetFrame() const
88  {
89  if(targetFrameMapped.empty())
90  return targetFrame;
91 
92  return targetFrameMapped;
93  }
94 
98  void reset()
99  {
100  valid = false;
101  transformationChain.clear();
102  lastGeneratedValue = base::Time();
103  generatedTransformations = 0;
104  failedNoChain = 0;
105  failedNoSample = 0;
106  failedInterpolationImpossible = 0;
107  }
108 
113  void registerUpdateCallback(boost::function<void (const base::Time &ts)> callback);
114 
121  bool get(const base::Time& atTime, transformer::TransformationType& result, bool interpolate = false) const;
122  bool getChain(const base::Time& atTime, std::vector<TransformationType>& result, bool interpolate = false) const;
123 
124  template <class T>
125  bool get(const base::Time& atTime, T& result, bool interpolate = false) const;
126  bool getChain(const base::Time& atTime, std::vector<Eigen::Affine3d>& result, bool interpolate = false) const;
127 };
128 
133  public:
134  TransformationElement(const std::string &sourceFrame, const std::string &targetFrame): sourceFrame(sourceFrame), targetFrame(targetFrame) {};
136 
144  virtual bool getTransformation(const base::Time &atTime, bool doInterpolation, TransformationType &tr) = 0;
145 
150  virtual void addTransformationChangedCallback(boost::function<void (const base::Time &ts)> callback)
151  {
152  elementChangedCallbacks.push_back(callback);
153  };
154 
159  {
160  elementChangedCallbacks.clear();
161  }
162 
166  const std::string &getSourceFrame() const
167  {
168  return sourceFrame;
169  }
170 
174  const std::string &getTargetFrame() const
175  {
176  return targetFrame;
177  }
178 
179  protected:
180  std::vector<boost::function<void (const base::Time &ts)> > elementChangedCallbacks;
181  private:
182  std::string sourceFrame;
183  std::string targetFrame;
184 };
185 
190  public:
191  StaticTransformationElement(const std::string &sourceFrame, const std::string &targetFrame, const TransformationType &transform) : TransformationElement(sourceFrame, targetFrame), staticTransform(transform) {};
193 
194  virtual bool getTransformation(const base::Time& atTime, bool doInterpolation, TransformationType& tr)
195  {
196  tr = staticTransform;
197  tr.time = atTime;
198  return true;
199  };
200  private:
201  TransformationType staticTransform;
202 };
203 
210  public:
211  DynamicTransformationElement(const std::string& sourceFrame, const std::string& targetFrame, aggregator::StreamAligner& aggregator, int priority = -10);
212  virtual ~DynamicTransformationElement();
213 
214  virtual bool getTransformation(const base::Time& atTime, bool doInterpolation, TransformationType& result);
215 
216  int getStreamIdx() const
217  {
218  return streamIdx;
219  }
220 
221  private:
222 
223  void aggregatorCallback(const base::Time &ts, const TransformationType &value);
224 
225  aggregator::StreamAligner &aggregator;
226  base::Time lastTransformTime;
227  TransformationType lastTransform;
228  bool gotTransform;
229  int streamIdx;
230 };
231 
236  public:
237  InverseTransformationElement(TransformationElement *source): TransformationElement(source->getTargetFrame(), source->getSourceFrame()), nonInverseElement(source) {};
239  virtual bool getTransformation(const base::Time& atTime, bool doInterpolation, TransformationType& tr);
240 
241  virtual void addTransformationChangedCallback(boost::function<void (const base::Time &ts)> callback)
242  {
243  nonInverseElement->addTransformationChangedCallback(callback);
244  };
245 
246  TransformationElement* getElement();
247  TransformationElement const* getElement() const;
248  private:
249  TransformationElement *nonInverseElement;
250 };
251 
252 
253 class TransformationNode;
254 
259 {
260  public:
262  TransformationTree() : maxSeekDepth(20) {};
263 
267  std::pair<int, int> getElementsCount() const;
268 
275  void addTransformation(TransformationElement *element);
276 
287  bool getTransformationChain(std::string from, std::string to, std::vector<TransformationElement *> &result);
288 
292  std::vector<TransformationElement *> &getAvailableElements()
293  {
294  return availableElements;
295  }
296 
300  ~TransformationTree();
301 
305  void clear();
306 
309  void dumpTree() const;
310 
311  private:
313  const int maxSeekDepth;
314 
321  void addMatchingTransforms(std::string from, transformer::TransformationNode* node);
322 
329  std::vector< TransformationNode* >::const_iterator checkForMatchingChildFrame(const std::string &to, const TransformationNode &node);
330 
332  std::vector<TransformationElement *> availableElements;
333 };
334 
339 {
340  protected:
341  aggregator::StreamAligner aggregator;
342  std::map<std::pair<std::string, std::string>, int> transformToStreamIndex;
343  std::vector<Transformation *> transformations;
345  int priority;
347 
348  void recomputeAvailableTransformations();
349 
350  public:
351 
357  Transformer( int priority = -10 )
358  : priority( priority ) {};
359 
368  virtual void clear();
369 
376  void addTransformationChain(std::string from, std::string to, const std::vector<TransformationElement *> &chain);
377 
386  Transformation &registerTransformation(std::string sourceFrame, std::string targetFrame);
387 
391  const std::vector<Transformation *> &getRegisteredTransformations()
392  {
393  return transformations;
394  }
395 
401  void unregisterTransformation(Transformation *transformation);
402 
408  void registerTransformCallback(Transformation &transform , boost::function<void (const base::Time &ts, const Transformation &t)> callback)
409  {
410  transform.registerUpdateCallback(boost::bind( callback, _1, boost::ref(transform) ));
411  }
412 
418  template <class T> int registerDataStream(base::Time dataPeriod, boost::function<void (const base::Time &ts, const T &value)> callback, int priority = -1, const std::string &name = std::string())
419  {
420  return aggregator.registerStream<T>(boost::bind( callback, _1, _2), 0, dataPeriod, priority, name);
421  };
422 
428  template <class T> int registerDataStreamWithTransform(base::Time dataPeriod, Transformation &transformation, boost::function<void (const base::Time &ts, const T &value, const Transformation &t)> callback, int priority = - 1, const std::string &name = std::string())
429  {
430  return aggregator.registerStream<T>(boost::bind( callback, _1, _2, boost::ref(transformation) ), 0, dataPeriod, priority, name);
431  };
432 
436  void unregisterDataStream(int idx)
437  {
438  return aggregator.unregisterStream(idx);
439  };
440 
444  void disableStream( int idx )
445  {
446  return aggregator.disableStream( idx );
447  }
448 
452  void enableStream( int idx )
453  {
454  return aggregator.enableStream( idx );
455  }
456 
460  bool isStreamActive( int idx ) const
461  {
462  return aggregator.isStreamActive( idx );
463  }
464 
465  void requestTransformationAtTime(int idx, base::Time ts)
466  {
467  aggregator.push(idx, ts, false);
468  };
469 
474  template <class T> void pushData( int idx,const base::Time &ts, const T& data )
475  {
476  aggregator.push(idx, ts, data);
477  };
478 
482  int step() {
483  return aggregator.step();
484  }
485 
489  const aggregator::StreamAlignerStatus &getStreamAlignerStatus()
490  {
491  return aggregator.getStatus();
492  }
493 
494  void setTimeout(const base::Time &t )
495  {
496  aggregator.setTimeout(t);
497  }
498 
506  virtual void pushDynamicTransformation(const TransformationType &tr);
507 
511  void pushStaticTransformation(const TransformationType &tr);
512 
513 
514  void setFrameMapping(const std::string &frameName, const std::string &newName);
515 
520  const aggregator::StreamAlignerStatus& getStatus()
521  {
522  return aggregator.getStatus();
523  }
524 
528  const TransformerStatus& getTransformerStatus();
529 
533  virtual ~Transformer();
534 };
535 
536 template<class T>
537 bool Transformation::get(const base::Time& atTime, T& result, bool interpolate) const
538 {
539  result = T::Identity();
540  if (!valid)
541  {
542  failedNoChain++;
543  return false;
544  }
545 
546  for(std::vector<TransformationElement *>::const_iterator it = transformationChain.begin(); it != transformationChain.end(); it++)
547  {
548  TransformationType tr;
549  if(!(*it)->getTransformation(atTime, interpolate, tr))
550  {
551  if (interpolate)
552  failedInterpolationImpossible++;
553  else
554  failedNoSample++;
555 
556  //no sample available, return
557  return false;
558  }
559 
560  //TODO, this might be a costly operation
561  T trans( tr );
562 
563  //apply transformation
564  result = result * trans;
565  }
566  lastGeneratedValue = atTime;
567  generatedTransformations++;
568  return true;
569 }
570 
571 }
572 #endif // TRANSFORMER_H
Definition: Transformer.hpp:18
const std::string & getSourceFrame() const
Definition: Transformer.hpp:76
virtual ~TransformationElement()
Definition: Transformer.hpp:135
void setTimeout(const base::Time &t)
Definition: Transformer.hpp:494
TransformationTree()
default constructor
Definition: Transformer.hpp:262
virtual bool getTransformation(const base::Time &atTime, bool doInterpolation, TransformationType &tr)
Definition: Transformer.hpp:194
const std::string & getTargetFrame() const
Definition: Transformer.hpp:87
const std::vector< Transformation * > & getRegisteredTransformations()
Definition: Transformer.hpp:391
virtual void addTransformationChangedCallback(boost::function< void(const base::Time &ts)> callback)
Definition: Transformer.hpp:241
void enableStream(int idx)
Definition: Transformer.hpp:452
std::vector< Transformation * > transformations
Definition: Transformer.hpp:343
virtual ~StaticTransformationElement()
Definition: Transformer.hpp:192
std::vector< boost::function< void(const base::Time &ts)> > elementChangedCallbacks
Definition: Transformer.hpp:180
virtual void clearTransformationChangedCallbacks()
Definition: Transformer.hpp:158
TransformerStatus transformerStatus
Definition: Transformer.hpp:346
aggregator::StreamAligner aggregator
Definition: Transformer.hpp:341
StaticTransformationElement(const std::string &sourceFrame, const std::string &targetFrame, const TransformationType &transform)
Definition: Transformer.hpp:191
Transformer(int priority=-10)
Definition: Transformer.hpp:357
void registerTransformCallback(Transformation &transform, boost::function< void(const base::Time &ts, const Transformation &t)> callback)
Definition: Transformer.hpp:408
Definition: TransformationStatus.hpp:13
void reset()
Definition: Transformer.hpp:98
TransformationTree transformationTree
Definition: Transformer.hpp:344
base::samples::RigidBodyState TransformationType
Definition: Transformer.hpp:15
virtual void addTransformationChangedCallback(boost::function< void(const base::Time &ts)> callback)
Definition: Transformer.hpp:150
const aggregator::StreamAlignerStatus & getStatus()
Definition: Transformer.hpp:520
Definition: NonAligningTransformer.hpp:6
void unregisterDataStream(int idx)
Definition: Transformer.hpp:436
int registerDataStream(base::Time dataPeriod, boost::function< void(const base::Time &ts, const T &value)> callback, int priority=-1, const std::string &name=std::string())
Definition: Transformer.hpp:418
void disableStream(int idx)
Definition: Transformer.hpp:444
Definition: TransformationStatus.hpp:70
Definition: Transformer.hpp:189
Definition: Transformer.hpp:132
TransformationElement(const std::string &sourceFrame, const std::string &targetFrame)
Definition: Transformer.hpp:134
bool getChain(const base::Time &atTime, std::vector< TransformationType > &result, bool interpolate=false) const
Definition: Transformer.cpp:390
int getStreamIdx() const
Definition: Transformer.hpp:216
Definition: Transformer.hpp:209
Definition: Transformer.hpp:338
const aggregator::StreamAlignerStatus & getStreamAlignerStatus()
Definition: Transformer.hpp:489
Definition: Transformer.cpp:76
InverseTransformationElement(TransformationElement *source)
Definition: Transformer.hpp:237
void updateStatus(TransformationStatus &status) const
Definition: Transformer.cpp:17
std::map< std::pair< std::string, std::string >, int > transformToStreamIndex
Definition: Transformer.hpp:342
std::vector< TransformationElement * > & getAvailableElements()
Definition: Transformer.hpp:292
const std::string & getTargetFrame() const
Definition: Transformer.hpp:174
const std::string & getSourceFrame() const
Definition: Transformer.hpp:166
void registerUpdateCallback(boost::function< void(const base::Time &ts)> callback)
Definition: Transformer.cpp:62
int priority
Definition: Transformer.hpp:345
int registerDataStreamWithTransform(base::Time dataPeriod, Transformation &transformation, boost::function< void(const base::Time &ts, const T &value, const Transformation &t)> callback, int priority=- 1, const std::string &name=std::string())
Definition: Transformer.hpp:428
void pushData(int idx, const base::Time &ts, const T &data)
Definition: Transformer.hpp:474
Definition: Transformer.hpp:235
TransformationStatus getStatus() const
Definition: Transformer.cpp:10
Definition: Transformer.hpp:258
virtual ~InverseTransformationElement()
Definition: Transformer.hpp:238
int step()
Definition: Transformer.hpp:482
bool get(const base::Time &atTime, transformer::TransformationType &result, bool interpolate=false) const
Definition: Transformer.cpp:374
void requestTransformationAtTime(int idx, base::Time ts)
Definition: Transformer.hpp:465
bool isStreamActive(int idx) const
Definition: Transformer.hpp:460