0

I intended to use the zstd compression api to compress the data sent from the client side of ROS topic communication to the server side . When I wrote the code and ran the code after compiling, the terminal reports an error

[ INFO] [1681284228.624025020]: started CSLAM server node...
terminate called after throwing an instance of 'ros::serialization::StreamOverrunException'
  what():  Buffer Overrun
[ccmslam/ccmslamServerNode-5] process has died [pid 163170, exit code -6, cmd /home/zwq-slamer/ccmslam_ws/devel/lib/ccmslam/ccmslamServerNode /home/zwq-slamer/ccmslam_ws/src/ccm_slam/cslam/conf/ORBvoc.txt __name:=ccmslamServerNode __log:=/home/zwq-slamer/.ros/log/f268b740-d902-11ed-aaaf-4dd03796d8e2/ccmslam-ccmslamServerNode-5.log].
log file: /home/zwq-slamer/.ros/log/f268b740-d902-11ed-aaaf-4dd03796d8e2/ccmslam-ccmslamServerNode-5*.log

It probably means that the buffer is not enough when serializing,but I don't know which part of the code is wrong.The results of searching with bing were all about increasing the size of the buffer or reducing the frequency of ROS.And I don't know how to properly modify the size of the serialized buffer, some say that the size of the buffer is only 512byte.

Here's the code I added to the source file

// serialize the msg sent to server
uint32_t serializedSize = ros::serialization::serializationLength(msgMap);

        boost::shared_array<uint8_t> buffer(new uint8_t[serializedSize]);

        ros::serialization::OStream stream(buffer.get(), serializedSize);

        ros::serialization::serialize(stream, msgMap);
//compress using zstd
        std::vector<char> compressedData(ZSTD_compressBound(serializedSize));

        size_t compressedSize = ZSTD_compress(compressedData.data(), compressedData.size(), buffer.get(), serializedSize,1);
       
        compressedData.resize(compressedSize);
       
        ccmslam_msgs::Map compressedMsgMap;
       
        compressedMsgMap.originalsize = serializedSize ;
        
        compressedMsgMap.compressed_data = std::string(compressedData.begin(),compressedData.end());
    //-----------------------------//
        mPubMap.publish(compressedMsgMap);
    }

the server side:

void Communicator::MapCbServer(ccmslam_msgs::MapConstPtr pMsg)
{
    {

        unique_lock<mutex> lock(mMutexBuffersIn);
        
        //decompress
        std::vector<uint8_t> uncompressedData(pMsg -> originalsize);
        size_t uncompressedSize = ZSTD_decompress(uncompressedData.data(),uncompressedData.size(),pMsg ->compressed_data.data(),pMsg -> compressed_data.size());
        uncompressedData.resize(uncompressedSize);

        //deserialize
        ccmslam_msgs::Map uncompressedMsgMap;
        ros::serialization::IStream stream(uncompressedData.data(), uncompressedData.size());
        ros::serialization::deserialize(stream, uncompressedMsgMap);
        

ccmslam_msgs::Map msgMap; buffer size

# ROS Message Buffer Sizes
Comm.Client.PubMapBuffer: 100
Comm.Client.SubMapBuffer: 100

Comm.Server.PubMapBuffer: 1000
Comm.Server.SubMapBuffer: 1000

I also don't know if this buffer size and serialized buffer size are the same thing

zwq
  • 5
  • 2

0 Answers0