MIRA
Channel.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_CHANNEL_H_
49 #define _MIRA_CHANNEL_H_
50 
51 #ifndef _MIRA_FRAMEWORK_H_
52 # error "Channel.h must be included via the Framework.h. You must not include it directly. Use #include <fw/Framework.h> instead"
53 #endif
54 
55 #ifndef Q_MOC_RUN
56 #include <boost/shared_ptr.hpp>
57 #include <boost/type_traits/is_polymorphic.hpp>
58 #endif
59 
60 #include <error/Exceptions.h>
61 
62 #include <factory/TypeId.h>
63 
64 #include <utils/EnumToFlags.h>
66 
67 #include <fw/Framework.h>
68 
69 #include <fw/AbstractChannel.h>
70 #include <fw/ChannelSubscriber.h>
71 #include <fw/ChannelReadWrite.h>
72 #include <fw/ChannelReadInterval.h>
74 
75 namespace mira {
76 
78 
82 MIRA_DEFINE_SERIALIZABLE_EXCEPTION(XInvalidRead, XRuntime)
83 
84 
87 template <typename T>
88 class Channel;
89 
91 
93 
98 template<typename T>
99 class ConcreteChannel : public AbstractChannel
100 {
101 public:
102 
103  typedef ChannelBuffer<T> Buffer;
104  typedef typename Buffer::ValueType ValueType;
105  typedef typename Buffer::Slot Slot;
106 
107  typedef ChannelSubscriber<T, ChannelRead<T> > Subscriber;
108  typedef boost::shared_ptr<Subscriber> SubscriberPtr;
109 
110 public:
111 
112  ConcreteChannel(const std::string& id) :
113  AbstractChannel(id, new ChannelBuffer<T>)
114  {
115  // make sure, that our ConcreteChannel class has the same size
116  // as AbstractChannel and that we are not polymorphic. Both is
117  // important for our channel_cast to work as expected.
118  static_assert(sizeof(ConcreteChannel)==sizeof(AbstractChannel),
119  "ConcreteChannel must have the same size as AbstractChannel");
120 
121  static_assert(boost::is_polymorphic<ConcreteChannel>::value==false,
122  "ConcreateChannel and AbstractChannel must not be polymorphic");
123  }
124 
125 public:
126 
131  void addSubscriber()
132  {
133  boost::mutex::scoped_lock lock(mSubscribersMutex);
134  mNrOfSubscribersWithoutChannelSubscriber++;
135  }
136 
141  void addSubscriber(SubscriberPtr subscriber)
142  {
143  boost::mutex::scoped_lock lock(mSubscribersMutex);
144  mSubscribers.push_back(subscriber);
145  subscriber->attachChannel(this);
146  }
147 
148 public:
149 
157  ChannelRead<T> read();
158 
169  ChannelRead<T> read(const Time& timestamp, SlotQueryMode mode = NEAREST_SLOT,
170  const Duration& tolerance = Duration::infinity());
171 
195  ChannelReadInterval<T> readInterval(const Time& timestamp, std::size_t nrSlots,
196  std::size_t olderSlots, std::size_t newerSlots,
197  IntervalFillMode fillMode = PREFER_NEWER);
198 
217  ChannelReadInterval<T> readInterval(const Time& from,
218  const Time& to = Time::eternity());
219 
232  ChannelWrite<T> write();
233 
234 public:
235  friend class Channel<T>;
236 };
237 
239 
240 
247 template<typename T>
248 struct ChannelCaster {
249  static ConcreteChannel<T>* cast(AbstractChannel* p)
250  {
251  // promote the channel if necessary (this will throw an exception, if
252  // the channel cannot be promoted to the desired type)
253  promote_channel<T>(p);
254 
255  assert(p->isTyped()); // at the point p will always be typed
256 
257  // check the type of our buffer's slot manually
258  if(typeId<T>()!=p->getTypeId())
259  MIRA_THROW(XBadCast, "Cannot cast channel '" << p->getID()
260  << "' (type '" << p->getTypename() << "') "
261  << " to typed channel of type '" << typeName<T>() << "'");
262 
263  // cast us "hard" using a static_cast.
264  // This is safe, since we have checked the types above
265  return static_cast<ConcreteChannel<T>*>(p);
266  }
267 };
268 
270 
271 // specialization to cast to untyped ConcreteChannel (void)
272 template<>
273 struct ChannelCaster<void> {
274  static ConcreteChannel<void>* cast(AbstractChannel* p)
275  {
276  // cast us "hard" using a static_cast.
277  // This is safe, since all channels can be casted to untyped channel
278  return static_cast<ConcreteChannel<void>* >(p);
279  }
280 };
281 
283 
284 // specialization to cast polymorphic channels
285 template<typename T>
286 struct ChannelCaster<T*> {
287  static ConcreteChannel<T*>* cast(AbstractChannel* p)
288  {
289  static_assert(std::is_base_of<mira::Object,T>::value,
290  "Pointers that are used in channels must be derived from "
291  "mira::Object. Pointers to other classes cannot be used.");
292 
293  // promote the channel if necessary (this will throw an exception, if the
294  // the channel cannot be promoted to the desired type)
295  promote_channel<T*>(p);
296 
297  // channel must be typed after promotion
298  assert(p->getBuffer()->isPolymorphic());
299 
300  // cast us "hard" using a static_cast.
301  // This is safe, since we have checked the types above
302  return static_cast<ConcreteChannel<T*>* >(p);
303  }
304 };
305 
307 
308 template<typename T>
309 inline ConcreteChannel<T>* channel_cast(AbstractChannel* p)
310 {
311  return ChannelCaster<T>::cast(p);
312 }
313 
315 
317 
319 template <typename T>
320 class Channel;
321 
323 template<typename T>
324 inline Channel<T> channel_cast(Channel<void> channel);
326 
327 
336 };
338 
339 
340 namespace {
341 
342 template <typename T>
343 struct ParamHelper {
344  typedef T type;
345 };
346 
347 template<>
348 struct ParamHelper<void> {
349  typedef int type; // arbitrary, it will not be used for T=void actually,
350  // but needs to name a valid argument type
351 };
352 
353 }
354 
356 
402 template <typename T>
403 class Channel
404 {
405 public:
406 
410  Channel() : mChannel(), mAccessFlags(CHANNEL_ACCESS_NONE) {}
411 
416  mChannel(channel), mAccessFlags(accessFlags) {
417  assert(mChannel!=NULL);
418  }
419 
423  void reset() {
424  mChannel=NULL;
425  mAccessFlags = CHANNEL_ACCESS_NONE;
426  }
427 
432  bool isValid() const {
433  return mChannel!=NULL;
434  }
435 
441  void validate() const {
442  if(mChannel==NULL)
443  MIRA_THROW(XAccessViolation,
444  "No channel assigned to the channel proxy (of type " <<
445  typeName<T>() << "). "
446  "You can obtain a channel using Authority::getChannel()!");
447  }
448 
454 
458  const std::string& getID() const {
459  validate();
460  return mChannel->getID();
461  }
462 
468  int getTypeId() const {
469  validate();
470  return mChannel->getTypeId();
471  }
472 
476  bool isTyped() const { return getTypeId()>=0; }
477 
483  validate();
484  return mChannel->getTypename();
485  }
486 
491  void setTypename(const Typename& type) {
492  validate();
493  mChannel->setTypename(type);
494  }
495 
500  validate();
501  return mChannel->getTypeMeta();
502  }
503 
508  validate();
509  mChannel->setTypeMeta(meta);
510  }
511 
513 
514 public:
515 
521 
525  bool isEmpty() const {
526  validate();
527  return mChannel->getNrOfSlots() == 0;
528  }
529 
533  bool hasSubscriber() const {
534  validate();
535  return mChannel->hasSubscriber();
536  }
537 
541  bool hasPublisher() const {
542  validate();
543  return mChannel->hasPublisher();
544  }
545 
549  bool hasSoloSlot() const {
550  validate();
551  return mChannel->getBuffer()->getMaxSlots() == 1;
552  }
553 
557  std::size_t getMaxSlots() const {
558  validate();
559  return mChannel->getBuffer()->getMaxSlots();
560  }
561 
565  std::size_t getMinSlots() const {
566  validate();
567  return mChannel->getBuffer()->getMinSlots();
568  }
569 
575  validate();
576  return mChannel->getBuffer()->getStorageDuration();
577  }
578 
583  validate();
584  return mChannel->getBuffer()->isAutoIncreasingStorageDuration();
585  }
586 
590  std::size_t getNrOfSlots() const {
591  validate();
592  return mChannel->getBuffer()->getSize();
593  }
594 
596 
597 public:
598 
605 
617  {
618  validateReadAccess();
619 
620  Time end;
621  if(!timeout.isValid() || timeout.isInfinity())
622  end = Time::eternity();
623  else
624  end = Time::now() + timeout;
625 
626  while(!boost::this_thread::interruption_requested())
627  {
628  try {
629  return mChannel->read();
630  } catch(XInvalidRead& ex) {}
631  if(Time::now()>end) // handle timeout
632  break;
633  MIRA_SLEEP(50)
634  }
635  return ChannelRead<T>();
636  }
637 
638 
648  bool waitForPublisher(const Duration& timeout = Duration::infinity()) const
649  {
650  validateReadAccess();
651 
652  Time end;
653  if(!timeout.isValid() || timeout.isInfinity())
654  end = Time::eternity();
655  else
656  end = Time::now() + timeout;
657 
658  while(!boost::this_thread::interruption_requested())
659  {
660  if(hasPublisher())
661  return true;
662  if(Time::now()>end) // handle timeout
663  break;
664  MIRA_SLEEP(50)
665  }
666  return false; // timeout
667  }
668 
669 
679  validateReadAccess();
680  return mChannel->read();
681  }
682 
704  const Duration& tolerance = Duration::infinity()) {
705  validateReadAccess();
706  return mChannel->read(timestamp, mode, tolerance);
707  }
708 
727  const Duration& searchInterval = Duration::seconds(1)) {
728  validateReadAccess();
729  Time newestSlotTime = mChannel->read()->timestamp;
730  ChannelReadInterval<T> interval = readInterval(newestSlotTime - searchInterval, newestSlotTime);
731  typename ChannelReadInterval<T>::const_iterator iter = interval.begin();
732  for(; iter != interval.end(); ++iter){
733  if(iter->sequenceID == sequenceID)
734  return (ChannelRead<T>)iter;
735  }
736  MIRA_THROW(XInvalidRead, "No slot with sequenceID "<<sequenceID<<
737  " found within searchInterval of channel");
738  }
739 
745  ChannelRead<T> read(const Time& timestamp, const Duration& tolerance) {
746  validateReadAccess();
747  return mChannel->read(timestamp, NEAREST_SLOT, tolerance);
748  }
749 
779  std::size_t nrSlots,
780  std::size_t olderSlots,
781  std::size_t newerSlots,
782  IntervalFillMode fillMode = PREFER_NEWER) {
783  validateReadAccess();
784  return mChannel->readInterval(timestamp, nrSlots, olderSlots,
785  newerSlots, fillMode);
786  }
787 
804  const Time& to=Time::eternity()) {
805  validateReadAccess();
806  return mChannel->readInterval(from, to);
807  }
808 
826  validateWriteAccess();
827  return mChannel->write();
828  }
829 
869  template <typename Fn = Stamped<T>(*)(const Stamped<T>&)>
870  ChannelWrite<T> write(bool copyLatestData, Fn fn = [](const auto& s){ return s; }) {
871  validateWriteAccess();
872 
873  // check if we should and need to copy data into the write slot
874  if(copyLatestData
875  && (mChannel->getBuffer()->getMaxSlots()>1) // only necessary if we may have more than one slot
876  && (mChannel->getBuffer()->getSize()>0)) // and only if we have at least one slot yet
877  {
878  ChannelRead<T> latest = mChannel->read();
879  Stamped<T> tmp(fn(*latest));
880  latest.finish();
881  ChannelWrite<T> writeSlot = mChannel->write();
882  *writeSlot = tmp;
883  return writeSlot;
884 
885  } else
886  return mChannel->write();
887  }
888 
902  Stamped<T> get() {
903  validateReadAccess();
904  ChannelRead<T> value = mChannel->read();
905  return *value;
906  }
907 
921  Stamped<T> get(const Time& timestamp, SlotQueryMode mode=NEAREST_SLOT,
922  const Duration& tolerance = Duration::infinity()) {
923  validateReadAccess();
924  ChannelRead<T> value = mChannel->read(timestamp, mode, tolerance);
925  return *value;
926  }
927 
933  Stamped<T> get(const Time& timestamp, Duration tolerance) {
934  validateReadAccess();
935  ChannelRead<T> value = mChannel->read(timestamp, NEAREST_SLOT, tolerance);
936  return *value;
937  }
938 
939 private:
940 
942 
944  struct GetTime
945  {
946  GetTime(const Time& iT0) : t0(iT0) {}
947 
948  //typedef const Time& result_type;
949  typedef float result_type;
950  result_type operator()(const Stamped<T>& p) const {
951  //return p.timestamp;
952  return (p.timestamp-t0).totalMilliseconds();
953  }
954 
955  Time t0;
956  };
957 
959  struct GetValue
960  {
961  typedef const T& result_type;
962  result_type operator()(const Stamped<T>& p) const {
963  return p;
964  }
965  };
966 
968 
969 public:
970 
989  template <typename Filter>
990  Stamped<T> get(const Time& timestamp, Filter&& filter) {
991  validateReadAccess();
992 
994  try
995  {
996  data = readInterval(timestamp, filter.samples(),
997  filter.samplesBefore(),
998  filter.samplesAfter());
999  // check filter requirements
1000  if (!filter.canExtrapolate())
1001  {
1002  int samplesBefore = filter.samplesBefore();
1003  int samplesAfter = filter.samplesAfter();
1004  // a rbegin in ChannelReadInterval could speed this up
1005  for (auto it = data.begin(); it != data.end(); ++it)
1006  {
1007  if (it->timestamp <= timestamp)
1008  --samplesBefore;
1009  else if (it->timestamp >= timestamp)
1010  --samplesAfter;
1011  }
1012 
1013  if (samplesBefore > 0)
1014  MIRA_THROW(XRuntime, "Filter::samplesBefore: Requirements not met. Missing " << samplesBefore << " items.");
1015  if (samplesAfter > 0)
1016  MIRA_THROW(XRuntime, "Filter::samplesAfter: Requirements not met. Missing " << samplesAfter << " items.");
1017  }
1018  }
1019  catch(Exception&)
1020  {
1021  // read interval failed so test if the channel only contains a single data element
1022  // if so return it as a special case for interpolation of channels that will only
1023  // receive a single update during their lifetime
1024  if (mChannel->getNrOfSlots() == 1)
1025  return get();
1026  // more than one data element in the channel but still not sufficient for interpolation
1027  // rethrow is our only option
1028  throw;
1029  }
1030 
1031  const Time t0 = data.begin()->timestamp;
1032 
1033  typedef typename ChannelReadInterval<T>::const_iterator const_iterator;
1034  typedef boost::transform_iterator<GetTime, const_iterator> GetTimeIterator;
1035  GetTimeIterator begin1 = GetTimeIterator(data.begin(), GetTime(t0));
1036  GetTimeIterator end1 = GetTimeIterator(data.end() , GetTime(t0));
1037 
1038  typedef boost::transform_iterator<GetValue, const_iterator> GetValueIterator;
1039 
1040  GetValueIterator begin2=GetValueIterator(data.begin(), GetValue());
1041  GetValueIterator end2 =GetValueIterator(data.end() , GetValue());
1042 
1043  typedef mira::IteratorRangeContainer<GetTimeIterator> TimeContainer;
1044  typedef mira::IteratorRangeContainer<GetValueIterator> ValueContainer;
1045  TimeContainer timeContainer(begin1, end1);
1046  ValueContainer valueContainer(begin2, end2);
1047 
1048  return makeStamped(filter.template apply<float, T>(timeContainer,
1049  valueContainer,
1050  (timestamp-t0).totalMilliseconds()),
1051  timestamp);
1052  }
1053 
1063  template <typename U = void>
1064  void post(const Stamped<T>& value) {
1065  validateWriteAccess();
1066  ChannelWrite<T> writeSlot = mChannel->write();
1067  *writeSlot = value;
1068  writeSlot.finish(); // explicit finish to avoid throwing in destructor
1069  }
1070 
1072  template <typename U = void>
1073  void post(Stamped<T>&& value) {
1074  validateWriteAccess();
1075  ChannelWrite<T> writeSlot = mChannel->write();
1076  *writeSlot = std::move(value);
1077  writeSlot.finish(); // explicit finish to avoid throwing in destructor
1078  }
1079 
1089  template <typename U>
1090  typename std::enable_if<!std::is_base_of_v<StampedHeader, std::decay_t<U>>>::type
1091  post(U&& value, const Time& timestamp = Time::now()) {
1092  validateWriteAccess();
1093  ChannelWrite<T> writeSlot = mChannel->write();
1094  *writeSlot = makeStamped(std::forward<U>(value), timestamp);
1095  writeSlot.finish(); // explicit finish to avoid throwing in destructor
1096  }
1097 
1107  template <typename U = T>
1108  typename std::enable_if<!std::is_void<U>::value>::type
1109  post(const typename ParamHelper<T>::type& value, const Time& timestamp = Time::now()) {
1110  validateWriteAccess();
1111  ChannelWrite<T> writeSlot = mChannel->write();
1112  *writeSlot = makeStamped(value, timestamp);
1113  writeSlot.finish(); // explicit finish to avoid throwing in destructor
1114  }
1115 
1117  template <typename U = T>
1118  typename std::enable_if<!std::is_void<U>::value>::type
1119  post(typename ParamHelper<T>::type&& value, const Time& timestamp = Time::now()) {
1120  validateWriteAccess();
1121  ChannelWrite<T> writeSlot = mChannel->write();
1122  *writeSlot = makeStamped(std::move(value), timestamp);
1123  writeSlot.finish(); // explicit finish to avoid throwing in destructor
1124  }
1125 
1127 
1128 public:
1129 
1131  template<typename U>
1132  friend Channel<U> channel_cast(Channel<void> channel);
1134 
1135 public:
1136 
1138  void dbgDump(bool brief=true) { mChannel->dbgDump(brief); }
1140 
1141 private:
1142 
1143  void validateReadAccess() const
1144  {
1145  validate();
1146  if((mAccessFlags & CHANNEL_ACCESS_READ)==0)
1147  MIRA_THROW(XAccessViolation, "You are not allowed to read from channel '"
1148  << mChannel->getID() << "'. Forgot to subscribe?");
1149  }
1150 
1151  void validateWriteAccess() const
1152  {
1153  validate();
1154  if((mAccessFlags & CHANNEL_ACCESS_WRITE)==0)
1155  MIRA_THROW(XAccessViolation, "You are not allowed to write to channel '"
1156  << mChannel->getID() << "'. Forgot to publish?");
1157  }
1158 
1159 private:
1160 
1161  ConcreteChannel<T>* mChannel;
1162  ChannelAccessFlags mAccessFlags;
1163 };
1164 
1166 
1168 template<typename U>
1169 inline Channel<U> channel_cast(Channel<void> channel)
1170 {
1171  channel.validate();
1172  return Channel<U>(channel_cast<U>(channel.mChannel), channel.mAccessFlags);
1173 }
1175 
1177 
1178 } // namespace
1179 
1180 #include "impl/ChannelReadWrite.hpp"
1181 #include "impl/ChannelReadInterval.hpp"
1182 
1183 #endif
TypeMetaPtr getTypeMeta() const
Return the type meta information for this channel.
Definition: Channel.h:499
void write(const Value &value, std::ostream &ioStream, bool formatted=false, int precision=-1)
Writes a json::Value into a given stream using the JSON format.
std::enable_if<!std::is_base_of_v< StampedHeader, std::decay_t< U > > >::type post(U &&value, const Time &timestamp=Time::now())
Writes the specified data with the specified time stamp into the channel.
Definition: Channel.h:1091
An object that allows read access to a whole interval of channel data.
Definition: ChannelReadInterval.h:72
const std::string & getID() const
Return the channel ID, its name.
Definition: Channel.h:458
Read access (Authority is a subscriber)
Definition: Channel.h:334
bool hasPublisher() const
Returns true, if this channel has at least one publisher.
Definition: Channel.h:541
void finish()
Releases the lock explicitly.
Definition: ChannelReadWrite.h:610
std::size_t getMaxSlots() const
Returns the upper limit of slots that are allowed for this channel.
Definition: Channel.h:557
void post(const Stamped< T > &value)
Writes the specified data into the channel.
Definition: Channel.h:1064
An exception that occurs whenever a channel has no data.
Definition: Channel.h:88
void post(Stamped< T > &&value)
Same as above, for rvalue reference (move semantics)
Definition: Channel.h:1073
Write access (Authority is a publisher)
Definition: Channel.h:335
Macros for generating logical operators for using enum values as flags.
ChannelRead< T > read(uint32 sequenceID, const Duration &searchInterval=Duration::seconds(1))
Obtains read access to the element with the specified sequenceID within the given search interval If ...
Definition: Channel.h:726
void validate() const
Checks if the channel is valid otherwise throws an exception.
Definition: Channel.h:441
#define MIRA_ENUM_TO_FLAGS(EnumType)
Macro that can be used with enums that contain flags.
Definition: EnumToFlags.h:80
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
Subscriber classes used to subscribe on channels for automatic notification.
Channel(ConcreteChannel< T > *channel, ChannelAccessFlags accessFlags)
Is used by Framework to create a channel proxy object.
Definition: Channel.h:415
std::string Typename
Definition: Typename.h:60
void setTypeMeta(TypeMetaPtr meta)
Set the type meta information for this channel.
Definition: Channel.h:507
bool isTyped() const
Returns true, if the channel is typed and false, if it is untyped.
Definition: Channel.h:476
An object that allows exclusive write access to data of a channel.
Definition: ChannelReadWrite.h:661
void read(const std::string &s, Value &oValue)
Read a json::Value from a string that contains JSON format.
uint32_t uint32
Definition: Types.h:64
#define MIRA_DEFINE_SERIALIZABLE_EXCEPTION(Ex, Base)
Macro for easily defining a new serializable exception class.
Definition: Exceptions.h:66
Definition: ChannelReadWrite.h:67
An object that allows read access to data of a channel.
Definition: ChannelReadWrite.h:503
ChannelReadInterval< T > readInterval(const Time &timestamp, std::size_t nrSlots, std::size_t olderSlots, std::size_t newerSlots, IntervalFillMode fillMode=PREFER_NEWER)
Obtains read access to an interval of elements before and after the requested timestamp.
Definition: Channel.h:778
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:78
Typename getTypename() const
Return the typename of the channel.
Definition: Channel.h:482
void finish()
Releases the lock explicitly and informs the Channel to signal all Subscribers that new data is avail...
Definition: ChannelReadWrite.h:776
Wrapper class for boost::posix_time::ptime for adding more functionality to it.
Definition: Time.h:418
ChannelRead< T > read(const Time &timestamp, SlotQueryMode mode=NEAREST_SLOT, const Duration &tolerance=Duration::infinity())
Obtains read access to the element at the specified timestamp.
Definition: Channel.h:703
const_iterator end() const
Definition: ChannelReadInterval.h:164
const_iterator begin() const
Definition: ChannelReadInterval.h:163
Classes for automatic locking/unlocking when reading and writing to channels.
Commonly used exception classes.
std::size_t getNrOfSlots() const
Returns how many slots (i.e.
Definition: Channel.h:590
PropertyHint type(const std::string &t)
Sets the attribute "type" to the specified value.
Definition: PropertyHint.h:295
Definition: AbstractChannel.h:70
bool hasSoloSlot() const
Returns true, if this channel has one solo slot only.
Definition: Channel.h:549
sec_type seconds() const
Returns normalized number of seconds (0..59)
Definition: Time.h:280
Use this class to represent time durations.
Definition: Time.h:106
ChannelRead< T > read(const Time &timestamp, const Duration &tolerance)
Same as above, but always takes the nearest slot.
Definition: Channel.h:745
ChannelRead< T > read()
Obtains read access to the latest data element of this channel.
Definition: Channel.h:678
void reset()
Reset the proxy object so that it becomes invalid.
Definition: Channel.h:423
Typed ChannelBuffer.
Definition: ChannelBuffer.h:896
The slot with smallest time difference to the requested will be chosen.
Definition: ChannelBuffer.h:102
Const iterator for iterating over the interval.
Definition: ChannelReadInterval.h:85
void setTypename(const Typename &type)
Set the typename of this channel.
Definition: Channel.h:491
static Time now()
Returns the current utc based time.
Definition: Time.h:481
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
boost::shared_ptr< TypeMeta > TypeMetaPtr
Definition: MetaSerializer.h:309
std::enable_if<!std::is_void< U >::value >::type post(typename ParamHelper< T >::type &&value, const Time &timestamp=Time::now())
Same as above, for rvalue reference (move semantics)
Definition: Channel.h:1119
bool isAutoIncreasingStorageDuration() const
Returns whether the channel buffer is automatically increasing the storage duration.
Definition: Channel.h:582
std::enable_if<!std::is_void< U >::value >::type post(const typename ParamHelper< T >::type &value, const Time &timestamp=Time::now())
This allows post({}, Time()); to deduce we want to post an object of the channel&#39;s type...
Definition: Channel.h:1109
Duration getStorageDuration() const
Returns the timeframe that specifies how long a slot is guaranteed to be kept in the channel buffer...
Definition: Channel.h:574
Stamped< typename std::decay< T >::type > makeStamped(T &&value, const Time &timestamp=Time::now(), const std::string &frameID=std::string(), uint32 sequenceID=0)
Declare stamped classes for all standard data types including std::string.
Definition: Stamped.h:471
static Time eternity()
Returns 9999/12/31 23:59:59.999999.
Definition: Time.h:489
Base class for exceptions.
Definition: Exception.h:195
Generic buffer class that can be used as a replacement for std::vector whenever copying and reallocat...
Definition: Buffer.h:84
bool hasSubscriber() const
Returns true, if this channel has at least one subscriber.
Definition: Channel.h:533
static Duration infinity()
Returns a special duration time representing positive infinity.
Definition: Time.h:242
An iterator range class.
ChannelWrite< T > write(bool copyLatestData, Fn fn=[](const auto &s){ return s;})
Same as write above with an additional parameter copyLatestData that allows you to specify whether th...
Definition: Channel.h:870
ChannelRead< T > waitForData(const Duration &timeout=Duration::infinity()) const
Waits until data in this channel becomes available.
Definition: Channel.h:616
Channel()
Create channel proxy that is not assigned to a channel.
Definition: Channel.h:410
ChannelWrite< T > write()
Obtains exclusive write access to the next free data slot of this channel.
Definition: Channel.h:825
No access at all (Authority is not a publisher nor a subscriber)
Definition: Channel.h:333
std::size_t getMinSlots() const
Returns the number slots that are guaranteed to be kept in the channel buffer.
Definition: Channel.h:565
int getTypeId() const
Returns the type id of the channel.
Definition: Channel.h:468
Prefer filling the interval with slots with timestamp > requested.
Definition: ChannelBuffer.h:114
bool isValid() const
Returns true if the proxy object is valid.
Definition: Channel.h:432
IntervalFillMode
Mode that is used to determine what slots should be added to the interval when not enough slots are a...
Definition: ChannelBuffer.h:109
SlotQueryMode
Mode that is used to determine the slot obtained from a channel when no slot exists at the exact time...
Definition: ChannelBuffer.h:93
Base class for all framework channels.
Infrastructure for promotion of channels from void to typed based on runtime knowledge of the typenam...
#define MIRA_SLEEP(ms)
Sleeps for ms milliseconds This is a thread interruption point - if interruption of the current threa...
Definition: Thread.h:97
Implements AbstractChannelSubscriber for a concrete data type.
Definition: ChannelSubscriber.h:82
The framework that holds all manager classes and provides startup and shutdown of all framework relat...
Provides method for generating a unique id for any type.
bool isEmpty() const
Returns if the channel is empty (no data has been published)
Definition: Channel.h:525
bool waitForPublisher(const Duration &timeout=Duration::infinity()) const
Waits until this channel has at least one publisher.
Definition: Channel.h:648
Wraps an STL conform container around a range of values within another container. ...
Definition: IteratorRangeContainer.h:64
Classes for reading whole intervals of data from channels.
ChannelReadInterval< T > readInterval(const Time &from, const Time &to=Time::eternity())
Obtains read access to an interval of elements in a given time span.
Definition: Channel.h:803
ChannelAccessFlags
Flags specifying the access rights of an authority to a channel Can be combined.
Definition: Channel.h:332