欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Open3D-3 中点云数据的序列化和联网。

最编程 2024-10-04 09:45:05
...

我使用的是nanomsg,比源码中使用的ZeroMQ好用,当然,对数据流的传输可以使用其他的各种方法。

3.1 本人使用的传输方法

我使用的是nanomsg进行网络传输,nanomsg的使用参考我其他的文章。

这里的代码如下:

#include <nanomsg/nn.h>
#include <nanomsg/bus.h>

/// 序列化内容和压缩内容见上两节,这里略
/
void main(){
    // std::shared_ptr<open3d::geometry::PointCloud> pcd;
    ...
    /// 1.对原点云数据进行下采样(有损压缩)
	pcd = pcd->VoxelDownSample(0.002);
    
    /// 2.将PointCloud转化为标准数据类型SetMeshData
    PACK pack = serialization(pcd);
    
    /// 3.将SetMeshData所在结构体用msgpack序列化
    msgpack::sbuffer sbuf;
    msgpack::pack(sbuf, pack); 
    /// 得到序列化后的数据sbuf
    
    /// 4.对数据进行压缩
    QByteArray byteArray(sbuf.data(), static_cast<int>(sbuf.size()));
    std::string originalData(byteArray.data(), byteArray.size());
    std::string compressedData;
    if(compress(originalData, compressedData, 1) != Z_OK){
    	std::cerr << "Compression failed." << std::endl;
    }
    /// 得到压缩后的数据compressedData
    
    /// 5.将压缩后的数据发送
    int socket = nn_socket(AF_SP, NN_BUS);
    nn_bind(socket, "ws://127.0.0.1:55555");
    if(nn_send(socket, compressedData.data(), compressedData.size(),0) < 0){
		std::cerr << "Send error" << std::endl;
	}
    /// 5.如果不需要压缩,直接发送序列化的数据
    if(nn_send(socket, sbuf.data(), sbuf.size(),0) < 0){
		std::cerr << "Send error" << std::endl;
	}
}

3.2 源码中的方法

Open3D使用ZeroMQ库进行网络传输

Open3D源码中对网络传输的声明定义:

using namespace open3d::utility;

namespace open3d {
namespace io {
namespace rpc {

Connection::Connection()
    : Connection(defaults.address, defaults.connect_timeout, defaults.timeout) {
}

Connection::Connection(const std::string& address,
                       int connect_timeout,
                       int timeout)
    : context_(GetZMQContext()), // GetZMQContext()在别处定义、实现
      socket_(new zmq::socket_t(*GetZMQContext(), ZMQ_REQ)),
      address_(address),
      connect_timeout_(connect_timeout),
      timeout_(timeout) {
    socket_->set(zmq::sockopt::linger, timeout_);
    socket_->set(zmq::sockopt::connect_timeout, connect_timeout_);
    socket_->set(zmq::sockopt::rcvtimeo, timeout_);
    socket_->set(zmq::sockopt::sndtimeo, timeout_);
    socket_->connect(address_.c_str());
}

Connection::~Connection() { socket_->close(); }

std::shared_ptr<zmq::message_t> Connection::Send(zmq::message_t& send_msg) {
    if (!socket_->send(send_msg, zmq::send_flags::none)) {
        zmq::error_t err;
        if (err.num()) {
            LogInfo("Connection::send() send failed with: {}", err.what());
        }
    }

    std::shared_ptr<zmq::message_t> msg(new zmq::message_t());
    if (socket_->recv(*msg)) {
        LogDebug("Connection::send() received answer with {} bytes",
                 msg->size());
    } else {
        zmq::error_t err;
        if (err.num()) {
            LogInfo("Connection::send() recv failed with: {}", err.what());
        }
    }
    return msg;
}

std::shared_ptr<zmq::message_t> Connection::Send(const void* data,
                                                 size_t size) {
    zmq::message_t send_msg(data, size);
    return Send(send_msg);
}
}

那么使用即为:

auto connection = std::make_shared<Connection>("tcp://127.0.0.1:51454", 500, 500);

/// 序列化内容见1
/// 得到序列化后的数据sbuf

zmq::message_t send_msg(sbuf.data(), sbuf.size());
auto reply = connection->Send(send_msg);

上一篇: 关于 kubernetes 的说明 (v)

下一篇:

推荐阅读