Pārlūkot izejas kodu

2021.9.1 param struct changed,
for adopting chutian infrastucture.
minor changes in printing.

yct 4 gadi atpakaļ
vecāks
revīzija
5b38ca56dc

+ 2 - 2
setting/communication.prototxt

@@ -3,8 +3,8 @@
 communication_parameters
 {
 
-  bind_string:"tcp://192.168.2.113:30010"
-  connect_string_vector:"tcp://192.168.2.113:30000"
+  bind_string:"tcp://192.168.1.39:30010"
+  connect_string_vector:"tcp://192.168.1.39:30000"
  # connect_string_vector:"tcp://192.168.2.166:9002"
 
   # connect_string_vector:"tcp://192.168.2.125:9876"

+ 89 - 4
setting/velodyne_manager.prototxt

@@ -1,10 +1,10 @@
-fence_data_path:"/home/zx/data/fence_wj"
+fence_data_path:"/home/youchen/extra_space/chutian/fence_wj"
 #fence_log_path:"/home/zx/yct/MainStructure/new_electronic_fence/log"
 left_model_path:"/home/youchen/extra_space/chutian/measure/puai_wj_2021/setting/left_model.txt"
 right_model_path:"/home/youchen/extra_space/chutian/measure/puai_wj_2021/setting/right_model.txt"
 distribution_mode:false
 
-#1
+# 1 lidar
 velodyne_lidars
 {
     ip:""
@@ -23,7 +23,45 @@ velodyne_lidars
     }
 }
 
-# 1
+# 2 lidar
+velodyne_lidars
+{
+    ip:""
+    port:2369
+    model:"VLP16"
+    calibrationFile:"../setting/VLP16db.yaml"
+    lidar_id:1
+    max_range:5.0
+    min_range:0.1
+    min_angle:0
+    max_angle:360
+    rpm:600
+    calib
+    {
+        y:1.57
+    }
+}
+
+# 3 lidar
+velodyne_lidars
+{
+    ip:""
+    port:2370
+    model:"VLP16"
+    calibrationFile:"../setting/VLP16db.yaml"
+    lidar_id:2
+    max_range:5.0
+    min_range:0.1
+    min_angle:0
+    max_angle:360
+    rpm:600
+    calib
+    {
+        y:1.57
+    }
+}
+
+# 1 region
 region
 {
     minx:-3.1
@@ -33,5 +71,52 @@ region
 	minz:0.01
 	maxz:0.2
     region_id:0
-    lidar_ids:0
+    lidar_exts
+    {
+        lidar_id:0
+        calib
+        {
+            cx:0.1
+            cy:0.3
+        }
+    }
+    lidar_exts
+    {
+        lidar_id:1
+        calib
+        {
+            cx:0.1
+            cy:0.3
+        }
+    }
+}
+
+# 2 region
+region
+{
+    minx:-3.1
+	maxx:0
+	miny:-2.75
+	maxy:3.08
+	minz:0.01
+	maxz:0.2
+    region_id:1
+    lidar_exts
+    {
+        lidar_id:1
+        calib
+        {
+            cx:0.1
+            cy:0.3
+        }
+    }
+    lidar_exts
+    {
+        lidar_id:2
+        calib
+        {
+            cx:0.1
+            cy:0.3
+        }
+    }
 }

+ 3 - 3
system/system_executor.cpp

@@ -268,12 +268,12 @@ Error_manager System_executor::encapsulate_send_status()
         t_multi_status_msg.set_terminal_id(iter->second->get_terminal_id());
 		t_multi_status_msg.set_region_worker_status((message::Region_worker_status)(iter->second->get_status()));
 		velodyne::Region t_param = iter->second->get_param();
-		for (size_t j = 0; j <t_param.lidar_ids_size(); j++)
+		for (size_t j = 0; j <t_param.lidar_exts_size(); j++)
 		{
-			std::map<int, Velodyne_lidar_device::Velodyne_lidar_device_status>::iterator t_status_iter = t_velodyne_lidar_status_map.find(t_param.lidar_ids(j));
+			std::map<int, Velodyne_lidar_device::Velodyne_lidar_device_status>::iterator t_status_iter = t_velodyne_lidar_status_map.find(t_param.lidar_exts(j).lidar_id());
 			if(t_status_iter== t_velodyne_lidar_status_map.end())
 			{
-				LOG(WARNING) << "lidar status "<<t_param.lidar_ids(j)<<" cannot be found, param error";
+				LOG(WARNING) << "lidar status "<<t_param.lidar_exts(j).lidar_id()<<" cannot be found, param error";
 			}else{
 				t_multi_status_msg.add_wanji_lidar_device_status((message::Wanji_lidar_device_status)t_status_iter->second);
 			}

+ 10 - 0
velodyne_lidar/ground_region.h

@@ -63,6 +63,16 @@ public:
    std::chrono::system_clock::time_point get_detect_update_time() { return m_detect_update_time; }
    // 获取配置参数
    velodyne::Region get_param() { return m_region; }
+   // 检查激光是否在区域中
+   bool check_lidar_inside(int lidar_id)
+   {
+      for (size_t i = 0; i < m_region.lidar_exts_size(); i++)
+      {
+         if(m_region.lidar_exts(i).lidar_id() == lidar_id)
+            return true;
+      }
+      return false;
+   }
 
 private:
    // 点云分类,z切,3d优化

+ 462 - 122
velodyne_lidar/velodyne_config.pb.cc

@@ -30,11 +30,16 @@ class velodyneLidarParamsDefaultTypeInternal {
   ::google::protobuf::internal::ExplicitlyConstructed<velodyneLidarParams>
       _instance;
 } _velodyneLidarParams_default_instance_;
-class Calib_parameterDefaultTypeInternal {
+class CalibParameterDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Calib_parameter>
+  ::google::protobuf::internal::ExplicitlyConstructed<CalibParameter>
       _instance;
-} _Calib_parameter_default_instance_;
+} _CalibParameter_default_instance_;
+class lidarExtrinsicDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<lidarExtrinsic>
+      _instance;
+} _lidarExtrinsic_default_instance_;
 class RegionDefaultTypeInternal {
  public:
   ::google::protobuf::internal::ExplicitlyConstructed<Region>
@@ -73,7 +78,7 @@ void InitDefaultsvelodyneLidarParamsImpl() {
 #else
   ::google::protobuf::internal::InitProtobufDefaults();
 #endif  // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
-  protobuf_velodyne_5fconfig_2eproto::InitDefaultsCalib_parameter();
+  protobuf_velodyne_5fconfig_2eproto::InitDefaultsCalibParameter();
   ::velodyne::velodyneLidarParams::_default_model_.DefaultConstruct();
   *::velodyne::velodyneLidarParams::_default_model_.get_mutable() = ::std::string("VLP16", 5);
   ::google::protobuf::internal::OnShutdownDestroyString(
@@ -91,7 +96,28 @@ void InitDefaultsvelodyneLidarParams() {
   ::google::protobuf::GoogleOnceInit(&once, &InitDefaultsvelodyneLidarParamsImpl);
 }
 
-void InitDefaultsCalib_parameterImpl() {
+void InitDefaultsCalibParameterImpl() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
+  ::google::protobuf::internal::InitProtobufDefaultsForceUnique();
+#else
+  ::google::protobuf::internal::InitProtobufDefaults();
+#endif  // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
+  {
+    void* ptr = &::velodyne::_CalibParameter_default_instance_;
+    new (ptr) ::velodyne::CalibParameter();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::velodyne::CalibParameter::InitAsDefaultInstance();
+}
+
+void InitDefaultsCalibParameter() {
+  static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+  ::google::protobuf::GoogleOnceInit(&once, &InitDefaultsCalibParameterImpl);
+}
+
+void InitDefaultslidarExtrinsicImpl() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
 #ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
@@ -99,17 +125,18 @@ void InitDefaultsCalib_parameterImpl() {
 #else
   ::google::protobuf::internal::InitProtobufDefaults();
 #endif  // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
+  protobuf_velodyne_5fconfig_2eproto::InitDefaultsCalibParameter();
   {
-    void* ptr = &::velodyne::_Calib_parameter_default_instance_;
-    new (ptr) ::velodyne::Calib_parameter();
+    void* ptr = &::velodyne::_lidarExtrinsic_default_instance_;
+    new (ptr) ::velodyne::lidarExtrinsic();
     ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
   }
-  ::velodyne::Calib_parameter::InitAsDefaultInstance();
+  ::velodyne::lidarExtrinsic::InitAsDefaultInstance();
 }
 
-void InitDefaultsCalib_parameter() {
+void InitDefaultslidarExtrinsic() {
   static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
-  ::google::protobuf::GoogleOnceInit(&once, &InitDefaultsCalib_parameterImpl);
+  ::google::protobuf::GoogleOnceInit(&once, &InitDefaultslidarExtrinsicImpl);
 }
 
 void InitDefaultsRegionImpl() {
@@ -120,6 +147,7 @@ void InitDefaultsRegionImpl() {
 #else
   ::google::protobuf::internal::InitProtobufDefaults();
 #endif  // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
+  protobuf_velodyne_5fconfig_2eproto::InitDefaultslidarExtrinsic();
   {
     void* ptr = &::velodyne::_Region_default_instance_;
     new (ptr) ::velodyne::Region();
@@ -133,7 +161,7 @@ void InitDefaultsRegion() {
   ::google::protobuf::GoogleOnceInit(&once, &InitDefaultsRegionImpl);
 }
 
-::google::protobuf::Metadata file_level_metadata[4];
+::google::protobuf::Metadata file_level_metadata[5];
 
 const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::velodyneManagerParams, _has_bits_),
@@ -182,23 +210,32 @@ const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUT
   10,
   6,
   3,
-  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::Calib_parameter, _has_bits_),
-  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::Calib_parameter, _internal_metadata_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::CalibParameter, _has_bits_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::CalibParameter, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
   ~0u,  // no _weak_field_map_
-  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::Calib_parameter, r_),
-  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::Calib_parameter, p_),
-  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::Calib_parameter, y_),
-  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::Calib_parameter, cx_),
-  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::Calib_parameter, cy_),
-  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::Calib_parameter, cz_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::CalibParameter, r_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::CalibParameter, p_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::CalibParameter, y_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::CalibParameter, cx_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::CalibParameter, cy_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::CalibParameter, cz_),
   0,
   1,
   2,
   3,
   4,
   5,
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::lidarExtrinsic, _has_bits_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::lidarExtrinsic, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::lidarExtrinsic, lidar_id_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::lidarExtrinsic, calib_),
+  1,
+  0,
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::Region, _has_bits_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::Region, _internal_metadata_),
   ~0u,  // no _extensions_
@@ -211,7 +248,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUT
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::Region, minz_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::Region, maxz_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::Region, region_id_),
-  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::Region, lidar_ids_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::velodyne::Region, lidar_exts_),
   0,
   1,
   2,
@@ -224,14 +261,16 @@ const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUT
 static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
   { 0, 12, sizeof(::velodyne::velodyneManagerParams)},
   { 19, 35, sizeof(::velodyne::velodyneLidarParams)},
