Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "variant_topic_tools/DataTypeRegistry.h"
00020 #include "variant_topic_tools/Exceptions.h"
00021 #include "variant_topic_tools/Message.h"
00022 #include "variant_topic_tools/Subscriber.h"
00023
00024 namespace variant_topic_tools {
00025
00026
00027
00028
00029
00030 Subscriber::Subscriber() {
00031 }
00032
00033 Subscriber::Subscriber(const Subscriber& src) :
00034 impl(src.impl) {
00035 }
00036
00037 Subscriber::~Subscriber() {
00038 }
00039
00040 Subscriber::Impl::Impl(ros::NodeHandle& nodeHandle, const MessageType& type,
00041 const std::string& topic, size_t queueSize, const SubscriberCallback&
00042 callback) :
00043 type(type),
00044 callback(callback) {
00045 subscriber = nodeHandle.subscribe(topic, queueSize,
00046 &Subscriber::Impl::eventCallback, this);
00047 }
00048
00049 Subscriber::Impl::~Impl() {
00050 shutdown();
00051 }
00052
00053
00054
00055
00056
00057 Subscriber::operator ros::Subscriber() const {
00058 if (impl)
00059 return impl->subscriber;
00060 else
00061 return ros::Subscriber();
00062 }
00063
00064
00065
00066
00067
00068 std::string Subscriber::getTopic() const {
00069 if (impl)
00070 return impl->subscriber.getTopic();
00071 else
00072 return std::string();
00073 }
00074
00075 size_t Subscriber::getNumPublishers() const {
00076 if (impl)
00077 return impl->subscriber.getNumPublishers();
00078 else
00079 return 0;
00080 }
00081
00082 bool Subscriber::Impl::isValid() const {
00083 return subscriber;
00084 }
00085
00086
00087
00088
00089
00090 void Subscriber::shutdown() {
00091 if (impl)
00092 impl->shutdown();
00093 }
00094
00095 void Subscriber::Impl::shutdown() {
00096 subscriber = ros::Subscriber();
00097
00098 type = MessageType();
00099 dataType = DataType();
00100 serializer = MessageSerializer();
00101 }
00102
00103 void Subscriber::Impl::eventCallback(const ros::MessageEvent<Message const>&
00104 event) {
00105 boost::shared_ptr<const Message> message = event.getConstMessage();
00106
00107 if (!type.isValid())
00108 type = message->getType();
00109
00110 if (message->getType().getDataType() == type.getDataType()) {
00111 if ((type.getMD5Sum() == "*") || (message->getType().getMD5Sum() == "*") ||
00112 (message->getType().getMD5Sum() == type.getMD5Sum())) {
00113 if (!dataType) {
00114 DataTypeRegistry registry;
00115 dataType = registry.getDataType(type.getDataType());
00116
00117 if (!dataType) {
00118 type = message->getType();
00119
00120 MessageDefinition definition(type);
00121 dataType = definition.getMessageDataType();
00122 }
00123 }
00124
00125 if (dataType && !serializer)
00126 serializer = dataType.createSerializer();
00127
00128 if (serializer) {
00129 MessageVariant variant = dataType.createVariant();
00130 ros::serialization::IStream stream(const_cast<uint8_t*>(
00131 message->getData().data()), message->getSize());
00132
00133 serializer.deserialize(stream, variant);
00134
00135 callback(variant, event.getReceiptTime());
00136 }
00137 }
00138 else
00139 throw MD5SumMismatchException(type.getMD5Sum(),
00140 message->getType().getMD5Sum());
00141 }
00142 else
00143 throw MessageTypeMismatchException(type.getDataType(),
00144 message->getType().getDataType());
00145 }
00146
00147 }