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  bool keepStorageDuration = false);
172 
196  ChannelReadInterval<T> readInterval(const Time& timestamp, std::size_t nrSlots,
197  std::size_t olderSlots, std::size_t newerSlots,
198  IntervalFillMode fillMode = PREFER_NEWER,
199  bool keepStorageDuration = false);
200 
219  ChannelReadInterval<T> readInterval(const Time& from,
220  const Time& to = Time::eternity(),
221  bool keepStorageDuration = false);
222 
235  ChannelWrite<T> write();
236 
237 public:
238  friend class Channel<T>;
239 };
240 
242 
243 
250 template<typename T>
251 struct ChannelCaster {
252  static ConcreteChannel<T>* cast(AbstractChannel* p)
253  {
254  // promote the channel if necessary (this will throw an exception, if
255  // the channel cannot be promoted to the desired type)
256  promote_channel<T>(p);
257 
258  assert(p->isTyped()); // at the point p will always be typed
259 
260  // check the type of our buffer's slot manually
261  if(typeId<T>()!=p->getTypeId())
262  MIRA_THROW(XBadCast, "Cannot cast channel '" << p->getID()
263  << "' (type '" << p->getTypename() << "') "
264  << " to typed channel of type '" << typeName<T>() << "'");
265 
266  // cast us "hard" using a static_cast.
267  // This is safe, since we have checked the types above
268  return static_cast<ConcreteChannel<T>*>(p);
269  }
270 };
271 
273 
274 // specialization to cast to untyped ConcreteChannel (void)
275 template<>
276 struct ChannelCaster<void> {
277  static ConcreteChannel<void>* cast(AbstractChannel* p)
278  {
279  // cast us "hard" using a static_cast.
280  // This is safe, since all channels can be casted to untyped channel
281  return static_cast<ConcreteChannel<void>* >(p);
282  }
283 };
284 
286 
287 // specialization to cast polymorphic channels
288 template<typename T>
289 struct ChannelCaster<T*> {
290  static ConcreteChannel<T*>* cast(AbstractChannel* p)
291  {
292  static_assert(std::is_base_of<mira::Object,T>::value,
293  "Pointers that are used in channels must be derived from "
294  "mira::Object. Pointers to other classes cannot be used.");
295 
296  // promote the channel if necessary (this will throw an exception, if the
297  // the channel cannot be promoted to the desired type)
298  promote_channel<T*>(p);
299 
300  // channel must be typed after promotion
301  assert(p->getBuffer()->isPolymorphic());
302 
303  // cast us "hard" using a static_cast.
304  // This is safe, since we have checked the types above
305  return static_cast<ConcreteChannel<T*>* >(p);
306  }
307 };
308 
310 
311 template<typename T>
312 inline ConcreteChannel<T>* channel_cast(AbstractChannel* p)
313 {
314  return ChannelCaster<T>::cast(p);
315 }
316 
318 
320 
322 template <typename T>
323 class Channel;
324 
326 template<typename T>
327 inline Channel<T> channel_cast(Channel<void> channel);
329 
330 
339 };
341 
342 
343 namespace {
344 
345 template <typename T>
346 struct ParamHelper {
347  typedef T type;
348 };
349 
350 template<>
351 struct ParamHelper<void> {
352  typedef int type; // arbitrary, it will not be used for T=void actually,
353  // but needs to name a valid argument type
354 };
355 
356 }
357 
359 
366 
412 template <typename T>
413 class Channel
414 {
415 public:
416 
420  Channel() : mChannel(), mAccessFlags(CHANNEL_ACCESS_NONE) {}
421 
426  mChannel(channel), mAccessFlags(accessFlags) {
427  assert(mChannel!=NULL);
428  }
429 
433  void reset() {
434  mChannel=NULL;
435  mAccessFlags = CHANNEL_ACCESS_NONE;
436  }
437 
442  bool isValid() const {
443  return mChannel!=NULL;
444  }
445 
451  void validate() const {
452  if(mChannel==NULL)
453  MIRA_THROW(XAccessViolation,
454  "No channel assigned to the channel proxy (of type " <<
455  typeName<T>() << "). "
456  "You can obtain a channel using Authority::getChannel()!");
457  }
458 
464 
468  const std::string& getID() const {
469  validate();
470  return mChannel->getID();
471  }
472 
478  int getTypeId() const {
479  validate();
480  return mChannel->getTypeId();
481  }
482 
486  bool isTyped() const { return getTypeId()>=0; }
487 
493  validate();
494  return mChannel->getTypename();
495  }
496 
501  void setTypename(const Typename& type) {
502  validate();
503  mChannel->setTypename(type);
504  }
505 
510  validate();
511  return mChannel->getTypeMeta();
512  }
513 
518  validate();
519  mChannel->setTypeMeta(meta);
520  }
521 
523 
524 public:
525 
531 
535  bool isEmpty() const {
536  validate();
537  return mChannel->getNrOfDataChanges() == 0;
538  }
539 
543  bool hasSubscriber() const {
544  validate();
545  return mChannel->hasSubscriber();
546  }
547 
551  bool hasPublisher() const {
552  validate();
553  return mChannel->hasPublisher();
554  }
555 
559  bool hasSoloSlot() const {
560  validate();
561  return mChannel->getBuffer()->getMaxSlots() == 1;
562  }
563 
567  std::size_t getMaxSlots() const {
568  validate();
569  return mChannel->getBuffer()->getMaxSlots();
570  }
571 
575  std::size_t getMinSlots() const {
576  validate();
577  return mChannel->getBuffer()->getMinSlots();
578  }
579 
585  validate();
586  return mChannel->getBuffer()->getStorageDuration();
587  }
588 
593  validate();
594  return mChannel->getBuffer()->isAutoIncreasingStorageDuration();
595  }
596 
600  std::size_t getNrOfSlots() const {
601  validate();
602  return mChannel->getBuffer()->getSize();
603  }
604 
606 
607 public:
608 
615 
627  {
628  validateReadAccess();
629 
630  Time end;
631  if(!timeout.isValid() || timeout.isInfinity())
632  end = Time::eternity();
633  else
634  end = Time::now() + timeout;
635 
636  while(!boost::this_thread::interruption_requested())
637  {
638  try {
639  return mChannel->read();
640  } catch(XInvalidRead& ex) {}
641  if(Time::now()>end) // handle timeout
642  break;
643  MIRA_SLEEP(50)
644  }
645  return ChannelRead<T>();
646  }
647 
648 
658  bool waitForPublisher(const Duration& timeout = Duration::infinity()) const
659  {
660  validateReadAccess();
661 
662  Time end;
663  if(!timeout.isValid() || timeout.isInfinity())
664  end = Time::eternity();
665  else
666  end = Time::now() + timeout;
667 
668  while(!boost::this_thread::interruption_requested())
669  {
670  if(hasPublisher())
671  return true;
672  if(Time::now()>end) // handle timeout
673  break;
674  MIRA_SLEEP(50)
675  }
676  return false; // timeout
677  }
678 
679 
689  validateReadAccess();
690  return mChannel->read();
691  }
692 
714  const Duration& tolerance = Duration::infinity()) {
715  validateReadAccess();
716  return mChannel->read(timestamp, mode, tolerance);
717  }
718 
737  const Duration& searchInterval = Duration::seconds(1)) {
738  validateReadAccess();
739  Time newestSlotTime = mChannel->read()->timestamp;
740  ChannelReadInterval<T> interval = readInterval(newestSlotTime - searchInterval, newestSlotTime);
741  typename ChannelReadInterval<T>::const_iterator iter = interval.begin();
742  for(; iter != interval.end(); ++iter){
743  if(iter->sequenceID == sequenceID)
744  return (ChannelRead<T>)iter;
745  }
746  MIRA_THROW(XInvalidRead, "No slot with sequenceID "<<sequenceID<<
747  " found within searchInterval of channel");
748  }
749 
755  ChannelRead<T> read(const Time& timestamp, const Duration& tolerance) {
756  validateReadAccess();
757  return mChannel->read(timestamp, NEAREST_SLOT, tolerance);
758  }
759 
789  std::size_t nrSlots,
790  std::size_t olderSlots,
791  std::size_t newerSlots,
792  IntervalFillMode fillMode = PREFER_NEWER) {
793  validateReadAccess();
794  return mChannel->readInterval(timestamp, nrSlots, olderSlots,
795  newerSlots, fillMode);
796  }
797 
814  const Time& to=Time::eternity()) {
815  validateReadAccess();
816  return mChannel->readInterval(from, to);
817  }
818 
823  const Time& to = Time::eternity()) {
824  validateReadAccess();
825  return mChannel->readInterval(from, to, true);
826  }
827 
845  validateWriteAccess();
846  return mChannel->write();
847  }
848 
888  template <typename Fn = Stamped<T>(*)(const Stamped<T>&)>
889  ChannelWrite<T> write(bool copyLatestData, Fn fn = [](const auto& s){ return s; }) {
890  validateWriteAccess();
891 
892  // check if we should and need to copy data into the write slot
893  if(copyLatestData
894  && (mChannel->getBuffer()->getMaxSlots()>1) // only necessary if we may have more than one slot
895  && (mChannel->getBuffer()->getSize()>0)) // and only if we have at least one slot yet
896  {
897  ChannelRead<T> latest = mChannel->read();
898  Stamped<T> tmp(fn(*latest));
899  latest.finish();
900  ChannelWrite<T> writeSlot = mChannel->write();
901  *writeSlot = tmp;
902  return writeSlot;
903 
904  } else
905  return mChannel->write();
906  }
907 
921  Stamped<T> get() {
922  validateReadAccess();
923  ChannelRead<T> value = mChannel->read();
924  return *value;
925  }
926 
940  Stamped<T> get(const Time& timestamp, SlotQueryMode mode=NEAREST_SLOT,
941  const Duration& tolerance = Duration::infinity()) {
942  validateReadAccess();
943  ChannelRead<T> value = mChannel->read(timestamp, mode, tolerance);
944  return *value;
945  }
946 
952  Stamped<T> get(const Time& timestamp, Duration tolerance) {
953  validateReadAccess();
954  ChannelRead<T> value = mChannel->read(timestamp, NEAREST_SLOT, tolerance);
955  return *value;
956  }
957 
958 private:
959 
961 
963  struct GetTime
964  {
965  GetTime(const Time& iT0) : t0(iT0) {}
966 
967  //typedef const Time& result_type;
968  typedef float result_type;
969  result_type operator()(const Stamped<T>& p) const {
970  //return p.timestamp;
971  return (p.timestamp-t0).totalMilliseconds();
972  }
973 
974  Time t0;
975  };
976 
978  struct GetValue
979  {
980  typedef const T& result_type;
981  result_type operator()(const Stamped<T>& p) const {
982  return p;
983  }
984  };
985 
987 
988 public:
989 
1008  template <typename Filter>
1009  Stamped<T> get(const Time& timestamp, Filter&& filter) {
1010  validateReadAccess();
1011 
1013  try
1014  {
1015  data = readInterval(timestamp, filter.samples(),
1016  filter.samplesBefore(),
1017  filter.samplesAfter());
1018  // check filter requirements
1019  if (!filter.canExtrapolate())
1020  {
1021  int samplesBefore = filter.samplesBefore();
1022  int samplesAfter = filter.samplesAfter();
1023  // a rbegin in ChannelReadInterval could speed this up
1024  for (auto it = data.begin(); it != data.end(); ++it)
1025  {
1026  if (it->timestamp <= timestamp)
1027  --samplesBefore;
1028  else if (it->timestamp >= timestamp)
1029  --samplesAfter;
1030  }
1031 
1032  if (samplesBefore > 0)
1033  MIRA_THROW(XRuntime, "Filter::samplesBefore: Requirements not met. Missing " << samplesBefore << " items.");
1034  if (samplesAfter > 0)
1035  MIRA_THROW(XRuntime, "Filter::samplesAfter: Requirements not met. Missing " << samplesAfter << " items.");
1036  }
1037  }
1038  catch(Exception&)
1039  {
1040  // read interval failed so test if the channel only contains a single data element
1041  // if so return it as a special case for interpolation of channels that will only
1042  // receive a single update during their lifetime
1043  if (mChannel->getNrOfSlots() == 1)
1044  return get();
1045  // more than one data element in the channel but still not sufficient for interpolation
1046  // rethrow is our only option
1047  throw;
1048  }
1049 
1050  const Time t0 = data.begin()->timestamp;
1051 
1052  typedef typename ChannelReadInterval<T>::const_iterator const_iterator;
1053  typedef boost::transform_iterator<GetTime, const_iterator> GetTimeIterator;
1054  GetTimeIterator begin1 = GetTimeIterator(data.begin(), GetTime(t0));
1055  GetTimeIterator end1 = GetTimeIterator(data.end() , GetTime(t0));
1056 
1057  typedef boost::transform_iterator<GetValue, const_iterator> GetValueIterator;
1058 
1059  GetValueIterator begin2=GetValueIterator(data.begin(), GetValue());
1060  GetValueIterator end2 =GetValueIterator(data.end() , GetValue());
1061 
1062  typedef mira::IteratorRangeContainer<GetTimeIterator> TimeContainer;
1063  typedef mira::IteratorRangeContainer<GetValueIterator> ValueContainer;
1064  TimeContainer timeContainer(begin1, end1);
1065  ValueContainer valueContainer(begin2, end2);
1066 
1067  return makeStamped(filter.template apply<float, T>(timeContainer,
1068  valueContainer,
1069  (timestamp-t0).totalMilliseconds()),
1070  timestamp);
1071  }
1072 
1082  template <typename U = void>
1083  void post(const Stamped<T>& value) {
1084  validateWriteAccess();
1085  ChannelWrite<T> writeSlot = mChannel->write();
1086  *writeSlot = value;
1087  writeSlot.finish(); // explicit finish to avoid throwing in destructor
1088  }
1089 
1091  template <typename U = void>
1092  void post(Stamped<T>&& value) {
1093  validateWriteAccess();
1094  ChannelWrite<T> writeSlot = mChannel->write();
1095  *writeSlot = std::move(value);
1096  writeSlot.finish(); // explicit finish to avoid throwing in destructor
1097  }
1098 
1108  template <typename U>
1109  typename std::enable_if<!std::is_base_of_v<StampedHeader, std::decay_t<U>>>::type
1110  post(U&& value, const Time& timestamp = Time::now()) {
1111  validateWriteAccess();
1112  ChannelWrite<T> writeSlot = mChannel->write();
1113  *writeSlot = makeStamped(std::forward<U>(value), timestamp);
1114  writeSlot.finish(); // explicit finish to avoid throwing in destructor
1115  }
1116 
1126  template <typename U = T>
1127  typename std::enable_if<!std::is_void<U>::value>::type
1128  post(const typename ParamHelper<T>::type& value, const Time& timestamp = Time::now()) {
1129  validateWriteAccess();
1130  ChannelWrite<T> writeSlot = mChannel->write();
1131  *writeSlot = makeStamped(value, timestamp);
1132  writeSlot.finish(); // explicit finish to avoid throwing in destructor
1133  }
1134 
1136  template <typename U = T>
1137  typename std::enable_if<!std::is_void<U>::value>::type
1138  post(typename ParamHelper<T>::type&& value, const Time& timestamp = Time::now()) {
1139  validateWriteAccess();
1140  ChannelWrite<T> writeSlot = mChannel->write();
1141  *writeSlot = makeStamped(std::move(value), timestamp);
1142  writeSlot.finish(); // explicit finish to avoid throwing in destructor
1143  }
1144 
1146 
1147 public:
1148 
1150  template<typename U>
1151  friend Channel<U> channel_cast(Channel<void> channel);
1153 
1154 public:
1155 
1157  void dbgDump(bool brief=true) { mChannel->dbgDump(brief); }
1159 
1160 private:
1161 
1162  void validateReadAccess() const
1163  {
1164  validate();
1165  if((mAccessFlags & CHANNEL_ACCESS_READ)==0)
1166  MIRA_THROW(XAccessViolation, "You are not allowed to read from channel '"
1167  << mChannel->getID() << "'. Forgot to subscribe?");
1168  }
1169 
1170  void validateWriteAccess() const
1171  {
1172  validate();
1173  if((mAccessFlags & CHANNEL_ACCESS_WRITE)==0)
1174  MIRA_THROW(XAccessViolation, "You are not allowed to write to channel '"
1175  << mChannel->getID() << "'. Forgot to publish?");
1176  }
1177 
1178 private:
1179 
1180  ConcreteChannel<T>* mChannel;
1181  ChannelAccessFlags mAccessFlags;
1182 };
1183 
1185 
1187 template<typename U>
1188 inline Channel<U> channel_cast(Channel<void> channel)
1189 {
1190  channel.validate();
1191  return Channel<U>(channel_cast<U>(channel.mChannel), channel.mAccessFlags);
1192 }
1194 
1196 
1197 } // namespace
1198 
1199 #include "impl/ChannelReadWrite.hpp"
1200 #include "impl/ChannelReadInterval.hpp"
1201 
1202 #endif
TypeMetaPtr getTypeMeta() const
Return the type meta information for this channel.
Definition: Channel.h:509
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:1110
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:468
Read access (Authority is a subscriber)
Definition: Channel.h:337
const KeepStorageDurationType KeepStorageDuration
Definition: Channel.h:365
bool hasPublisher() const
Returns true, if this channel has at least one publisher.
Definition: Channel.h:551
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:567
void post(const Stamped< T > &value)
Writes the specified data into the channel.
Definition: Channel.h:1083
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:1092
Write access (Authority is a publisher)
Definition: Channel.h:338
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:736
void validate() const
Checks if the channel is valid otherwise throws an exception.
Definition: Channel.h:451
#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:425
std::string Typename
Definition: Typename.h:60
void setTypeMeta(TypeMetaPtr meta)
Set the type meta information for this channel.
Definition: Channel.h:517
bool isTyped() const
Returns true, if the channel is typed and false, if it is untyped.
Definition: Channel.h:486
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:788
#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:492
void finish()
Releases the lock explicitly and informs the Channel to signal all Subscribers that new data is avail...
Definition: ChannelReadWrite.h:776
ChannelReadInterval< T > readInterval(const Time &from, KeepStorageDurationType, const Time &to=Time::eternity())
Same as above, but does not affect the channel&#39;s storage duration.
Definition: Channel.h:822
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:713
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:600
PropertyHint type(const std::string &t)
Sets the attribute "type" to the specified value.
Definition: PropertyHint.h:296
Definition: AbstractChannel.h:70
bool hasSoloSlot() const
Returns true, if this channel has one solo slot only.
Definition: Channel.h:559
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:755
ChannelRead< T > read()
Obtains read access to the latest data element of this channel.
Definition: Channel.h:688
void reset()
Reset the proxy object so that it becomes invalid.
Definition: Channel.h:433
Typed ChannelBuffer.
Definition: ChannelBuffer.h:919
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:501
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:1138
bool isAutoIncreasingStorageDuration() const
Returns whether the channel buffer is automatically increasing the storage duration.
Definition: Channel.h:592
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:1128
Duration getStorageDuration() const
Returns the timeframe that specifies how long a slot is guaranteed to be kept in the channel buffer...
Definition: Channel.h:584
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:543
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:889
ChannelRead< T > waitForData(const Duration &timeout=Duration::infinity()) const
Waits until data in this channel becomes available.
Definition: Channel.h:626
Channel()
Create channel proxy that is not assigned to a channel.
Definition: Channel.h:420
ChannelWrite< T > write()
Obtains exclusive write access to the next free data slot of this channel.
Definition: Channel.h:844
No access at all (Authority is not a publisher nor a subscriber)
Definition: Channel.h:336
std::size_t getMinSlots() const
Returns the number slots that are guaranteed to be kept in the channel buffer.
Definition: Channel.h:575
int getTypeId() const
Returns the type id of the channel.
Definition: Channel.h:478
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:442
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
This tag class can be used when calling Channel::readInterval() to specify the channel&#39;s storage dura...
Definition: Channel.h:364
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:535
bool waitForPublisher(const Duration &timeout=Duration::infinity()) const
Waits until this channel has at least one publisher.
Definition: Channel.h:658
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:813
ChannelAccessFlags
Flags specifying the access rights of an authority to a channel Can be combined.
Definition: Channel.h:335