-  { 46, 57, sizeof(::velodyne::Calib_parameter)},
-  { 63, 76, sizeof(::velodyne::Region)},
+  { 46, 57, sizeof(::velodyne::CalibParameter)},
+  { 63, 70, sizeof(::velodyne::lidarExtrinsic)},
+  { 72, 85, sizeof(::velodyne::Region)},
 };
 
 static ::google::protobuf::Message const * const file_default_instances[] = {
   reinterpret_cast<const ::google::protobuf::Message*>(&::velodyne::_velodyneManagerParams_default_instance_),
   reinterpret_cast<const ::google::protobuf::Message*>(&::velodyne::_velodyneLidarParams_default_instance_),
-  reinterpret_cast<const ::google::protobuf::Message*>(&::velodyne::_Calib_parameter_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::velodyne::_CalibParameter_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::velodyne::_lidarExtrinsic_default_instance_),
   reinterpret_cast<const ::google::protobuf::Message*>(&::velodyne::_Region_default_instance_),
 };
 
@@ -251,7 +290,7 @@ void protobuf_AssignDescriptorsOnce() {
 void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
 void protobuf_RegisterTypes(const ::std::string&) {
   protobuf_AssignDescriptorsOnce();
-  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 4);
+  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 5);
 }
 
 void AddDescriptorsImpl() {
@@ -264,23 +303,25 @@ void AddDescriptorsImpl() {
       "ata_path\030\003 \001(\t:\000\022\030\n\016fence_log_path\030\004 \001(\t"
       ":\000\022\031\n\017left_model_path\030\005 \001(\t:\000\022\032\n\020right_m"
       "odel_path\030\006 \001(\t:\000\022 \n\021distribution_mode\030\007"
-      " \002(\010:\005false\"\227\002\n\023velodyneLidarParams\022\014\n\002i"
+      " \002(\010:\005false\"\226\002\n\023velodyneLidarParams\022\014\n\002i"
       "p\030\001 \002(\t:\000\022\022\n\004port\030\002 \002(\005:\0042368\022\024\n\005model\030\003"
       " \002(\t:\005VLP16\022\031\n\017calibrationFile\030\004 \002(\t:\000\022\023"
       "\n\010lidar_id\030\005 \002(\005:\0010\022\025\n\tmax_range\030\006 \001(\002:\002"
       "10\022\027\n\tmin_range\030\007 \001(\002:\0040.15\022\024\n\tmin_angle"
       "\030\010 \001(\005:\0010\022\026\n\tmax_angle\030\t \001(\005:\003360\022\020\n\003rpm"
-      "\030\n \001(\005:\003600\022(\n\005calib\030\013 \001(\0132\031.velodyne.Ca"
-      "lib_parameter\"h\n\017Calib_parameter\022\014\n\001r\030\001 "
-      "\001(\002:\0010\022\014\n\001p\030\002 \001(\002:\0010\022\014\n\001y\030\003 \001(\002:\0010\022\r\n\002cx"
-      "\030\004 \001(\002:\0010\022\r\n\002cy\030\005 \001(\002:\0010\022\r\n\002cz\030\006 \001(\002:\0010\""
-      "\202\001\n\006Region\022\014\n\004minx\030\001 \002(\002\022\014\n\004maxx\030\002 \002(\002\022\014"
-      "\n\004miny\030\003 \002(\002\022\014\n\004maxy\030\004 \002(\002\022\014\n\004minz\030\005 \002(\002"
-      "\022\014\n\004maxz\030\006 \002(\002\022\021\n\tregion_id\030\007 \002(\005\022\021\n\tlid"
-      "ar_ids\030\010 \003(\005"
+      "\030\n \001(\005:\003600\022\'\n\005calib\030\013 \001(\0132\030.velodyne.Ca"
+      "libParameter\"g\n\016CalibParameter\022\014\n\001r\030\001 \001("
+      "\002:\0010\022\014\n\001p\030\002 \001(\002:\0010\022\014\n\001y\030\003 \001(\002:\0010\022\r\n\002cx\030\004"
+      " \001(\002:\0010\022\r\n\002cy\030\005 \001(\002:\0010\022\r\n\002cz\030\006 \001(\002:\0010\"K\n"
+      "\016lidarExtrinsic\022\020\n\010lidar_id\030\001 \002(\005\022\'\n\005cal"
+      "ib\030\002 \001(\0132\030.velodyne.CalibParameter\"\235\001\n\006R"
+      "egion\022\014\n\004minx\030\001 \002(\002\022\014\n\004maxx\030\002 \002(\002\022\014\n\004min"
+      "y\030\003 \002(\002\022\014\n\004maxy\030\004 \002(\002\022\014\n\004minz\030\005 \002(\002\022\014\n\004m"
+      "axz\030\006 \002(\002\022\021\n\tregion_id\030\007 \002(\005\022,\n\nlidar_ex"
+      "ts\030\010 \003(\0132\030.velodyne.lidarExtrinsic"
   };
   ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 812);
+      descriptor, 914);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "velodyne_config.proto", &protobuf_RegisterTypes);
 }
@@ -877,8 +918,8 @@ void velodyneManagerParams::InternalSwap(velodyneManagerParams* other) {
 // ===================================================================
 
 void velodyneLidarParams::InitAsDefaultInstance() {
-  ::velodyne::_velodyneLidarParams_default_instance_._instance.get_mutable()->calib_ = const_cast< ::velodyne::Calib_parameter*>(
-      ::velodyne::Calib_parameter::internal_default_instance());
+  ::velodyne::_velodyneLidarParams_default_instance_._instance.get_mutable()->calib_ = const_cast< ::velodyne::CalibParameter*>(
+      ::velodyne::CalibParameter::internal_default_instance());
 }
 ::google::protobuf::internal::ExplicitlyConstructed< ::std::string> velodyneLidarParams::_default_model_;
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -922,7 +963,7 @@ velodyneLidarParams::velodyneLidarParams(const velodyneLidarParams& from)
     calibrationfile_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.calibrationfile_);
   }
   if (from.has_calib()) {
-    calib_ = new ::velodyne::Calib_parameter(*from.calib_);
+    calib_ = new ::velodyne::CalibParameter(*from.calib_);
   } else {
     calib_ = NULL;
   }
@@ -1179,7 +1220,7 @@ bool velodyneLidarParams::MergePartialFromCodedStream(
         break;
       }
 
