ROS messages are transferred over TCP as serialized data.
If you're subscribing to normal message type (for example std_msgs/String
or whatever), then ros::serialization::Serializer<std_msgs::String>::read()
is called by roscpp to deserialize the message, and the deserialized message is passed to your callback.
If you're publishing to normal message type (for example std_msgs/String
or whatever), then ros::serialization::Serializer<std_msgs::String>::write()
is called after you call publish()
, to serialize the message.
If you're publishing and subscribing std_msgs::String::ConstPtr
within the same process (often when using nodelets), the serialization and deserialization steps are skipped for messages passed within the same process. (if there are publishers or subscribers outside the process, serialization still happens).
rosbag is a bit of a special case; instead of handling normal messages, it directly handles the serialized data and message description. When rosbag records, it writes the serialized data (and the message MD5) directly to the bag file, without deserialized it (and without needing to be compiled against every message type). When rosbag plays back a file, it advertises with the same MD5 that was used during recording, and then it reads the serialized data and publishes it directly. Deserialization of these messages happens in the subscriber in the normal way (assuming the MD5 still matches).
The rosbag instantiate()
is only used in the rosbag C++ API, if you want to read a specific message type from a bag file in C++.
In ROS, the ros::serialization::read() method is used for deserialization, converting serialized data into a ROS message object. On the other hand, the ros::serialization::write() method is used for serialization, converting a ROS message object into a byte stream.
When you publish a message, ROS internally calls ros::serialization::write() to serialize the message before sending it over the network.
When you subscribe to a particular message type, ROS internally calls the instantiate() method of the message type to create an instance of that message type. Then, it calls the ros::serialization::read() method to deserialize the received byte stream into the instantiated message object.
If you publish a rosbag::MessageInstance from a publisher and subscribe to MsgType on the receiver side, ROS will internally call instantiate() to create an instance of MsgType. Then it will call ros::serialization::read() to deserialize the rosbag::MessageInstance into the MsgType ...(more)