c++ 如何实现ros2消息的格式化

k4ymrczo  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(275)

在我序列化ros2消息并提取缓冲区数据后,当我如下所示进行序列化时,它存在以下问题:在引发“rcpputils::IllegalStateException”的示例后调用终止what():错误初始化。序列化消息的大小为零。[ros2run]:Aborted

void callbackCloudResponseMessage(const planning_interface::msg::Cloud & msg) {

    /* serialize */
    rclcpp::Serialization<planning_interface::msg::Cloud> cloudSerializer;
    rclcpp::SerializedMessage serialized_msg;
    cloudSerializer.serialize_message(&msg, &serialized_msg);

    uint8_t* serialized_data = serialized_msg.get_rcl_serialized_message().buffer;
    size_t serialized_size = serialized_msg.size();
    
    static uint8_t buf_test[FRAME_LENGTH_MAX+1];
    uint8_t *pmsg_test = buf_test + DATA_PAYLOAD;
    memcpy(pmsg_test, serialized_data, serialized_size);

    /* deserialize */
    planning_interface::msg::Cloud test_msg;
    rclcpp::SerializedMessage serialize_test_msg(serialized_size);
    memcpy(new_msg.get_rcl_serialized_message().buffer, pmsg_test, serialized_size);
    cloudSerializer.deserialize_message(&new_msg, &test_msg);

}

我尝试了上述方法,并期望能够实现

lp0sw83n

lp0sw83n1#

(我假设serialize_test_msg只是new_msg的一个未完成的重命名,反之亦然,这是你在运行 * 之后 * 做的,否则你的例子一开始就不会编译)
问题是,当你调用deserialize_message时,new_msg的大小为零,因为你使用的rclcpp::SerializedMessage构造函数将size_t作为创建的缓冲区的 capacity,而不是 size。它分配内存(然后您成功地将memcpy分配到内存)并设置底层结构体的bufferbuffer_capacityallocator字段,但buffer_length字段保持为零,缓冲区最初为空。memcpy只将数据写入缓冲区(在容量范围内,所以这里没有问题),但buffer_length保持不变,因此new_msg.get_rcl_serialized_message()处于逻辑无效状态,无法被deserialize_message正确解释。因此,在进行重新配置之前,您应该通过手动设置buffer_length来解决这个问题(这不需要重新分配,因为它在它所相等的容量范围内):

// ...
memcpy(new_msg.get_rcl_serialized_message().buffer, pmsg_test, serialized_size);
new_msg.get_rcl_serialized_message().buffer_length = serialized_size;
cloudSerializer.deserialize_message(&new_msg, &test_msg);

相关问题