ROS serialization&deserialization [URGENT]
Hi guys ! I want to serialize and deserialize ROS messages in order to send them over UDP to make other stuff. I've already managed to do serialization like so:
/// \brief serializes an interAgentInfo message to send over UDP as a string
/// of bytes.
/// \param msg - pointer to interAgentInfo object to be serialized
/// \param packet - uint8_t vector containing the serialized message
void serializeInterAgentInfo(interAgentInfo *msg, uint8_t **packet, uint32_t *packet_size)
{
pthread_mutex_lock (&message_mutex); //Lock mutex
uint32_t serial_size = ros::serialization::serializationLength( *msg );
serialization_buffer.reset(new uint8_t[serial_size]);
ros::serialization::OStream stream( serialization_buffer.get(), serial_size );
ros::serialization::serialize( stream, *msg);
(*packet) = serialization_buffer.get();
(*packet_size) = serial_size;
pthread_mutex_unlock (&message_mutex); //Unlock mutex
}
The deserialization would also be easy if i had a "normal" message. The message interAgentInfo has some variable sized vectors. I don't seem to find any helpful documentation anywhere to solve my problem. I can't either get strlen() of the generated packet as i was expecting doing ...
Any hints guys ?
Thanks in advance to you all,
Pedro
Asked by wicked88 on 2016-11-10 14:31:27 UTC
Answers
I made a quick work around, don't know if you will propose a better way, but here it is. In the message interAgentInfo i've put a uint16 as the first member of the message and named it packet_size.
When doing serialization, i compute :
uint32_t serial_size = ros::serialization::serializationLength( *msg );
This allows to fill in :
msg.packet_size = serial_size;
Then i serialize and send the message over UDP. On the reception side, to get the packet size, i first deserialize just the first member of the whole message, packet_size, to get the whole packet size.
/// \brief deserializes a string of bytes into a interAgentInfo message
/// \param packet - uint8_t vector containing message to deserialize
/// \param msg - pointer to interAgentInfo destination object
void deserializeInterAgentInfo(uint8_t *packet, interAgentInfo *msg)
{
std_msgs::UInt16 packet_size;
ros::serialization::IStream psize_stream(packet, 2);
ros::serialization::deserialize(psize_stream, packet_size);
ros::serialization::IStream istream(packet, packet_size.data);
ros::serialization::deserialize(istream, *msg);
}
This way, from the first two bytes i get the size of the whole packet, and then i can deserialize the whole message.
Asked by wicked88 on 2016-11-10 15:03:35 UTC
Comments