proto使用

8 minute read

Published:

本文介绍proto使用,生成cc和py文件,以及进行开发。

1, proto文件

创建proto 目录,存放config_camera.proto 和geometry.proto

config_camera.proto

syntax = "proto3";

package yr.proto.config;

import "geometry.proto";

message CameraExtrinsic {
    Transformation3d sensor_to_cam = 1;
}

message CameraPinholeIntrinsic {
    int32 img_width = 1;
    int32 img_height = 2;
    double f_x = 3;
    double f_y = 4;
    double o_x = 5;
    double o_y = 6;
    double k_1 = 7;
    double k_2 = 8;
    double p_1 = 9;
    double p_2 = 10;
}

message CameraKannalaIntrinsic {
    
    double k_3 = 9;
    double k_4 = 10;      
}

message CameraIntrinsic {
    int32 img_width = 1;
    int32 img_height = 2;
    double f_x = 3;
    double f_y = 4;
    double o_x = 5;
    double o_y = 6;
    double k_1 = 7;
    double k_2 = 8;
    oneof special_param {
        double p_1 = 9;
        double k_3 = 10;
    }
    oneof special_param_second {
        double p_2 = 11;
        double k_4 = 12; 
    }
    enum ModelType {
        PINHOLE = 0;
        KANNALA_BRANDT = 1;
    }  
    ModelType model_type = 13;
}

message CameraParameters {
    CameraExtrinsic extrinsic = 1;
    CameraIntrinsic intrinsic = 2;
}

message Camera {
    string camera_dev = 1;
    CameraParameters parameters = 2;
    Vector3d install_angle_error = 3;
    enum CalibType {
        CALIB_TYPE_UNKNOWN = 0;
        CALIB_TYPE_ONLINE = 1;
        CALIB_TYPE_OFFLINE = 2;
    }
    CalibType calib_type = 4;
}

message ConfigCameras {
    repeated Camera config = 1;
}

geometry.proto

syntax = "proto3";

package yr.proto.config;

message Vector3d {
    double x = 1;
    double y = 2;
    double z = 3;
}

message Quaterniond {
    double qx = 1;
    double qy = 2;
    double qz = 3;
    double qw = 4;
}

message Transformation3d {
    Vector3d position = 1;
    Quaterniond orientation = 2;
}

2, compile proto


#!/bin/bash

set -e

SHELL_FOLDER=$(cd $(dirname "$0") && pwd)
echo  $SHELL_FOLDER

PROTO_INTERFACE_DIR=$SHELL_FOLDER/proto

# protoc --help

# build proto
function build_proto() {
    cd $PROTO_INTERFACE_DIR
    for proto_file in *.proto; do
        if [ -f "$proto_file" ]; then
            # protoc --python_out=. $proto_file     
            protoc --cpp_out=$SHELL_FOLDER $proto_file
            if [ $? -ne 0 ]; then
                echo "protoc command failed"
                exit 1
            fi
        fi
    done
}

build_proto "$@"

3, main.cpp


#include <algorithm>
#include <fstream>
#include <map>
#include <sstream>
#include <string>

#include <google/protobuf/text_format.h>
#include <google/protobuf/util/message_differencer.h>

#include "proto/config_camera.pb.h"
#include "proto/geometry.pb.h"

// .pb
void read_from_file(const std::string& filename) {
  yr::proto::config::ConfigCameras sensor_para;
  std::ifstream in(filename, std::ios::binary);
  if (!sensor_para.ParseFromIstream(&in)) {
    std::cerr << "Failed to parse file" << std::endl;
    return;
  }

  std::cout << "length: " << sensor_para.config().size() << std::endl;
}

// .prototxt
void read_from_file(const std::string& filename, yr::proto::config::ConfigCameras& sensor_para) {
  std::ifstream input_file(filename);
  std::stringstream buffer;
  buffer << input_file.rdbuf();
  std::string prototxt_content;
  prototxt_content = buffer.str();

  if (!google::protobuf::TextFormat::ParseFromString(prototxt_content, &sensor_para)) {
    std::cerr << "Failed to parse prototxt" << std::endl;
  }
}

