소스 검색

vlp16测量消息调整,device内参,增加task与errorcode

yct 3 년 전
부모
커밋
159facb5c8

+ 23 - 0
error_code/error_code.h

@@ -252,6 +252,7 @@ enum Error_code
 	WANJI_LIDAR_DEVICE_TASK_TYPE_ERROR,								//万集设备模块,任务类型错误
 	WANJI_LIDAR_DEVICE_TASK_OVER_TIME,								//万集设备模块,任务超时
 	WANJI_LIDAR_DEVICE_NO_CLOUD,									//万集设备模块,没有点云
+    // velodyne设备模块
     VELODYNE_LIDAR_DEVICE_ERROR_BASE,								//velodyne设备模块,错误基类
     VELODYNE_LIDAR_DEVICE_STATUS_BUSY,									//velodyne设备模块,状态正忙
 	VELODYNE_LIDAR_DEVICE_STATUS_ERROR,								//velodyne设备模块,状态错误
@@ -270,6 +271,7 @@ enum Error_code
     WJ_LIDAR_READ_FAILED,											//万集通信,读取失败
     WJ_LIDAR_WRITE_FAILED,											//万集通信,写入失败
     WJ_LIDAR_GET_CLOUD_TIMEOUT,										//万集通信,获取点云超时
+    // velodyne通信
     VELODYNE_LIDAR_COMMUNICATION_UNINITIALIZED,							//velodyne通信,未初始化
 	VELODYNE_LIDAR_COMMUNICATION_DISCONNECT,								//velodyne通信,断连
 	VELODYNE_LIDAR_COMMUNICATION_FAULT,									//velodyne通信,故障
@@ -297,6 +299,15 @@ enum Error_code
     WJ_REGION_RECTANGLE_SYMMETRY_ERROR,								//万集测量,矩形对称错误
     WJ_REGION_CLUSTER_SIZE_ERROR,									//万集测量,簇大小错误
     WJ_REGION_CERES_SOLVE_ERROR,                                    //万集测量,优化失败
+    //velodyne测量范围
+	VELODYNE_REGION_ERROR_BASE,
+	VELODYNE_REGION_EMPTY_CLOUD,											//velodyne测量,空点云	
+	VELODYNE_REGION_EMPTY_NO_WHEEL_INFORMATION,							//velodyne测量,没有车轮信息
+    VELODYNE_REGION_RECTANGLE_ANGLE_ERROR,								//velodyne测量,矩形旋转角错误
+    VELODYNE_REGION_RECTANGLE_SIZE_ERROR,									//velodyne测量,矩形大小错误
+    VELODYNE_REGION_RECTANGLE_SYMMETRY_ERROR,								//velodyne测量,矩形对称错误
+    VELODYNE_REGION_CLUSTER_SIZE_ERROR,									//velodyne测量,簇大小错误
+    VELODYNE_REGION_CERES_SOLVE_ERROR,                                    //velodyne测量,优化失败
 
 //万集管理模块
 	WJ_MANAGER_ERROR_BASE										= 0x06040000,
@@ -312,6 +323,18 @@ enum Error_code
 	WJ_MANAGER_LASER_INDEX_ERRPR,								//万集管理模块,雷达索引错误,编号错误。
 	WJ_MANAGER_LASER_INDEX_REPEAT,								//万集管理模块,需要扫描的雷达索引重复,可忽略的错误,提示作用
 	WJ_MANAGER_TASK_OVER_TIME,									//万集管理模块,任务超时
+    VELODYNE_MANAGER_ERROR_BASE,										
+    VELODYNE_MANAGER_UNINITIALIZED,									//velodyne管理模块,未初始化
+    VELODYNE_MANAGER_LIDAR_DISCONNECTED,								//velodyne管理模块,雷达断链
+    VELODYNE_MANAGER_EMPTY_CLOUD,										//velodyne管理模块,空点云
+	VELODYNE_MANAGER_READ_PROTOBUF_ERROR,								//velodyne管理模块,读取参数错误
+	VELODYNE_MANAGER_INIT_ERROR,										//velodyne管理模块,初始化error
+	VELODYNE_MANAGER_TASK_TYPE_ERROR,									//velodyne管理模块,任务类型错误
+	VELODYNE_MANAGER_STATUS_BUSY,										//velodyne管理模块,状态正忙
+	VELODYNE_MANAGER_STATUS_ERROR,									//velodyne管理模块,状态错误
+	VELODYNE_MANAGER_LASER_INDEX_ERRPR,								//velodyne管理模块,雷达索引错误,编号错误。
+	VELODYNE_MANAGER_LASER_INDEX_REPEAT,								//velodyne管理模块,需要扫描的雷达索引重复,可忽略的错误,提示作用
+	VELODYNE_MANAGER_TASK_OVER_TIME,									//velodyne管理模块,任务超时
 
 //万集任务模块
 	WJ_LIDAR_TASK_ERROR_BASE									=0x06050000,

+ 137 - 65
message/measure_message.pb.cc

@@ -301,7 +301,7 @@ void InitDefaultsLocate_sift_response_msg() {
 }
 
 ::google::protobuf::Metadata file_level_metadata[10];
-const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors[6];
+const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors[7];
 
 const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::message::Measure_status_msg, _has_bits_),
@@ -384,6 +384,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUT
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::message::Ground_status_msg, wanji_lidar_device_status_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::message::Ground_status_msg, region_worker_status_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::message::Ground_status_msg, locate_information_realtime_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::message::Ground_status_msg, ground_status_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::message::Ground_status_msg, error_manager_),
   0,
   3,
@@ -391,6 +392,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUT
   ~0u,
   5,
   1,
+  6,
   2,
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::message::Cloud_coordinate, _has_bits_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::message::Cloud_coordinate, _internal_metadata_),
@@ -449,11 +451,11 @@ static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_PROT
   { 28, 38, sizeof(::message::Measure_response_msg)},
   { 43, 51, sizeof(::message::Ground_detect_request_msg)},
   { 54, 64, sizeof(::message::Ground_detect_response_msg)},
