MIRA
TransformerNode.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Contact: info@mira-project.org
9  *
10  * Commercial Usage:
11  * Licensees holding valid commercial licenses may use this file in
12  * accordance with the commercial license agreement provided with the
13  * software or, alternatively, in accordance with the terms contained in
14  * a written agreement between you and MLAB or NICR.
15  *
16  * GNU General Public License Usage:
17  * Alternatively, this file may be used under the terms of the GNU
18  * General Public License version 3.0 as published by the Free Software
19  * Foundation and appearing in the file LICENSE.GPL3 included in the
20  * packaging of this file. Please review the following information to
21  * ensure the GNU General Public License version 3.0 requirements will be
22  * met: http://www.gnu.org/copyleft/gpl.html.
23  * Alternatively you may (at your option) use any later version of the GNU
24  * General Public License if such license has been publicly approved by
25  * MLAB and NICR (or its successors, if any).
26  *
27  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
28  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
29  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
30  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
33  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
34  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
35  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
36  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
37  */
38 
48 #ifndef _MIRA_TRANSFORMERNODE_H_
49 #define _MIRA_TRANSFORMERNODE_H_
50 
51 #include <string>
52 
53 #ifndef Q_MOC_RUN
54 #include <boost/iterator/transform_iterator.hpp>
55 #endif
56 
57 #include <utils/Stamped.h>
58 #include <utils/Time.h>
59 
60 #include <utils/StampedDataQueue.h>
62 
64 
65 namespace mira {
66 
68 
69 // forward decls
70 class TransformerBase;
71 class NearestNeighborInterpolator;
72 
89 {
90 public:
91 
94 
95 protected:
96  AbstractTransformerNode(const std::string& id) :
97  mID(id), mParent(NULL) {}
98 
100 
101 public:
102 
104  const std::string& getID() const { return mID; }
105 
107  const std::list<AbstractNodePtr>& getChildren() const { return mChildren; }
108 
110  const AbstractNodePtr& getParent() const { return mParent; }
111 
113  uint32 getDescendantCount() const;
114 
118  bool isAncestorOf(const AbstractNodePtr other) const;
119 
120 public:
121 
123  virtual bool isEmpty() const = 0;
124 
132  template<typename Transform, typename Filter>
133  Transform getTransform(const Time& time, Filter&& filter) {
134  // #####################################################################
135  // If you get a compiler error here, the class that was passed as
136  // template parameter TNode does not implement the necessary
137  // getTransform() method. Please implement that method in your transform
138  // node class!
139  // #####################################################################
140  static_assert(sizeof(Transform)==0,
141  "getTransform() must be implemented in your derived Node class");
142  return Transform(); // to prevent compiler warning
143  }
144 
145 protected:
146  friend class TransformerBase;
147 
149  std::string mID;
150 
153 
155  std::list<AbstractNodePtr> mChildren;
156 };
157 
158 
160 
161 template <typename T, int D, template <typename T_, int D_> class TTransform>
162 class Transformer;
163 
178 template <typename StorageTransform>
180 {
182 
185 
186 protected:
187  template <typename T, int D, template <typename T_, int D_> class TTransform_>
188  friend class Transformer;
189 
197  TransformerNode(const std::string& id) : Base(id) {}
198 
199 private:
201 
202  // the following two types are used in getTransform(...,Filter&&)
203  // they extract the time(as uint64) and the transform out of a
204  // Stamped<Transform>
205  template <typename Transform>
206  struct GetTime
207  {
208  GetTime(const Time& iT0) : t0(iT0) {}
209 
210  typedef int64 result_type;
211  result_type operator()(const Stamped<Transform>& p) const {
212  return (result_type)(p.timestamp-t0).totalMilliseconds();
213  }
214 
215  Time t0;
216  };
217 
218  template <typename Transform>
219  struct GetTransform
220  {
221  typedef const Transform& result_type;
222  result_type operator()(const Stamped<Transform>& p) const {
223  return p;
224  }
225  };
226 
228 
229 public:
230 
237 
242  void setTransform(const StorageTransform& transform, const Time& time) {
243  mTransformStorage.insert(typename Storage::value_type(transform, time));
244  }
246  virtual bool isEmpty() const { return mTransformStorage.empty(); }
247 
249  template<typename Transform, typename Filter>
250  Transform getTransform(const Time& time, Filter&& filter)
251  {
252  // get interval that is required by the filter
253  auto its = mTransformStorage.getInterval(time,filter.samples(),
254  filter.samplesBefore(),
255  filter.samplesAfter());
256 
257  const Time t0 = its.first->timestamp;
258 
259  // using adapters, iterators and the IteratorRangeContainer, the
260  // following code mimics two different containers: one that contains
261  // the time as float and one that contains the transforms. In fact
262  // there is one container only (mTransformStorage) that contains both
263  // within a single container.
264  typedef typename Storage::const_iterator const_iterator;
265  typedef boost::transform_iterator<GetTime<Transform>, const_iterator> GetTimeIterator;
266  GetTimeIterator begin1 = GetTimeIterator(its.first ,GetTime<Transform>(t0));
267  GetTimeIterator end1 = GetTimeIterator(its.second,GetTime<Transform>(t0));
268 
269  typedef boost::transform_iterator<GetTransform<Transform>, const_iterator> GetTransformIterator;
270  GetTransformIterator begin2 = GetTransformIterator(its.first ,GetTransform<Transform>());
271  GetTransformIterator end2 = GetTransformIterator(its.second,GetTransform<Transform>());
272 
273  typedef mira::IteratorRangeContainer<GetTimeIterator> TimeContainer;
274  typedef mira::IteratorRangeContainer<GetTransformIterator> TransformContainer;
275  TimeContainer timeContainer(begin1, end1);
276  TransformContainer transformContainer(begin2, end2);
277 
278  // call the filter to obtain the filtered transform at the desired time
279  return filter.template apply<float, Transform>(timeContainer,
280  transformContainer, (float)(time-t0).totalMilliseconds());
281  }
282 
283  // specialize for NearestNeighborInterpolator and make a direct call
284  // to getData for better performance
285  template<typename Transform>
286  Transform getTransform(const Time& time, NearestNeighborInterpolator&) {
287  return mTransformStorage.getData(time);
288  }
289 
290 protected:
291 
294 };
295 
296 
298 
299 } // namespace
300 
301 #endif /* _MIRA_TRANSFORMERNODE_H_ */
TransformerNode(const std::string &id)
Creates a new node of the transform tree, that can be added to the corresponding Transformer using ad...
Definition: TransformerNode.h:197
AbstractTransformerNode(const std::string &id)
Definition: TransformerNode.h:96
1D nearest neighbor interpolator.
Definition: NearestNeighborInterpolator.h:68
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
Time and Duration wrapper class.
std::string mID
The id of this node.
Definition: TransformerNode.h:149
std::list< AbstractNodePtr > mChildren
List with pointers to the children within the transformation tree.
Definition: TransformerNode.h:155
uint32_t uint32
Definition: Types.h:64
AbstractNodePtr mParent
Pointer to the parent node within the tree.
Definition: TransformerNode.h:152
const std::string & getID() const
Returns the id of this node.
Definition: TransformerNode.h:104
Queue for Stamped data.
Wrapper class for boost::posix_time::ptime for adding more functionality to it.
Definition: Time.h:418
Transform getTransform(const Time &time, NearestNeighborInterpolator &)
Definition: TransformerNode.h:286
virtual bool isEmpty() const =0
Returns if the node has data or is empty.
const std::list< AbstractNodePtr > & getChildren() const
Returns a list with all children of this node.
Definition: TransformerNode.h:107
Storage & storage()
Grants access to the internal storage for transformations.
Definition: TransformerNode.h:236
std::pair< const_iterator, const_iterator > getInterval(const Time &timestamp, std::size_t size, std::size_t before, std::size_t after)
Returns two iterators that mark the begin and end of an interval of data.
Definition: StampedDataQueue.h:240
Base class for Transformer to decouple base functionality that is type independent from type dependen...
Definition: Transformer.h:78
Container::const_iterator const_iterator
some typedefs for STL compliance
Definition: StampedDataQueue.h:95
Rigid transformation class.
Mix in for adding a timestamp to data types.
A full features transformer class based on GenericTransformer.
Definition: Transformer.h:573
AbstractTransformerNode * AbstractNodePtr
Pointer type for this AbstractTransformerNode.
Definition: TransformerNode.h:93
bool empty() const
Returns true, if no element is stored.
Definition: StampedDataQueue.h:146
An iterator range class.
bool insert(const Stamped< T > &data)
Inserts new data to the queue.
Definition: StampedDataQueue.h:154
int64_t int64
Definition: Types.h:61
const Stamped< T > & getData(const Time &timestamp) const
Returns the data from the queue whose time stamp is closest to the specified timestamp.
Definition: StampedDataQueue.h:199
virtual bool isEmpty() const
Implementation of AbstractTransformerNode::isEmpty()
Definition: TransformerNode.h:246
Storage mTransformStorage
storage that takes all transforms with their timestamps that were added.
Definition: TransformerNode.h:293
uint32 getDescendantCount() const
Returns the number of descendants of this node (children, grandchildren, etc.)
Abstract base class where all other different types of transformation nodes must be derived from...
Definition: TransformerNode.h:88
Transform getTransform(const Time &time, Filter &&filter)
Implementation of AbstractTransformerNode::getTransform()
Definition: TransformerNode.h:250
bool isAncestorOf(const AbstractNodePtr other) const
Returns true, if the this node is an ancestor of the given &#39;other&#39; node.
Transform getTransform(const Time &time, Filter &&filter)
Returns the transform stored in this node at the specified time stamp.
Definition: TransformerNode.h:133
virtual ~AbstractTransformerNode()
Definition: TransformerNode.h:99
void setTransform(const StorageTransform &transform, const Time &time)
Inserts the specified transform with the specified time stamp into the internal storage.
Definition: TransformerNode.h:242
Wraps an STL conform container around a range of values within another container. ...
Definition: IteratorRangeContainer.h:64
const AbstractNodePtr & getParent() const
Returns the parent of the node.
Definition: TransformerNode.h:110
Basic reference implementation of an AbstractTransformerNode that stores the transformation data inte...
Definition: TransformerNode.h:179