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 <ros/console.h>
00020
00021 #include "variant_topic_tools/DataTypeRegistry.h"
00022 #include "variant_topic_tools/Exceptions.h"
00023 #include "variant_topic_tools/Message.h"
00024 #include "variant_topic_tools/Publisher.h"
00025
00026 namespace variant_topic_tools {
00027
00028
00029
00030
00031
00032 Publisher::Publisher() {
00033 }
00034
00035 Publisher::Publisher(const Publisher& src) :
00036 impl(src.impl) {
00037 }
00038
00039 Publisher::~Publisher() {
00040 }
00041
00042 Publisher::Impl::Impl(ros::NodeHandle& nodeHandle, const MessageType&
00043 type, const std::string& topic, size_t queueSize, bool latch, const
00044 ros::SubscriberStatusCallback& connectCallback) :
00045 type(type),
00046 sequenceNumber(0) {
00047 DataTypeRegistry registry;
00048 DataType dataType = registry.getDataType(type.getDataType());
00049
00050 if (!dataType) {
00051 MessageDefinition definition(type);
00052 dataType = definition.getMessageDataType();
00053 }
00054
00055 serializer = dataType.createSerializer();
00056
00057 ros::AdvertiseOptions options(topic, queueSize, type.getMD5Sum(),
00058 type.getDataType(), type.getDefinition(), connectCallback);
00059 options.latch = latch;
00060
00061 publisher = nodeHandle.advertise(options);
00062 }
00063
00064 Publisher::Impl::~Impl() {
00065 shutdown();
00066 }
00067
00068
00069
00070
00071
00072 Publisher::operator ros::Publisher() const {
00073 if (impl)
00074 return impl->publisher;
00075 else
00076 return ros::Publisher();
00077 }
00078
00079
00080
00081
00082
00083 std::string Publisher::getTopic() const {
00084 if (impl)
00085 return impl->publisher.getTopic();
00086 else
00087 return std::string();
00088 }
00089
00090 size_t Publisher::getNumSubscribers() const {
00091 if (impl)
00092 return impl->publisher.getNumSubscribers();
00093 else
00094 return 0;
00095 }
00096
00097 bool Publisher::isLatched() const {
00098 if (impl)
00099 return impl->publisher.isLatched();
00100 else
00101 return false;
00102 }
00103
00104 bool Publisher::Impl::isValid() const {
00105 return type.isValid() && serializer && publisher;
00106 }
00107
00108
00109
00110
00111
00112 void Publisher::shutdown() {
00113 if (impl)
00114 impl->shutdown();
00115 }
00116
00117 void Publisher::publish(const MessageVariant& variant) {
00118 if (impl && impl->isValid())
00119 impl->publish(variant);
00120 else
00121 ROS_ASSERT_MSG(false, "Call to publish() on an invalid Publisher");
00122 }
00123
00124 void Publisher::Impl::shutdown() {
00125 type = MessageType();
00126 serializer = MessageSerializer();
00127 sequenceNumber = 0;
00128 publisher = ros::Publisher();
00129 }
00130
00131 void Publisher::Impl::publish(const MessageVariant& variant) {
00132 if (variant.getType().getIdentifier() == type.getDataType()) {
00133 Message message;
00134 MessageDataType dataType = variant.getType();
00135
00136 if (dataType.hasHeader())
00137 variant["header/seq"] = sequenceNumber+1;
00138
00139 message.setType(type);
00140 message.setSize(serializer.getSerializedLength(variant));
00141 ros::serialization::OStream stream(const_cast<uint8_t*>(
00142 message.getData().data()), message.getSize());
00143
00144 serializer.serialize(stream, variant);
00145 publisher.publish(message);
00146
00147 ++sequenceNumber;
00148 }
00149 else
00150 throw MessageTypeMismatchException(type.getDataType(),
00151 variant.getType().getIdentifier());
00152 }
00153
00154 }