-  { 69, 81, sizeof(::message::Ground_status_msg)},
-  { 88, 96, sizeof(::message::Cloud_coordinate)},
-  { 99, 105, sizeof(::message::Cloud_type)},
-  { 106, 116, sizeof(::message::Locate_sift_request_msg)},
-  { 121, 132, sizeof(::message::Locate_sift_response_msg)},
+  { 69, 82, sizeof(::message::Ground_status_msg)},
+  { 90, 98, sizeof(::message::Cloud_coordinate)},
+  { 101, 107, sizeof(::message::Cloud_type)},
+  { 108, 118, sizeof(::message::Locate_sift_request_msg)},
+  { 123, 134, sizeof(::message::Locate_sift_response_msg)},
 };
 
 static ::google::protobuf::Message const * const file_default_instances[] = {
@@ -515,7 +517,7 @@ void AddDescriptorsImpl() {
       ".Base_info\022\023\n\013command_key\030\002 \002(\t\022\023\n\013termi"
       "nal_id\030\003 \002(\005\0227\n\022locate_information\030\004 \001(\013"
       "2\033.message.Locate_information\022-\n\rerror_m"
-      "anager\030\005 \002(\0132\026.message.Error_manager\"\201\003\n"
+      "anager\030\005 \002(\0132\026.message.Error_manager\"\257\003\n"
       "\021Ground_status_msg\022%\n\tbase_info\030\001 \002(\0132\022."
       "message.Base_info\022\023\n\013terminal_id\030\002 \002(\005\022;"
       "\n\024wanji_manager_status\030\003 \002(\0162\035.message.W"
@@ -524,48 +526,52 @@ void AddDescriptorsImpl() {
       "ice_status\022;\n\024region_worker_status\030\005 \002(\016"
       "2\035.message.Region_worker_status\022@\n\033locat"
       "e_information_realtime\030\006 \002(\0132\033.message.L"
-      "ocate_information\022-\n\rerror_manager\030\007 \002(\013"
-      "2\026.message.Error_manager\"3\n\020Cloud_coordi"
-      "nate\022\t\n\001x\030\001 \002(\002\022\t\n\001y\030\002 \002(\002\022\t\n\001z\030\003 \002(\002\"\032\n"
-      "\nCloud_type\022\014\n\004type\030\001 \002(\005\"\262\001\n\027Locate_sif"
-      "t_request_msg\022%\n\tbase_info\030\001 \002(\0132\022.messa"
-      "ge.Base_info\022\023\n\013command_key\030\002 \002(\t\022\023\n\013ter"
-      "minal_id\030\003 \002(\005\022\020\n\010lidar_id\030\004 \002(\005\0224\n\021clou"
-      "d_coordinates\030\005 \003(\0132\031.message.Cloud_coor"
-      "dinate\"\325\001\n\030Locate_sift_response_msg\022%\n\tb"
-      "ase_info\030\001 \002(\0132\022.message.Base_info\022\023\n\013co"
-      "mmand_key\030\002 \002(\t\022\023\n\013terminal_id\030\003 \002(\005\022\020\n\010"
-      "lidar_id\030\004 \002(\005\022\'\n\ncloud_type\030\005 \003(\0132\023.mes"
-      "sage.Cloud_type\022-\n\rerror_manager\030\006 \002(\0132\026"
-      ".message.Error_manager*\237\001\n\024Laser_manager"
-      "_status\022\030\n\024LASER_MANAGER_UNKNOW\020\000\022\027\n\023LAS"
-      "ER_MANAGER_READY\020\001\022\035\n\031LASER_MANAGER_ISSU"
-      "ED_TASK\020\002\022\034\n\030LASER_MANAGER_WAIT_REPLY\020\003\022"
-      "\027\n\023LASER_MANAGER_FAULT\020\004*U\n\013Laser_statu\022"
-      "\024\n\020LASER_DISCONNECT\020\000\022\017\n\013LASER_READY\020\001\022\016"
-      "\n\nLASER_BUSY\020\002\022\017\n\013LASER_FAULT\020\003*\261\001\n\025Loca"
-      "te_manager_status\022\031\n\025LOCATE_MANAGER_UNKN"
-      "OW\020\000\022\030\n\024LOCATE_MANAGER_READY\020\001\022\027\n\023LOCATE"
-      "_MANAGER_SIFT\020\002\022\026\n\022LOCATE_MANAGER_CAR\020\003\022"
-      "\030\n\024LOCATE_MANAGER_WHEEL\020\004\022\030\n\024LOCATE_MANA"
-      "GER_FAULT\020\005*\367\001\n\024Wanji_manager_status\022\031\n\025"
-      "WANJI_MANAGER_UNKNOWN\020\000\022\027\n\023WANJI_MANAGER"
-      "_READY\020\001\022\026\n\022WANJI_MANAGER_BUSY\020\002\022\035\n\031WANJ"
-      "I_MANAGER_ISSUED_SCAN\020\003\022\033\n\027WANJI_MANAGER"
-      "_WAIT_SCAN\020\004\022\037\n\033WANJI_MANAGER_ISSUED_DET"
-      "ECT\020\005\022\035\n\031WANJI_MANAGER_WAIT_DETECT\020\006\022\027\n\023"
-      "WANJI_MANAGER_FAULT\020\n*\267\001\n\031Wanji_lidar_de"
-      "vice_status\022\036\n\032WANJI_LIDAR_DEVICE_UNKNOW"
-      "N\020\000\022\034\n\030WANJI_LIDAR_DEVICE_READY\020\001\022!\n\035WAN"
-      "JI_LIDAR_DEVICE_DISCONNECT\020\002\022\033\n\027WANJI_LI"
-      "DAR_DEVICE_BUSY\020\003\022\034\n\030WANJI_LIDAR_DEVICE_"
-      "FAULT\020\n*{\n\024Region_worker_status\022\031\n\025REGIO"
-      "N_WORKER_UNKNOWN\020\000\022\027\n\023REGION_WORKER_READ"
-      "Y\020\001\022\026\n\022REGION_WORKER_BUSY\020\002\022\027\n\023REGION_WO"
-      "RKER_FAULT\020\n"
+      "ocate_information\022,\n\rground_status\030\007 \002(\016"
+      "2\025.message.Ground_statu\022-\n\rerror_manager"
+      "\030\010 \002(\0132\026.message.Error_manager\"3\n\020Cloud_"
+      "coordinate\022\t\n\001x\030\001 \002(\002\022\t\n\001y\030\002 \002(\002\022\t\n\001z\030\003 "
+      "\002(\002\"\032\n\nCloud_type\022\014\n\004type\030\001 \002(\005\"\262\001\n\027Loca"
+      "te_sift_request_msg\022%\n\tbase_info\030\001 \002(\0132\022"
+      ".message.Base_info\022\023\n\013command_key\030\002 \002(\t\022"
+      "\023\n\013terminal_id\030\003 \002(\005\022\020\n\010lidar_id\030\004 \002(\005\0224"
+      "\n\021cloud_coordinates\030\005 \003(\0132\031.message.Clou"
+      "d_coordinate\"\325\001\n\030Locate_sift_response_ms"
+      "g\022%\n\tbase_info\030\001 \002(\0132\022.message.Base_info"
+      "\022\023\n\013command_key\030\002 \002(\t\022\023\n\013terminal_id\030\003 \002"
+      "(\005\022\020\n\010lidar_id\030\004 \002(\005\022\'\n\ncloud_type\030\005 \003(\013"
+      "2\023.message.Cloud_type\022-\n\rerror_manager\030\006"
+      " \002(\0132\026.message.Error_manager*\237\001\n\024Laser_m"
+      "anager_status\022\030\n\024LASER_MANAGER_UNKNOW\020\000\022"
+      "\027\n\023LASER_MANAGER_READY\020\001\022\035\n\031LASER_MANAGE"
+      "R_ISSUED_TASK\020\002\022\034\n\030LASER_MANAGER_WAIT_RE"
+      "PLY\020\003\022\027\n\023LASER_MANAGER_FAULT\020\004*U\n\013Laser_"
+      "statu\022\024\n\020LASER_DISCONNECT\020\000\022\017\n\013LASER_REA"
+      "DY\020\001\022\016\n\nLASER_BUSY\020\002\022\017\n\013LASER_FAULT\020\003*\261\001"
+      "\n\025Locate_manager_status\022\031\n\025LOCATE_MANAGE"
+      "R_UNKNOW\020\000\022\030\n\024LOCATE_MANAGER_READY\020\001\022\027\n\023"
+      "LOCATE_MANAGER_SIFT\020\002\022\026\n\022LOCATE_MANAGER_"
+      "CAR\020\003\022\030\n\024LOCATE_MANAGER_WHEEL\020\004\022\030\n\024LOCAT"
+      "E_MANAGER_FAULT\020\005*\367\001\n\024Wanji_manager_stat"
+      "us\022\031\n\025WANJI_MANAGER_UNKNOWN\020\000\022\027\n\023WANJI_M"
+      "ANAGER_READY\020\001\022\026\n\022WANJI_MANAGER_BUSY\020\002\022\035"
+      "\n\031WANJI_MANAGER_ISSUED_SCAN\020\003\022\033\n\027WANJI_M"
+      "ANAGER_WAIT_SCAN\020\004\022\037\n\033WANJI_MANAGER_ISSU"
+      "ED_DETECT\020\005\022\035\n\031WANJI_MANAGER_WAIT_DETECT"
+      "\020\006\022\027\n\023WANJI_MANAGER_FAULT\020\n*\267\001\n\031Wanji_li"
+      "dar_device_status\022\036\n\032WANJI_LIDAR_DEVICE_"
+      "UNKNOWN\020\000\022\034\n\030WANJI_LIDAR_DEVICE_READY\020\001\022"
+      "!\n\035WANJI_LIDAR_DEVICE_DISCONNECT\020\002\022\033\n\027WA"
+      "NJI_LIDAR_DEVICE_BUSY\020\003\022\034\n\030WANJI_LIDAR_D"
+      "EVICE_FAULT\020\n*{\n\024Region_worker_status\022\031\n"
+      "\025REGION_WORKER_UNKNOWN\020\000\022\027\n\023REGION_WORKE"
+      "R_READY\020\001\022\026\n\022REGION_WORKER_BUSY\020\002\022\027\n\023REG"
+      "ION_WORKER_FAULT\020\n*\201\001\n\014Ground_statu\022\013\n\007N"
+      "othing\020\000\022\t\n\005Noise\020\001\022\017\n\013Car_correct\020\002\022\020\n\014"
+      "Car_left_out\020\003\022\021\n\rCar_right_out\020\004\022\017\n\013Car"
+      "_top_out\020\005\022\022\n\016Car_bottom_out\020\006"
   };
   ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 2852);
+      descriptor, 3030);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "measure_message.proto", &protobuf_RegisterTypes);
   ::protobuf_message_5fbase_2eproto::AddDescriptors();
@@ -687,6 +693,25 @@ bool Region_worker_status_IsValid(int value) {
   }
 }
 
+const ::google::protobuf::EnumDescriptor* Ground_statu_descriptor() {
+  protobuf_measure_5fmessage_2eproto::protobuf_AssignDescriptorsOnce();
+  return protobuf_measure_5fmessage_2eproto::file_level_enum_descriptors[6];
+}
+bool Ground_statu_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+      return true;
+    default:
+      return false;
+  }
+}
+
 
 // ===================================================================
 
@@ -3065,6 +3090,7 @@ const int Ground_status_msg::kWanjiManagerStatusFieldNumber;
 const int Ground_status_msg::kWanjiLidarDeviceStatusFieldNumber;
 const int Ground_status_msg::kRegionWorkerStatusFieldNumber;
 const int Ground_status_msg::kLocateInformationRealtimeFieldNumber;
+const int Ground_status_msg::kGroundStatusFieldNumber;
 const int Ground_status_msg::kErrorManagerFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
@@ -3099,16 +3125,16 @@ Ground_status_msg::Ground_status_msg(const Ground_status_msg& from)
     error_manager_ = NULL;
   }
   ::memcpy(&terminal_id_, &from.terminal_id_,
-    static_cast<size_t>(reinterpret_cast<char*>(&region_worker_status_) -
-    reinterpret_cast<char*>(&terminal_id_)) + sizeof(region_worker_status_));
+    static_cast<size_t>(reinterpret_cast<char*>(&ground_status_) -
+    reinterpret_cast<char*>(&terminal_id_)) + sizeof(ground_status_));
   // @@protoc_insertion_point(copy_constructor:message.Ground_status_msg)
 }
 
 void Ground_status_msg::SharedCtor() {
   _cached_size_ = 0;
   ::memset(&base_info_, 0, static_cast<size_t>(
-      reinterpret_cast<char*>(&region_worker_status_) -
-      reinterpret_cast<char*>(&base_info_)) + sizeof(region_worker_status_));
+      reinterpret_cast<char*>(&ground_status_) -
+      reinterpret_cast<char*>(&base_info_)) + sizeof(ground_status_));
 }
 
 Ground_status_msg::~Ground_status_msg() {
@@ -3167,10 +3193,10 @@ void Ground_status_msg::Clear() {
       error_manager_->Clear();
     }
   }
-  if (cached_has_bits & 56u) {
+  if (cached_has_bits & 120u) {
     ::memset(&terminal_id_, 0, static_cast<size_t>(
-        reinterpret_cast<char*>(&region_worker_status_) -
-        reinterpret_cast<char*>(&terminal_id_)) + sizeof(region_worker_status_));
+        reinterpret_cast<char*>(&ground_status_) -
+        reinterpret_cast<char*>(&terminal_id_)) + sizeof(ground_status_));
   }
   _has_bits_.Clear();
   _internal_metadata_.Clear();
@@ -3293,10 +3319,30 @@ bool Ground_status_msg::MergePartialFromCodedStream(
         break;
       }
 
-      // required .message.Error_manager error_manager = 7;
+      // required .message.Ground_statu ground_status = 7;
       case 7: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(58u /* 58 & 0xFF */)) {
+            static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) {
+          int value;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          if (::message::Ground_statu_IsValid(value)) {
+            set_ground_status(static_cast< ::message::Ground_statu >(value));
+          } else {
+            mutable_unknown_fields()->AddVarint(
+                7, static_cast< ::google::protobuf::uint64>(value));
+          }
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // required .message.Error_manager error_manager = 8;
+      case 8: {
+        if (static_cast< ::google::protobuf::uint8>(tag) ==
+            static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_error_manager()));
         } else {
@@ -3367,10 +3413,16 @@ void Ground_status_msg::SerializeWithCachedSizes(
       6, *this->locate_information_realtime_, output);
   }
 
-  // required .message.Error_manager error_manager = 7;
+  // required .message.Ground_statu ground_status = 7;
+  if (cached_has_bits & 0x00000040u) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      7, this->ground_status(), output);
+  }
+
+  // required .message.Error_manager error_manager = 8;
   if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      7, *this->error_manager_, output);
+      8, *this->error_manager_, output);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -3423,11 +3475,17 @@ void Ground_status_msg::SerializeWithCachedSizes(
         6, *this->locate_information_realtime_, deterministic, target);
   }
 
-  // required .message.Error_manager error_manager = 7;
+  // required .message.Ground_statu ground_status = 7;
+  if (cached_has_bits & 0x00000040u) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      7, this->ground_status(), target);
+  }
+
+  // required .message.Error_manager error_manager = 8;
   if (cached_has_bits & 0x00000004u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        7, *this->error_manager_, deterministic, target);
