There is a simple way to look at it. (People who don't know the basic Operating Systems concepts - like me - tend to find it utterly difficult to understand ROS. Tutorials, I feel, should not assume computer science knowledge).
(1). Whatsapp = ROS.
(2). Your contacts list = ROS env variables in the .bashrc file...
Example: You are registered on whatsapp with your phone number. If you have a friend's contact, and if he happens to be on whatsapp you can see him.
Analogy: The computer itself is 'registered' by using ROS_HOSTNAME. This is usually set to the ip of the computer whose bashrc you are looking at. If you have the ROS_MASTER_URI set, and if the computer with that ip is running a ROS master you can see it.
(3). Whatsapp groups = ROS TOPIC
This analogy is crude. But, I hope it helps.
If someone adds you to a group, you start receiving messages from them (whenever a participant posts a message). Each contact in whatsapp is analogous to a node in ROS. So, if a node registers a subscription to a particular topic, it receives data from the topic (whenever a message is posted on a topic). Note here that no-one needs to add that node to the topic. It can register a subscription, if it has the data-type of the data that is being posted on the topic (this is not true in whatsapp. The creator of a group adds participants to it.). Similarly a node can also publish on that topic (simply send a data structure to it).
What happens when you send a message to a ROS topic?
We usually do,
ros::Publisher my_pub = nh.advertise<my_pkg::MyDataType> ("/topic_name", 1) // register a publisher.
mypkg::MyDataType garbage_data; // Create the variable. Later you will set the variables.
my_pub.publish(garbage_data); // Send the data to the topic.
refer to the tutorials (writing a simple publisher/subscriber)) for what this means.
IMPORTANT: The publisher dictates the type of a topic.
Then, ROS will serialize the data into bytes and send it to all subscribers (including a 'rostopic echo' - it is after-all a subscriber). But, on the receiving end, it will be assembled back together (de-serialzed). This means on the receiving end we need to specify the data-type properly. This is done in the definition of the callback function (c++).
void callback(const my_pkg::MyDataTypeConstPtr _msg)
What is this ConstPtr? It simply expands to:
boost::shared_ptr <const my_pkg::MyDataType>
Why is it const? We don't want to modify it even accidentally. Assume that _msg is of type MyDataType* (only that it is not a normal pointer: it is a smart pointer) and to de-reference you can simply do _msg->
or *_msg
Another point that starters take time to understand is that one node can subscribe and publish to the same topic (just like whatsapp groups). And one node can subscribe to one topic and publish to another at the same time (One group is muted and the other is not ... (more)