Closed Heyangq closed 3 weeks ago
If I'm doing this as a wrong example, I want to have a correct example that will allow me to serialize and deserialize PointCloud2
auto size = calculate_serialized_size(cal, msg, current_alignment);
char* buffer = new char[size+10]; eprosima::fastcdr::FastBuffer fast_buffer(buffer, size+10); eprosima::fastcdr::Cdr cdr(fast_buffer); serialize(cdr, msg);
When my buffer does not use size+10, but uses the calculated size, he will report an error, why?
terminate called after throwing an instance of 'eprosima::fastcdr::exception::NotEnoughMemoryException' what(): Not enough memory in the buffer stream Aborted (core dumped)
It only fires when deserialize, and my serialization uses (FastBuffer = size) as normal
I found my problem
rest is required after serialization, sorry
int main() {
sensor_msgs::msg::PointCloud2 msg; msg.header().frame_id("map");
msg.height(1); msg.width(20000);
sensor_msgs::msg::PointField field_x; field_x.name("x");
field_x.offset(0);
field_x.datatype(sensor_msgs::msg::PointField_Constants::FLOAT32);
field_x.count(1);
sensor_msgs::msg::PointField field_y;
field_y.name("y");
field_y.offset(4);
field_y.datatype(sensor_msgs::msg::PointField_Constants::FLOAT32);
field_y.count(1);
sensor_msgs::msg::PointField field_z;
field_z.name("z");
field_z.offset(8);
field_z.datatype(sensor_msgs::msg::PointField_Constants::FLOAT32);
field_z.count(1);
msg.fields({field_x, field_y, field_z});
msg.is_bigendian(false); msg.point_step(12);
msg.row_step(msg.point_step() msg.width());
msg.is_dense(true);
std::vector
eprosima::fastcdr::CdrSizeCalculator cal(eprosima::fastcdr::CdrVersion::XCDRv2); size_t current_alignment = 0; auto size = calculate_serialized_size(cal, msg, current_alignment);
char* buffer = new char[size]; eprosima::fastcdr::FastBuffer fast_buffer(buffer, size); eprosima::fastcdr::Cdr cdr(fast_buffer); serialize(cdr, msg); /////////////////////////////////// cdr.reset(); ///////////////////////////////////
sensor_msgs::msg::PointCloud2 msg2; deserialize(cdr, msg2); std::cout << msg2.data().size() << std::endl; delete[] buffer; return 0; }
This is my main:
int main() { sensor_msgs::msg::PointCloud2 msg; msg.header().frame_id("map"); msg.height(1); msg.width(20000); sensor_msgs::msg::PointField field_x; field_x.name("x"); field_x.offset(0); field_x.datatype(sensor_msgs::msg::PointField_Constants::FLOAT32); field_x.count(1); sensor_msgs::msg::PointField field_y; field_y.name("y"); field_y.offset(4); field_y.datatype(sensor_msgs::msg::PointField_Constants::FLOAT32); field_y.count(1); sensor_msgs::msg::PointField field_z; field_z.name("z"); field_z.offset(8); field_z.datatype(sensor_msgs::msg::PointField_Constants::FLOAT32); field_z.count(1); msg.fields({field_x, field_y, field_z}); msg.is_bigendian(false); msg.point_step(12); msg.row_step(msg.point_step() msg.width()); msg.is_dense(true); std::vector points; float point_x=0.0, point_y=0.0, point_z=0.0;
for(int i=0; i<20000; ++i) {
point_x += 0.01; point_y += 0.01;
point_z += 0.01; points.push_back(point_x);
points.push_back(point_y); points.push_back(point_z);
}
msg.data().resize(points.size() sizeof(float)); memcpy(&msg.data()[0], &points[0], msg.data().size());
eprosima::fastcdr::CdrSizeCalculator cal(eprosima::fastcdr::CdrVersion::XCDRv2); size_t current_alignment = 0; auto size = calculate_serialized_size(cal, msg, current_alignment);
char* buffer = new char[size+10]; eprosima::fastcdr::FastBuffer fast_buffer(buffer, size+10); eprosima::fastcdr::Cdr cdr(fast_buffer); serialize(cdr, msg);
sensor_msgs::msg::PointCloud2 msg2; deserialize(cdr, msg2); std::cout << msg2.data().size() << std::endl; delete[] buffer; return 0; }
I used fastddsgen to generate PointCloud2CdrAux
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License.
/*!
ifndef _FAST_DDS_GENERATED_SENSOR_MSGS_MSG_POINTCLOUD2CDRAUXIPP
define _FAST_DDS_GENERATED_SENSOR_MSGS_MSG_POINTCLOUD2CDRAUXIPP
include "PointCloud2CdrAux.hpp"
include <fastcdr/Cdr.h>
include <fastcdr/CdrSizeCalculator.hpp>
include <fastcdr/exceptions/BadParamException.h>
using namespace eprosima::fastcdr::exception;
namespace eprosima { namespace fastcdr {
template<> eProsima_user_DllExport size_t calculate_serialized_size( eprosima::fastcdr::CdrSizeCalculator& calculator, const sensor_msgs::msg::PointCloud2& data, size_t& current_alignment) { using namespace sensor_msgs::msg;
}
template<> eProsima_user_DllExport void serialize( eprosima::fastcdr::Cdr& scdr, const sensor_msgs::msg::PointCloud2& data) { using namespace sensor_msgs::msg;
; scdr.end_serialize_type(current_state); }
template<> eProsima_user_DllExport void deserialize( eprosima::fastcdr::Cdr& cdr, sensor_msgs::msg::PointCloud2& data) { using namespace sensor_msgs::msg;
}
void serialize_key( eprosima::fastcdr::Cdr& scdr, const sensor_msgs::msg::PointCloud2& data) { using namespace sensor_msgs::msg;
}
} // namespace fastcdr } // namespace eprosima
endif // _FAST_DDS_GENERATED_SENSOR_MSGS_MSG_POINTCLOUD2CDRAUXIPP
Serialization is normal, but my deserialization failed, I hope to get to the root of the problem, thanks!