MIRA
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
152  void removeSubscriber()
153  {
154  boost::mutex::scoped_lock lock(mSubscribersMutex);
155  if (mNrOfSubscribersWithoutChannelSubscriber>0)
156  --mNrOfSubscribersWithoutChannelSubscriber;
157  }
158 
163  void removeSubscriber(SubscriberPtr subscriber)
164  {
166  }
167 
168 public:
169 
178 
189  ChannelRead<T> read(const Time& timestamp, SlotQueryMode mode = NEAREST_SLOT,
190  const Duration& tolerance = Duration::infinity());
191 
215  ChannelReadInterval<T> readInterval(const Time& timestamp, std::size_t nrSlots,
216  std::size_t olderSlots, std::size_t newerSlots,
217  IntervalFillMode fillMode = PREFER_NEWER);
218 
237  ChannelReadInterval<T> readInterval(const Time& from,
238  const Time& to = Time::eternity());
239 
252 
253 public:
254  friend class Channel<T>;
255 };
256 
258 
259 
266 template<typename T>
267 struct ChannelCaster {
268  static ConcreteChannel<T>* cast(AbstractChannel* p)
269  {
270  // promote the channel if necessary (this will throw an exception, if
271  // the channel cannot be promoted to the desired type)
272  promote_channel<T>(p);
273 
274  assert(p->isTyped()); // at the point p will always be typed
275 
276  // check the type of our buffer's slot manually
277  if(typeId<T>()!=p->getTypeId())
278  MIRA_THROW(XBadCast, "Cannot cast channel '" << p->getID()
279  << "' (type '" << p->getTypename() << "') "
280  << " to typed channel of type '" << typeName<T>() << "'");
281 
282  // cast us "hard" using a static_cast.
283  // This is safe, since we have checked the types above
284  return static_cast<ConcreteChannel<T>*>(p);
285  }
286 };
287 
289 
290 // specialization to cast to untyped ConcreteChannel (void)
291 template<>
292 struct ChannelCaster<void> {
293  static ConcreteChannel<void>* cast(AbstractChannel* p)
294  {
295  // cast us "hard" using a static_cast.
296  // This is safe, since all channels can be casted to untyped channel
297  return static_cast<ConcreteChannel<void>* >(p);
298  }
299 };
300 
302 
303 // specialization to cast polymorphic channels
304 template<typename T>
305 struct ChannelCaster<T*> {
306  static ConcreteChannel<T*>* cast(AbstractChannel* p)
307  {
308  static_assert(std::is_base_of<mira::Object,T>::value,
309  "Pointers that are used in channels must be derived from "
310  "mira::Object. Pointers to other classes cannot be used.");
311 
312  // promote the channel if necessary (this will throw an exception, if the
313  // the channel cannot be promoted to the desired type)
314  promote_channel<T*>(p);
315 
316  // channel must be typed after promotion
317  assert(p->getBuffer()->isPolymorphic());
318 
319  // cast us "hard" using a static_cast.
320  // This is safe, since we have checked the types above
321  return static_cast<ConcreteChannel<T*>* >(p);
322  }
323 };
324 
326 
327 template<typename T>
328 inline ConcreteChannel<T>* channel_cast(AbstractChannel* p)
329 {
330  return ChannelCaster<T>::cast(p);
331 }
332 
334 
336 
338 template <typename T>
339 class Channel;
340 
342 template<typename T>
343 inline Channel<T> channel_cast(Channel<void> channel);
345 
346 
355 };
357 
358 
359 namespace {
360 
361 template <typename T>
362 struct ParamHelper {
363  typedef T type;
364 };
365 
366 template<>
367 struct ParamHelper<void> {
368  typedef int type; // arbitrary, it will not be used for T=void actually,
369  // but needs to name a valid argument type
370 };
371 
372 }
373 
375 
421 template <typename T>
422 class Channel
423 {
424 public:
425 
429  Channel() : mChannel(), mAccessFlags(CHANNEL_ACCESS_NONE) {}
430 
435  mChannel(channel), mAccessFlags(accessFlags) {
436  assert(mChannel!=NULL);
437  }
438 
442  void reset() {
443  mChannel=NULL;
444  mAccessFlags = CHANNEL_ACCESS_NONE;
445  }
446 
451  bool isValid() const {
452  return mChannel!=NULL;
453  }
454 
460  void validate() const {
461  if(mChannel==NULL)
462  MIRA_THROW(XAccessViolation, "No channel assigned to the channel proxy. "
463  "You can obtain a channel using Authority::getChannel()!");
464  }
465 
471 
475  const std::string& getID() const {
476  validate();
477  return mChannel->getID();
478  }
479 
485  int getTypeId() const {
486  validate();
487  return mChannel->getTypeId();
488  }
489 
493  bool isTyped() const { return getTypeId()>=0; }
494 
500  validate();
501  return mChannel->getTypename();
502  }
503 
508  void setTypename(const Typename& type) {
509  validate();
510  mChannel->setTypename(type);
511  }
512 
517  validate();
518  return mChannel->getTypeMeta();
519  }
520 
525  validate();
526  mChannel->setTypeMeta(meta);
527  }
528 
530 
531 public:
532 
538 
542  bool isEmpty() const {
543  validate();
544  return mChannel->getNrOfSlots() == 0;
545  }
546 
550  bool hasSubscriber() const {
551  validate();
552  return mChannel->hasSubscriber();
553  }
554 
558  bool hasPublisher() const {
559  validate();
560  return mChannel->hasPublisher();
561  }
562 
566  bool hasSoloSlot() const {
567  validate();
568  return mChannel->getBuffer()->getMaxSlots() == 1;
569  }
570 
574  std::size_t getMaxSlots() const {
575  validate();
576  return mChannel->getBuffer()->getMaxSlots();
577  }
578 
582  std::size_t getMinSlots() const {
583  validate();
584  return mChannel->getBuffer()->getMinSlots();
585  }
586 
592  validate();
593  return mChannel->getBuffer()->getStorageDuration();
594  }
595 
600  validate();
601  return mChannel->getBuffer()->isAutoIncreasingStorageDuration();
602  }
603 
607  std::size_t getNrOfSlots() const {
608  validate();
609  return mChannel->getBuffer()->getSize();
610  }
611 
613 
614 public:
615 
622 
634  {
635  validateReadAccess();
636 
637  Time end;
638  if(!timeout.isValid() || timeout.isInfinity())
639  end = Time::eternity();
640  else
641  end = Time::now() + timeout;
642 
643  while(!boost::this_thread::interruption_requested())
644  {
645  try {
646  return mChannel->read();
647  } catch(XInvalidRead& ex) {}
648  if(Time::now()>end) // handle timeout
649  break;
650  MIRA_SLEEP(50)
651  }
652  return ChannelRead<T>();
653  }
654 
655 
665  bool waitForPublisher(const Duration& timeout = Duration::infinity()) const
666  {
667  validateReadAccess();
668 
669  Time end;
670  if(!timeout.isValid() || timeout.isInfinity())
671  end = Time::eternity();
672  else
673  end = Time::now() + timeout;
674 
675  while(!boost::this_thread::interruption_requested())
676  {
677  if(hasPublisher())
678  return true;
679  if(Time::now()>end) // handle timeout
680  break;
681  MIRA_SLEEP(50)
682  }
683  return false; // timeout
684  }
685 
686 
696  validateReadAccess();
697  return mChannel->read();
698  }
699 
721  const Duration& tolerance = Duration::infinity()) {
722  validateReadAccess();
723  return mChannel->read(timestamp, mode, tolerance);
724  }
725 
743  ChannelRead<T> read(uint32 sequenceID,
744  const Duration& searchInterval = Duration::seconds(1)) {
745  validateReadAccess();
746  Time newestSlotTime = mChannel->read()->timestamp;
747  ChannelReadInterval<T> interval = readInterval(newestSlotTime - searchInterval, newestSlotTime);
748  typename ChannelReadInterval<T>::const_iterator iter = interval.begin();
749  for(; iter != interval.end(); ++iter){
750  if(iter->sequenceID == sequenceID)
751  return (ChannelRead<T>)iter;
752  }
753  MIRA_THROW(XInvalidRead, "No slot with sequenceID "<<sequenceID<<
754  " found within searchInterval of channel");
755  }
756 
762  ChannelRead<T> read(const Time& timestamp, const Duration& tolerance) {
763  validateReadAccess();
764  return mChannel->read(timestamp, NEAREST_SLOT, tolerance);
765  }
766 
796  std::size_t nrSlots,
797  std::size_t olderSlots,
798  std::size_t newerSlots,
799  IntervalFillMode fillMode = PREFER_NEWER) {
800  validateReadAccess();
801  return mChannel->readInterval(timestamp, nrSlots, olderSlots,
802  newerSlots, fillMode);
803  }
804 
821  const Time& to=Time::eternity()) {
822  validateReadAccess();
823  return mChannel->readInterval(from, to);
824  }
825 
842  validateWriteAccess();
843  return mChannel->write();
844  }
845 
871  ChannelWrite<T> write(bool copyLatestData) {
872  validateWriteAccess();
873 
874  // check if we should and need to copy data into the write slot
875  if(copyLatestData
876  && (mChannel->getBuffer()->getMaxSlots()>1) // only necessary if we may have more than one slot
877  && (mChannel->getBuffer()->getSize()>0)) // and only if we have at least one slot yet
878  {
879  ChannelRead<T> latest = mChannel->read();
880  Stamped<T> tmp(*latest);
881  latest.finish();
882  ChannelWrite<T> writeSlot = mChannel->write();
883  *writeSlot = tmp;
884  return writeSlot;
885 
886  } else
887  return mChannel->write();
888  }
889 
903  Stamped<T> get() {
904  validateReadAccess();
905  ChannelRead<T> value = mChannel->read();
906  return *value;
907  }
908 
922  Stamped<T> get(const Time& timestamp, SlotQueryMode mode=NEAREST_SLOT,
923  const Duration& tolerance = Duration::infinity()) {
924  validateReadAccess();
925  ChannelRead<T> value = mChannel->read(timestamp, mode, tolerance);
926  return *value;
927  }
928 
934  Stamped<T> get(const Time& timestamp, Duration tolerance) {
935  validateReadAccess();
936  ChannelRead<T> value = mChannel->read(timestamp, NEAREST_SLOT, tolerance);
937  return *value;
938  }
939 
940 private:
941 
943 
945  struct GetTime
946  {
947  GetTime(const Time& iT0) : t0(iT0) {}
948 
949  //typedef const Time& result_type;
950  typedef float result_type;
951  result_type operator()(const Stamped<T>& p) const {
952  //return p.timestamp;
953  return (p.timestamp-t0).totalMilliseconds();
954  }
955 
956  Time t0;
957  };
958 
960  struct GetValue
961  {
962  typedef const T& result_type;
963  result_type operator()(const Stamped<T>& p) const {
964  return p;
965  }
966  };
967 
969 
970 public:
971 
990  template <typename Filter>
991  Stamped<T> get(const Time& timestamp, Filter&& filter) {
992  validateReadAccess();
993 
995  try
996  {
997  data = readInterval(timestamp, filter.samples(),
998  filter.samplesBefore(),
999  filter.samplesAfter());
1000  // check filter requirements
1001  if (!filter.canExtrapolate())
1002  {
1003  int samplesBefore = filter.samplesBefore();
1004  int samplesAfter = filter.samplesAfter();
1005  // a rbegin in ChannelReadInterval could speed this up
1006  for (auto it = data.begin(); it != data.end(); ++it)
1007  {
1008  if (it->timestamp <= timestamp)
1009  --samplesBefore;
1010  else if (it->timestamp >= timestamp)
1011  --samplesAfter;
1012  }
1013 
1014  if (samplesBefore > 0)
1015  MIRA_THROW(XRuntime, "Filter::samplesBefore: Requirements not met. Missing " << samplesBefore << " items.");
1016  if (samplesAfter > 0)
1017  MIRA_THROW(XRuntime, "Filter::samplesAfter: Requirements not met. Missing " << samplesAfter << " items.");
1018  }
1019  }
1020  catch(Exception&)
1021  {
1022  // read interval failed so test if the channel only contains a single data element
1023  // if so return it as a special case for interpolation of channels that will only
1024  // receive a single update during their lifetime
1025  if (mChannel->getNrOfSlots() == 1)
1026  return get();
1027  // more than one data element in the channel but still not sufficient for interpolation
1028  // rethrow is our only option
1029  throw;
1030  }
1031 
1032  const Time t0 = data.begin()->timestamp;
1033 
1034  typedef typename ChannelReadInterval<T>::const_iterator const_iterator;
1035  typedef boost::transform_iterator<GetTime, const_iterator> GetTimeIterator;
1036  GetTimeIterator begin1 = GetTimeIterator(data.begin(), GetTime(t0));
1037  GetTimeIterator end1 = GetTimeIterator(data.end() , GetTime(t0));
1038 
1039  typedef boost::transform_iterator<GetValue, const_iterator> GetValueIterator;
1040 
1041  GetValueIterator begin2=GetValueIterator(data.begin(), GetValue());
1042  GetValueIterator end2 =GetValueIterator(data.end() , GetValue());
1043 
1044  typedef mira::IteratorRangeContainer<GetTimeIterator> TimeContainer;
1045  typedef mira::IteratorRangeContainer<GetValueIterator> ValueContainer;
1046  TimeContainer timeContainer(begin1, end1);
1047  ValueContainer valueContainer(begin2, end2);
1048 
1049  return makeStamped(filter.template apply<float, T>(timeContainer,
1050  valueContainer,
1051  (timestamp-t0).totalMilliseconds()),
1052  timestamp);
1053  }
1054 
1064  template <typename U = void>
1065  void post(const Stamped<T>& value) {
1066  validateWriteAccess();
1067  ChannelWrite<T> writeSlot = mChannel->write();
1068  *writeSlot = value;
1069  writeSlot.finish(); // explicit finish to avoid throwing in destructor
1070  }
1071 
1073  template <typename U = void>
1074  void post(Stamped<T>&& value) {
1075  validateWriteAccess();
1076  ChannelWrite<T> writeSlot = mChannel->write();
1077  *writeSlot = std::move(value);
1078  writeSlot.finish(); // explicit finish to avoid throwing in destructor
1079  }
1080 
1090  template <typename U>
1091  void 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
void post(U &&value, const Time &timestamp=Time::now())
Writes the specified data with the specified time stamp into the channel.
Definition: Channel.h:1091
TypeMetaPtr getTypeMeta() const
Return the type meta information for this channel.
Definition: Channel.h:516
An object that allows read access to a whole interval of channel data.
Definition: ChannelReadInterval.h:72
Read access (Authority is a subscriber)
Definition: Channel.h:353
void finish()
Releases the lock explicitly.
Definition: ChannelReadWrite.h:543
void post(const Stamped< T > &value)
Writes the specified data into the channel.
Definition: Channel.h:1065
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:1074
Write access (Authority is a publisher)
Definition: Channel.h:354
std::size_t getNrOfSlots() const
Returns how many slots (i.e.
Definition: Channel.h:607
std::size_t getMinSlots() const
Returns the number slots that are guaranteed to be kept in the channel buffer.
Definition: Channel.h:582
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:743
bool isValid() const
Returns true if the proxy object is valid.
Definition: Channel.h:451
Typename getTypename() const
Returns the platform independent typename of the items that are stored in the slots of the underlying...
Definition: AbstractChannel.h:107
#define MIRA_ENUM_TO_FLAGS(EnumType)
Macro that can be used with enums that contain flags.
Definition: EnumToFlags.h:80
int getTypeId() const
Returns the non-portable typeid of the items that are stored in the slots of the underlying channel b...
Definition: AbstractChannel.h:99
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:434
std::string Typename
Definition: Typename.h:59
void setTypeMeta(TypeMetaPtr meta)
Set the type meta information for this channel.
Definition: Channel.h:524
const_iterator begin() const
Definition: ChannelReadInterval.h:163
An object that allows exclusive write access to data of a channel.
Definition: ChannelReadWrite.h:594
bool isTyped() const
Returns true, if the channel is typed and false, if it is untyped.
Definition: Channel.h:493
const_iterator end() const
Definition: ChannelReadInterval.h:164
#define MIRA_DEFINE_SERIALIZABLE_EXCEPTION(Ex, Base)
Macro for easily defining a new serializable exception class.
Definition: Exceptions.h:66
Definition: ChannelReadWrite.h:65
An object that allows read access to data of a channel.
Definition: ChannelReadWrite.h:435
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:795
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:91
void finish()
Releases the lock explicitly and informs the Channel to signal all Subscribers that new data is avail...
Definition: ChannelReadWrite.h:704
Wrapper class for boost::posix_time::ptime for adding more functionality to it.
Definition: Time.h:421
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:720
Duration getStorageDuration() const
Returns the timeframe that specifies how long a slot is guaranteed to be kept in the channel buffer...
Definition: Channel.h:591
Classes for automatic locking/unlocking when reading and writing to channels.
MIRA_BASE_EXPORT 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.
bool isTyped() const
Returns true, if the channel is typed and false, if it is untyped.
Definition: AbstractChannel.h:143
Commonly used exception classes.
PropertyHint type(const std::string &t)
Sets the attribute &quot;type&quot; to the specified value.
Definition: PropertyHint.h:295
Definition: AbstractChannel.h:70
ChannelRead< T > waitForData(const Duration &timeout=Duration::infinity()) const
Waits until data in this channel becomes available.
Definition: Channel.h:633
Use this class to represent time durations.
Definition: Time.h:104
ChannelRead< T > read(const Time &timestamp, const Duration &tolerance)
Same as above, but always takes the nearest slot.
Definition: Channel.h:762
bool isAutoIncreasingStorageDuration() const
Returns whether the channel buffer is automatically increasing the storage duration.
Definition: Channel.h:599
ChannelRead< T > read()
Obtains read access to the latest data element of this channel.
Definition: Channel.h:695
void reset()
Reset the proxy object so that it becomes invalid.
Definition: Channel.h:442
bool isEmpty() const
Returns if the channel is empty (no data has been published)
Definition: Channel.h:542
MIRA_BASE_EXPORT void read(const std::string &s, Value &oValue)
Read a json::Value from a string that contains JSON format.
Typed ChannelBuffer.
Definition: ChannelBuffer.h:860
The slot with smallest time difference to the requested will be chosen.
Definition: ChannelBuffer.h:103
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:508
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
sec_type seconds() const
Returns normalized number of seconds (0..59)
Definition: Time.h:283
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
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
Base class for exceptions.
Definition: Exception.h:204
Generic buffer class that can be used as a replacement for std::vector whenever copying and reallocat...
Definition: Buffer.h:84
static Duration infinity()
Returns a special duration time representing positive infinity.
Definition: Time.h:245
An iterator range class.
Channel()
Create channel proxy that is not assigned to a channel.
Definition: Channel.h:429
bool hasPublisher() const
Returns true, if this channel has at least one publisher.
Definition: Channel.h:558
const std::string & getID() const
Returns the channel id of this channel.
Definition: AbstractChannel.h:89
ChannelWrite< T > write()
Obtains exclusive write access to the next free data slot of this channel.
Definition: Channel.h:841
No access at all (Authority is not a publisher nor a subscriber)
Definition: Channel.h:352
ChannelWrite< T > write(bool copyLatestData)
Same as write above with an additional parameter copyLatestData that allows you to specify whether th...
Definition: Channel.h:871
static Time now() static Time eternity()
Returns the current utc based time.
Definition: Time.h:484
const std::string & getID() const
Return the channel ID, its name.
Definition: Channel.h:475
Typename getTypename() const
Return the typename of the channel.
Definition: Channel.h:499
Prefer filling the interval with slots with timestamp &gt; requested.
Definition: ChannelBuffer.h:115
void validate() const
Checks if the channel is valid otherwise throws an exception.
Definition: Channel.h:460
std::size_t getMaxSlots() const
Returns the upper limit of slots that are allowed for this channel.
Definition: Channel.h:574
IntervalFillMode
Mode that is used to determine what slots should be added to the interval when not enough slots are a...
Definition: ChannelBuffer.h:110
SlotQueryMode
Mode that is used to determine the slot obtained from a channel when no slot exists at the exact time...
Definition: ChannelBuffer.h:94
bool hasSubscriber() const
Returns true, if this channel has at least one subscriber.
Definition: Channel.h:550
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:95
Implements AbstractChannelSubscriber for a concrete data type.
Definition: ChannelSubscriber.h:82
void removeSubscriber(AbstractChannelSubscriberPtr subscriber)
Removes the specified subscriber from this channel and calls its detach() method. ...
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 hasSoloSlot() const
Returns true, if this channel has one solo slot only.
Definition: Channel.h:566
int getTypeId() const
Returns the type id of the channel.
Definition: Channel.h:485
Wraps an STL conform container around a range of values within another container. ...
Definition: IteratorRangeContainer.h:64
bool waitForPublisher(const Duration &timeout=Duration::infinity()) const
Waits until this channel has at least one publisher.
Definition: Channel.h:665
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:820
ChannelAccessFlags
Flags specifying the access rights of an authority to a channel Can be combined.
Definition: Channel.h:351