void parse_each_item(const ::yr::proto::config::Camera& item) {
  const std::vector<std::string> vec{
    "camera_1", // "front/fov120"},
    "camera_4", //"rear"},
    "panoramic_1", //"around/front"},
    "panoramic_2", //"around/right"},
    "panoramic_3", //"around/rear"},
    "panoramic_4"}; //"around/left"}};

  auto it = std::find(vec.begin(), vec.end(), item.camera_dev());
  if (it != vec.end()) {
    std::cout << item.camera_dev() << std::endl;
  }
}

bool IsEqualStructured(const google::protobuf::Message& msg1, const google::protobuf::Message& msg2) {
  return google::protobuf::util::MessageDifferencer::Equals(msg1, msg2);
}

bool IsEqualBinary(const google::protobuf::Message& msg1, const google::protobuf::Message& msg2) {
  return msg1.SerializeAsString() == msg2.SerializeAsString();
}

std::string get_basename_noext_manual(const std::string& path) {
  size_t sep_pos = path.find_last_of("/\\");
  size_t dot_pos = path.find_last_of('.');

  std::string basename = (sep_pos != std::string::npos) ? path.substr(sep_pos + 1) : path;

  if (dot_pos != std::string::npos && dot_pos > sep_pos) {
    basename = basename.substr(0, dot_pos - (sep_pos + 1));
  }
  return basename;
}

void parse_each_file(
  const std::string& filename, std::map<std::string /* package name */, ::yr::proto::config::ConfigCameras>& ccfgs) {
  yr::proto::config::ConfigCameras sensor_para;
  read_from_file(filename + "/cameras.cfg", sensor_para);

  auto package = get_basename_noext_manual(filename);

  std::cout << "package:" << package << std::endl;
  ccfgs.insert(std::make_pair(package, sensor_para));
}

int main() {
  const std::vector<std::string> filenames{"data/YR-C01-27_20240221_092617"};

  std::map<std::string /* package name */, ::yr::proto::config::ConfigCameras> ccfgs;
  for (auto it : filenames) {
    parse_each_file(it, ccfgs);
  }

  std::cout << "ccfgs length: " << ccfgs.size() << std::endl;
  auto target = ccfgs["YR-C01-27_20240221_092617"];

  int i = 0;
  for (const auto& it : ccfgs) {
    ++i;
    auto t = IsEqualStructured(target, it.second);
    if (t) {
      std::cout << "-----" << it.first << ", " << i << std::endl;
    }
  }

  return 0;
}

/*

export  LD_LIBRARY_PATH=/workspaces/gitlab/env/third_party/release/x86_2004/protobuf-3.14.0/lib:$LD_LIBRARY_PATH


g++  main.cpp  geometry.pb.cc  config_camera.pb.cc  \
-lprotoc -lprotobuf -lpthread -lz \
-L/workspaces/gitlab/env/third_party/release/x86_2004/protobuf-3.14.0/lib \
-I/workspaces/gitlab/env/third_party/release/x86_2004/protobuf-3.14.0/include

*/

cameras.cfg

## 2024/1/30/14:1:57

