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
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:416
Transform getTransform(const Time &time, NearestNeighborInterpolator &)
Definition: TransformerNode.h:286
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
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
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
Transform getTransform(const Time &time, Filter &&filter)
Returns the transform stored in this node at the specified time stamp.
Definition: TransformerNode.h:133
#define MIRA_BASE_EXPORT
This is required because on windows there is a macro defined called ERROR.
Definition: Platform.h:153
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