Go to the documentation of this file.00001
00036 #include <ros/ros.h>
00037 #include <rosserial_msgs/TopicInfo.h>
00038 #include <rosserial_msgs/RequestMessageInfo.h>
00039 #include <topic_tools/shape_shifter.h>
00040
00041
00042 class Publisher {
00043 public:
00044 Publisher(ros::NodeHandle& nh, const rosserial_msgs::TopicInfo& topic_info) {
00045 if (!message_service_.isValid()) {
00046
00047 message_service_ = nh.serviceClient<rosserial_msgs::RequestMessageInfo>("message_info");
00048 if (!message_service_.waitForExistence(ros::Duration(5.0))) {
00049 ROS_WARN("Timed out waiting for message_info service to become available.");
00050 }
00051 }
00052
00053 rosserial_msgs::RequestMessageInfo info;
00054 info.request.type = topic_info.message_type;
00055 if (message_service_.call(info)) {
00056 if (info.response.md5 != topic_info.md5sum) {
00057 ROS_WARN_STREAM("Message" << topic_info.message_type << "MD5 sum from client does not match that in system. Will avoid using system's message definition.");
00058 info.response.definition = "";
00059 }
00060 } else {
00061 ROS_WARN("Failed to call message_info service. Proceeding without full message definition.");
00062 }
00063
00064 message_.morph(topic_info.md5sum, topic_info.message_type, info.response.definition, "false");
00065 publisher_ = message_.advertise(nh, topic_info.topic_name, 1);
00066 }
00067
00068 void handle(ros::serialization::IStream stream) {
00069 ros::serialization::Serializer<topic_tools::ShapeShifter>::read(stream, message_);
00070 publisher_.publish(message_);
00071 }
00072
00073 std::string get_topic() {
00074 return publisher_.getTopic();
00075 }
00076
00077 private:
00078 ros::Publisher publisher_;
00079 topic_tools::ShapeShifter message_;
00080
00081 static ros::ServiceClient message_service_;
00082 };
00083
00084 ros::ServiceClient Publisher::message_service_;
00085 typedef boost::shared_ptr<Publisher> PublisherPtr;
00086
00087
00088 class Subscriber {
00089 public:
00090 Subscriber(ros::NodeHandle& nh, rosserial_msgs::TopicInfo& topic_info,
00091 boost::function<void(std::vector<uint8_t> buffer)> write_fn)
00092 : write_fn_(write_fn) {
00093 ros::SubscribeOptions opts;
00094 opts.init<topic_tools::ShapeShifter>(
00095 topic_info.topic_name, 1, boost::bind(&Subscriber::handle, this, _1));
00096 opts.md5sum = topic_info.md5sum;
00097 opts.datatype = topic_info.message_type;
00098 subscriber_ = nh.subscribe(opts);
00099 }
00100
00101 std::string get_topic() {
00102 return subscriber_.getTopic();
00103 }
00104
00105 private:
00106 void handle(const boost::shared_ptr<topic_tools::ShapeShifter const>& msg) {
00107 size_t length = ros::serialization::serializationLength(*msg);
00108 std::vector<uint8_t> buffer(length);
00109
00110 ros::serialization::OStream ostream(&buffer[0], length);
00111 ros::serialization::Serializer<topic_tools::ShapeShifter>::write(ostream, *msg);
00112
00113 write_fn_(buffer);
00114 }
00115
00116 ros::Subscriber subscriber_;
00117 boost::function<void(std::vector<uint8_t> buffer)> write_fn_;
00118 };
00119
00120 typedef boost::shared_ptr<Subscriber> SubscriberPtr;