48 #ifndef _MIRA_CHANNEL_H_ 49 #define _MIRA_CHANNEL_H_ 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" 56 #include <boost/shared_ptr.hpp> 57 #include <boost/type_traits/is_polymorphic.hpp> 104 typedef typename Buffer::ValueType ValueType;
105 typedef typename Buffer::Slot Slot;
108 typedef boost::shared_ptr<Subscriber> SubscriberPtr;
119 "ConcreteChannel must have the same size as AbstractChannel");
121 static_assert(boost::is_polymorphic<ConcreteChannel>::value==
false,
122 "ConcreateChannel and AbstractChannel must not be polymorphic");
133 boost::mutex::scoped_lock lock(mSubscribersMutex);
134 mNrOfSubscribersWithoutChannelSubscriber++;
141 void addSubscriber(SubscriberPtr subscriber)
143 boost::mutex::scoped_lock lock(mSubscribersMutex);
144 mSubscribers.push_back(subscriber);
145 subscriber->attachChannel(
this);
157 ChannelRead<T>
read();
171 bool keepStorageDuration =
false);
196 ChannelReadInterval<T> readInterval(
const Time& timestamp, std::size_t nrSlots,
197 std::size_t olderSlots, std::size_t newerSlots,
199 bool keepStorageDuration =
false);
219 ChannelReadInterval<T> readInterval(
const Time& from,
221 bool keepStorageDuration =
false);
235 ChannelWrite<T>
write();
238 friend class Channel<T>;
251 struct ChannelCaster {
252 static ConcreteChannel<T>* cast(AbstractChannel* p)
256 promote_channel<T>(p);
258 assert(p->isTyped());
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>() <<
"'");
268 return static_cast<ConcreteChannel<T>*
>(p);
276 struct ChannelCaster<void> {
277 static ConcreteChannel<void>* cast(AbstractChannel* p)
281 return static_cast<ConcreteChannel<void>*
>(p);
289 struct ChannelCaster<T*> {
290 static ConcreteChannel<T*>* cast(AbstractChannel* p)
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.");
298 promote_channel<T*>(p);
301 assert(p->getBuffer()->isPolymorphic());
305 return static_cast<ConcreteChannel<T*>*
>(p);
312 inline ConcreteChannel<T>* channel_cast(AbstractChannel* p)
314 return ChannelCaster<T>::cast(p);
322 template <
typename T>
327 inline Channel<T> channel_cast(Channel<void> channel);
345 template <
typename T>
351 struct ParamHelper<void> {
412 template <
typename T>
426 mChannel(channel), mAccessFlags(accessFlags) {
427 assert(mChannel!=NULL);
443 return mChannel!=NULL;
454 "No channel assigned to the channel proxy (of type " <<
455 typeName<T>() <<
"). " 456 "You can obtain a channel using Authority::getChannel()!");
470 return mChannel->getID();
480 return mChannel->getTypeId();
494 return mChannel->getTypename();
503 mChannel->setTypename(
type);
511 return mChannel->getTypeMeta();
519 mChannel->setTypeMeta(meta);
537 return mChannel->getNrOfDataChanges() == 0;
545 return mChannel->hasSubscriber();
553 return mChannel->hasPublisher();
561 return mChannel->getBuffer()->getMaxSlots() == 1;
569 return mChannel->getBuffer()->getMaxSlots();
577 return mChannel->getBuffer()->getMinSlots();
586 return mChannel->getBuffer()->getStorageDuration();
594 return mChannel->getBuffer()->isAutoIncreasingStorageDuration();
602 return mChannel->getBuffer()->getSize();
628 validateReadAccess();
631 if(!timeout.isValid() || timeout.isInfinity())
636 while(!boost::this_thread::interruption_requested())
639 return mChannel->read();
640 }
catch(XInvalidRead& ex) {}
660 validateReadAccess();
663 if(!timeout.isValid() || timeout.isInfinity())
668 while(!boost::this_thread::interruption_requested())
689 validateReadAccess();
690 return mChannel->read();
715 validateReadAccess();
716 return mChannel->read(timestamp, mode, tolerance);
738 validateReadAccess();
739 Time newestSlotTime = mChannel->read()->timestamp;
742 for(; iter != interval.
end(); ++iter){
743 if(iter->sequenceID == sequenceID)
746 MIRA_THROW(XInvalidRead,
"No slot with sequenceID "<<sequenceID<<
747 " found within searchInterval of channel");
756 validateReadAccess();
757 return mChannel->read(timestamp,
NEAREST_SLOT, tolerance);
790 std::size_t olderSlots,
791 std::size_t newerSlots,
793 validateReadAccess();
794 return mChannel->readInterval(timestamp, nrSlots, olderSlots,
795 newerSlots, fillMode);
815 validateReadAccess();
816 return mChannel->readInterval(from, to);
824 validateReadAccess();
825 return mChannel->readInterval(from, to,
true);
845 validateWriteAccess();
846 return mChannel->write();
888 template <
typename Fn = Stamped<T>(*)(const Stamped<T>&)>
890 validateWriteAccess();
894 && (mChannel->getBuffer()->getMaxSlots()>1)
895 && (mChannel->getBuffer()->getSize()>0))
905 return mChannel->write();
922 validateReadAccess();
942 validateReadAccess();
943 ChannelRead<T> value = mChannel->read(timestamp, mode, tolerance);
953 validateReadAccess();
965 GetTime(
const Time& iT0) : t0(iT0) {}
968 typedef float result_type;
969 result_type operator()(
const Stamped<T>& p)
const {
971 return (p.timestamp-t0).totalMilliseconds();
980 typedef const T& result_type;
981 result_type operator()(
const Stamped<T>& p)
const {
1008 template <
typename Filter>
1010 validateReadAccess();
1016 filter.samplesBefore(),
1017 filter.samplesAfter());
1019 if (!filter.canExtrapolate())
1021 int samplesBefore = filter.samplesBefore();
1022 int samplesAfter = filter.samplesAfter();
1024 for (
auto it = data.
begin(); it != data.
end(); ++it)
1026 if (it->timestamp <= timestamp)
1028 else if (it->timestamp >= timestamp)
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.");
1043 if (mChannel->getNrOfSlots() == 1)
1050 const Time t0 = data.
begin()->timestamp;
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));
1057 typedef boost::transform_iterator<GetValue, const_iterator> GetValueIterator;
1059 GetValueIterator begin2=GetValueIterator(data.
begin(), GetValue());
1060 GetValueIterator end2 =GetValueIterator(data.
end() , GetValue());
1064 TimeContainer timeContainer(begin1, end1);
1065 ValueContainer valueContainer(begin2, end2);
1067 return makeStamped(filter.template apply<float, T>(timeContainer,
1069 (timestamp-t0).totalMilliseconds()),
1082 template <
typename U =
void>
1084 validateWriteAccess();
1091 template <
typename U =
void>
1093 validateWriteAccess();
1095 *writeSlot = std::move(value);
1108 template <
typename U>
1109 typename std::enable_if<!std::is_base_of_v<StampedHeader, std::decay_t<U>>>
::type 1111 validateWriteAccess();
1113 *writeSlot =
makeStamped(std::forward<U>(value), timestamp);
1126 template <
typename U = T>
1127 typename std::enable_if<!std::is_void<U>::value>
::type 1129 validateWriteAccess();
1136 template <
typename U = T>
1137 typename std::enable_if<!std::is_void<U>::value>
::type 1139 validateWriteAccess();
1141 *writeSlot =
makeStamped(std::move(value), timestamp);
1150 template<
typename U>
1157 void dbgDump(
bool brief=
true) { mChannel->dbgDump(brief); }
1162 void validateReadAccess()
const 1166 MIRA_THROW(XAccessViolation,
"You are not allowed to read from channel '" 1167 << mChannel->getID() <<
"'. Forgot to subscribe?");
1170 void validateWriteAccess()
const 1174 MIRA_THROW(XAccessViolation,
"You are not allowed to write to channel '" 1175 << mChannel->getID() <<
"'. Forgot to publish?");
1180 ConcreteChannel<T>* mChannel;
1187 template<
typename U>
1188 inline Channel<U> channel_cast(Channel<void> channel)
1191 return Channel<U>(channel_cast<U>(channel.mChannel), channel.mAccessFlags);
1199 #include "impl/ChannelReadWrite.hpp" 1200 #include "impl/ChannelReadInterval.hpp" 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 ×tamp=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.
#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 ×tamp, 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'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 ×tamp, 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 ×tamp, 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 ×tamp=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 ×tamp=Time::now())
This allows post({}, Time()); to deduce we want to post an object of the channel'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 ×tamp=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
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.
#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'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