config {
  camera_dev: "traffic_2"
  parameters {
    extrinsic {
      sensor_to_cam {
        position {
          x: 0.590764
          y: -0.294134766
          z: -0.22177729
        }
        orientation {
          qx: 0.507374644
          qy: -0.500638843
          qz: 0.495600224
          qw: -0.496298462
        }
      }
    }
    intrinsic {
      img_width: 3840
      img_height: 2160
      f_x: 7336.2
      f_y: 7333.02246
      o_x: 1916.78406
      o_y: 1057.37732
      k_1: -0.265921056
      k_2: -0.362021714
      p_1: 6.15431918e-06
      p_2: -5.42116084e-07
      model_type: PINHOLE
    }
  }
  install_angle_error {
    x: -0.356843412
    y: -4.49255848
    z: 2.09944987
  }
}
config {
  camera_dev: "camera_1"
  parameters {
    extrinsic {
      sensor_to_cam {
        position {
          x: 0.574804842
          y: -0.102718443
          z: -0.227736428
        }
        orientation {
          qx: 0.504593
          qy: -0.503456533
          qz: 0.498221487
          qw: -0.493652433
        }
      }
    }
    intrinsic {
      img_width: 3840
      img_height: 2160
      f_x: 1912.44556
      f_y: 1911.9198
      o_x: 1921.53406
      o_y: 1088.81812
      k_1: -0.027984
      k_2: -0.0096184
      k_3: 0.0022653
      k_4: 0.0003351
      model_type: KANNALA_BRANDT
    }
  }
  install_angle_error {
    x: -0.169420242
    y: 0.263182
    z: 0.302423239
  }
}
config {
  camera_dev: "camera_2"
  parameters {
    extrinsic {
      sensor_to_cam {
        position {
          x: 1.01473808
          y: -0.979388297
          z: -0.815055
        }
        orientation {
          qx: 0.275003165
          qy: 0.654340267
          qz: -0.654294133
          qw: -0.260981411
        }
      }
    }
    intrinsic {
      img_width: 1920
      img_height: 1080
      f_x: 1155.05957
      f_y: 1154.927
      o_x: 962.005371
      o_y: 541.871033
      k_1: -0.0636888
      k_2: 0.0156328
      k_3: -0.0282869
      k_4: 0.0147581
      model_type: KANNALA_BRANDT
    }
  }
  install_angle_error {
    x: 0.0774992332
    y: -0.904488683
    z: -0.0479211062
  }
}
config {
  camera_dev: "camera_3"
  parameters {
    extrinsic {
      sensor_to_cam {
        position {
          x: 1.12408698
          y: -0.961270511
          z: -0.824891448
        }
        orientation {
          qx: -0.278253257
          qy: 0.650842607
          qz: -0.648706138
          qw: 0.279569864
        }
      }
    }
    intrinsic {
      img_width: 1920
      img_height: 1080
      f_x: 1163.14062
      f_y: 1162.91626
      o_x: 966.856567
      o_y: 542.519775
      k_1: -0.06246
      k_2: 0.0108769
      k_3: -0.0220825
      k_4: 0.0114848
      model_type: KANNALA_BRANDT
    }
  }
  install_angle_error {
    x: 0.357076347
    y: 0.150318027
    z: 0.141636
  }
}
config {
  camera_dev: "camera_4"
  parameters {
    extrinsic {
      sensor_to_cam {
        position {
          x: -2.32428336
          y: 0.0220099315
          z: -0.255792856
        }
        orientation {
          qx: 0.509601295
          qy: 0.501107335
          qz: -0.494983643
          qw: -0.494155
        }
      }
    }
    intrinsic {
      img_width: 1920
      img_height: 1080
      f_x: 1158.39453
      f_y: 1158.16382
      o_x: 961.045959
      o_y: 541.766907
      k_1: -0.0603645
      k_2: 0.0058936
      k_3: -0.016518
      k_4: 0.0090391
      model_type: KANNALA_BRANDT
    }
  }
  install_angle_error {
    x: -1.38462579
    y: 3.66519141
    z: -0.841244102
  }
}
config {
  camera_dev: "camera_5"
  parameters {
    extrinsic {
      sensor_to_cam {
        position {
          x: 1.16047227
          y: 0.978168368
          z: -0.824836612
        }
        orientation {
          qx: -0.656737268
          qy: 0.275898814
          qz: -0.264566422
          qw: 0.650062
        }
      }
    }
    intrinsic {
      img_width: 1920
      img_height: 1080
      f_x: 1156.68103
      f_y: 1156.68469
      o_x: 957.756042
      o_y: 543.66095
      k_1: -0.0623628
      k_2: 0.0089609
      k_3: -0.0159229
      k_4: 0.0075733
      model_type: KANNALA_BRANDT
    }
  }
  install_angle_error {
    x: -1.29805696
    y: 0.255227327
    z: -0.334254295
  }
}
config {
  camera_dev: "camera_6"
  parameters {
    extrinsic {
      sensor_to_cam {
        position {
          x: 1.03506219
          y: 0.977498233
          z: -0.821782053
        }
        orientation {
          qx: -0.651781678
          qy: -0.268218845
          qz: 0.278900743
          qw: 0.652268112
        }
      }
    }
    intrinsic {
      img_width: 1920
      img_height: 1080
      f_x: 1155.68677
      f_y: 1155.86096
      o_x: 958.949
      o_y: 539.089539
      k_1: -0.0615112
      k_2: 0.0093348
      k_3: -0.0162229
      k_4: 0.0075525
      model_type: KANNALA_BRANDT
    }
  }
  install_angle_error {
    x: -0.269571096
    y: 0.635011137
    z: -0.302366108
  }
}
config {
  camera_dev: "panoramic_1"
  parameters {
    extrinsic {
      sensor_to_cam {
        position {
          x: 2.47179699
          y: 0.0240998603
          z: -1.15628052
        }
        orientation {
          qx: -0.595373869
          qy: 0.600872397
          qz: -0.371507645
          qw: 0.382706612
        }
      }
    }
    intrinsic {
      img_width: 1920
      img_height: 1440
      f_x: 437.240509
      f_y: 437.077515
      o_x: 960.346863
      o_y: 721.32843
      k_1: 0.221225694
      k_2: -0.058466
      k_3: 0.0079281
      k_4: -0.0008349
      model_type: KANNALA_BRANDT
    }
  }
  install_angle_error {
    x: 0.130019799
    y: 0.227325067
    z: -0.11199867
  }
}
config {
  camera_dev: "panoramic_2"
  parameters {
    extrinsic {
      sensor_to_cam {
        position {
          x: 0.671558857
          y: -1.07404351
          z: -0.613530874
        }
        orientation {
          qx: -0.0145979431
          qy: 0.884804249
          qz: -0.465718806
          qw: 0.00377853285
        }
      }
    }
    intrinsic {
      img_width: 1920
      img_height: 1440
      f_x: 444.437439
      f_y: 444.489471
      o_x: 960.74469
      o_y: 719.184692
      k_1: 0.2189769
      k_2: -0.0567729
      k_3: 0.007488
      k_4: -0.0008241
      model_type: KANNALA_BRANDT
    }
  }
  install_angle_error {
    x: -2.5642066
    y: 0.710839927
    z: 0.349668
  }
}
config {
  camera_dev: "panoramic_3"
  parameters {
    extrinsic {
      sensor_to_cam {
        position {
          x: -2.61856484
          y: 0.0602845214
          z: -0.721125066
        }
        orientation {
          qx: 0.634574294
          qy: 0.624404132
          qz: -0.332132459
          qw: -0.311645538
        }
      }
    }
    intrinsic {
      img_width: 1920
      img_height: 1440
      f_x: 439.244202
      f_y: 438.87085
      o_x: 958.602722
      o_y: 723.472656
      k_1: 0.220488206
      k_2: -0.0569902
      k_3: 0.006983
      k_4: -0.0006463
      model_type: KANNALA_BRANDT
    }
  }
  install_angle_error {
    x: -2.03066826
    y: -1.78798783
    z: -0.109067626
  }
}
config {
  camera_dev: "panoramic_4"
  parameters {
    extrinsic {
      sensor_to_cam {
        position {
          x: 0.678423703
          y: 1.09688294
          z: -0.625479341
        }
        orientation {
          qx: 0.90571928
          qy: -0.0199170522
          qz: 0.00324988808
          qw: -0.423397332
        }
      }
    }
    intrinsic {
      img_width: 1920
      img_height: 1440
      f_x: 439.194366
      f_y: 438.922455
      o_x: 960.698853
      o_y: 720.764099
      k_1: 0.221919402
      k_2: -0.0579017
      k_3: 0.0072076
      k_4: -0.0006757
      model_type: KANNALA_BRANDT
    }
  }
  install_angle_error {
    x: -0.83289361
    y: 0.928895593
    z: -1.9849534
  }
}