Writing a simple publisher and subscriber
The three important entities in DDS are : Domain Participant, Publisher and Subscriber.
Each individual application has one domain participant. It is reposible for connecting to the netwrok, finfing other nodes, etc. Publisher transmit data of a given message type and topic name. Subscribers initialized with the same message type and topic name can receive the data. All publishers and subscribers in an application must register to the domain participant
Running the demo
Open the publisher in one terminal tab
./build/demo/simple_publisher/simple_publisher
Open the subscriber in one terminal tab
./build/demo/simple_subscriber/simple_subscriber
Writing a simple publisher
Let us create a publisher that sends messages of type position.
#include "PositionPubSubTypes.h"
#include "default_participant.h"
#include "default_publisher.h"
#include "geometry_msgs/msgs/Position.h"
#include <chrono>
int main() {
// Create participant. Arguments: Domain id, Name
DefaultParticipant dp(0, "sample_participant");
// Create publisher with msg type and topic name
DDSPublisher position_pub(idl_msg::PositionPubSubType(), "position", dp.participant());
// create message of position type
cpp_msg::Position pos_msg;
for (int i = 0; i < 10; i++) {
pos_msg.x = i + 1;
pos_msg.y = i - 1;
pos_msg.z = i;
position_pub.publish(pos_msg);
std::this_thread::sleep_for(std::chrono::milliseconds(250));
}
}
#include "default_participant.h"
#include "default_publisher.h"
#include "PositionPubSubTypes.h"
#include "geometry_msgs/msgs/Position.h"
#include <chrono>
The first two lines allow the usage of the domain participant and publisher. The third line includes the message type for pubisher initialization. The fourth line includes the corresponding message type for actual data publishing
// Create domain participant. Arguments: Domain id, Name
DefaultParticipant dp(0, "sample_participant");
The DefaultParticipant class creates a DDS domain participant with the domain id and name specified. Each application contains one domain partipant, to which all publishers and subscribers must register. Individual applications can commmunicate only if their domain id’s are the same.
// Create publisher with msg type and topic name
DDSPublisher position_pub(idl_msg::PositionPubSubType(), "position", dp.participant());
// create message of position type
cpp_msg::Position pos_msg;
The DDSPublisher class creates a DDS Pulbisher with the given message type and topic name. In addition, the domain participant is also required. The next line creates the message to be published.
for (int i = 0; i < 10; i++) {
pos_msg.x = i + 1;
pos_msg.y = i - 1;
pos_msg.z = i;
position_pub.publish(pos_msg);
std::this_thread::sleep_for(std::chrono::milliseconds(250));
}
10 samples are published with a delay of 250ms between each publication.
Writing a simple subscriber
Let us create a subscriber that subscribes to the publisher above.
#include "PositionPubSubTypes.h"
#include "default_participant.h"
#include "default_subscriber.h"
#include "geometry_msgs/msgs/Position.h"
#include "logger.h"
int main() {
// Create participant. Arguments-> Domain id, QOS name
DefaultParticipant dp(0, "selva");
// Message
// idl_msg::Position pos_msg{};
cpp_msg::Position pos_msg{};
// Create subscriber with msg type
DDSSubscriber mocap_sub(idl_msg::PositionPubSubType(), &pos_msg, "position",
dp.participant());
for (;;) {
// Blocks until new data is available
mocap_sub.listener->wait_for_data();
sflog << pos_msg.x;
}
}
#include "PositionPubSubTypes.h"
#include "default_participant.h"
#include "default_subscriber.h"
#include "geometry_msgs/msgs/Position.h"
#include "logger.h"
int main() {
// Create participant. Arguments-> Domain id, QOS name
DefaultParticipant dp(0, "selva");
// Message
// idl_msg::Position pos_msg{};
cpp_msg::Position pos_msg{};
Same function as in the publisher example
// Create subscriber with msg type
DDSSubscriber mocap_sub(idl_msg::PositionPubSubType(), &pos_msg, "position",
dp.participant());
Like the publisher, the message type, topic name and domain participant are required to initialize a subscriber. In addition, the the pos_msg variable is passed by reference. The latest data sample received by the publisher is saved to this variable.
// Blocks until new data is available
mocap_sub.listener->wait_for_data();
The wait_for_data() function block code execution until the subscriber receives a message.