-      // optional .velodyne.Calib_parameter calib = 11;
+      // optional .velodyne.CalibParameter calib = 11;
       case 11: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(90u /* 90 & 0xFF */)) {
@@ -1283,7 +1324,7 @@ void velodyneLidarParams::SerializeWithCachedSizes(
     ::google::protobuf::internal::WireFormatLite::WriteInt32(10, this->rpm(), output);
   }
 
-  // optional .velodyne.Calib_parameter calib = 11;
+  // optional .velodyne.CalibParameter calib = 11;
   if (cached_has_bits & 0x00000008u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
       11, *this->calib_, output);
@@ -1372,7 +1413,7 @@ void velodyneLidarParams::SerializeWithCachedSizes(
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(10, this->rpm(), target);
   }
 
-  // optional .velodyne.Calib_parameter calib = 11;
+  // optional .velodyne.CalibParameter calib = 11;
   if (cached_has_bits & 0x00000008u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
@@ -1466,7 +1507,7 @@ size_t velodyneLidarParams::ByteSizeLong() const {
   } else {
     total_size += RequiredFieldsByteSizeFallback();
   }
-  // optional .velodyne.Calib_parameter calib = 11;
+  // optional .velodyne.CalibParameter calib = 11;
   if (has_calib()) {
     total_size += 1 +
       ::google::protobuf::internal::WireFormatLite::MessageSize(
@@ -1552,7 +1593,7 @@ void velodyneLidarParams::MergeFrom(const velodyneLidarParams& from) {
       calibrationfile_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.calibrationfile_);
     }
     if (cached_has_bits & 0x00000008u) {
-      mutable_calib()->::velodyne::Calib_parameter::MergeFrom(from.calib());
+      mutable_calib()->::velodyne::CalibParameter::MergeFrom(from.calib());
     }
     if (cached_has_bits & 0x00000010u) {
       lidar_id_ = from.lidar_id_;
@@ -1631,26 +1672,26 @@ void velodyneLidarParams::InternalSwap(velodyneLidarParams* other) {
 
 // ===================================================================
 
-void Calib_parameter::InitAsDefaultInstance() {
+void CalibParameter::InitAsDefaultInstance() {
 }
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
-const int Calib_parameter::kRFieldNumber;
-const int Calib_parameter::kPFieldNumber;
-const int Calib_parameter::kYFieldNumber;
-const int Calib_parameter::kCxFieldNumber;
-const int Calib_parameter::kCyFieldNumber;
-const int Calib_parameter::kCzFieldNumber;
+const int CalibParameter::kRFieldNumber;
+const int CalibParameter::kPFieldNumber;
+const int CalibParameter::kYFieldNumber;
+const int CalibParameter::kCxFieldNumber;
+const int CalibParameter::kCyFieldNumber;
+const int CalibParameter::kCzFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
-Calib_parameter::Calib_parameter()
+CalibParameter::CalibParameter()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
   if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
-    ::protobuf_velodyne_5fconfig_2eproto::InitDefaultsCalib_parameter();
+    ::protobuf_velodyne_5fconfig_2eproto::InitDefaultsCalibParameter();
   }
   SharedCtor();
-  // @@protoc_insertion_point(constructor:velodyne.Calib_parameter)
+  // @@protoc_insertion_point(constructor:velodyne.CalibParameter)
 }
-Calib_parameter::Calib_parameter(const Calib_parameter& from)
+CalibParameter::CalibParameter(const CalibParameter& from)
   : ::google::protobuf::Message(),
       _internal_metadata_(NULL),
       _has_bits_(from._has_bits_),
@@ -1659,49 +1700,49 @@ Calib_parameter::Calib_parameter(const Calib_parameter& from)
   ::memcpy(&r_, &from.r_,
     static_cast<size_t>(reinterpret_cast<char*>(&cz_) -
     reinterpret_cast<char*>(&r_)) + sizeof(cz_));
-  // @@protoc_insertion_point(copy_constructor:velodyne.Calib_parameter)
+  // @@protoc_insertion_point(copy_constructor:velodyne.CalibParameter)
 }
 
-void Calib_parameter::SharedCtor() {
+void CalibParameter::SharedCtor() {
   _cached_size_ = 0;
   ::memset(&r_, 0, static_cast<size_t>(
       reinterpret_cast<char*>(&cz_) -
       reinterpret_cast<char*>(&r_)) + sizeof(cz_));
 }
 
-Calib_parameter::~Calib_parameter() {
-  // @@protoc_insertion_point(destructor:velodyne.Calib_parameter)
+CalibParameter::~CalibParameter() {
+  // @@protoc_insertion_point(destructor:velodyne.CalibParameter)
   SharedDtor();
 }
 
-void Calib_parameter::SharedDtor() {
+void CalibParameter::SharedDtor() {
 }
 
-void Calib_parameter::SetCachedSize(int size) const {
+void CalibParameter::SetCachedSize(int size) const {
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = size;
   GOOGLE_SAFE_CONCURRENT_WRITES_END();
 }
-const ::google::protobuf::Descriptor* Calib_parameter::descriptor() {
+const ::google::protobuf::Descriptor* CalibParameter::descriptor() {
   ::protobuf_velodyne_5fconfig_2eproto::protobuf_AssignDescriptorsOnce();
   return ::protobuf_velodyne_5fconfig_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
-const Calib_parameter& Calib_parameter::default_instance() {
-  ::protobuf_velodyne_5fconfig_2eproto::InitDefaultsCalib_parameter();
+const CalibParameter& CalibParameter::default_instance() {
+  ::protobuf_velodyne_5fconfig_2eproto::InitDefaultsCalibParameter();
   return *internal_default_instance();
 }
 
-Calib_parameter* Calib_parameter::New(::google::protobuf::Arena* arena) const {
-  Calib_parameter* n = new Calib_parameter;
+CalibParameter* CalibParameter::New(::google::protobuf::Arena* arena) const {
+  CalibParameter* n = new CalibParameter;
   if (arena != NULL) {
     arena->Own(n);
   }
   return n;
 }
 
-void Calib_parameter::Clear() {
-// @@protoc_insertion_point(message_clear_start:velodyne.Calib_parameter)
+void CalibParameter::Clear() {
+// @@protoc_insertion_point(message_clear_start:velodyne.CalibParameter)
   ::google::protobuf::uint32 cached_has_bits = 0;
   // Prevent compiler warnings about cached_has_bits being unused
   (void) cached_has_bits;
@@ -1716,11 +1757,11 @@ void Calib_parameter::Clear() {
   _internal_metadata_.Clear();
 }
 
-bool Calib_parameter::MergePartialFromCodedStream(
+bool CalibParameter::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
 #define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
-  // @@protoc_insertion_point(parse_start:velodyne.Calib_parameter)
+  // @@protoc_insertion_point(parse_start:velodyne.CalibParameter)
   for (;;) {
     ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
     tag = p.first;
@@ -1822,17 +1863,17 @@ bool Calib_parameter::MergePartialFromCodedStream(
     }
   }
 success:
-  // @@protoc_insertion_point(parse_success:velodyne.Calib_parameter)
+  // @@protoc_insertion_point(parse_success:velodyne.CalibParameter)
   return true;
 failure:
-  // @@protoc_insertion_point(parse_failure:velodyne.Calib_parameter)
+  // @@protoc_insertion_point(parse_failure:velodyne.CalibParameter)
   return false;
 #undef DO_
 }
 
-void Calib_parameter::SerializeWithCachedSizes(
+void CalibParameter::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
-  // @@protoc_insertion_point(serialize_start:velodyne.Calib_parameter)
+  // @@protoc_insertion_point(serialize_start:velodyne.CalibParameter)
   ::google::protobuf::uint32 cached_has_bits = 0;
   (void) cached_has_bits;
 
@@ -1871,13 +1912,13 @@ void Calib_parameter::SerializeWithCachedSizes(
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
         _internal_metadata_.unknown_fields(), output);
   }
-  // @@protoc_insertion_point(serialize_end:velodyne.Calib_parameter)
+  // @@protoc_insertion_point(serialize_end:velodyne.CalibParameter)
 }
 
-::google::protobuf::uint8* Calib_parameter::InternalSerializeWithCachedSizesToArray(
+::google::protobuf::uint8* CalibParameter::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
   (void)deterministic; // Unused
-  // @@protoc_insertion_point(serialize_to_array_start:velodyne.Calib_parameter)
+  // @@protoc_insertion_point(serialize_to_array_start:velodyne.CalibParameter)
   ::google::protobuf::uint32 cached_has_bits = 0;
   (void) cached_has_bits;
 
@@ -1916,12 +1957,12 @@ void Calib_parameter::SerializeWithCachedSizes(
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
         _internal_metadata_.unknown_fields(), target);
   }
-  // @@protoc_insertion_point(serialize_to_array_end:velodyne.Calib_parameter)
+  // @@protoc_insertion_point(serialize_to_array_end:velodyne.CalibParameter)
   return target;
 }
 
-size_t Calib_parameter::ByteSizeLong() const {
-// @@protoc_insertion_point(message_byte_size_start:velodyne.Calib_parameter)
+size_t CalibParameter::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:velodyne.CalibParameter)
   size_t total_size = 0;
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -1968,23 +2009,23 @@ size_t Calib_parameter::ByteSizeLong() const {
   return total_size;
 }
 
-void Calib_parameter::MergeFrom(const ::google::protobuf::Message& from) {
-// @@protoc_insertion_point(generalized_merge_from_start:velodyne.Calib_parameter)
+void CalibParameter::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:velodyne.CalibParameter)
   GOOGLE_DCHECK_NE(&from, this);
-  const Calib_parameter* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const Calib_parameter>(
+  const CalibParameter* source =
+      ::google::protobuf::internal::DynamicCastToGenerated<const CalibParameter>(
           &from);
   if (source == NULL) {
-  // @@protoc_insertion_point(generalized_merge_from_cast_fail:velodyne.Calib_parameter)
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:velodyne.CalibParameter)
     ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
-  // @@protoc_insertion_point(generalized_merge_from_cast_success:velodyne.Calib_parameter)
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:velodyne.CalibParameter)
     MergeFrom(*source);
   }
 }
 
-void Calib_parameter::MergeFrom(const Calib_parameter& from) {
-// @@protoc_insertion_point(class_specific_merge_from_start:velodyne.Calib_parameter)
+void CalibParameter::MergeFrom(const CalibParameter& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:velodyne.CalibParameter)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
   ::google::protobuf::uint32 cached_has_bits = 0;
@@ -2014,29 +2055,29 @@ void Calib_parameter::MergeFrom(const Calib_parameter& from) {
   }
 }
 
-void Calib_parameter::CopyFrom(const ::google::protobuf::Message& from) {
-// @@protoc_insertion_point(generalized_copy_from_start:velodyne.Calib_parameter)
+void CalibParameter::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:velodyne.CalibParameter)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
 }
 
-void Calib_parameter::CopyFrom(const Calib_parameter& from) {
-// @@protoc_insertion_point(class_specific_copy_from_start:velodyne.Calib_parameter)
+void CalibParameter::CopyFrom(const CalibParameter& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:velodyne.CalibParameter)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
 }
 
-bool Calib_parameter::IsInitialized() const {
+bool CalibParameter::IsInitialized() const {
   return true;
 }
 
-void Calib_parameter::Swap(Calib_parameter* other) {
+void CalibParameter::Swap(CalibParameter* other) {
   if (other == this) return;
   InternalSwap(other);
 }
-void Calib_parameter::InternalSwap(Calib_parameter* other) {
+void CalibParameter::InternalSwap(CalibParameter* other) {
   using std::swap;
   swap(r_, other->r_);
   swap(p_, other->p_);
@@ -2049,7 +2090,306 @@ void Calib_parameter::InternalSwap(Calib_parameter* other) {
   swap(_cached_size_, other->_cached_size_);
 }
 
-::google::protobuf::Metadata Calib_parameter::GetMetadata() const {
+::google::protobuf::Metadata CalibParameter::GetMetadata() const {
+  protobuf_velodyne_5fconfig_2eproto::protobuf_AssignDescriptorsOnce();
+  return ::protobuf_velodyne_5fconfig_2eproto::file_level_metadata[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void lidarExtrinsic::InitAsDefaultInstance() {
+  ::velodyne::_lidarExtrinsic_default_instance_._instance.get_mutable()->calib_ = const_cast< ::velodyne::CalibParameter*>(
+      ::velodyne::CalibParameter::internal_default_instance());
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int lidarExtrinsic::kLidarIdFieldNumber;
+const int lidarExtrinsic::kCalibFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+lidarExtrinsic::lidarExtrinsic()
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
+    ::protobuf_velodyne_5fconfig_2eproto::InitDefaultslidarExtrinsic();
+  }
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:velodyne.lidarExtrinsic)
+}
+lidarExtrinsic::lidarExtrinsic(const lidarExtrinsic& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(NULL),
+      _has_bits_(from._has_bits_),
+      _cached_size_(0) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_calib()) {
+    calib_ = new ::velodyne::CalibParameter(*from.calib_);
+  } else {
+    calib_ = NULL;
+  }
+  lidar_id_ = from.lidar_id_;
+  // @@protoc_insertion_point(copy_constructor:velodyne.lidarExtrinsic)
+}
+
+void lidarExtrinsic::SharedCtor() {
+  _cached_size_ = 0;
+  ::memset(&calib_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&lidar_id_) -
+      reinterpret_cast<char*>(&calib_)) + sizeof(lidar_id_));
+}
+
+lidarExtrinsic::~lidarExtrinsic() {
+  // @@protoc_insertion_point(destructor:velodyne.lidarExtrinsic)
+  SharedDtor();
+}
+
+void lidarExtrinsic::SharedDtor() {
+  if (this != internal_default_instance()) delete calib_;
+}
+
+void lidarExtrinsic::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* lidarExtrinsic::descriptor() {
+  ::protobuf_velodyne_5fconfig_2eproto::protobuf_AssignDescriptorsOnce();
+  return ::protobuf_velodyne_5fconfig_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
+}
+
+const lidarExtrinsic& lidarExtrinsic::default_instance() {
+  ::protobuf_velodyne_5fconfig_2eproto::InitDefaultslidarExtrinsic();
+  return *internal_default_instance();
+}
+
+lidarExtrinsic* lidarExtrinsic::New(::google::protobuf::Arena* arena) const {
+  lidarExtrinsic* n = new lidarExtrinsic;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void lidarExtrinsic::Clear() {
+// @@protoc_insertion_point(message_clear_start:velodyne.lidarExtrinsic)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000001u) {
+    GOOGLE_DCHECK(calib_ != NULL);
+    calib_->Clear();
+  }
+  lidar_id_ = 0;
+  _has_bits_.Clear();
+  _internal_metadata_.Clear();
+}
+
+bool lidarExtrinsic::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:velodyne.lidarExtrinsic)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // required int32 lidar_id = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) ==
+            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
+          set_has_lidar_id();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &lidar_id_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // optional .velodyne.CalibParameter calib = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) ==
+            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_calib()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:velodyne.lidarExtrinsic)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:velodyne.lidarExtrinsic)
+  return false;
+#undef DO_
+}
+
+void lidarExtrinsic::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:velodyne.lidarExtrinsic)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
+  // required int32 lidar_id = 1;
+  if (cached_has_bits & 0x00000002u) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->lidar_id(), output);
+  }
+
+  // optional .velodyne.CalibParameter calib = 2;
+  if (cached_has_bits & 0x00000001u) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, *this->calib_, output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:velodyne.lidarExtrinsic)
+}
+
+::google::protobuf::uint8* lidarExtrinsic::InternalSerializeWithCachedSizesToArray(
+    bool deterministic, ::google::protobuf::uint8* target) const {
+  (void)deterministic; // Unused
+  // @@protoc_insertion_point(serialize_to_array_start:velodyne.lidarExtrinsic)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
+  // required int32 lidar_id = 1;
+  if (cached_has_bits & 0x00000002u) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->lidar_id(), target);
+  }
+
+  // optional .velodyne.CalibParameter calib = 2;
+  if (cached_has_bits & 0x00000001u) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, *this->calib_, deterministic, target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:velodyne.lidarExtrinsic)
+  return target;
+}
+
+size_t lidarExtrinsic::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:velodyne.lidarExtrinsic)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  // required int32 lidar_id = 1;
+  if (has_lidar_id()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::Int32Size(
+        this->lidar_id());
+  }
+  // optional .velodyne.CalibParameter calib = 2;
+  if (has_calib()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *this->calib_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = cached_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void lidarExtrinsic::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:velodyne.lidarExtrinsic)
+  GOOGLE_DCHECK_NE(&from, this);
+  const lidarExtrinsic* source =
+      ::google::protobuf::internal::DynamicCastToGenerated<const lidarExtrinsic>(
+          &from);
+  if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:velodyne.lidarExtrinsic)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:velodyne.lidarExtrinsic)
+    MergeFrom(*source);
+  }
+}
+
+void lidarExtrinsic::MergeFrom(const lidarExtrinsic& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:velodyne.lidarExtrinsic)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 3u) {
+    if (cached_has_bits & 0x00000001u) {
+      mutable_calib()->::velodyne::CalibParameter::MergeFrom(from.calib());
+    }
+    if (cached_has_bits & 0x00000002u) {
+      lidar_id_ = from.lidar_id_;
+    }
+    _has_bits_[0] |= cached_has_bits;
+  }
+}
+
+void lidarExtrinsic::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:velodyne.lidarExtrinsic)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void lidarExtrinsic::CopyFrom(const lidarExtrinsic& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:velodyne.lidarExtrinsic)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool lidarExtrinsic::IsInitialized() const {
+  if ((_has_bits_[0] & 0x00000002) != 0x00000002) return false;
+  return true;
+}
+
+void lidarExtrinsic::Swap(lidarExtrinsic* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void lidarExtrinsic::InternalSwap(lidarExtrinsic* other) {
+  using std::swap;
+  swap(calib_, other->calib_);
+  swap(lidar_id_, other->lidar_id_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata lidarExtrinsic::GetMetadata() const {
   protobuf_velodyne_5fconfig_2eproto::protobuf_AssignDescriptorsOnce();
   return ::protobuf_velodyne_5fconfig_2eproto::file_level_metadata[kIndexInFileMessages];
 }
@@ -2067,7 +2407,7 @@ const int Region::kMaxyFieldNumber;
 const int Region::kMinzFieldNumber;
 const int Region::kMaxzFieldNumber;
 const int Region::kRegionIdFieldNumber;
-const int Region::kLidarIdsFieldNumber;
+const int Region::kLidarExtsFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 Region::Region()
@@ -2083,7 +2423,7 @@ Region::Region(const Region& from)
       _internal_metadata_(NULL),
       _has_bits_(from._has_bits_),
       _cached_size_(0),
-      lidar_ids_(from.lidar_ids_) {
+      lidar_exts_(from.lidar_exts_) {
   _internal_metadata_.MergeFrom(from._internal_metadata_);
   ::memcpy(&minx_, &from.minx_,
     static_cast<size_t>(reinterpret_cast<char*>(&region_id_) -
@@ -2135,7 +2475,7 @@ void Region::Clear() {
   // Prevent compiler warnings about cached_has_bits being unused
   (void) cached_has_bits;
 
-  lidar_ids_.Clear();
+  lidar_exts_.Clear();
   cached_has_bits = _has_bits_[0];
   if (cached_has_bits & 127u) {
     ::memset(&minx_, 0, static_cast<size_t>(
@@ -2254,19 +2594,11 @@ bool Region::MergePartialFromCodedStream(
         break;
       }
 
-      // repeated int32 lidar_ids = 8;
+      // repeated .velodyne.lidarExtrinsic lidar_exts = 8;
       case 8: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(64u /* 64 & 0xFF */)) {
-          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive<
-                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
-                 1, 64u, input, this->mutable_lidar_ids())));
-        } else if (
-            static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) {
-          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline<
-                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
-                 input, this->mutable_lidar_ids())));
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(input, add_lidar_exts()));
         } else {
           goto handle_unusual;
         }
@@ -2335,10 +2667,11 @@ void Region::SerializeWithCachedSizes(
     ::google::protobuf::internal::WireFormatLite::WriteInt32(7, this->region_id(), output);
   }
 
-  // repeated int32 lidar_ids = 8;
-  for (int i = 0, n = this->lidar_ids_size(); i < n; i++) {
-    ::google::protobuf::internal::WireFormatLite::WriteInt32(
-      8, this->lidar_ids(i), output);
+  // repeated .velodyne.lidarExtrinsic lidar_exts = 8;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->lidar_exts_size()); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      8, this->lidar_exts(static_cast<int>(i)), output);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -2391,9 +2724,13 @@ void Region::SerializeWithCachedSizes(
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(7, this->region_id(), target);
   }
 
-  // repeated int32 lidar_ids = 8;
-  target = ::google::protobuf::internal::WireFormatLite::
-    WriteInt32ToArray(8, this->lidar_ids_, target);
+  // repeated .velodyne.lidarExtrinsic lidar_exts = 8;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->lidar_exts_size()); i < n; i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        8, this->lidar_exts(static_cast<int>(i)), deterministic, target);
+  }
 
   if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
@@ -2482,13 +2819,15 @@ size_t Region::ByteSizeLong() const {
   } else {
     total_size += RequiredFieldsByteSizeFallback();
   }
-  // repeated int32 lidar_ids = 8;
+  // repeated .velodyne.lidarExtrinsic lidar_exts = 8;
   {
-    size_t data_size = ::google::protobuf::internal::WireFormatLite::
-      Int32Size(this->lidar_ids_);
-    total_size += 1 *
-                  ::google::protobuf::internal::FromIntSize(this->lidar_ids_size());
-    total_size += data_size;
+    unsigned int count = static_cast<unsigned int>(this->lidar_exts_size());
+    total_size += 1UL * count;
+    for (unsigned int i = 0; i < count; i++) {
+      total_size +=
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          this->lidar_exts(static_cast<int>(i)));
+    }
   }
 
   int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
@@ -2520,7 +2859,7 @@ void Region::MergeFrom(const Region& from) {
   ::google::protobuf::uint32 cached_has_bits = 0;
   (void) cached_has_bits;
 
-  lidar_ids_.MergeFrom(from.lidar_ids_);
+  lidar_exts_.MergeFrom(from.lidar_exts_);
   cached_has_bits = from._has_bits_[0];
   if (cached_has_bits & 127u) {
     if (cached_has_bits & 0x00000001u) {
@@ -2564,6 +2903,7 @@ void Region::CopyFrom(const Region& from) {
 
 bool Region::IsInitialized() const {
   if ((_has_bits_[0] & 0x0000007f) != 0x0000007f) return false;
+  if (!::google::protobuf::internal::AllAreInitialized(this->lidar_exts())) return false;
   return true;
 }
 
@@ -2573,7 +2913,7 @@ void Region::Swap(Region* other) {
 }
 void Region::InternalSwap(Region* other) {
   using std::swap;
-  lidar_ids_.InternalSwap(&other->lidar_ids_);
+  lidar_exts_.InternalSwap(&other->lidar_exts_);
   swap(minx_, other->minx_);
   swap(maxx_, other->maxx_);
   swap(miny_, other->miny_);

+ 340 - 128
velodyne_lidar/velodyne_config.pb.h

@@ -36,7 +36,7 @@ namespace protobuf_velodyne_5fconfig_2eproto {
 struct TableStruct {
   static const ::google::protobuf::internal::ParseTableField entries[];
   static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
-  static const ::google::protobuf::internal::ParseTable schema[4];
+  static const ::google::protobuf::internal::ParseTable schema[5];
   static const ::google::protobuf::internal::FieldMetadata field_metadata[];
   static const ::google::protobuf::internal::SerializationTable serialization_table[];
   static const ::google::protobuf::uint32 offsets[];
@@ -46,24 +46,30 @@ void InitDefaultsvelodyneManagerParamsImpl();
 void InitDefaultsvelodyneManagerParams();
 void InitDefaultsvelodyneLidarParamsImpl();
 void InitDefaultsvelodyneLidarParams();
-void InitDefaultsCalib_parameterImpl();
-void InitDefaultsCalib_parameter();
+void InitDefaultsCalibParameterImpl();
+void InitDefaultsCalibParameter();
+void InitDefaultslidarExtrinsicImpl();
+void InitDefaultslidarExtrinsic();
 void InitDefaultsRegionImpl();
 void InitDefaultsRegion();
 inline void InitDefaults() {
   InitDefaultsvelodyneManagerParams();
   InitDefaultsvelodyneLidarParams();
-  InitDefaultsCalib_parameter();
+  InitDefaultsCalibParameter();
+  InitDefaultslidarExtrinsic();
   InitDefaultsRegion();
 }
 }  // namespace protobuf_velodyne_5fconfig_2eproto
 namespace velodyne {
-class Calib_parameter;
-class Calib_parameterDefaultTypeInternal;
-extern Calib_parameterDefaultTypeInternal _Calib_parameter_default_instance_;
+class CalibParameter;
+class CalibParameterDefaultTypeInternal;
+extern CalibParameterDefaultTypeInternal _CalibParameter_default_instance_;
 class Region;
 class RegionDefaultTypeInternal;
 extern RegionDefaultTypeInternal _Region_default_instance_;
+class lidarExtrinsic;
+class lidarExtrinsicDefaultTypeInternal;
+extern lidarExtrinsicDefaultTypeInternal _lidarExtrinsic_default_instance_;
 class velodyneLidarParams;
 class velodyneLidarParamsDefaultTypeInternal;
 extern velodyneLidarParamsDefaultTypeInternal _velodyneLidarParams_default_instance_;
@@ -417,14 +423,14 @@ class velodyneLidarParams : public ::google::protobuf::Message /* @@protoc_inser
   ::std::string* release_calibrationfile();
   void set_allocated_calibrationfile(::std::string* calibrationfile);
 
-  // optional .velodyne.Calib_parameter calib = 11;
+  // optional .velodyne.CalibParameter calib = 11;
   bool has_calib() const;
   void clear_calib();
   static const int kCalibFieldNumber = 11;
-  const ::velodyne::Calib_parameter& calib() const;
-  ::velodyne::Calib_parameter* release_calib();
-  ::velodyne::Calib_parameter* mutable_calib();
-  void set_allocated_calib(::velodyne::Calib_parameter* calib);
+  const ::velodyne::CalibParameter& calib() const;
+  ::velodyne::CalibParameter* release_calib();
+  ::velodyne::CalibParameter* mutable_calib();
+  void set_allocated_calib(::velodyne::CalibParameter* calib);
 
   // required int32 lidar_id = 5 [default = 0];
   bool has_lidar_id() const;
@@ -510,7 +516,7 @@ class velodyneLidarParams : public ::google::protobuf::Message /* @@protoc_inser
   static ::google::protobuf::internal::ExplicitlyConstructed< ::std::string> _default_model_;
   ::google::protobuf::internal::ArenaStringPtr model_;
   ::google::protobuf::internal::ArenaStringPtr calibrationfile_;
-  ::velodyne::Calib_parameter* calib_;
+  ::velodyne::CalibParameter* calib_;
   ::google::protobuf::int32 lidar_id_;
   ::google::protobuf::int32 min_angle_;
   ::google::protobuf::int32 rpm_;
@@ -523,24 +529,24 @@ class velodyneLidarParams : public ::google::protobuf::Message /* @@protoc_inser
 };
 // -------------------------------------------------------------------
 
-class Calib_parameter : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:velodyne.Calib_parameter) */ {
+class CalibParameter : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:velodyne.CalibParameter) */ {
  public:
-  Calib_parameter();
-  virtual ~Calib_parameter();
+  CalibParameter();
+  virtual ~CalibParameter();
 
-  Calib_parameter(const Calib_parameter& from);
+  CalibParameter(const CalibParameter& from);
 
-  inline Calib_parameter& operator=(const Calib_parameter& from) {
+  inline CalibParameter& operator=(const CalibParameter& from) {
     CopyFrom(from);
     return *this;
   }
   #if LANG_CXX11
-  Calib_parameter(Calib_parameter&& from) noexcept
-    : Calib_parameter() {
+  CalibParameter(CalibParameter&& from) noexcept
+    : CalibParameter() {
     *this = ::std::move(from);
   }
 
-  inline Calib_parameter& operator=(Calib_parameter&& from) noexcept {
+  inline CalibParameter& operator=(CalibParameter&& from) noexcept {
     if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
       if (this != &from) InternalSwap(&from);
     } else {
@@ -557,30 +563,30 @@ class Calib_parameter : public ::google::protobuf::Message /* @@protoc_insertion
   }
 
   static const ::google::protobuf::Descriptor* descriptor();
-  static const Calib_parameter& default_instance();
+  static const CalibParameter& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
-  static inline const Calib_parameter* internal_default_instance() {
-    return reinterpret_cast<const Calib_parameter*>(
-               &_Calib_parameter_default_instance_);
+  static inline const CalibParameter* internal_default_instance() {
+    return reinterpret_cast<const CalibParameter*>(
+               &_CalibParameter_default_instance_);
   }
   static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
     2;
 
-  void Swap(Calib_parameter* other);
-  friend void swap(Calib_parameter& a, Calib_parameter& b) {
+  void Swap(CalibParameter* other);
+  friend void swap(CalibParameter& a, CalibParameter& b) {
     a.Swap(&b);
   }
 
   // implements Message ----------------------------------------------
 
-  inline Calib_parameter* New() const PROTOBUF_FINAL { return New(NULL); }
+  inline CalibParameter* New() const PROTOBUF_FINAL { return New(NULL); }
 
-  Calib_parameter* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
+  CalibParameter* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
   void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
   void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
-  void CopyFrom(const Calib_parameter& from);
-  void MergeFrom(const Calib_parameter& from);
+  void CopyFrom(const CalibParameter& from);
+  void MergeFrom(const CalibParameter& from);
   void Clear() PROTOBUF_FINAL;
   bool IsInitialized() const PROTOBUF_FINAL;
 
@@ -596,7 +602,7 @@ class Calib_parameter : public ::google::protobuf::Message /* @@protoc_insertion
   void SharedCtor();
   void SharedDtor();
   void SetCachedSize(int size) const PROTOBUF_FINAL;
-  void InternalSwap(Calib_parameter* other);
+  void InternalSwap(CalibParameter* other);
   private:
   inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
     return NULL;
@@ -654,7 +660,7 @@ class Calib_parameter : public ::google::protobuf::Message /* @@protoc_insertion
   float cz() const;
   void set_cz(float value);
 
-  // @@protoc_insertion_point(class_scope:velodyne.Calib_parameter)
+  // @@protoc_insertion_point(class_scope:velodyne.CalibParameter)
  private:
   void set_has_r();
   void clear_has_r();
@@ -679,7 +685,129 @@ class Calib_parameter : public ::google::protobuf::Message /* @@protoc_insertion
   float cy_;
   float cz_;
   friend struct ::protobuf_velodyne_5fconfig_2eproto::TableStruct;
-  friend void ::protobuf_velodyne_5fconfig_2eproto::InitDefaultsCalib_parameterImpl();
+  friend void ::protobuf_velodyne_5fconfig_2eproto::InitDefaultsCalibParameterImpl();
+};
+// -------------------------------------------------------------------
+
+class lidarExtrinsic : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:velodyne.lidarExtrinsic) */ {
+ public:
+  lidarExtrinsic();
+  virtual ~lidarExtrinsic();
+
+  lidarExtrinsic(const lidarExtrinsic& from);
+
+  inline lidarExtrinsic& operator=(const lidarExtrinsic& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  lidarExtrinsic(lidarExtrinsic&& from) noexcept
+    : lidarExtrinsic() {
+    *this = ::std::move(from);
+  }
+
+  inline lidarExtrinsic& operator=(lidarExtrinsic&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _internal_metadata_.unknown_fields();
+  }
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _internal_metadata_.mutable_unknown_fields();
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const lidarExtrinsic& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const lidarExtrinsic* internal_default_instance() {
+    return reinterpret_cast<const lidarExtrinsic*>(
+               &_lidarExtrinsic_default_instance_);
+  }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    3;
+
+  void Swap(lidarExtrinsic* other);
+  friend void swap(lidarExtrinsic& a, lidarExtrinsic& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline lidarExtrinsic* New() const PROTOBUF_FINAL { return New(NULL); }
+
+  lidarExtrinsic* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
+  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+  void CopyFrom(const lidarExtrinsic& from);
+  void MergeFrom(const lidarExtrinsic& from);
+  void Clear() PROTOBUF_FINAL;
+  bool IsInitialized() const PROTOBUF_FINAL;
+
+  size_t ByteSizeLong() const PROTOBUF_FINAL;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
+  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const PROTOBUF_FINAL;
+  void InternalSwap(lidarExtrinsic* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return NULL;
+  }
+  inline void* MaybeArenaPtr() const {
+    return NULL;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional .velodyne.CalibParameter calib = 2;
+  bool has_calib() const;
+  void clear_calib();
+  static const int kCalibFieldNumber = 2;
+  const ::velodyne::CalibParameter& calib() const;
+  ::velodyne::CalibParameter* release_calib();
+  ::velodyne::CalibParameter* mutable_calib();
+  void set_allocated_calib(::velodyne::CalibParameter* calib);
+
+  // required int32 lidar_id = 1;
+  bool has_lidar_id() const;
+  void clear_lidar_id();
+  static const int kLidarIdFieldNumber = 1;
+  ::google::protobuf::int32 lidar_id() const;
+  void set_lidar_id(::google::protobuf::int32 value);
+
+  // @@protoc_insertion_point(class_scope:velodyne.lidarExtrinsic)
+ private:
+  void set_has_lidar_id();
+  void clear_has_lidar_id();
+  void set_has_calib();
+  void clear_has_calib();
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::HasBits<1> _has_bits_;
+  mutable int _cached_size_;
+  ::velodyne::CalibParameter* calib_;
+  ::google::protobuf::int32 lidar_id_;
+  friend struct ::protobuf_velodyne_5fconfig_2eproto::TableStruct;
+  friend void ::protobuf_velodyne_5fconfig_2eproto::InitDefaultslidarExtrinsicImpl();
 };
 // -------------------------------------------------------------------
 
@@ -725,7 +853,7 @@ class Region : public ::google::protobuf::Message /* @@protoc_insertion_point(cl
                &_Region_default_instance_);
   }
   static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
-    3;
+    4;
 
   void Swap(Region* other);
   friend void swap(Region& a, Region& b) {
@@ -772,17 +900,17 @@ class Region : public ::google::protobuf::Message /* @@protoc_insertion_point(cl
 
   // accessors -------------------------------------------------------
 
-  // repeated int32 lidar_ids = 8;
-  int lidar_ids_size() const;
-  void clear_lidar_ids();
-  static const int kLidarIdsFieldNumber = 8;
-  ::google::protobuf::int32 lidar_ids(int index) const;
-  void set_lidar_ids(int index, ::google::protobuf::int32 value);
-  void add_lidar_ids(::google::protobuf::int32 value);
-  const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
-      lidar_ids() const;
-  ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
-      mutable_lidar_ids();
+  // repeated .velodyne.lidarExtrinsic lidar_exts = 8;
+  int lidar_exts_size() const;
+  void clear_lidar_exts();
+  static const int kLidarExtsFieldNumber = 8;
+  const ::velodyne::lidarExtrinsic& lidar_exts(int index) const;
+  ::velodyne::lidarExtrinsic* mutable_lidar_exts(int index);
+  ::velodyne::lidarExtrinsic* add_lidar_exts();
+  ::google::protobuf::RepeatedPtrField< ::velodyne::lidarExtrinsic >*
+      mutable_lidar_exts();
+  const ::google::protobuf::RepeatedPtrField< ::velodyne::lidarExtrinsic >&
+      lidar_exts() const;
 
   // required float minx = 1;
   bool has_minx() const;
@@ -856,7 +984,7 @@ class Region : public ::google::protobuf::Message /* @@protoc_insertion_point(cl
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   ::google::protobuf::internal::HasBits<1> _has_bits_;
   mutable int _cached_size_;
-  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > lidar_ids_;
+  ::google::protobuf::RepeatedPtrField< ::velodyne::lidarExtrinsic > lidar_exts_;
   float minx_;
   float maxx_;
   float miny_;
@@ -1575,7 +1703,7 @@ inline void velodyneLidarParams::set_rpm(::google::protobuf::int32 value) {
   // @@protoc_insertion_point(field_set:velodyne.velodyneLidarParams.rpm)
 }
 
-// optional .velodyne.Calib_parameter calib = 11;
+// optional .velodyne.CalibParameter calib = 11;
 inline bool velodyneLidarParams::has_calib() const {
   return (_has_bits_[0] & 0x00000008u) != 0;
 }
@@ -1589,28 +1717,28 @@ inline void velodyneLidarParams::clear_calib() {
   if (calib_ != NULL) calib_->Clear();
   clear_has_calib();
 }
-inline const ::velodyne::Calib_parameter& velodyneLidarParams::calib() const {
-  const ::velodyne::Calib_parameter* p = calib_;
+inline const ::velodyne::CalibParameter& velodyneLidarParams::calib() const {
+  const ::velodyne::CalibParameter* p = calib_;
   // @@protoc_insertion_point(field_get:velodyne.velodyneLidarParams.calib)
-  return p != NULL ? *p : *reinterpret_cast<const ::velodyne::Calib_parameter*>(
-      &::velodyne::_Calib_parameter_default_instance_);
+  return p != NULL ? *p : *reinterpret_cast<const ::velodyne::CalibParameter*>(
+      &::velodyne::_CalibParameter_default_instance_);
 }
-inline ::velodyne::Calib_parameter* velodyneLidarParams::release_calib() {
+inline ::velodyne::CalibParameter* velodyneLidarParams::release_calib() {
   // @@protoc_insertion_point(field_release:velodyne.velodyneLidarParams.calib)
   clear_has_calib();
-  ::velodyne::Calib_parameter* temp = calib_;
+  ::velodyne::CalibParameter* temp = calib_;
   calib_ = NULL;
   return temp;
 }
-inline ::velodyne::Calib_parameter* velodyneLidarParams::mutable_calib() {
+inline ::velodyne::CalibParameter* velodyneLidarParams::mutable_calib() {
   set_has_calib();
   if (calib_ == NULL) {
-    calib_ = new ::velodyne::Calib_parameter;
+    calib_ = new ::velodyne::CalibParameter;
   }
   // @@protoc_insertion_point(field_mutable:velodyne.velodyneLidarParams.calib)
   return calib_;
 }
-inline void velodyneLidarParams::set_allocated_calib(::velodyne::Calib_parameter* calib) {
+inline void velodyneLidarParams::set_allocated_calib(::velodyne::CalibParameter* calib) {
   ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
   if (message_arena == NULL) {
     delete calib_;
@@ -1631,150 +1759,232 @@ inline void velodyneLidarParams::set_allocated_calib(::velodyne::Calib_parameter
 
 // -------------------------------------------------------------------
 
-// Calib_parameter
+// CalibParameter
 
 // optional float r = 1 [default = 0];
-inline bool Calib_parameter::has_r() const {
+inline bool CalibParameter::has_r() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void Calib_parameter::set_has_r() {
+inline void CalibParameter::set_has_r() {
   _has_bits_[0] |= 0x00000001u;
 }
-inline void Calib_parameter::clear_has_r() {
+inline void CalibParameter::clear_has_r() {
   _has_bits_[0] &= ~0x00000001u;
 }
-inline void Calib_parameter::clear_r() {
+inline void CalibParameter::clear_r() {
   r_ = 0;
   clear_has_r();
 }
-inline float Calib_parameter::r() const {
-  // @@protoc_insertion_point(field_get:velodyne.Calib_parameter.r)
+inline float CalibParameter::r() const {
+  // @@protoc_insertion_point(field_get:velodyne.CalibParameter.r)
   return r_;
 }
-inline void Calib_parameter::set_r(float value) {
+inline void CalibParameter::set_r(float value) {
   set_has_r();
   r_ = value;
-  // @@protoc_insertion_point(field_set:velodyne.Calib_parameter.r)
+  // @@protoc_insertion_point(field_set:velodyne.CalibParameter.r)
 }
 
 // optional float p = 2 [default = 0];
-inline bool Calib_parameter::has_p() const {
+inline bool CalibParameter::has_p() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void Calib_parameter::set_has_p() {
+inline void CalibParameter::set_has_p() {
   _has_bits_[0] |= 0x00000002u;
 }
-inline void Calib_parameter::clear_has_p() {
+inline void CalibParameter::clear_has_p() {
   _has_bits_[0] &= ~0x00000002u;
 }
-inline void Calib_parameter::clear_p() {
+inline void CalibParameter::clear_p() {
   p_ = 0;
   clear_has_p();
 }
-inline float Calib_parameter::p() const {
-  // @@protoc_insertion_point(field_get:velodyne.Calib_parameter.p)
+inline float CalibParameter::p() const {
+  // @@protoc_insertion_point(field_get:velodyne.CalibParameter.p)
   return p_;
 }
-inline void Calib_parameter::set_p(float value) {
+inline void CalibParameter::set_p(float value) {
   set_has_p();
   p_ = value;
-  // @@protoc_insertion_point(field_set:velodyne.Calib_parameter.p)
+  // @@protoc_insertion_point(field_set:velodyne.CalibParameter.p)
 }
 
 // optional float y = 3 [default = 0];
-inline bool Calib_parameter::has_y() const {
+inline bool CalibParameter::has_y() const {
   return (_has_bits_[0] & 0x00000004u) != 0;
 }
-inline void Calib_parameter::set_has_y() {
+inline void CalibParameter::set_has_y() {
   _has_bits_[0] |= 0x00000004u;
 }
-inline void Calib_parameter::clear_has_y() {
+inline void CalibParameter::clear_has_y() {
   _has_bits_[0] &= ~0x00000004u;
 }
-inline void Calib_parameter::clear_y() {
+inline void CalibParameter::clear_y() {
   y_ = 0;
   clear_has_y();
 }
-inline float Calib_parameter::y() const {
-  // @@protoc_insertion_point(field_get:velodyne.Calib_parameter.y)
+inline float CalibParameter::y() const {
+  // @@protoc_insertion_point(field_get:velodyne.CalibParameter.y)
   return y_;
 }
-inline void Calib_parameter::set_y(float value) {
+inline void CalibParameter::set_y(float value) {
   set_has_y();
   y_ = value;
-  // @@protoc_insertion_point(field_set:velodyne.Calib_parameter.y)
+  // @@protoc_insertion_point(field_set:velodyne.CalibParameter.y)
 }
 
 // optional float cx = 4 [default = 0];
-inline bool Calib_parameter::has_cx() const {
+inline bool CalibParameter::has_cx() const {
   return (_has_bits_[0] & 0x00000008u) != 0;
 }
-inline void Calib_parameter::set_has_cx() {
+inline void CalibParameter::set_has_cx() {
   _has_bits_[0] |= 0x00000008u;
 }
-inline void Calib_parameter::clear_has_cx() {
+inline void CalibParameter::clear_has_cx() {
   _has_bits_[0] &= ~0x00000008u;
 }
-inline void Calib_parameter::clear_cx() {
+inline void CalibParameter::clear_cx() {
   cx_ = 0;
   clear_has_cx();
 }
-inline float Calib_parameter::cx() const {
-  // @@protoc_insertion_point(field_get:velodyne.Calib_parameter.cx)
+inline float CalibParameter::cx() const {
+  // @@protoc_insertion_point(field_get:velodyne.CalibParameter.cx)
   return cx_;
 }
-inline void Calib_parameter::set_cx(float value) {
+inline void CalibParameter::set_cx(float value) {
   set_has_cx();
   cx_ = value;
-  // @@protoc_insertion_point(field_set:velodyne.Calib_parameter.cx)
+  // @@protoc_insertion_point(field_set:velodyne.CalibParameter.cx)
 }
 
 // optional float cy = 5 [default = 0];
-inline bool Calib_parameter::has_cy() const {
+inline bool CalibParameter::has_cy() const {
   return (_has_bits_[0] & 0x00000010u) != 0;
 }
-inline void Calib_parameter::set_has_cy() {
+inline void CalibParameter::set_has_cy() {
   _has_bits_[0] |= 0x00000010u;
 }
-inline void Calib_parameter::clear_has_cy() {
+inline void CalibParameter::clear_has_cy() {
   _has_bits_[0] &= ~0x00000010u;
 }
-inline void Calib_parameter::clear_cy() {
+inline void CalibParameter::clear_cy() {
   cy_ = 0;
   clear_has_cy();
 }
-inline float Calib_parameter::cy() const {
-  // @@protoc_insertion_point(field_get:velodyne.Calib_parameter.cy)
+inline float CalibParameter::cy() const {
+  // @@protoc_insertion_point(field_get:velodyne.CalibParameter.cy)
   return cy_;
 }
-inline void Calib_parameter::set_cy(float value) {
+inline void CalibParameter::set_cy(float value) {
   set_has_cy();
   cy_ = value;
-  // @@protoc_insertion_point(field_set:velodyne.Calib_parameter.cy)
+  // @@protoc_insertion_point(field_set:velodyne.CalibParameter.cy)
 }
 
 // optional float cz = 6 [default = 0];
-inline bool Calib_parameter::has_cz() const {
+inline bool CalibParameter::has_cz() const {
   return (_has_bits_[0] & 0x00000020u) != 0;
 }
-inline void Calib_parameter::set_has_cz() {
+inline void CalibParameter::set_has_cz() {
   _has_bits_[0] |= 0x00000020u;
 }
-inline void Calib_parameter::clear_has_cz() {
+inline void CalibParameter::clear_has_cz() {
   _has_bits_[0] &= ~0x00000020u;
 }
-inline void Calib_parameter::clear_cz() {
+inline void CalibParameter::clear_cz() {
   cz_ = 0;
   clear_has_cz();
 }
-inline float Calib_parameter::cz() const {
-  // @@protoc_insertion_point(field_get:velodyne.Calib_parameter.cz)
+inline float CalibParameter::cz() const {
+  // @@protoc_insertion_point(field_get:velodyne.CalibParameter.cz)
   return cz_;
 }
-inline void Calib_parameter::set_cz(float value) {
+inline void CalibParameter::set_cz(float value) {
   set_has_cz();
   cz_ = value;
-  // @@protoc_insertion_point(field_set:velodyne.Calib_parameter.cz)
+  // @@protoc_insertion_point(field_set:velodyne.CalibParameter.cz)
+}
+
+// -------------------------------------------------------------------
+
+// lidarExtrinsic
+
+// required int32 lidar_id = 1;
+inline bool lidarExtrinsic::has_lidar_id() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void lidarExtrinsic::set_has_lidar_id() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void lidarExtrinsic::clear_has_lidar_id() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void lidarExtrinsic::clear_lidar_id() {
+  lidar_id_ = 0;
+  clear_has_lidar_id();
+}
+inline ::google::protobuf::int32 lidarExtrinsic::lidar_id() const {
+  // @@protoc_insertion_point(field_get:velodyne.lidarExtrinsic.lidar_id)
+  return lidar_id_;
+}
+inline void lidarExtrinsic::set_lidar_id(::google::protobuf::int32 value) {
+  set_has_lidar_id();
+  lidar_id_ = value;
+  // @@protoc_insertion_point(field_set:velodyne.lidarExtrinsic.lidar_id)
+}
+
+// optional .velodyne.CalibParameter calib = 2;
+inline bool lidarExtrinsic::has_calib() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void lidarExtrinsic::set_has_calib() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void lidarExtrinsic::clear_has_calib() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void lidarExtrinsic::clear_calib() {
+  if (calib_ != NULL) calib_->Clear();
+  clear_has_calib();
+}
+inline const ::velodyne::CalibParameter& lidarExtrinsic::calib() const {
+  const ::velodyne::CalibParameter* p = calib_;
+  // @@protoc_insertion_point(field_get:velodyne.lidarExtrinsic.calib)
+  return p != NULL ? *p : *reinterpret_cast<const ::velodyne::CalibParameter*>(
+      &::velodyne::_CalibParameter_default_instance_);
+}
+inline ::velodyne::CalibParameter* lidarExtrinsic::release_calib() {
+  // @@protoc_insertion_point(field_release:velodyne.lidarExtrinsic.calib)
+  clear_has_calib();
+  ::velodyne::CalibParameter* temp = calib_;
+  calib_ = NULL;
+  return temp;
+}
+inline ::velodyne::CalibParameter* lidarExtrinsic::mutable_calib() {
+  set_has_calib();
+  if (calib_ == NULL) {
+    calib_ = new ::velodyne::CalibParameter;
+  }
+  // @@protoc_insertion_point(field_mutable:velodyne.lidarExtrinsic.calib)
+  return calib_;
+}
+inline void lidarExtrinsic::set_allocated_calib(::velodyne::CalibParameter* calib) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == NULL) {
+    delete calib_;
+  }
+  if (calib) {
+    ::google::protobuf::Arena* submessage_arena = NULL;
+    if (message_arena != submessage_arena) {
+      calib = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, calib, submessage_arena);
+    }
+    set_has_calib();
+  } else {
+    clear_has_calib();
+  }
+  calib_ = calib;
+  // @@protoc_insertion_point(field_set_allocated:velodyne.lidarExtrinsic.calib)
 }
 
 // -------------------------------------------------------------------
@@ -1949,34 +2159,34 @@ inline void Region::set_region_id(::google::protobuf::int32 value) {
   // @@protoc_insertion_point(field_set:velodyne.Region.region_id)
 }
 
-// repeated int32 lidar_ids = 8;
-inline int Region::lidar_ids_size() const {
-  return lidar_ids_.size();
+// repeated .velodyne.lidarExtrinsic lidar_exts = 8;
+inline int Region::lidar_exts_size() const {
+  return lidar_exts_.size();
 }
-inline void Region::clear_lidar_ids() {
-  lidar_ids_.Clear();
+inline void Region::clear_lidar_exts() {
+  lidar_exts_.Clear();
 }
-inline ::google::protobuf::int32 Region::lidar_ids(int index) const {
-  // @@protoc_insertion_point(field_get:velodyne.Region.lidar_ids)
-  return lidar_ids_.Get(index);
+inline const ::velodyne::lidarExtrinsic& Region::lidar_exts(int index) const {
+  // @@protoc_insertion_point(field_get:velodyne.Region.lidar_exts)
+  return lidar_exts_.Get(index);
 }
-inline void Region::set_lidar_ids(int index, ::google::protobuf::int32 value) {
-  lidar_ids_.Set(index, value);
-  // @@protoc_insertion_point(field_set:velodyne.Region.lidar_ids)
+inline ::velodyne::lidarExtrinsic* Region::mutable_lidar_exts(int index) {
+  // @@protoc_insertion_point(field_mutable:velodyne.Region.lidar_exts)
+  return lidar_exts_.Mutable(index);
 }
-inline void Region::add_lidar_ids(::google::protobuf::int32 value) {
-  lidar_ids_.Add(value);
-  // @@protoc_insertion_point(field_add:velodyne.Region.lidar_ids)
+inline ::velodyne::lidarExtrinsic* Region::add_lidar_exts() {
+  // @@protoc_insertion_point(field_add:velodyne.Region.lidar_exts)
+  return lidar_exts_.Add();
 }
-inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
-Region::lidar_ids() const {
-  // @@protoc_insertion_point(field_list:velodyne.Region.lidar_ids)
-  return lidar_ids_;
+inline ::google::protobuf::RepeatedPtrField< ::velodyne::lidarExtrinsic >*
+Region::mutable_lidar_exts() {
+  // @@protoc_insertion_point(field_mutable_list:velodyne.Region.lidar_exts)
+  return &lidar_exts_;
 }
-inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
-Region::mutable_lidar_ids() {
-  // @@protoc_insertion_point(field_mutable_list:velodyne.Region.lidar_ids)
-  return &lidar_ids_;
+inline const ::google::protobuf::RepeatedPtrField< ::velodyne::lidarExtrinsic >&
+Region::lidar_exts() const {
+  // @@protoc_insertion_point(field_list:velodyne.Region.lidar_exts)
+  return lidar_exts_;
 }
 
 #ifdef __GNUC__
@@ -1988,6 +2198,8 @@ Region::mutable_lidar_ids() {
 
 // -------------------------------------------------------------------
 
+// -------------------------------------------------------------------
+
 
 // @@protoc_insertion_point(namespace_scope)
 

+ 9 - 3
velodyne_lidar/velodyne_config.proto

@@ -24,10 +24,10 @@ message velodyneLidarParams
     optional int32 min_angle=8[default=0];
     optional int32 max_angle=9[default=360];
     optional int32 rpm=10[default=600];
-    optional Calib_parameter calib=11;
+    optional CalibParameter calib=11;
 }
 
-message Calib_parameter
+message CalibParameter
 {
     optional float r=1 [default=0];
     optional float p=2 [default=0];
@@ -37,6 +37,12 @@ message Calib_parameter
     optional float cz=6 [default=0];
 }
 
+message lidarExtrinsic
+{
+    required int32 lidar_id=1;
+    optional CalibParameter calib=2;
+}
+
 message Region
 {
     required float minx=1;
@@ -46,5 +52,5 @@ message Region
     required float minz=5;
     required float maxz=6;
     required int32 region_id=7;
-    repeated int32 lidar_ids=8;
+    repeated lidarExtrinsic lidar_exts=8;
 }

+ 3 - 3
velodyne_lidar/velodyne_driver/input.cc

@@ -146,17 +146,17 @@ namespace velodyne_driver
         if (retval < 0) // poll() error?
         {
           if (errno != EINTR)
-            LOG(ERROR) << "poll() error:" << strerror(errno);
+            LOG(ERROR) << m_port << " poll() error:" << strerror(errno);
           return -1;
         }
         if (retval == 0) // poll() timeout?
         {
-          LOG(WARNING) << "Velodyne poll() timeout";
+          LOG_EVERY_N(WARNING, 1) << "Velodyne poll() timeout "<<m_port;
           return -1;
         }
         if ((fds[0].revents & POLLERR) || (fds[0].revents & POLLHUP) || (fds[0].revents & POLLNVAL)) // device error?
         {
-          LOG(ERROR) << "poll() reports Velodyne error";
+          LOG(ERROR) << "poll() reports Velodyne error " << m_port;
           return -1;
         }
       } while ((fds[0].revents & POLLIN) == 0);

+ 9 - 9
velodyne_lidar/velodyne_driver/rawdata.cc

@@ -223,15 +223,15 @@ namespace velodyne_rawdata
 
     if (timing_offsets.size())
     {
-      // ROS_INFO("VELODYNE TIMING TABLE:");
-      for (size_t x = 0; x < timing_offsets.size(); ++x)
-      {
-        for (size_t y = 0; y < timing_offsets[x].size(); ++y)
-        {
-          printf("%04.3f ", timing_offsets[x][y] * 1e6);
-        }
-        printf("\n");
-      }
+      // // ROS_INFO("VELODYNE TIMING TABLE:");
+      // for (size_t x = 0; x < timing_offsets.size(); ++x)
+      // {
+      //   for (size_t y = 0; y < timing_offsets[x].size(); ++y)
+      //   {
+      //     printf("%04.3f ", timing_offsets[x][y] * 1e6);
+      //   }
+      //   printf("\n");
+      // }
       return true;
     }
     else

+ 108 - 15
velodyne_lidar/velodyne_manager.cpp

@@ -2,7 +2,7 @@
  * @Description: 
  * @Author: yct
  * @Date: 2021-07-23 16:39:04
- * @LastEditTime: 2021-08-01 16:34:26
+ * @LastEditTime: 2021-09-01 09:14:32
  * @LastEditors: yct
  */
 #include "velodyne_manager.h"
@@ -37,7 +37,7 @@ Error_manager Velodyne_manager::velodyne_manager_init_from_protobuf(velodyne::ve
 							 " velodyne_manager::velodyne_manager_init_from_protobuf init repeat error ");
 	}
 	m_terminal_id = terminal;
-	mp_cloud_collection = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
+	// mp_cloud_collection = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
 
 	// 判断参数合法性
 	if(!velodyne_parameters.has_left_model_path() || ! velodyne_parameters.has_right_model_path())
@@ -65,9 +65,9 @@ Error_manager Velodyne_manager::velodyne_manager_init_from_protobuf(velodyne::ve
 			// 分布式模式记录待创建雷达编号
 			if(velodyne_parameters.distribution_mode())
 			{
-				for (size_t j = 0; j < velodyne_parameters.region(i).lidar_ids_size(); j++)
+				for (size_t j = 0; j < velodyne_parameters.region(i).lidar_exts_size(); j++)
 				{
-					lidar_selection_set.emplace(velodyne_parameters.region(i).lidar_ids(j));
+					lidar_selection_set.emplace(velodyne_parameters.region(i).lidar_exts(j).lidar_id());
 				}
 			}
 
@@ -79,6 +79,7 @@ Error_manager Velodyne_manager::velodyne_manager_init_from_protobuf(velodyne::ve
 				return t_error;
 			}
 			m_ground_region_map[velodyne_parameters.region(i).region_id()] = p_ground_region;
+			LOG(WARNING) << "ground region " << std::to_string(velodyne_parameters.region(i).region_id()) << " created!!!";
 		}
 	}
 	// 检查是否存在该区域
@@ -103,6 +104,32 @@ Error_manager Velodyne_manager::velodyne_manager_init_from_protobuf(velodyne::ve
 				return t_error;
 			}
 			m_velodyne_lidar_device_map[velodyne_parameters.velodyne_lidars(i).lidar_id()] = p_velodyne_lidar_device;
+			LOG(WARNING) << "velodyne lidar " << std::to_string(velodyne_parameters.velodyne_lidars(i).lidar_id()) << " created!!!";
+
+			// 根据创建的雷达与区域,初始化点云缓存map
+			for (std::map<int, Ground_region *>::iterator iter = m_ground_region_map.begin(); iter != m_ground_region_map.end(); iter++)
+			{
+				velodyne::Region t_region_param = iter->second->get_param();
+				std::string t_region_lidar_key = generate_region_lidar_key(iter->first, velodyne_parameters.velodyne_lidars(i).lidar_id());
+				// 遍历区域内激光内参列表,找到lidar_id对应内参
+				for (size_t j = 0; j < t_region_param.lidar_exts_size(); j++)
+				{
+					if(t_region_param.lidar_exts(j).lidar_id() == velodyne_parameters.velodyne_lidars(i).lidar_id())
+					{
+						// 未找到则创建
+						if (m_region_laser_to_cloud_collection_map.find(t_region_lidar_key) == m_region_laser_to_cloud_collection_map.end())
+						{
+							m_region_laser_to_cloud_collection_map.emplace(std::pair<std::string,
+																					 std::shared_ptr<Timestamped_cloud>>(t_region_lidar_key, std::shared_ptr<Timestamped_cloud>(new Timestamped_cloud(t_region_param.lidar_exts(j).calib()))));
+							LOG(WARNING) << "pair of (lidar " << std::to_string(velodyne_parameters.velodyne_lidars(i).lidar_id()) <<", region "<<std::to_string(iter->first) << ") created!!!";
+						}
+						else
+						{
+							LOG(ERROR) << "region lidar repeated? " << t_region_lidar_key;
+						}
+					}
+				}
+			}
 		}
 	}
 	// 检查设备与区域个数,不可为0
@@ -324,32 +351,69 @@ void Velodyne_manager::collect_cloud_thread_fun()
 		if ( m_collect_cloud_condition.is_alive() )
 		{
 			{
-				//全局加锁, 并清空点云.
+				//全局加锁
 				std::unique_lock<std::mutex> t_lock(m_cloud_collection_mutex);
-				mp_cloud_collection->clear();
+				// mp_cloud_collection->clear();
 
 				//重新收集最近的点云, 不允许阻塞
 				// added by yct, 测试雷达功能
-//				int get_cloud_count=0;
+				//				int get_cloud_count=0;
+				pcl::PointCloud<pcl::PointXYZ>::Ptr t_cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
 				for (auto iter = m_velodyne_lidar_device_map.begin(); iter != m_velodyne_lidar_device_map.end(); ++iter)
 				{
-					t_error = iter->second->get_last_cloud(mp_cloud_collection, std::chrono::steady_clock::now());
-					if ( t_error != Error_code::SUCCESS )
+					t_cloud->clear();
+					t_error = iter->second->get_last_cloud(t_cloud, std::chrono::steady_clock::now());
+					if (t_error != Error_code::SUCCESS)
 					{
 						t_result.compare_and_cover_error(t_error);
-//						LOG(WARNING) << "cloud timeout: "<<get_cloud_count;
+						//						LOG(WARNING) << "cloud timeout: "<<get_cloud_count;
+						// 将该雷达对应所有区域点云清空
+					}
+					//                    get_cloud_count++;
+					
+					// 点云放入对应缓存
+					for (std::map<int, Ground_region *>::iterator iter_region = m_ground_region_map.begin(); iter_region != m_ground_region_map.end(); iter_region++)
+					{
+						if (!iter_region->second->check_lidar_inside(iter->first))
+							continue;
+						std::string t_region_lidar_key = generate_region_lidar_key(iter_region->first, iter->first);
+						// 未找到则报错
+						if (m_region_laser_to_cloud_collection_map.find(t_region_lidar_key) == m_region_laser_to_cloud_collection_map.end())
+						{
+							// m_region_laser_to_cloud_collection_map.emplace(std::pair<std::string,
+							// 														 std::shared_ptr<Timestamped_cloud>>(t_region_lidar_key, std::shared_ptr<Timestamped_cloud>(new Timestamped_cloud())));
+							// if (t_error != SUCCESS)
+							// {
+							// 	m_region_laser_to_cloud_collection_map[t_region_lidar_key]->clearCloud();
+							// }
+							// else
+							// {
+							// 	m_region_laser_to_cloud_collection_map[t_region_lidar_key]->setCloud(t_cloud);
+							// }
+							LOG(ERROR) << "current lidar cloud not initialized: " << t_region_lidar_key;
+						}
+						else
+						{
+							if (t_error != SUCCESS)
+							{
+								m_region_laser_to_cloud_collection_map[t_region_lidar_key]->clearCloud();
+							}
+							else
+							{
+								m_region_laser_to_cloud_collection_map[t_region_lidar_key]->setCloud(t_cloud);
+							}
+						}
 					}
-//                    get_cloud_count++;
 				}
-				if ( t_result == SUCCESS && mp_cloud_collection->size()>0 )
+				if ( t_result == SUCCESS)
 				{
-					m_cloud_update_time = std::chrono::system_clock::now();
+					// m_cloud_update_time = std::chrono::system_clock::now();
 					//成功则唤醒预测算法
 					update_region_cloud();
 				}
 				else
 				{
-					mp_cloud_collection->clear();
+					// mp_cloud_collection->clear();
 //					LOG(WARNING) << t_result.to_string();
 					// // 未连接雷达时,可读入点云用于测试
 					// read_pointcloud("/home/youchen/extra_space/chutian/measure/puai_wj_2021/build/comb_calib.txt", mp_cloud_collection);
@@ -368,7 +432,36 @@ Error_manager Velodyne_manager::update_region_cloud()
 {
 	for (auto iter = m_ground_region_map.begin(); iter != m_ground_region_map.end(); ++iter)
 	{
-		iter->second->update_cloud(mp_cloud_collection);
+		pcl::PointCloud<pcl::PointXYZ>::Ptr t_region_cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
+
+		// 遍历激光列表,找到终端对应点云数据,经过外参变换后叠加更新区域点云
+		for (auto iter_lidar = m_velodyne_lidar_device_map.begin(); iter_lidar != m_velodyne_lidar_device_map.end(); ++iter_lidar)
+		{
+			if(!iter->second->check_lidar_inside(iter_lidar->first))
+				continue;
+			std::string t_region_lidar_key = generate_region_lidar_key(iter->first, iter_lidar->first);
+			//将点云经过外参变换后,添加到对应区域中
+			if(m_region_laser_to_cloud_collection_map.find(t_region_lidar_key) != m_region_laser_to_cloud_collection_map.end())
+			{
+				std::shared_ptr<Timestamped_cloud> t_timed_cloud = m_region_laser_to_cloud_collection_map[t_region_lidar_key];
+				if (t_timed_cloud->m_cloud->size() > 0)
+				{
+					t_region_cloud->operator+=(*t_timed_cloud->transCloud());
+				}
+				else
+				{
+					LOG(WARNING) << "编号" << iter_lidar->first << "雷达在区域" << iter->first << "中未获得点云。";
+					continue;
+				}
+			}
+			else
+			{
+				LOG(WARNING) << "编号" << iter_lidar->first << "雷达在区域" << iter->first << "中未初始化完全。";
+				continue;
+			}
+		}
+
+		iter->second->update_cloud(t_region_cloud);
 	}
 	return Error_code::SUCCESS;
 }

+ 84 - 3
velodyne_lidar/velodyne_manager.h

@@ -4,7 +4,7 @@
  * 分布式模式下,程序各自独立,分别只实例化一个设定的区域,以及相应雷达
  * @Author: yct
  * @Date: 2021-07-23 16:37:33
- * @LastEditTime: 2021-08-01 14:56:58
+ * @LastEditTime: 2021-08-31 17:34:39
  * @LastEditors: yct
  */
 
@@ -12,6 +12,7 @@
 #define VELODYNE_MANAGER_HH
 #include <thread>
 #include <map>
+#include <memory>
 
 #include "../tool/singleton.h"
 #include "../tool/point_tool.h"
@@ -22,6 +23,82 @@
 #include "velodyne_config.pb.h"
 #include "velodyne_manager_task.h"
 
+struct Timestamped_cloud
+{
+	public:
+		Timestamped_cloud(velodyne::CalibParameter calib)
+		{
+			m_cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
+			m_time_collected = std::chrono::system_clock::now();
+			m_extrinsic.CopyFrom(calib);
+			updateMatrix();
+		}
+		Timestamped_cloud(velodyne::CalibParameter calib, pcl::PointCloud<pcl::PointXYZ>::Ptr input_cloud)
+		{
+			m_cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
+			m_cloud->operator+=(*input_cloud);
+			m_time_collected = std::chrono::system_clock::now();
+			m_extrinsic.CopyFrom(calib);
+			updateMatrix();
+		}
+		~Timestamped_cloud(){}
+
+		// 设置点云,覆盖
+		void setCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr input_cloud)
+		{
+			m_cloud->clear();
+			m_cloud->operator+=(*input_cloud);
+			m_time_collected = std::chrono::system_clock::now();
+		}
+		// 添加点云至现有点云中
+		void addCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr input_cloud)
+		{
+			m_cloud->operator+=(*input_cloud);
+			m_time_collected = std::chrono::system_clock::now();
+		}
+		void clearCloud()
+		{
+			m_cloud->clear();
+			m_time_collected = std::chrono::system_clock::now();
+		}
+		// 更新外参矩阵
+		void updateMatrix()
+		{
+			Eigen::AngleAxisd rot_x = Eigen::AngleAxisd(m_extrinsic.r(), Eigen::Vector3d::UnitX());
+			Eigen::AngleAxisd rot_y = Eigen::AngleAxisd(m_extrinsic.p(), Eigen::Vector3d::UnitY());
+			Eigen::AngleAxisd rot_z = Eigen::AngleAxisd(m_extrinsic.y(), Eigen::Vector3d::UnitZ());
+			Eigen::Vector3d trans(m_extrinsic.cx(), m_extrinsic.cy(), m_extrinsic.cz());
+			m_extrin_matrix << rot_x.toRotationMatrix() * rot_y.toRotationMatrix() * rot_z.toRotationMatrix(), trans, 0.0, 0.0, 0.0, 1.0;
+		}
+		// 使用外参返回变换后点云
+		pcl::PointCloud<pcl::PointXYZ>::Ptr transCloud()
+		{
+			pcl::PointCloud<pcl::PointXYZ>::Ptr t_cloud(new pcl::PointCloud<pcl::PointXYZ>);
+			if(m_cloud->size() > 0)
+			{
+				for (size_t i = 0; i < m_cloud->size(); i++)
+				{
+					Eigen::Vector4d t_point(m_cloud->points[i].x, m_cloud->points[i].y, m_cloud->points[i].z, 1.0);
+					t_point = m_extrin_matrix * t_point;
+					m_cloud->points[i].x = t_point.x() / t_point.w();
+					m_cloud->points[i].y = t_point.y() / t_point.w();
+					m_cloud->points[i].z = t_point.z() / t_point.w();
+				}
+			}
+
+			return t_cloud;			
+		}
+
+		// 时间戳
+		std::chrono::system_clock::time_point m_time_collected;
+		// 点云
+		pcl::PointCloud<pcl::PointXYZ>::Ptr m_cloud;
+		// 外参数据
+		velodyne::CalibParameter m_extrinsic;
+		// 外参齐次矩阵
+		Eigen::Matrix4d m_extrin_matrix;
+};
+
 class Velodyne_manager : public Singleton<Velodyne_manager>
 {
     // 子类必须把父类设定为友元函数,这样父类才能使用子类的私有构造函数。
@@ -87,6 +164,9 @@ protected://member functions
 	//执行外界任务的执行函数
 	void execute_thread_fun();
 
+	// 根据区域与激光id生成唯一string作为key
+	std::string generate_region_lidar_key(int region_id, int lidar_id) { return std::to_string(region_id) + std::string("-") + std::to_string(lidar_id); }
+
 private:
     // 父类的构造函数必须保护,子类的构造函数必须私有。
     Velodyne_manager() = default;
@@ -99,8 +179,9 @@ private:
 
 	//velodyne雷达的自动功能, 定时收集所有点云, 然后通知detect去计算车轮信息.
 	std::mutex	 								m_cloud_collection_mutex;       // 点云更新互斥锁
-	pcl::PointCloud<pcl::PointXYZ>::Ptr 		mp_cloud_collection;			//扫描点的点云集合, 内存由本类管理
-	std::chrono::system_clock::time_point		m_cloud_update_time;			//扫描点的更新时间.
+	std::map<std::string, std::shared_ptr<Timestamped_cloud>> 		m_region_laser_to_cloud_collection_map;			//扫描点的点云集合, 内存由本类管理
+	// std::chrono::system_clock::time_point		m_cloud_update_time;			//扫描点的更新时间. 已被时间戳点云替换
+	
 	std::thread*        						mp_collect_cloud_thread;   		//收集点云的线程指针,内存由本类管理
 	Thread_condition							m_collect_cloud_condition;		//收集点云的条件变量