MIRA
TapeVisitor.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 
47 #ifndef _MIRA_TAPEVISITOR_H_
48 #define _MIRA_TAPEVISITOR_H_
49 
50 #include <fw/Tape.h>
51 
52 namespace mira {
53 
55 
67 {
68 public:
69 
72  {
74  tape(NULL), offset(0) {}
75 
78 
80  uint64 offset;
81 
83  std::string frameID;
84 
86  uint32 sequenceID;
87 
90 
92  bool compressed;
93  };
94 
96  struct MessageInfo
97  {
99  tape(NULL),
100  info(NULL),
101  index(NULL) {}
102 
105 
108 
111 
114 
115  bool operator<(const MessageInfo& other) const
116  {
117  return timeOffset < other.timeOffset;
118  }
119  };
120 
122  typedef std::vector<MessageInfo> MessageMap;
124  typedef std::map<std::string, const Tape::ChannelInfo*> ChannelMap;
125 
127  class iterator;
128  friend class iterator;
129 
134  {
135  public:
137  mVisitor(NULL) {}
138 
139  iterator(TapeVisitor* visitor, MessageMap::iterator message) :
140  mVisitor(visitor),
141  mMessage(message) {}
142 
143  iterator& operator=(const iterator& other)
144  {
145  mVisitor = other.mVisitor;
146  mMessage = other.mMessage;
147  return *this;
148  }
149 
151  {
152  ++mMessage;
153  return *this;
154  }
155 
157  {
158  --mMessage;
159  return *this;
160  }
161 
165  const MessageInstance& operator*() const
166  {
167  if (!mVisitor || mMessage == mVisitor->mMessages.end() )
168  MIRA_THROW(XIO, "Cannot instantiate message from the end iterator");
169 
170  // If we are already instantiated return us
171  if (mInstance.tape == mMessage->tape &&
172  mInstance.offset == (mMessage->index->block+mMessage->index->offset))
173  return mInstance;
174 
175  // copy informations about the message
176  mInstance.tape = mMessage->tape;
177  mInstance.offset = mMessage->index->block+mMessage->index->offset;
178 
179  // read the message from tape
180  Duration oTime;
181  mMessage->tape->readMessage(*mMessage->index, mInstance.frameID,
182  mInstance.sequenceID, mInstance.data, oTime,
183  mInstance.compressed);
184  return mInstance;
185  }
186 
191  {
192  return &this->operator *();
193  }
194 
202  template <typename T>
203  void read(Stamped<T>& oData)
204  {
205  validate();
206  // perform type check
207  if(mMessage->info->type!=typeName<T>()) {
208  MIRA_THROW(XIO, "Cannot read a '"<<typeName<T>()<<
209  "' from Tape-Iterator message which has type '"<<mMessage->info->type<<"'");
210  }
211 
212  // instantiate the data
213  const MessageInstance& msgInst = this->operator*();
214  Buffer<uint8> buf(msgInst.data);
215  BinaryBufferDeserializer bs(&buf);
216  // deserialize it ...
217  bs.deserialize(oData.value(),false);
218  // and fill in the header info
219  oData.timestamp = mVisitor->getStartTime() + getTimeOffset();
220  oData.frameID = msgInst.frameID;
221  oData.sequenceID = msgInst.sequenceID;
222  }
223 
229  void readJSON(Stamped<JSONValue>& oData);
230 
231 
232  bool operator==(const iterator& other) const
233  {
234  return mVisitor == other.mVisitor && mMessage == other.mMessage;
235  }
236 
237  bool operator!=(const iterator& other) const
238  {
239  return mVisitor != other.mVisitor || mMessage != other.mMessage;
240  }
241 
248  {
249  validate();
250  return mMessage->timeOffset;
251  }
252 
260  validate();
261  return mMessage->info;
262  }
263 
268  {
269  validate();
270  return mMessage->tape->getTZOffset();
271  }
272 
273 
274  friend class TapeVisitor;
275 
276  protected:
277 
278  void validate() const
279  {
280  if (!mVisitor || mMessage == mVisitor->mMessages.end())
281  MIRA_THROW(XIO, "Cannot access message at the end iterator");
282  }
283 
286  MessageMap::iterator mMessage;
287  };
288 
305  void visit(Tape* iTape,
307  Duration last = Duration::infinity(),
308  bool ignoreStartTime = false);
309 
320  void visit(Tape* iTape, const std::vector<std::string>& channels,
322  Duration last = Duration::infinity(),
323  bool ignoreStartTime = false);
324 
330  {
331  if ( mStart )
332  return *mStart;
333  return Time::invalid();
334  }
335 
339  void setStartTime(const Time& start)
340  {
341  mStart.reset(start);
342  for (uint32 i=0; i<mMessages.size(); ++i)
343  mMessages[i].timeOffset = (mMessages[i].tape->getStartTime() +
344  mMessages[i].index->timeOffset) - *mStart;
345  }
346 
352  {
353  if (mMessages.size() > 0)
354  return mMessages.begin()->timeOffset;
355  return Duration::nanoseconds(0);
356  }
357 
363  {
364  if (mMessages.size() > 0)
365  return mMessages.rbegin()->timeOffset;
366  return Duration::nanoseconds(0);
367  }
368 
374  {
375  if (mMessages.size() > 0)
376  return mMessages.rbegin()->tape->getTZOffset();
377  return Duration::nanoseconds(0);
378  }
379 
384  uint32 getMessageCount() const
385  {
386  return mMessages.size();
387  }
388 
394  {
395  return iterator(this, mMessages.begin());
396  }
397 
403  iterator at(Duration timeOffset)
404  {
405  if ( mMessages.size() == 0 )
406  return iterator(this, mMessages.end());
407  if ( mMessages.size() == 1 )
408  return iterator(this, mMessages.begin());
409  MessageMap::iterator it = mMessages.begin();
410  Duration diffNext = abs(mMessages[0].timeOffset-timeOffset);
411  for(uint32 i=0; i<mMessages.size()-1;++i, ++it)
412  {
413  Duration diffNow = diffNext;
414  diffNext = abs(mMessages[i+1].timeOffset-timeOffset);
415  if ( diffNow < diffNext )
416  return iterator(this, it);
417  }
418  return iterator(this, mMessages.end());
419  }
420 
426  {
427  return iterator(this, mMessages.end());
428  }
429 
435  iterator findNextOf(Duration startOffset, const std::string& channel)
436  {
437  return findNextOf(at(startOffset), channel);
438  }
439 
445  iterator findNextOf(const iterator& start, const std::string& channel)
446  {
447  MessageMap::iterator i = start.mMessage;
448  for(; i!=mMessages.end(); ++i)
449  if (i->info->name == channel)
450  return iterator(this, i);
451  return iterator(this, mMessages.end());
452  }
453 
459  iterator findNextOfAnyOf(Duration startOffset, const std::vector<std::string>& channels)
460  {
461  return findNextOfAnyOf(at(startOffset), channels);
462  }
463 
469  iterator findNextOfAnyOf(const iterator& start, const std::vector<std::string>& channels)
470  {
471  MessageMap::iterator i = start.mMessage;
472  for(; i!=mMessages.end(); ++i)
473  if (std::find(channels.begin(), channels.end(), i->info->name) != channels.end())
474  return iterator(this, i);
475 
476  return iterator(this, mMessages.end());
477  }
478 
483  const ChannelMap& getChannels() const
484  {
485  return mChannels;
486  }
487 
488 protected:
489 
490  void addChannel(Tape* tape, const Tape::ChannelInfo* channel,
491  Duration first = Duration::nanoseconds(0),
492  Duration last = Duration::infinity());
493 
494  void reIndex(Tape* tape, bool ignoreStartTime = false);
495 
496  boost::optional<Time> mStart;
499 };
500 
502 
503 }
504 
505 #endif
iterator & operator++()
Definition: TapeVisitor.h:150
A tape is a binary file that contains recorded/serialized data of one or multiple channels...
Definition: Tape.h:142
iterator & operator--()
Definition: TapeVisitor.h:156
T & value()
Returns a read-write reference to the underlying data.
Definition: Stamped.h:202
const MessageInstance * operator->() const
Instantiates the message by loading it from the underlying tape file.
Definition: TapeVisitor.h:190
ChannelMap mChannels
Definition: TapeVisitor.h:498
Duration getTimeOffset() const
Get the offset of the recording time for this message.
Definition: TapeVisitor.h:247
Time timestamp
The time stamp when the data was obtained.
Definition: Stamped.h:104
iterator at(Duration timeOffset)
Iterator to the message at the given offset since start of tape.
Definition: TapeVisitor.h:403
A Tape is a representation of recorded channel data in a binary file.
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
const ChannelMap & getChannels() const
Get a list of the visited channels.
Definition: TapeVisitor.h:483
std::map< std::string, const Tape::ChannelInfo * > ChannelMap
Maps channel info to channel names.
Definition: TapeVisitor.h:124
iterator end()
Iterator to the end of visited messages.
Definition: TapeVisitor.h:425
Duration timeOffset
time offset of the message relative to start of recording
Definition: TapeVisitor.h:107
Time getStartTime() const
Get the common start time of the visit for all tapes.
Definition: TapeVisitor.h:329
MessageInstance mInstance
Definition: TapeVisitor.h:284
Duration getLastMessageTimeOffset() const
Get the time offset of the last visited message.
Definition: TapeVisitor.h:362
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:81
Information about a channel in a tape.
Definition: Tape.h:186
Iterator to iterate over all messages in all tapes visited by the visitor.
Definition: TapeVisitor.h:133
Buffer< uint8 > data
serialized message data
Definition: TapeVisitor.h:89
Duration getTZOffset() const
Get the time zone offset of the tape containing this message.
Definition: TapeVisitor.h:267
Wrapper class for boost::posix_time::ptime for adding more functionality to it.
Definition: Time.h:421
iterator & operator=(const iterator &other)
Definition: TapeVisitor.h:143
Duration abs(const Duration &duration)
Get the absolute duration from a duration.
Definition: Time.h:404
uint32 getMessageCount() const
Get the number of messages to visit.
Definition: TapeVisitor.h:384
TapeVisitor * mVisitor
Definition: TapeVisitor.h:285
MessageMap mMessages
Definition: TapeVisitor.h:497
const Tape::ChannelInfo * info
pointer to the info object of the channel
Definition: TapeVisitor.h:110
const Tape::ChannelInfo * getChannelInfo() const
Get the information object about the channel this message belongs to.
Definition: TapeVisitor.h:259
MessageMap::iterator mMessage
Definition: TapeVisitor.h:286
bool operator<(const MessageInfo &other) const
Definition: TapeVisitor.h:115
void read(Stamped< T > &oData)
Instantiates the message by loading it from the underlying tape file and deserializes its content int...
Definition: TapeVisitor.h:203
#define MIRA_FRAMEWORK_EXPORT
Definition: FrameworkExports.h:61
Use this class to represent time durations.
Definition: Time.h:104
boost::optional< Time > mStart
Definition: TapeVisitor.h:496
void setStartTime(const Time &start)
Set the common start time of the visit for all tapes.
Definition: TapeVisitor.h:339
uint64 offset
offset of the message in the tape
Definition: TapeVisitor.h:80
Mix in for adding a time stamp, an optional frame id and an optional sequence id to data types like P...
Definition: Stamped.h:149
iterator(TapeVisitor *visitor, MessageMap::iterator message)
Definition: TapeVisitor.h:139
iterator findNextOf(const iterator &start, const std::string &channel)
Returns the iterator to the next message from given channel, starting at the given start iterator...
Definition: TapeVisitor.h:445
static Duration infinity()
Returns a special duration time representing positive infinity.
Definition: Time.h:245
Duration getFirstMessageTimeOffset() const
Get the time offset of the first visited message.
Definition: TapeVisitor.h:351
Instance of a message from a tape.
Definition: TapeVisitor.h:71
iterator begin()
Iterator to the first visited message in a tape.
Definition: TapeVisitor.h:393
Visitor class to inspect tapes by channels and/or time interval.
Definition: TapeVisitor.h:66
static Duration negativeInfinity()
Returns a special duration time representing negative infinity.
Definition: Time.h:238
std::vector< MessageInfo > MessageMap
Vector of message informations.
Definition: TapeVisitor.h:122
const Tape::MessageIndex * index
pointer to the index object of the message
Definition: TapeVisitor.h:113
iterator findNextOfAnyOf(Duration startOffset, const std::vector< std::string > &channels)
Returns the iterator to the next message from any of the given channels with a time offset of at leas...
Definition: TapeVisitor.h:459
Info about a message entry in a tape.
Definition: TapeVisitor.h:96
iterator findNextOfAnyOf(const iterator &start, const std::vector< std::string > &channels)
Returns the iterator to the next message from any of the given channels, starting at the given start ...
Definition: TapeVisitor.h:469
void deserialize(T &value, bool enableTypeCheck=true, bool recursive=false)
Provides a special deserialize interface for the BinaryDeserializer.
Definition: BinarySerializer.h:1340
Tape * tape
pointer to tape the message is stored in
Definition: TapeVisitor.h:77
static Time invalid()
Returns an invalid time.
Definition: Time.h:505
MessageInstance()
Definition: TapeVisitor.h:73
bool compressed
specifies whether the data was compressed within the tape or not
Definition: TapeVisitor.h:92
MessageInfo()
Definition: TapeVisitor.h:98
iterator findNextOf(Duration startOffset, const std::string &channel)
Returns the iterator to the next message from given channel with a time offset of at least startOffse...
Definition: TapeVisitor.h:435
const MessageInstance & operator*() const
Instantiates the message by loading it from the underlying tape file.
Definition: TapeVisitor.h:165
tick_type nanoseconds() const
Returns normalized number of nanoseconds (0..999)
Definition: Time.h:298
Index entry for a message in the tape.
Definition: Tape.h:178
void validate() const
Definition: TapeVisitor.h:278
std::string frameID
frame id of the channel
Definition: TapeVisitor.h:83
uint32 sequenceID
A user defined sequence ID.
Definition: Stamped.h:111
Duration getLastMessageTZOffset() const
Get the time zone offset of the last visited message.
Definition: TapeVisitor.h:373
bool operator!=(const iterator &other) const
Definition: TapeVisitor.h:237
uint32 sequenceID
sequence id
Definition: TapeVisitor.h:86
std::string frameID
The unique id of the transform frame that this data is assigned to (if any, otherwise empty) ...
Definition: Stamped.h:108
bool operator==(const iterator &other) const
Definition: TapeVisitor.h:232
iterator()
Definition: TapeVisitor.h:136
Tape * tape
pointer to tape the message is stored in
Definition: TapeVisitor.h:104