根据Apollo学习protobuf

根据Apollo学习protobuf

根据Apollo学习protobuf_第1张图片上图引至Protobuf学习
根据Apollo学习protobuf_第2张图片

参考文档:
Protobuffer简介

Protobuf是Protocol Buffers的简称,它是Google公司开发的一种数据描述语言,用于描述一种轻便高效的结构化数据存储格式,并于2008年对外开源。Protobuf可以用于结构化数据串行化,或者说序列化。它的设计非常适用于在网络通讯中的数据载体,很适合做数据存储或 RPC 数据交换格式,它序列化出来的数据量少再加上以 K-V 的方式来存储数据,对消息的版本兼容性非常强,可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。开发者可以通过Protobuf附带的工具生成代码并实现将结构化数据序列化的功能。

Protobuf中最基本的数据单元是message。在message中可以嵌套message或其它的基础数据类型的成员。

定义Message

首先看一个简单apollo中的例子,比如说你定义一个车辆参数,车辆参数主要用于定义不同的车辆,以及可选的一些参数。在.proto文件中定义如下:

syntax = "proto2";

package apollo.common;

import "modules/common/proto/header.proto";
import "modules/common/proto/geometry.proto";

message Transform {
  optional bytes source_frame = 1;  // Also known as "frame_id."

  optional bytes target_frame = 2;  // Also known as "child_frame_id."

  // Position of target in the source frame.
  optional Point3D translation = 3;

  // Activate rotation from the source frame to the target frame.
  optional Quaternion rotation = 4;
}

message Extrinsics {
  repeated Transform tansforms = 1;
}

// Vehicle parameters shared among several modules.
// By default, all are measured with the SI units (meters, meters per second,
// etc.).

enum VehicleBrand {
  LINCOLN_MKZ = 0;
  GEM = 1;
  LEXUS = 2;
  TRANSIT = 3;
  GE3 = 4;
  WEY = 5;
  ZHONGYUN = 6;
  CH = 7;
}

message VehicleID {
  optional string vin = 1;
  optional string plate = 2;
  optional string other_unique_id = 3;
}

message LatencyParam {
  // latency parameters, in second (s)
  optional double dead_time = 1;
  optional double rise_time = 2;
  optional double peak_time = 3;
  optional double settling_time = 4;
}

message VehicleParam {
  optional VehicleBrand brand = 1;
  // Car center point is car reference point, i.e., center of rear axle.
  optional VehicleID vehicle_id = 2;
  optional double front_edge_to_center = 3 [default = nan];
  optional double back_edge_to_center = 4 [default = nan];
  optional double left_edge_to_center = 5 [default = nan];
  optional double right_edge_to_center = 6 [default = nan];

  optional double length = 7 [default = nan];
  optional double width = 8 [default = nan];
  optional double height = 9 [default = nan];

  optional double min_turn_radius = 10 [default = nan];
  optional double max_acceleration = 11 [default = nan];
  optional double max_deceleration = 12 [default = nan];

  // The following items are used to compute trajectory constraints in
  // planning/control/canbus,
  // vehicle max steer angle
  optional double max_steer_angle = 13 [default = nan];
  // vehicle max steer rate; how fast can the steering wheel turn.
  optional double max_steer_angle_rate = 14 [default = nan];
  // vehicle min steer rate;
  optional double min_steer_angle_rate = 15 [default = nan];
  // ratio between the turn of steering wheel and the turn of wheels
  optional double steer_ratio = 16 [default = nan];
  // the distance between the front and back wheels
  optional double wheel_base = 17 [default = nan];
  // Tire effective rolling radius (vertical distance between the wheel center
  // and the ground).
  optional double wheel_rolling_radius = 18 [default = nan];

  // minimum differentiable vehicle speed, in m/s
  optional float max_abs_speed_when_stopped = 19 [default = nan];

  // minimum value get from chassis.brake, in percentage
  optional double brake_deadzone = 20 [default = nan];
  // minimum value get from chassis.throttle, in percentage
  optional double throttle_deadzone = 21 [default = nan];

  // vehicle latency parameters
  optional LatencyParam steering_latency_param = 22;
  optional LatencyParam throttle_latency_param = 23;
  optional LatencyParam brake_latency_param = 24;
}

message VehicleConfig {
  optional apollo.common.Header header = 1;
  optional VehicleParam vehicle_param = 2;
  optional Extrinsics extrinsics = 3;
}

.proto文件的第一行指定了使用proto2语法。如果省略protocol buffer编译器默认使用proto2语法。他必须是文件中非空非注释行的第一行。VehicleBrand定义中指定了一个枚举字段,字段包含两对键值对(name/value键值对),可选的定义了几个字段,每个字段都会有名称和类型。

其中apollo中默认的车辆是MKZ ,因此在测试用例里也都是用mkz,具体启动车辆时可设置具体选择哪个车辆的驱动。

设置车辆的语句如下:

class LincolnVehicleFactoryTest : public ::testing::Test {
 public:
  virtual void SetUp() {
    VehicleParameter parameter;
    parameter.set_brand(apollo::common::LINCOLN_MKZ);
    lincoln_factory_.SetVehicleParameter(parameter);
  }

这个例程中就完成了参数的定义到使用的过程。
parameter是类VehicleParameter的一个对象,set是成员函数。

另外需要说明的是,protobuf会根据我们的定义自动生成类代码,键值对的存在只是他内部使用,我们只需要按照他的要求进行定义即可。

有两个疑问待解:

  1. 如何让程序自动去解析protobuf文件

针对问题1,apollo已经集成好了protobuf的解析器,编写好文件后,编译apollo代码,自动生成protobuf的头文件,然后根据头文件去写代码即可。

你可能感兴趣的:(百度APollo)