+        8, *this->error_manager_, deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -3457,7 +3515,7 @@ size_t Ground_status_msg::RequiredFieldsByteSizeFallback() const {
   }
 
   if (has_error_manager()) {
-    // required .message.Error_manager error_manager = 7;
+    // required .message.Error_manager error_manager = 8;
     total_size += 1 +
       ::google::protobuf::internal::WireFormatLite::MessageSize(
         *this->error_manager_);
@@ -3482,6 +3540,12 @@ size_t Ground_status_msg::RequiredFieldsByteSizeFallback() const {
       ::google::protobuf::internal::WireFormatLite::EnumSize(this->region_worker_status());
   }
 
+  if (has_ground_status()) {
+    // required .message.Ground_statu ground_status = 7;
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->ground_status());
+  }
+
   return total_size;
 }
 size_t Ground_status_msg::ByteSizeLong() const {
@@ -3493,7 +3557,7 @@ size_t Ground_status_msg::ByteSizeLong() const {
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
-  if (((_has_bits_[0] & 0x0000003f) ^ 0x0000003f) == 0) {  // All required fields are present.
+  if (((_has_bits_[0] & 0x0000007f) ^ 0x0000007f) == 0) {  // All required fields are present.
     // required .message.Base_info base_info = 1;
     total_size += 1 +
       ::google::protobuf::internal::WireFormatLite::MessageSize(
@@ -3504,7 +3568,7 @@ size_t Ground_status_msg::ByteSizeLong() const {
       ::google::protobuf::internal::WireFormatLite::MessageSize(
         *this->locate_information_realtime_);
 
-    // required .message.Error_manager error_manager = 7;
+    // required .message.Error_manager error_manager = 8;
     total_size += 1 +
       ::google::protobuf::internal::WireFormatLite::MessageSize(
         *this->error_manager_);
@@ -3522,6 +3586,10 @@ size_t Ground_status_msg::ByteSizeLong() const {
     total_size += 1 +
       ::google::protobuf::internal::WireFormatLite::EnumSize(this->region_worker_status());
 
+    // required .message.Ground_statu ground_status = 7;
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->ground_status());
+
   } else {
     total_size += RequiredFieldsByteSizeFallback();
   }
@@ -3566,7 +3634,7 @@ void Ground_status_msg::MergeFrom(const Ground_status_msg& from) {
 
   wanji_lidar_device_status_.MergeFrom(from.wanji_lidar_device_status_);
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 63u) {
+  if (cached_has_bits & 127u) {
     if (cached_has_bits & 0x00000001u) {
       mutable_base_info()->::message::Base_info::MergeFrom(from.base_info());
     }
@@ -3585,6 +3653,9 @@ void Ground_status_msg::MergeFrom(const Ground_status_msg& from) {
     if (cached_has_bits & 0x00000020u) {
       region_worker_status_ = from.region_worker_status_;
     }
+    if (cached_has_bits & 0x00000040u) {
+      ground_status_ = from.ground_status_;
+    }
     _has_bits_[0] |= cached_has_bits;
   }
 }
@@ -3604,7 +3675,7 @@ void Ground_status_msg::CopyFrom(const Ground_status_msg& from) {
 }
 
 bool Ground_status_msg::IsInitialized() const {
-  if ((_has_bits_[0] & 0x0000003f) != 0x0000003f) return false;
+  if ((_has_bits_[0] & 0x0000007f) != 0x0000007f) return false;
   if (has_base_info()) {
     if (!this->base_info_->IsInitialized()) return false;
   }
@@ -3627,6 +3698,7 @@ void Ground_status_msg::InternalSwap(Ground_status_msg* other) {
   swap(terminal_id_, other->terminal_id_);
   swap(wanji_manager_status_, other->wanji_manager_status_);
   swap(region_worker_status_, other->region_worker_status_);
+  swap(ground_status_, other->ground_status_);
   swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
   swap(_cached_size_, other->_cached_size_);

+ 67 - 3
message/measure_message.pb.h

@@ -245,6 +245,30 @@ inline bool Region_worker_status_Parse(
   return ::google::protobuf::internal::ParseNamedEnum<Region_worker_status>(
     Region_worker_status_descriptor(), name, value);
 }
+enum Ground_statu {
+  Nothing = 0,
+  Noise = 1,
+  Car_correct = 2,
+  Car_left_out = 3,
+  Car_right_out = 4,
+  Car_top_out = 5,
+  Car_bottom_out = 6
+};
+bool Ground_statu_IsValid(int value);
+const Ground_statu Ground_statu_MIN = Nothing;
+const Ground_statu Ground_statu_MAX = Car_bottom_out;
+const int Ground_statu_ARRAYSIZE = Ground_statu_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* Ground_statu_descriptor();
+inline const ::std::string& Ground_statu_Name(Ground_statu value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    Ground_statu_descriptor(), value);
+}
+inline bool Ground_statu_Parse(
+    const ::std::string& name, Ground_statu* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<Ground_statu>(
+    Ground_statu_descriptor(), name, value);
+}
 // ===================================================================
 
 class Measure_status_msg : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:message.Measure_status_msg) */ {
@@ -1152,10 +1176,10 @@ class Ground_status_msg : public ::google::protobuf::Message /* @@protoc_inserti
   ::message::Locate_information* mutable_locate_information_realtime();
   void set_allocated_locate_information_realtime(::message::Locate_information* locate_information_realtime);
 
-  // required .message.Error_manager error_manager = 7;
+  // required .message.Error_manager error_manager = 8;
   bool has_error_manager() const;
   void clear_error_manager();
-  static const int kErrorManagerFieldNumber = 7;
+  static const int kErrorManagerFieldNumber = 8;
   const ::message::Error_manager& error_manager() const;
   ::message::Error_manager* release_error_manager();
   ::message::Error_manager* mutable_error_manager();
@@ -1182,6 +1206,13 @@ class Ground_status_msg : public ::google::protobuf::Message /* @@protoc_inserti
   ::message::Region_worker_status region_worker_status() const;
   void set_region_worker_status(::message::Region_worker_status value);
 
+  // required .message.Ground_statu ground_status = 7;
+  bool has_ground_status() const;
+  void clear_ground_status();
+  static const int kGroundStatusFieldNumber = 7;
+  ::message::Ground_statu ground_status() const;
+  void set_ground_status(::message::Ground_statu value);
+
   // @@protoc_insertion_point(class_scope:message.Ground_status_msg)
  private:
   void set_has_base_info();
@@ -1194,6 +1225,8 @@ class Ground_status_msg : public ::google::protobuf::Message /* @@protoc_inserti
   void clear_has_region_worker_status();
   void set_has_locate_information_realtime();
   void clear_has_locate_information_realtime();
+  void set_has_ground_status();
+  void clear_has_ground_status();
   void set_has_error_manager();
   void clear_has_error_manager();
 
@@ -1210,6 +1243,7 @@ class Ground_status_msg : public ::google::protobuf::Message /* @@protoc_inserti
   ::google::protobuf::int32 terminal_id_;
   int wanji_manager_status_;
   int region_worker_status_;
+  int ground_status_;
   friend struct ::protobuf_measure_5fmessage_2eproto::TableStruct;
   friend void ::protobuf_measure_5fmessage_2eproto::InitDefaultsGround_status_msgImpl();
 };
@@ -2991,7 +3025,32 @@ inline void Ground_status_msg::set_allocated_locate_information_realtime(::messa
   // @@protoc_insertion_point(field_set_allocated:message.Ground_status_msg.locate_information_realtime)
 }
 
-// required .message.Error_manager error_manager = 7;
+// required .message.Ground_statu ground_status = 7;
+inline bool Ground_status_msg::has_ground_status() const {
+  return (_has_bits_[0] & 0x00000040u) != 0;
+}
+inline void Ground_status_msg::set_has_ground_status() {
+  _has_bits_[0] |= 0x00000040u;
+}
+inline void Ground_status_msg::clear_has_ground_status() {
+  _has_bits_[0] &= ~0x00000040u;
+}
+inline void Ground_status_msg::clear_ground_status() {
+  ground_status_ = 0;
+  clear_has_ground_status();
+}
+inline ::message::Ground_statu Ground_status_msg::ground_status() const {
+  // @@protoc_insertion_point(field_get:message.Ground_status_msg.ground_status)
+  return static_cast< ::message::Ground_statu >(ground_status_);
+}
+inline void Ground_status_msg::set_ground_status(::message::Ground_statu value) {
+  assert(::message::Ground_statu_IsValid(value));
+  set_has_ground_status();
+  ground_status_ = value;
+  // @@protoc_insertion_point(field_set:message.Ground_status_msg.ground_status)
+}
+
+// required .message.Error_manager error_manager = 8;
 inline bool Ground_status_msg::has_error_manager() const {
   return (_has_bits_[0] & 0x00000004u) != 0;
 }
@@ -3644,6 +3703,11 @@ template <>
 inline const EnumDescriptor* GetEnumDescriptor< ::message::Region_worker_status>() {
   return ::message::Region_worker_status_descriptor();
 }
+template <> struct is_proto_enum< ::message::Ground_statu> : ::google::protobuf::internal::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::message::Ground_statu>() {
+  return ::message::Ground_statu_descriptor();
+}
 
 }  // namespace protobuf
 }  // namespace google

+ 14 - 1
message/measure_message.proto

@@ -123,6 +123,18 @@ message Ground_detect_response_msg
     required Error_manager              error_manager = 5;
 }
 
+// 电子围栏状态
+enum Ground_statu
+{
+    Nothing=0;
+    Noise=1;
+    Car_correct=2;
+    Car_left_out=3;
+    Car_right_out=4;
+    Car_top_out=5;
+    Car_bottom_out=6;
+}
+
 message Ground_status_msg
 {
     required Base_info                  base_info=1;                 //消息类型
@@ -132,8 +144,9 @@ message Ground_status_msg
     repeated Wanji_lidar_device_status  wanji_lidar_device_status = 4;  //万集设备身状态
     required Region_worker_status       region_worker_status = 5;       //万集区域功能的状态
     required Locate_information         locate_information_realtime = 6;//地面雷达的 实时定位信息
+    required Ground_statu               ground_status=7; // 电子围栏状态
 
-    required Error_manager              error_manager = 7;
+    required Error_manager              error_manager = 8;
 }
 
 //点云坐标

+ 31 - 0
setting/velodyne_manager.prototxt

@@ -0,0 +1,31 @@
+fence_data_path:"/home/zx/data/fence_wj"
+#fence_log_path:"/home/zx/yct/MainStructure/new_electronic_fence/log"
+
+#1
+velodyne_lidars
+{
+    ip:""
+    port:2368
+    model:"VLP16"
+    calibrationFile:"../setting/VLP16db.yaml"
+    max_range:5.0
+    min_range:0.1
+    min_angle:0
+    max_angle:360
+    rpm:600
+    calib
+    {
+        y:1.57
+    }
+}
+
+# 1
+region
+{
+    minx:-3.1
+	maxx:0
+	miny:-2.75
+	maxy:3.08
+	minz:0.01
+	maxz:0.2
+}

+ 2 - 1
tests/vlp16_driver_test.cpp

@@ -2,7 +2,7 @@
  * @Description: vlp16驱动测试
  * @Author: yct
  * @Date: 2021-07-26 14:11:26
- * @LastEditTime: 2021-07-28 10:14:20
+ * @LastEditTime: 2021-07-28 15:42:50
  * @LastEditors: yct
  */
 
@@ -73,6 +73,7 @@ void device_test()
     params.set_port(2368);
     params.set_model("VLP16");
     params.set_calibrationfile("/home/youchen/extra_space/chutian/measure/puai_wj_2021/setting/VLP16db.yaml");
+    params.mutable_calib()->set_y(1.57);
 
     Velodyne_lidar_device t_device;
     t_device.init(params);

+ 159 - 393
velodyne_lidar/ground_region.cpp

@@ -9,8 +9,7 @@
 #include <pcl/filters/voxel_grid.h>
 #include <pcl/segmentation/extract_clusters.h>
 #include <fcntl.h>
-#include "publisher.h"
-#include "point_tool.h"
+
 //欧式聚类*******************************************************
 std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> Ground_region::segmentation(pcl::PointCloud<pcl::PointXYZ>::Ptr sor_cloud)
 {
@@ -24,24 +23,34 @@ std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> Ground_region::segmentation(pcl
     ece.setSearchMethod(tree);
     ece.extract(ece_inlier);
 
-    std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>  segmentation_clouds;
+    std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> segmentation_clouds;
     for (int i = 0; i < ece_inlier.size(); i++)
     {
         pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_copy(new pcl::PointCloud<pcl::PointXYZ>);
         std::vector<int> ece_inlier_ext = ece_inlier[i].indices;
-        copyPointCloud(*sor_cloud, ece_inlier_ext, *cloud_copy);//按照索引提取点云数据
+        copyPointCloud(*sor_cloud, ece_inlier_ext, *cloud_copy); //按照索引提取点云数据
         segmentation_clouds.push_back(cloud_copy);
     }
     return segmentation_clouds;
 }
 
+/**
+ * @description: distance between two points
+ * @param {Point2f} p1
+ * @param {Point2f} p2
+ * @return the distance
+ */
 double Ground_region::distance(cv::Point2f p1, cv::Point2f p2)
 {
     return sqrt(pow(p1.x - p2.x, 2.0) + pow(p1.y - p2.y, 2.0));
 }
 
-
-bool Ground_region::isRect(std::vector<cv::Point2f>& points)
+/**
+ * @description: point rectangle detect
+ * @param  points detect if points obey the rectangle rule
+ * @return wether forms a rectangle
+ */
+bool Ground_region::isRect(std::vector<cv::Point2f> &points)
 {
     if (points.size() == 4)
     {
@@ -54,7 +63,8 @@ bool Ground_region::isRect(std::vector<cv::Point2f>& points)
         double l2 = L[2];
         cv::Point2f ps = points[0], pt = points[1];
         cv::Point2f pc = points[2];
-        for (int i = 1; i < 3; ++i) {
+        for (int i = 1; i < 3; ++i)
+        {
             if (L[i] > max_l)
             {
                 max_l = L[i];
@@ -67,26 +77,27 @@ bool Ground_region::isRect(std::vector<cv::Point2f>& points)
         }
 
         //直角边与坐标轴的夹角 <20°
-        float thresh=20.0*M_PI/180.0;
-        cv::Point2f vct(pt.x-pc.x,pt.y-pc.y);
-        float angle=atan2(vct.y,vct.x);
-        if(!(fabs(angle)<thresh || (M_PI_2-fabs(angle)<thresh)))
+        float thresh = 20.0 * M_PI / 180.0;
+        cv::Point2f vct(pt.x - pc.x, pt.y - pc.y);
+        float angle = atan2(vct.y, vct.x);
+        if (!(fabs(angle) < thresh || (M_PI_2 - fabs(angle) < thresh)))
         {
             //std::cout<<" 4 wheel axis angle : "<<angle<<std::endl;
             return false;
         }
 
         double cosa = (l1 * l1 + l2 * l2 - max_l * max_l) / (2.0 * l1 * l2);
-        if (fabs(cosa) >= 0.15) {
+        if (fabs(cosa) >= 0.15)
+        {
             /*char description[255]={0};
             sprintf(description,"angle cos value(%.2f) >0.13 ",cosa);
             std::cout<<description<<std::endl;*/
             return false;
         }
 
-        float width=std::min(l1,l2);
-        float length=std::max(l1,l2);
-        if(width<1.400 || width >1.900 || length >3.300 ||length < 2.200)
+        float width = std::min(l1, l2);
+        float length = std::max(l1, l2);
+        if (width < 1.400 || width > 1.900 || length > 3.300 || length < 2.200)
         {
             /*char description[255]={0};
             sprintf(description,"width<1400 || width >1900 || length >3300 ||length < 2200 l:%.1f,w:%.1f",length,width);
@@ -97,7 +108,8 @@ bool Ground_region::isRect(std::vector<cv::Point2f>& points)
         double d = distance(pc, points[3]);
         cv::Point2f center1 = (ps + pt) * 0.5;
         cv::Point2f center2 = (pc + points[3]) * 0.5;
-        if (fabs(d - max_l) > max_l * 0.1 || distance(center1, center2) > 0.150) {
+        if (fabs(d - max_l) > max_l * 0.1 || distance(center1, center2) > 0.150)
+        {
             /*std::cout << "d:" << d << " maxl:" << max_l << "  center1:" << center1 << "  center2:" << center2<<std::endl;
             char description[255]={0};
             sprintf(description,"Verify failed-4  fabs(d - max_l) > max_l * 0.1 || distance(center1, center2) > 0.150 ");
@@ -106,10 +118,9 @@ bool Ground_region::isRect(std::vector<cv::Point2f>& points)
         }
         //std::cout << "d:" << d << " maxl:" << max_l << "  center1:" << center1 << "  center2:" << center2<<std::endl;
 
-
         return true;
     }
-    else if(points.size()==3)
+    else if (points.size() == 3)
     {
         double L[3] = {0.0};
         L[0] = distance(points[0], points[1]);
@@ -121,8 +132,10 @@ bool Ground_region::isRect(std::vector<cv::Point2f>& points)
         int max_index = 0;
         cv::Point2f ps = points[0], pt = points[1];
         cv::Point2f pc = points[2];
-        for (int i = 1; i < 3; ++i) {
-            if (L[i] > max_l) {
+        for (int i = 1; i < 3; ++i)
+        {
+            if (L[i] > max_l)
+            {
                 max_index = i;
                 max_l = L[i];
                 l1 = L[abs(i + 1) % 3];
@@ -134,31 +147,32 @@ bool Ground_region::isRect(std::vector<cv::Point2f>& points)
         }
 
         //直角边与坐标轴的夹角 <20°
-        float thresh=20.0*M_PI/180.0;
-        cv::Point2f vct(pt.x-pc.x,pt.y-pc.y);
-        float angle=atan2(vct.y,vct.x);
-        if(!(fabs(angle)<thresh || (M_PI_2-fabs(angle)<thresh)))
+        float thresh = 20.0 * M_PI / 180.0;
+        cv::Point2f vct(pt.x - pc.x, pt.y - pc.y);
+        float angle = atan2(vct.y, vct.x);
+        if (!(fabs(angle) < thresh || (M_PI_2 - fabs(angle) < thresh)))
         {
             //std::cout<<" 4 wheel axis angle : "<<angle<<std::endl;
             return false;
         }
 
         double cosa = (l1 * l1 + l2 * l2 - max_l * max_l) / (2.0 * l1 * l2);
-        if (fabs(cosa) >= 0.15) {
+        if (fabs(cosa) >= 0.15)
+        {
             /*char description[255]={0};
             sprintf(description,"3 wheels angle cos value(%.2f) >0.13 ",cosa);
             std::cout<<description<<std::endl;*/
             return false;
         }
 
-        double l=std::max(l1,l2);
-        double w=std::min(l1,l2);
-        if(l>2.100 && l<3.300 && w>1.400 && w<2.100)
+        double l = std::max(l1, l2);
+        double w = std::min(l1, l2);
+        if (l > 2.100 && l < 3.300 && w > 1.400 && w < 2.100)
         {
             //生成第四个点
-            cv::Point2f vec1=ps-pc;
-            cv::Point2f vec2=pt-pc;
-            cv::Point2f point4=(vec1+vec2)+pc;
+            cv::Point2f vec1 = ps - pc;
+            cv::Point2f vec2 = pt - pc;
+            cv::Point2f point4 = (vec1 + vec2) + pc;
             points.push_back(point4);
 
             /*char description[255]={0};
@@ -174,70 +188,75 @@ bool Ground_region::isRect(std::vector<cv::Point2f>& points)
             std::cout<<description<<std::endl;*/
             return false;
         }
-
     }
     //std::cout<<" default false"<<std::endl;
     return false;
-
 }
-bool Ground_region::classify_ceres_detect(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,double thresh_z,
-        detect_wheel_ceres3d::Detect_result& result)
+
+/**
+ * @description: 3d wheel detect core func
+ * @param cloud  input cloud for measure
+ * @param thresh_z  z value to cut wheel
+ * @param result  detect result
+ * @return wether successfully detected
+ */
+bool Ground_region::classify_ceres_detect(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, double thresh_z,
+                                          detect_wheel_ceres3d::Detect_result &result)
 {
-    if(m_detector== nullptr)
+    if (m_detector == nullptr)
         return false;
     pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
-    for(int i=0;i<cloud->size();++i)
+    for (int i = 0; i < cloud->size(); ++i)
     {
-        pcl::PointXYZ pt=cloud->points[i];
-        if(pt.z< thresh_z)
+        pcl::PointXYZ pt = cloud->points[i];
+        if (pt.z < thresh_z)
         {
             cloud_filtered->push_back(pt);
         }
     }
     //下采样
-    pcl::VoxelGrid<pcl::PointXYZ> vox;  //创建滤波对象
-    vox.setInputCloud(cloud_filtered);                 //设置需要过滤的点云给滤波对象
-    vox.setLeafSize(0.02f, 0.02f, 0.2f);     //设置滤波时创建的体素体积为1cm的立方体
+    pcl::VoxelGrid<pcl::PointXYZ> vox;   //创建滤波对象
+    vox.setInputCloud(cloud_filtered);   //设置需要过滤的点云给滤波对象
+    vox.setLeafSize(0.02f, 0.02f, 0.2f); //设置滤波时创建的体素体积为1cm的立方体
     vox.filter(*cloud_filtered);         //执行滤波处理,存储输出
-    if(cloud_filtered->size()==0)
+    if (cloud_filtered->size() == 0)
     {
         return false;
     }
 
-    if(cloud_filtered->size()==0)
+    if (cloud_filtered->size() == 0)
         return false;
-    pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;   //创建滤波器对象
-    sor.setInputCloud (cloud_filtered);                           //设置待滤波的点云
-    sor.setMeanK (5);                               //设置在进行统计时考虑的临近点个数
-    sor.setStddevMulThresh (3.0);                      //设置判断是否为离群点的阀值,用来倍乘标准差,也就是上面的std_mul
-    sor.filter (*cloud_filtered);                    //滤波结果存储到cloud_filtered
+    pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor; //创建滤波器对象
+    sor.setInputCloud(cloud_filtered);                 //设置待滤波的点云
+    sor.setMeanK(5);                                   //设置在进行统计时考虑的临近点个数
+    sor.setStddevMulThresh(3.0);                       //设置判断是否为离群点的阀值,用来倍乘标准差,也就是上面的std_mul
+    sor.filter(*cloud_filtered);                       //滤波结果存储到cloud_filtered
 
-    if(cloud_filtered->size()==0)
+    if (cloud_filtered->size() == 0)
     {
         return false;
     }
 
     std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> seg_clouds;
-    seg_clouds=segmentation(cloud_filtered);
+    seg_clouds = segmentation(cloud_filtered);
 
-    if(!(seg_clouds.size()==4 || seg_clouds.size()==3))
+    if (!(seg_clouds.size() == 4 || seg_clouds.size() == 3))
     {
         return false;
     }
     std::vector<cv::Point2f> centers;
-    for(int i=0;i<seg_clouds.size();++i)
+    for (int i = 0; i < seg_clouds.size(); ++i)
     {
         Eigen::Vector4f centroid;
         pcl::compute3DCentroid(*seg_clouds[i], centroid);
-        centers.push_back(cv::Point2f(centroid[0],centroid[1]));
-
+        centers.push_back(cv::Point2f(centroid[0], centroid[1]));
     }
-    bool ret= isRect(centers);
-    if(ret)
+    bool ret = isRect(centers);
+    if (ret)
     {
 
         std::string error_str;
-        if(m_detector->detect(seg_clouds,result,error_str))
+        if (m_detector->detect(seg_clouds, result, error_str))
         {
             return true;
         }
@@ -249,409 +268,156 @@ bool Ground_region::classify_ceres_detect(pcl::PointCloud<pcl::PointXYZ>::Ptr cl
     return ret;
 }
 
-
-Ground_region::~Ground_region()
-{
-    m_exit_condition.set_pass_ever(true);
-    // Close Capturte Thread
-    if( m_running_thread && m_running_thread->joinable() ){
-        m_running_thread->join();
-        m_running_thread->~thread();
-        delete m_running_thread;
-        m_running_thread = nullptr;
-    }
-
-    for(int i=0;i<m_lidars.size();++i)
-    {
-        if(m_lidars[i]!= nullptr)
-        {
-            m_lidars[i]->close();
-            delete m_lidars[i];
-        }
-    }
-    m_lidars.clear();
-    if(m_detector)
-    {
-        delete m_detector;
-        m_detector= nullptr;
-    }
-
-
-}
+// constructor
 Ground_region::Ground_region()
 {
-    m_detector= nullptr ;
-    m_running_thread=nullptr;
-}
-Error_manager Ground_region::init(std::string configure_file)
-{
-    if(read_proto_param(configure_file,m_configure)==false)
-    {
-        return Error_manager(FAILED,NORMAL,"read proto failed");
-    }
-
-    pcl::PointCloud<pcl::PointXYZ>::Ptr left_model=ReadTxtCloud("/media/youchen/block_ntfs/yct/catkin_ws/src/feature_extra/left_model.txt");
-    // std::cout << "left model:" << left_model->size() << std::endl;
-    pcl::PointCloud<pcl::PointXYZ>::Ptr right_model = ReadTxtCloud("/media/youchen/block_ntfs/yct/catkin_ws/src/feature_extra/right_model.txt");
-    // std::cout << "right model:" << right_model->size() << std::endl;
-    m_detector=new detect_wheel_ceres3d(left_model,right_model);
-    // std::cout << "????" << std::endl;
-
-    return init(m_configure);
-
-}
-Error_manager Ground_region::init(ground_region::Configure configure)
-{
-    //绑定通讯ip
-    /*char connect_str[255]={0};
-    sprintf(connect_str,"tcp://%s:%d",configure.communication_cfg().ip().c_str(),
-            configure.communication_cfg().port());
-    Publisher::get_instance_pointer()->communication_bind(connect_str);
-    Publisher::get_instance_pointer()->communication_run();
-
-    //创建雷达
-    m_lidars.resize(configure.lidar_size());
-    for(int i=0;i<configure.lidar_size();++i)
-    {
-        const boost::asio::ip::address address = boost::asio::ip::address::from_string( configure.lidar(i).ip() );
-        const unsigned short port = configure.lidar(i).port();
-        m_lidars[i]=new velodyne::VLP16Capture(address,port);
-        if( !m_lidars[i]->isOpen() ){
-            char description[255]={0};
-            sprintf(description,"lidar [%d] open failed  ip:%s ,port:%d",i,configure.lidar(i).ip().c_str(),port);
-            return Error_manager(FAILED,NORMAL,description);
-        }
-    }
-*/
-    m_configure=configure;
-    m_running_thread=new std::thread(std::bind(thread_measure_func,this));
-    return SUCCESS;
+    m_detector = nullptr;
+    m_measure_thread = nullptr;
 }
 
-bool Ground_region::read_proto_param(std::string file, ::google::protobuf::Message& parameter)
-{
-    int fd = open(file.c_str(), O_RDONLY);
-    if (fd == -1) return false;
-    FileInputStream* input = new FileInputStream(fd);
-    bool success = google::protobuf::TextFormat::Parse(input, &parameter);
-    delete input;
-    close(fd);
-    return success;
-}
-
-pcl::PointCloud<pcl::PointXYZ>::Ptr Ground_region::scans2cloud(const velodyne::Frame& frame,
-        const ground_region::Calib_parameter& calib)
-{
-    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
-    for(int i=0;i<frame.scans.size();++i)
-    {
-        pcl::PointXYZ pt;
-
-    }
-    // 变换
-    Eigen::Matrix3d rotation_matrix3 ;
-    rotation_matrix3= Eigen::AngleAxisd(calib.r(), Eigen::Vector3d::UnitZ()) *
-            Eigen::AngleAxisd(calib.p(), Eigen::Vector3d::UnitY()) *
-            Eigen::AngleAxisd(calib.y(), Eigen::Vector3d::UnitX());
-
-    Eigen::Affine3d transform_2 = Eigen::Affine3d::Identity();
-    transform_2.translation() << calib.cx(),calib.cy(),calib.cz();
-    transform_2.rotate (rotation_matrix3);
-    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_transpose(new pcl::PointCloud<pcl::PointXYZ>);
-    pcl::transformPointCloud (*cloud, *cloud_transpose, transform_2);
-
-    return cloud_transpose;
-}
-
-Error_manager Ground_region::sync_capture(std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& clouds,double timeout_second)
+// deconstructor
+Ground_region::~Ground_region()
 {
-    Tick timer;
-    bool sync=false;
-    clouds.clear();
-    std::vector<velodyne::Frame>  sync_frames;
-    while((false==m_exit_condition.wait_for_ex(std::chrono::microseconds(1))) && sync==false)
-    {
-        bool sync_once=true;
-        for(int i=0;i<m_lidars.size();++i)
-        {
-            velodyne::Frame frame;
-            m_lidars[i]->get_frame(frame);
-            if(frame.tic.tic()>0.2)
-            {
-                sync_frames.clear();
-                sync_once=false;
-                break;
-            }
-            else
-            {
-                sync_frames.push_back(frame);
-            }
-        }
-        if(timer.tic()>timeout_second)
-        {
-            return Error_manager(FAILED,NORMAL,"sync capture time out");
-        }
-        sync=sync_once;
-        usleep(1);
-    }
-    if(sync)
-    {
-        for(int i=0;i<sync_frames.size();++i)
+    if(m_measure_thread){
+        m_measure_condition.kill_all();
+        // Close Capturte Thread
+        if (m_measure_thread->joinable())
         {
-            pcl::PointCloud<pcl::PointXYZ>::Ptr cloud=(scans2cloud(sync_frames[i],m_configure.lidar(i).calib()));
-            clouds.push_back(cloud);
+            m_measure_thread->join();
+            delete m_measure_thread;
+            m_measure_thread = nullptr;
         }
-        return SUCCESS;
     }
-    return FAILED;
-
 }
 
-Error_manager Ground_region::prehandle_cloud(std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& clouds,
-                                             message::Ground_measure_statu_msg& msg)
+Error_manager Ground_region::init(velodyne::Region region)
 {
-    if(msg.laser_statu_vector_size()!=m_lidars.size())
-        return ERROR;
-    //直通滤波
-    ground_region::Box box = m_configure.box();
-    std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> filtered_cloud_vector;
-    for (int i = 0; i < clouds.size(); ++i)
-    {
-        pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
-        for (int j = 0; j < clouds[i]->size(); ++j)
-        {
-            pcl::PointXYZ pt = clouds[i]->points[j];
-            if (pt.x > box.minx() && pt.x < box.maxx()
-                    && pt.y > box.miny() && pt.y < box.maxy()
-                    && pt.z > box.minz() && pt.z < box.maxz())
-            {
-                cloud_filtered->push_back(pt);
-            }
-        }
-        filtered_cloud_vector.push_back(cloud_filtered);
-    }
-    //根据点云判断雷达状态,若所有雷达滤波后都有点, 则正常,lidar_statu_bit 各个位代表雷达是否有点, 有点为0,无点为1
-    int lidar_statu_bit = 0;
-    for (int i = 0; i < filtered_cloud_vector.size(); ++i)
-    {
-        if (filtered_cloud_vector[i]->size() == 0)
-            lidar_statu_bit |= (0x01 << i);
-        else
-            msg.set_laser_statu_vector(i, message::LASER_READY);//雷达正常
-    }
-    if (lidar_statu_bit == 0)
-    {
-        clouds = filtered_cloud_vector;
-        return SUCCESS;
-    }
-
-    //判断是否有雷达故障
-    for (int i = 0; i < filtered_cloud_vector.size(); ++i)
-    {
-        if (filtered_cloud_vector[i]->size() == 0)
-        {
-            //滤波之前也没有点,雷达故障
-            if (clouds[i]->size() == 0)
-            {
-                clouds = filtered_cloud_vector;
-                msg.set_laser_statu_vector(i, message::LASER_DISCONNECT);
-                return Error_manager(DISCONNECT, NORMAL, "雷达故障");
-            }
-        }
-    }
-    //判断是不是所有雷达在该区域都没有点,表示该区域没有东西
-    int temp = 0;
-    if (~(((~temp) << (filtered_cloud_vector.size())) | lidar_statu_bit) == 0)
-    {
-        clouds = filtered_cloud_vector;
-        return Error_manager(POINT_EMPTY, NORMAL, "区域无点");
-    }
-    else
-    {
-        clouds = filtered_cloud_vector;
-        return Error_manager(CLOUD_INCOMPLETED, NORMAL, "点云不完整(雷达正常)");
-    }
-
+    m_region = region;
+    m_measure_thread = new std::thread(&Ground_region::thread_measure_func, this);
+    return SUCCESS;
 }
 
-
-bool computer_var(std::vector<double> data,double& var)
+// 计算均方误差
+bool computer_var(std::vector<double> data, double &var)
 {
-    if(data.size()==0)
+    if (data.size() == 0)
         return false;
-    Eigen::VectorXd  dis_vec(data.size());
-    for(int i=0;i<data.size();++i)
+    Eigen::VectorXd dis_vec(data.size());
+    for (int i = 0; i < data.size(); ++i)
     {
-        dis_vec[i]=data[i];
+        dis_vec[i] = data[i];
     }
-    double mean=dis_vec.mean();
+    double mean = dis_vec.mean();
     Eigen::VectorXd mean_vec(data.size());
-    Eigen::VectorXd mat=dis_vec-(mean_vec.setOnes()*mean);
-    Eigen::MatrixXd result=(mat.transpose())*mat;
-    var=sqrt(result(0)/double(data.size()));
+    Eigen::VectorXd mat = dis_vec - (mean_vec.setOnes() * mean);
+    Eigen::MatrixXd result = (mat.transpose()) * mat;
+    var = sqrt(result(0) / double(data.size()));
     return true;
-
 }
 
-
-Error_manager Ground_region::detect(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
-                                    const ground_region::Box& box,detect_wheel_ceres3d::Detect_result& last_result)
+Error_manager Ground_region::detect(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, detect_wheel_ceres3d::Detect_result &last_result)
 {
-    if(cloud->size()==0)
-        return Error_manager(POINT_EMPTY,NORMAL,"no point");
+    if (cloud->size() == 0)
+        return Error_manager(VELODYNE_REGION_EMPTY_CLOUD, NORMAL, "no point");
 
     pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
-    for(int i=0;i<cloud->size();++i)
+    for (int i = 0; i < cloud->size(); ++i)
     {
-        pcl::PointXYZ pt=cloud->points[i];
-        if(pt.x>box.minx()&&pt.x<box.maxx()
-        &&pt.y>box.miny()&&pt.y<box.maxy()
-        &&pt.z>box.minz()&&pt.z<box.maxz())
+        pcl::PointXYZ pt = cloud->points[i];
+        if (pt.x > m_region.minx() && pt.x < m_region.maxx() && pt.y > m_region.miny() && pt.y < m_region.maxy() && pt.z > m_region.minz() && pt.z < m_region.maxz())
         {
             cloud_filtered->push_back(pt);
         }
     }
-    if(cloud_filtered->size()==0)
-        return Error_manager(POINT_EMPTY,NORMAL,"filtered no point");
-
-    float start_z=box.minz();
-    float max_z=0.2;
-    float center_z=(start_z+max_z)/2.0;
-    float last_center_z=start_z;
-    float last_succ_z=-1.0;
-    int count=0;
+    if (cloud_filtered->size() == 0)
+        return Error_manager(VELODYNE_REGION_EMPTY_CLOUD, NORMAL, "filtered no point");
+
+    float start_z = m_region.minz();
+    float max_z = 0.2;
+    float center_z = (start_z + max_z) / 2.0;
+    float last_center_z = start_z;
+    float last_succ_z = -1.0;
+    int count = 0;
     //二分法 找识别成功的 最高的z
     std::vector<detect_wheel_ceres3d::Detect_result> results;
     do
     {
         detect_wheel_ceres3d::Detect_result result;
-        bool ret = classify_ceres_detect(cloud_filtered, center_z,result);
+        bool ret = classify_ceres_detect(cloud_filtered, center_z, result);
         // std::cout << "z: " << center_z <<", "<<start_z<<"," << max_z << std::endl;
-        if(ret)
+        if (ret)
         {
             results.push_back(result);
-            last_succ_z=center_z;
-            start_z=center_z;
-            last_center_z=center_z;
-
+            last_succ_z = center_z;
+            start_z = center_z;
+            last_center_z = center_z;
         }
         else
         {
-            max_z=center_z;
-            last_center_z=center_z;
-
+            max_z = center_z;
+            last_center_z = center_z;
         }
-        center_z=(start_z+max_z)/2.0;
+        center_z = (start_z + max_z) / 2.0;
         count++;
-        
+
     } while (fabs(center_z - last_center_z) > 0.01);
 
     //
-    if(results.size()==0)
+    if (results.size() == 0)
     {
-        return Error_manager(FAILED,NORMAL,"nor car");
+        return Error_manager(FAILED, NORMAL, "no car detected");
     }
     ///  to be
-    float min_mean_loss=1.0;
-    for(int i=0;i<results.size();++i)
+    float min_mean_loss = 1.0;
+    for (int i = 0; i < results.size(); ++i)
     {
-        detect_wheel_ceres3d::Detect_result result=results[i];
+        detect_wheel_ceres3d::Detect_result result = results[i];
         std::vector<double> loss;
         loss.push_back(result.loss.lf_loss);
         loss.push_back(result.loss.rf_loss);
         loss.push_back(result.loss.lb_loss);
         loss.push_back(result.loss.rb_loss);
-        double mean=(result.loss.lf_loss+result.loss.rf_loss+result.loss.lb_loss+result.loss.rb_loss)/4.0;
-        double var=-1.;
-        computer_var(loss,var);
-        if(mean<min_mean_loss)
+        double mean = (result.loss.lf_loss + result.loss.rf_loss + result.loss.lb_loss + result.loss.rb_loss) / 4.0;
+        double var = -1.;
+        computer_var(loss, var);
+        if (mean < min_mean_loss)
         {
-            last_result=result;
-            min_mean_loss=mean;
+            last_result = result;
+            min_mean_loss = mean;
         }
-
     }
     printf("z : %.3f  angle : %.3f front : %.3f wheel_base:%.3f,width:%.3f, mean:%.5f\n",
-           center_z,last_result.theta,last_result.front_theta,last_result.wheel_base,last_result.width,
+           center_z, last_result.theta, last_result.front_theta, last_result.wheel_base, last_result.width,
            min_mean_loss);
     //m_detector->save_debug_data("/home/zx/zzw/catkin_ws/src/feature_extra/debug");
     return SUCCESS;
 }
 
 #include "message/message_base.pb.h"
-void Ground_region::thread_measure_func(Ground_region* p)
+void Ground_region::thread_measure_func()
 {
-    return ;
-    message::Ground_measure_statu_msg msg;
-    message::Base_info base_info;
-    base_info.set_msg_type(message::eGround_measure_statu_msg);
-    base_info.set_sender(message::eEmpty);
-    base_info.set_receiver(message::eEmpty);
-    msg.mutable_base_info()->CopyFrom(base_info);
-    msg.set_ground_statu(message::Nothing);
-    const float fps=10.;
     //保持 10 fps
-    while(false==p->m_exit_condition.wait_for_millisecond(int(1000./fps)))
+    while (m_measure_condition.is_alive())
     {
-        for(int i=0;i<p->m_lidars.size();++i)
+        m_measure_condition.wait();
+        if (m_measure_condition.is_alive())
         {
-            msg.add_laser_statu_vector(
-                    p->m_lidars[i]->isRun()?message::LASER_READY:message::LASER_DISCONNECT);
+            //  to be 发布结果
+            msg.set_ground_statu(message::Car_correct);
+            message::Locate_information locate_information;
+            locate_information.set_locate_x(result.cx);
+            locate_information.set_locate_y(result.cy);
+            locate_information.set_locate_angle(result.theta);
+            locate_information.set_locate_wheel_base(result.wheel_base);
+            locate_information.set_locate_length(result.wheel_base);
+            locate_information.set_locate_wheel_width(result.width);
+            locate_information.set_locate_width(result.body_width);
+            locate_information.set_locate_front_theta(result.front_theta);
+            locate_information.set_locate_correct(true);
+
+            Communication_message c_msg;
+            c_msg.reset(msg.base_info(), msg.SerializeAsString());
+            Publisher::get_instance_pointer()->publish_msg(&c_msg);
         }
-
-        std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> clouds;
-        Error_manager code=p->sync_capture(clouds,0.5);
-        if(code!=SUCCESS)
-        {
-            LOG(WARNING)<<code.get_error_description();
-            continue;
-        }
-
-        Tick tick;
-        code=p->prehandle_cloud(clouds,msg);
-        if(code!=SUCCESS)
-        {
-            LOG(WARNING)<<code.get_error_description();
-            continue;
-        }
-        detect_wheel_ceres3d::Detect_result result;
-        pcl::PointCloud<pcl::PointXYZ>::Ptr correct_cloud(new pcl::PointCloud<pcl::PointXYZ>);
-        for(int i=0;i<clouds.size();++i)
-        {
-            *correct_cloud+=(*clouds[i]);
-        }
-        code=p->detect(correct_cloud,p->m_configure.box(),result);
-
-        if(tick.tic()>1./fps)
-        {
-            LOG(WARNING)<<" detect fps < capture fps";
-        }
-        if(code!=SUCCESS)
-        {
-            LOG_EVERY_N(INFO,20)<<code.get_error_description();
-            continue;
-        }
-
-        //  to be 发布结果
-        msg.set_ground_statu(message::Car_correct);
-        message::Locate_information locate_information;
-        locate_information.set_locate_x(result.cx);
-        locate_information.set_locate_y(result.cy);
-        locate_information.set_locate_angle(result.theta);
-        locate_information.set_locate_wheel_base(result.wheel_base);
-        locate_information.set_locate_length(result.wheel_base);
-        locate_information.set_locate_wheel_width(result.width);
-        locate_information.set_locate_width(result.body_width);
-        locate_information.set_locate_front_theta(result.front_theta);
-        locate_information.set_locate_correct(true);
-
-        Communication_message c_msg;
-        c_msg.reset(msg.base_info(),msg.SerializeAsString());
-        Publisher::get_instance_pointer()->publish_msg(&c_msg);
-
-
     }
 }
-
-
-

+ 45 - 54
velodyne_lidar/ground_region.h

@@ -5,68 +5,59 @@
 #ifndef LIDARMEASURE__GROUD_REGION_HPP_
 #define LIDARMEASURE__GROUD_REGION_HPP_
 
-#include "error_code/error_code.h"
-#include <opencv2/opencv.hpp>
+#include <thread>
+
+#include "../tool/thread_condition.h"
+#include "../tool/common_data.h"
+#include "../error_code/error_code.h"
 #include "match3d/detect_wheel_ceres3d.h"
-#include "configure.pb.h"
-#include "vlp16.hpp"
+#include "velodyne_config.pb.h"
+#include "message/measure_message.pb.h"
+
+#include <opencv2/opencv.hpp>
 #include <glog/logging.h>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
-#include <google/protobuf/text_format.h>
-#include <google/protobuf/message.h>
-#include "tool/thread_condition.h"
-using google::protobuf::Message;
-using google::protobuf::io::CodedInputStream;
-using google::protobuf::io::CodedOutputStream;
-using google::protobuf::io::FileInputStream;
-using google::protobuf::io::FileOutputStream;
-using google::protobuf::io::ZeroCopyInputStream;
-using google::protobuf::io::ZeroCopyOutputStream;
 
 #include <pcl/point_types.h>
 #include <pcl/point_cloud.h>
-#include "message/ground_measure_msg.pb.h"
 
 class Ground_region
 {
- public:
-    Ground_region();
-    ~Ground_region();
-    Error_manager init(std::string configure_file);
-    Error_manager init(ground_region::Configure configure);
-
-    Error_manager detect(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,const ground_region::Box& box,
-                         detect_wheel_ceres3d::Detect_result& result);
-
- private:
-    bool read_proto_param(std::string file, ::google::protobuf::Message& parameter);
-    Error_manager sync_capture(std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& cloud,double timeout_second=1.0);
-    pcl::PointCloud<pcl::PointXYZ>::Ptr scans2cloud(const velodyne::Frame& frame,const ground_region::Calib_parameter& calib);
-
-    //预处理点云, 并并判断雷达状态
-    Error_manager prehandle_cloud(std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& clouds,
-            message::Ground_measure_statu_msg& msg);
-    bool classify_ceres_detect(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,double thresh_z,
-                               detect_wheel_ceres3d::Detect_result& result);
-
-    static void thread_measure_func(Ground_region* p);
-
-    std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> segmentation(pcl::PointCloud<pcl::PointXYZ>::Ptr sor_cloud);
-    double distance(cv::Point2f p1, cv::Point2f p2);
-    bool isRect(std::vector<cv::Point2f>& points);
- private:
-
-    std::vector<velodyne::VLP16Capture*>     m_lidars;
- public:
-    ground_region::Configure                m_configure;
-    detect_wheel_ceres3d*                      m_detector;
- private:
-    std::thread*                            m_running_thread;
-    Thread_condition                        m_exit_condition;
-
-
-
+public:
+   Ground_region();
+   ~Ground_region();
+   // 区域类初始化
+   Error_manager init(velodyne::Region region);
+   // 公有检测函数,根据初始化设置的区域进行裁剪,并识别获得结果
+   Error_manager detect(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, detect_wheel_ceres3d::Detect_result &result);
+   // 公有点云更新函数,传入最新点云获得结果
+   Error_manager update_cloud(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud);
+
+private:
+   // 点云分类,z切,3d优化
+   bool classify_ceres_detect(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, double thresh_z,
+                              detect_wheel_ceres3d::Detect_result &result);
+   // 自动检测线程函数
+   void thread_measure_func();
+
+   std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> segmentation(pcl::PointCloud<pcl::PointXYZ>::Ptr sor_cloud);
+
+   double distance(cv::Point2f p1, cv::Point2f p2);
+
+   bool isRect(std::vector<cv::Point2f> &points);
+
+public:
+   velodyne::Region m_region;
+   detect_wheel_ceres3d *m_detector;
+
+private:
+   // 自动检测线程
+   std::thread *m_measure_thread;
+   Thread_condition m_measure_condition;
+
+   std::mutex*	 								mp_cloud_collection_mutex;       // 点云更新互斥锁, 内存由上级管理
+	pcl::PointCloud<pcl::PointXYZ>::Ptr 		mp_cloud_collection;			//扫描点的点云集合, 内存由上级管理
+	Common_data::Car_wheel_information			m_car_wheel_information;		//车轮的定位结果,
+	std::chrono::system_clock::time_point		m_detect_updata_time;			//定位结果的更新时间.
 };
 
-
 #endif //LIDARMEASURE__GROUD_REGION_HPP_

+ 0 - 1
velodyne_lidar/match3d/detect_wheel_ceres3d.cpp

@@ -435,7 +435,6 @@ bool detect_wheel_ceres3d::detect(std::vector<pcl::PointCloud<pcl::PointXYZ>::Pt
             detect_result.loss = t_loss_result;
             solve_result = current_result;
             loss_result = t_loss_result;
-
     }
 
     return solve_result;

+ 2 - 1
velodyne_lidar/match3d/hybrid_grid.hpp

@@ -24,10 +24,11 @@
 #include <vector>
 
 #include <Eigen/Core>
+#include <glog/logging.h>
+
 #include "common/math.h"
 #include "common/port.h"
 //#include "probability_values.h"
-#include "glog/logging.h"
 
 
 // Converts an 'index' with each dimension from 0 to 2^'bits' - 1 to a flat

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1339 - 70
velodyne_lidar/velodyne_config.pb.cc


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 974 - 25
velodyne_lidar/velodyne_config.pb.h


+ 25 - 1
velodyne_lidar/velodyne_config.proto

@@ -3,7 +3,10 @@ package velodyne;
 
 message velodyneManagerParams
 {
-
+    repeated velodyneLidarParams velodyne_lidars=1;
+    repeated Region region=2;
+    optional string fence_data_path=3 [default=""];
+    optional string fence_log_path=4 [default=""];
 }
 
 message velodyneLidarParams
@@ -17,4 +20,25 @@ message velodyneLidarParams
     optional int32 min_angle=7[default=0];
     optional int32 max_angle=8[default=360];
     optional int32 rpm=9[default=600];
+    optional Calib_parameter calib=10;
+}
+
+message Calib_parameter
+{
+    optional float r=1 [default=0];
+    optional float p=2 [default=0];
+    optional float y=3 [default=0];
+    optional float cx=4 [default=0];
+    optional float cy=5 [default=0];
+    optional float cz=6 [default=0];
+}
+
+message Region
+{
+    required float minx=1;
+    required float maxx=2;
+    required float miny=3;
+    required float maxy=4;
+    required float minz=5;
+    required float maxz=6;
 }

+ 14 - 14
velodyne_lidar/velodyne_driver/rawdata.h

@@ -46,15 +46,15 @@
 #include <errno.h>
 #include <stdint.h>
 #include <string>
-#include <boost/format.hpp>
 #include <math.h>
 #include <vector>
 #include <mutex>
 #include <atomic>
 #include <chrono>
 #include <glog/logging.h>
-#include <pcl/point_types.h>
-#include <pcl/point_cloud.h>
+#include <Eigen/Core>
+// #include <pcl/point_types.h>
+// #include <pcl/point_cloud.h>
 
 #include "calibration.h"
 
@@ -119,17 +119,17 @@ struct Lidar_point
   }
 };
 
-struct PointXYZIRT
-{
-  PCL_ADD_POINT4D;                // quad-word XYZ
-  float intensity;                ///< laser intensity reading
-  uint16_t ring;                  ///< laser ring number
-  float time;                     ///< laser time reading
-  EIGEN_MAKE_ALIGNED_OPERATOR_NEW // ensure proper alignment
-} EIGEN_ALIGN16;
-
-POINT_CLOUD_REGISTER_POINT_STRUCT(PointXYZIRT,
-                                  (float, x, x)(float, y, y)(float, z, z)(float, intensity, intensity)(uint16_t, ring, ring)(float, time, time))
+// struct PointXYZIRT
+// {
+//   PCL_ADD_POINT4D;                // quad-word XYZ
+//   float intensity;                ///< laser intensity reading
+//   uint16_t ring;                  ///< laser ring number
+//   float time;                     ///< laser time reading
+//   EIGEN_MAKE_ALIGNED_OPERATOR_NEW // ensure proper alignment
+// } EIGEN_ALIGN16;
+
+// POINT_CLOUD_REGISTER_POINT_STRUCT(PointXYZIRT,
+//                                   (float, x, x)(float, y, y)(float, z, z)(float, intensity, intensity)(uint16_t, ring, ring)(float, time, time))
 
 namespace velodyne_rawdata
 {

+ 12 - 0
velodyne_lidar/velodyne_driver/velodyne_lidar_device.cpp

@@ -82,6 +82,13 @@ Error_manager Velodyne_lidar_device::init(velodyne::velodyneLidarParams params)
 	m_velodyne_socket_status = E_UNKNOWN;
 	m_velodyne_protocol_status = E_UNKNOWN;
 
+	// 设置雷达内参矩阵
+	Eigen::AngleAxisd rot_x = Eigen::AngleAxisd(params.calib().r(), Eigen::Vector3d::UnitX());
+	Eigen::AngleAxisd rot_y = Eigen::AngleAxisd(params.calib().p(), Eigen::Vector3d::UnitY());
+	Eigen::AngleAxisd rot_z = Eigen::AngleAxisd(params.calib().y(), Eigen::Vector3d::UnitZ());
+	Eigen::Vector3d trans(params.calib().cx(), params.calib().cy(), params.calib().cz());
+	m_calib_matrix << rot_x.toRotationMatrix() * rot_y.toRotationMatrix() * rot_z.toRotationMatrix(), trans, 0.0, 0.0, 0.0, 1.0;
+
 	//唤醒队列
 	m_communication_data_queue.wake_queue();
 
@@ -558,6 +565,11 @@ void Velodyne_lidar_device::parse_thread_fun()
 						m_ring_cloud.clear();
 						m_ring_cloud = m_cloud_buf;
 						m_cloud_buf.clear();
+						// 对环点云进行内参变换
+						for (size_t i = 0; i < m_ring_cloud.size(); i++)
+						{
+							m_ring_cloud[i].transform(m_calib_matrix);
+						}
 						m_parse_ring_time = std::chrono::steady_clock::now();
 					}
 				}

+ 6 - 4
velodyne_lidar/velodyne_driver/velodyne_lidar_device.h

@@ -9,10 +9,10 @@
 #include <Eigen/Geometry>
 #include <thread>
 
-#include "../error_code/error_code.h"
-#include "../tool/binary_buf.h"
-#include "../tool/thread_safe_queue.h"
-#include "../tool/thread_condition.h"
+#include "../../error_code/error_code.h"
+#include "../../tool/binary_buf.h"
+#include "../../tool/thread_safe_queue.h"
+#include "../../tool/thread_condition.h"
 
 class Velodyne_lidar_device
 {
@@ -126,6 +126,8 @@ protected:
 	//点云解析线程
 	std::thread *mp_parse_thread; // 解析点云线程指针,内存由本类管理
 	Thread_condition m_parse_condition; // 解析点云条件变量
+	// 点云内参齐次矩阵
+	Eigen::Matrix4d m_calib_matrix;
 
 	//任务执行线程
 	std::thread*        						mp_execute_thread;   			//执行的线程指针,内存由本类管理

+ 2 - 2
velodyne_lidar/velodyne_driver/velodyne_lidar_scan_task.cpp

@@ -7,8 +7,8 @@
 //构造函数,构造函数锁定任务类型为LASER_TASK,后续不允许更改
 Velodyne_lidar_scan_task::Velodyne_lidar_scan_task()
 {
-	//构造函数锁定任务类型为 WANJI_LIDAR_SCAN,后续不允许更改
-	m_task_type = WANJI_LIDAR_SCAN;
+	//构造函数锁定任务类型为 VELODYNE_LIDAR_SCAN_TASK,后续不允许更改
+	m_task_type = Task_type::VELODYNE_LIDAR_SCAN;
 	m_task_statu = TASK_CREATED;
 	m_task_statu_information.clear();
 	m_task_error_manager.error_manager_clear_all();

+ 88 - 1
velodyne_lidar/velodyne_manager.cpp

@@ -2,6 +2,93 @@
  * @Description: 
  * @Author: yct
  * @Date: 2021-07-23 16:39:04
- * @LastEditTime: 2021-07-23 16:39:05
+ * @LastEditTime: 2021-07-28 16:29:13
  * @LastEditors: yct
  */
+#include "velodyne_manager.h"
+#include "../tool/proto_tool.h"
+
+//初始化 雷达 管理模块。如下三选一
+Error_manager Velodyne_manager::velodyne_manager_init()
+{
+    return velodyne_manager_init_from_protobuf(VELODYNE_MANAGER_PARAMETER_PATH);
+}
+
+//初始化 雷达 管理模块。从文件读取
+Error_manager Velodyne_manager::velodyne_manager_init_from_protobuf(std::string prototxt_path)
+{
+    velodyne::velodyneManagerParams t_velo_params;
+    if (!proto_tool::read_proto_param(prototxt_path, t_velo_params))
+    {
+        return Error_manager(WJ_MANAGER_READ_PROTOBUF_ERROR, MINOR_ERROR, "velodyne_manager read_proto_param  failed");
+    }
+
+    return velodyne_manager_init_from_protobuf(t_velo_params);
+}
+
+//初始化 雷达 管理模块。从protobuf读取
+Error_manager Velodyne_manager::velodyne_manager_init_from_protobuf(velodyne::velodyneManagerParams & velodyne_parameters)
+{
+    LOG(INFO) << " ---velodyne_manager_init_from_protobuf run--- "<< this;
+	Error_manager t_error;
+	if ( m_velodyne_manager_status != E_UNKNOWN)
+	{
+		return Error_manager(Error_code::WJ_MANAGER_INIT_ERROR, Error_level::MINOR_ERROR,
+							 " velodyne_manager::velodyne_manager_init_from_protobuf init repeat error ");
+	}
+
+	//创建雷达设备
+	int t_velodyne_lidar_size = velodyne_parameters.velodyne_lidars_size();
+	for(int i=0;i<t_velodyne_lidar_size;++i)
+	{
+		Velodyne_lidar_device* p_velodyne_lidar_device(new Velodyne_lidar_device);
+		t_error = p_velodyne_lidar_device->init(velodyne_parameters.velodyne_lidars(i));
+//		LOG(WARNING) << wanji_parameters.wj_lidar(i).DebugString();
+		if ( t_error != Error_code::SUCCESS )
+		{
+			delete(p_velodyne_lidar_device);
+			return t_error;
+		}
+		m_velodyne_lidar_device_map[i] = (p_velodyne_lidar_device);
+	}
+
+	//创建预测算法
+	int t_ground_region_size = velodyne_parameters.region_size;
+	for(int i=0;i<t_ground_region_size;++i)
+	{
+		Region_worker* p_region_worker(new Region_worker);
+		Point2D_tool::Point2D_box t_point2d_box;
+		t_point2d_box.x_min = wanji_parameters.regions(i).minx();
+		t_point2d_box.x_max = wanji_parameters.regions(i).maxx();
+		t_point2d_box.y_min = wanji_parameters.regions(i).miny();
+		t_point2d_box.y_max = wanji_parameters.regions(i).maxy();
+		// changed by yct, 传入终端index,仅普爱使用
+		t_error = p_region_worker->init(t_point2d_box, &m_cloud_collection_mutex, mp_cloud_collection, i);
+		if ( t_error != Error_code::SUCCESS )
+		{
+			delete(p_region_worker);
+			return t_error;
+		}
+		m_region_worker_map[i] = p_region_worker;
+	}
+
+
+
+	//启动 收集点云的线程。默认 。
+	m_collect_cloud_condition.reset(false, false, false);
+	mp_collect_cloud_thread = new std::thread(&Wanji_manager::collect_cloud_thread_fun, this);
+
+	//启动 执行的线程。默认 。
+	m_execute_condition.reset(false, false, false);
+	mp_execute_thread = new std::thread(&Wanji_manager::execute_thread_fun, this);
+
+	m_wanji_manager_status = E_READY;
+
+	return Error_code::SUCCESS;
+}
+
+// 反初始化
+Error_manager Velodyne_manager::Velodyne_manager_uninit()
+{
+    
+}

+ 51 - 4
velodyne_lidar/velodyne_manager.h

@@ -2,7 +2,7 @@
  * @Description: velodyne多线雷达管理类
  * @Author: yct
  * @Date: 2021-07-23 16:37:33
- * @LastEditTime: 2021-07-27 16:04:00
+ * @LastEditTime: 2021-07-28 16:10:45
  * @LastEditors: yct
  */
 
@@ -14,7 +14,10 @@
 #include "../tool/singleton.h"
 #include "../error_code/error_code.h"
 
-
+#include "./velodyne_driver/velodyne_lidar_device.h"
+#include "./ground_region.h"
+#include "velodyne_config.pb.h"
+#include "velodyne_manager_task.h"
 
 class Velodyne_manager : public Singleton<Velodyne_manager>
 {
@@ -50,16 +53,60 @@ public:
 	//初始化 雷达 管理模块。从文件读取
 	Error_manager velodyne_manager_init_from_protobuf(std::string prototxt_path);
 	//初始化 雷达 管理模块。从protobuf读取
-	Error_manager velodyne_manager_init_from_protobuf(wj::wjManagerParams& velodyne_parameters);
+	Error_manager velodyne_manager_init_from_protobuf(velodyne::velodyneManagerParams & velodyne_parameters);
 
     // 反初始化
     Error_manager Velodyne_manager_uninit();
 
+	//对外的接口函数,负责接受并处理任务单,
+	Error_manager execute_task(Task_Base* p_velodyne_manager_task);
+	//结束任务单,里面会根据任务的故障等级修正雷达管理模块的状态和任务单的状态
+	Error_manager end_task();
+	//取消任务单,由发送方提前取消任务单
+	Error_manager cancel_task(Task_Base* p_velodyne_manager_task);
+
+	//检查雷达状态,是否正常运行
+	Error_manager check_status();
+	//判断是否为待机,如果已经准备好,则可以执行任务。
+	bool is_ready();
+
+public://get or set member variable
+	Velodyne_manager_status get_status() { return m_velodyne_manager_status; }
+	std::map<int, Velodyne_lidar_device *> &get_velodyne_lidar_device_map() { return m_velodyne_lidar_device_map; }
+	std::map<int, Ground_region *> &get_ground_region_map() { return m_ground_region_map; }
+
+protected://member functions
+	//自动收集点云的线程函数
+	void collect_cloud_thread_fun();
+	//开始自动预测的算法线程
+	Error_manager start_auto_detect();
+	//关闭自动预测的算法线程
+	Error_manager stop_auto_detect();
+
+	//执行外界任务的执行函数
+	void execute_thread_fun();
+
 private:
     // 父类的构造函数必须保护,子类的构造函数必须私有。
     Velodyne_manager() = default;
 
-    
+	Velodyne_manager_status m_velodyne_manager_status; //velodyne管理状态
+
+	std::map<int, Velodyne_lidar_device *> 		m_velodyne_lidar_device_map; 		// velodyne雷达实例指针数组, 内存由本类管理
+	std::map<int, Ground_region *> 				m_ground_region_map;  			// 区域功能实例指针数组, 内存由本类管理
+
+	//velodyne雷达的自动功能, 定时收集所有点云, 然后通知detect去计算车轮信息.
+	std::mutex	 								m_cloud_collection_mutex;       // 点云更新互斥锁
+	pcl::PointCloud<pcl::PointXYZ>::Ptr 		mp_cloud_collection;			//扫描点的点云集合, 内存由本类管理
+	std::chrono::system_clock::time_point		m_cloud_updata_time;			//扫描点的更新时间.
+	std::thread*        						mp_collect_cloud_thread;   		//收集点云的线程指针,内存由本类管理
+	Thread_condition							m_collect_cloud_condition;		//收集点云的条件变量
+
+	//任务执行线程
+	std::thread*        						mp_execute_thread;   			//执行的线程指针,内存由本类管理
+	Thread_condition							m_execute_condition;			//执行的条件变量
+
+	Velodyne_manager_task*							mp_velodyne_manager_task;			//velodyne管理模块的任务单的指针,内存由发送方管理。
 };
 
 #endif // !VELODYNE_MANAGER_HH

+ 65 - 0
velodyne_lidar/velodyne_manager_task.cpp

@@ -0,0 +1,65 @@
+#include "velodyne_manager_task.h"
+
+
+Velodyne_manager_task::Velodyne_manager_task()
+{
+    m_task_type = Task_type::VELODYNE_MANAGER_TASK;
+	m_task_statu = TASK_CREATED;
+	m_task_statu_information.clear();
+	m_task_error_manager.error_manager_clear_all();
+
+	m_terminal_id = 0;
+}
+
+Velodyne_manager_task::~Velodyne_manager_task()
+{
+}
+
+//初始化函数
+Error_manager Velodyne_manager_task::task_init(int terminal_id, std::chrono::steady_clock::time_point command_time	)
+{
+	m_task_statu = TASK_CREATED;
+	m_task_statu_information.clear();
+	m_task_error_manager.error_manager_clear_all();
+
+	m_terminal_id = terminal_id;
+	m_command_time = command_time;
+
+	return Error_code::SUCCESS;
+}
+Error_manager Velodyne_manager_task::task_init(Task_statu task_statu,
+						std::string task_statu_information,
+						void* p_tast_receiver,
+						std::chrono::milliseconds task_over_time,
+						int terminal_id,
+						std::chrono::steady_clock::time_point command_time
+)
+{
+	m_task_statu = task_statu;
+	m_task_statu_information = task_statu_information;
+	mp_tast_receiver = p_tast_receiver;
+	m_task_over_time = task_over_time;
+	m_task_error_manager.error_manager_clear_all();
+
+	m_terminal_id = terminal_id;
+	m_command_time = command_time;
+
+	return Error_code::SUCCESS;
+}
+
+int Velodyne_manager_task::get_terminal_id()
+{
+	return m_terminal_id;
+}
+std::chrono::steady_clock::time_point Velodyne_manager_task::get_command_time()
+{
+	return m_command_time;
+}
+Common_data::Car_wheel_information Velodyne_manager_task::get_car_wheel_information()
+{
+	return m_car_wheel_information;
+}
+void Velodyne_manager_task::set_car_wheel_information(Common_data::Car_wheel_information car_wheel_information)
+{
+	m_car_wheel_information = car_wheel_information;
+}

+ 46 - 0
velodyne_lidar/velodyne_manager_task.h

@@ -0,0 +1,46 @@
+#ifndef WJ_LIDAR_TASK_HH
+#define WJ_LIDAR_TASK_HH
+#include <string.h>
+#include <mutex>
+#include <atomic>
+#include <chrono>
+
+#include "../task/task_command_manager.h"
+#include "../error_code/error_code.h"
+#include "../tool/common_data.h"
+
+
+//万集测量任务单
+class Velodyne_manager_task : public Task_Base
+{
+public:
+    // 构造函数
+	Velodyne_manager_task();
+    // 析构
+    ~Velodyne_manager_task();
+	//初始化函数
+	Error_manager task_init(int terminal_id, std::chrono::steady_clock::time_point command_time	);
+	Error_manager task_init(Task_statu task_statu,
+							std::string task_statu_information,
+							void* p_tast_receiver,
+							std::chrono::milliseconds task_over_time,
+							int terminal_id,
+							std::chrono::steady_clock::time_point command_time
+	);
+public://get or set member variable
+	int get_terminal_id();
+	std::chrono::steady_clock::time_point get_command_time();
+	Common_data::Car_wheel_information get_car_wheel_information();
+	void set_car_wheel_information(Common_data::Car_wheel_information car_wheel_information);
+
+private:
+	//终端id
+	int 										m_terminal_id;
+	//下发指令的时间点. 从command_time提前一个扫描周期, 然后取最新的点
+	std::chrono::steady_clock::time_point 		m_command_time;
+    // 测量结果
+    Common_data::Car_wheel_information			m_car_wheel_information;
+
+};
+
+#endif // !WJ_LIDAR_TASK_HH

+ 0 - 2
wanji_lidar/wanji_manager.h

@@ -106,8 +106,6 @@ protected://member variable
 	std::thread*        						mp_collect_cloud_thread;   		//收集点云的线程指针,内存由本类管理
 	Thread_condition							m_collect_cloud_condition;		//收集点云的条件变量
 
-
-
 	//任务执行线程
 	std::thread*        						mp_execute_thread;   			//执行的线程指针,内存由本类管理
 	Thread_condition							m_execute_condition;			//执行的条件变量