【问题标题】:Using Google Protocol Buffer - How to define fields in .proto file使用 Google 协议缓冲区 - 如何在 .proto 文件中定义字段
【发布时间】:2018-01-29 20:21:42
【问题描述】:

我正在使用Simulation Open Framework Architecture SOFAC++ 语言),我的目标是在一些沙发源原生数据与其他外部应用程序之间设置某种通信类型。通过这个命令,我使用 ZeroMQ 将沙发数据传输到 python 外部应用程序。

在 SOFA (C++) 我有以下 instrumentData 结构

#include <sofa/core/behavior/BaseController.h>
#include <sofa/defaulttype/VecTypes.h>

// To Quat datatype
#include <sofa/defaulttype/Quat.h>
using sofa::defaulttype::Quat;

using std::string;

namespace sofa
{

namespace component
{
namespace controller
{
struct instrumentData
{
  typedef sofa::defaulttype::Vec3d Vec3d;
  Vec3d pos;
  Quat quat;
  int btnState;
  float openInst;
  bool blnDataReady;
};
}
}
}

我正在尝试通过 zmq 对以下数据成员 instrumentData 结构进行数据通信,并按照我的 python 命运数据应用程序的顺序对这些数据进行序列化/反序列化,我正在使用 Google Protocol Buffer 理解并解释它的内容instrumentData 数据成员结构。目前这个数据成员结构以二进制格式/内容到达你的命运。

Google Protocol Buffer 需要在.proto 文件扩展名中以构建格式描述协议,这是必要的

您需要从 .proto 文件开始。 .proto 文件中的定义很简单:为每个要序列化的数据结构添加一条消息,然后为消息中的每个字段指定名称和类型。

如何在我的instrumentdata.proto 文件中表示以下字段:posquatbool ...?

typedef sofa::defaulttype::Vec3d Vec3d;
Vec3d pos;

using sofa::defaulttype::Quat;
Quat quat;

bool blnDataReady;

目前,in the documentation 不清楚我应该如何定义与向量和其他数据类型(如 SOFA 原生的 Quat(四元数))相关的字段。

Vec3dQuat 由一些元素组成,如下所示:

void ZMQServerComponent::instrumentDataSend(instrumentData a)
{
    a.pos = sofa::defaulttype::Vec3d(1.0f, 1.0f, 1.0f);
    a.quat = defaulttype::Quat(1.0f, 1.0f, 4.0f, 1.0f);
}

是否可以定义为enumerators

更新

目前我正在根据documentation 构建的暂定instumentdata.proto 文件是:

sintax = "proto3";
message InstrumentData {
    // enum Pos {}
    // enum Quat {}
    int32 btnState;
    float openInst;
    bool blnDataReady
}

虽然我对这个单一的协议定义有些怀疑

【问题讨论】:

  • 您可能需要一些额外的.proto 文件(消息描述)来描述Vec3DQuat 类型。你能展示你对.proto文件的尝试吗?无论如何,您的原生结构的映射层是必要的,您不能直接表示这些原生结构。当然也可以在协议缓冲区语言中定义枚举。你有没有费心阅读他们的documentation
  • @TheDude 首先感谢您的提示。并不是我没有研究或阅读,而是我已经有一些原始文件版本,只是我不认为这是足够好的构建。你能看看我的UPDATE吗?
  • @TheDude 当然,我已经阅读了枚举文档并且我已经清楚了他们的应用案例,我的问题是关于如何将枚举概念与我的Vec3dQuat 数据类型结构。如果我的问题降低了 stackoverflow 的哲学,我真的很抱歉,我会带上你的 cmets 并建议一个更好的方法 :) 当然。我将对我的问题进行大量研究。最好的问候
  • 这些不能表示为 enums 的数组。如前所述,您必须将这些类型类似于单独的 message 定义。很好,您现在提供了.proto 语言尝试。
  • @TheDude 好的,谢谢!我将跟踪研究并记录我如何在我的.proto 文件中表示此SOFA 数据类型结构,这些结构不包含在C++ 堆栈中

标签: c++ data-structures protocol-buffers


【解决方案1】:

根据描述,Vec3dQuat 不是枚举,而是结构,您可以将其描述为单独的 message 类型,例如

message Vec3d {
  float x = 1;
  float y = 2;
  float z = 3;
}

message Quat {
  float a = 1;
  float b = 2;
  float c = 3;
  float d = 4;
}

这些消息类型随后可用于InstrumentData 消息类型

message InstrumentData {
  Vec3d pos = 1;
  Quat quat = 2;
  int32 btnState = 3;
  float openInst = 4;
  bool blnDataReady = 5;
}

【讨论】:

  • 就我对 Sofa 文档Vec3D 的理解而言,它类似于一系列点,看起来你在那里缺少了一层间接性。还有Quat好像是个错字,原来的类型其实是Quad
  • 此外,如果您仔细查看 Quad 定义,实际上并没有 float 值,而是 PointID 值,最终结果是 unsigned int typedef 的值。
  • 根据Vec.h,我会说这只是3个双打的向量。
  • 啊,是几何向量的意思。在这种情况下,你是对的。
  • 看看Quat.h,它是浮点数或双精度数。
【解决方案2】:

如前所述,您必须将框架中的类型与合理的消息定义相似,并提供映射层以将生成的内容转换为您的框架原生类。

Vec3DQuad 在您的框架中不是 enums,因此不应在协议缓冲区消息定义中如此表示。

您的.proto 文件应该看起来像(尚未测试):

message Vec3D {
    required float x = 1;
    required float y = 2;
    required float z = 3;
}

message Quad {
    required float a = 1;
    required float b = 2;
    required float c = 3;
    required float d = 4;
}

message InstrumentData {
    optional Vec3D = 1;
    optional Quat = 2;
    optional int32 btnState = 3;
    optional float openInst = 4;
    optional bool blnDataReady = 5;
}

【讨论】:

    猜你喜欢
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-09
    • 2017-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多